#include "assemblyDefinition.h"
#include "adskRepresentationFactory.h"
#include <maya/MPxRepresentation.h>
#include <maya/MFnAssembly.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnContainerNode.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnCompoundAttribute.h>
#include <maya/MStringArray.h>
#include <maya/MNamespace.h>
#include <maya/MGlobal.h>
#include <maya/MExternalContentInfoTable.h>
#include <maya/MExternalContentLocationTable.h>
#include <string>
#include <map>
#include <iostream>             
using namespace std;            
#define DIMOF(array) (sizeof(array)/sizeof((array)[0]))
namespace {
const char* const ICON_NAME = "out_assemblyDefinition.png";
const MString REPRESENTATIONS_ATTR_UINAME( 
"representations" );
 
const MString REPRESENTATIONS_ATTR_SHORTNAME( 
"rep" );
 
const MString REPRESENTATION_DATA_ATTR_UINAME( 
"repData" );
 
const MString REPRESENTATION_DATA_ATTR_SHORTNAME( 
"rda" );
 
typedef std::map<std::string, AdskRepresentationFactory*>
RepresentationFactories;
RepresentationFactories repFactories;
}
const MTypeId AssemblyDefinition::id(0x580000b2);
 
const MString AssemblyDefinition::typeName(
"assemblyDefinition");
 
MObject AssemblyDefinition::aRepresentations;
 
MObject AssemblyDefinition::aRepName;
 
MObject AssemblyDefinition::aRepLabel;
 
MObject AssemblyDefinition::aRepType;
 
MObject AssemblyDefinition::aRepData;
 
void* AssemblyDefinition::creator()
{
   return new AssemblyDefinition;
}
MStatus AssemblyDefinition::initRepresentations(
 
   eStorable storable,
)
{
   aRepData = stringAttrFn.
create(
      REPRESENTATION_DATA_ATTR_UINAME, REPRESENTATION_DATA_ATTR_SHORTNAME,
   
   aRepresentations = representationsAttrFn.
create(
      REPRESENTATIONS_ATTR_UINAME, REPRESENTATIONS_ATTR_SHORTNAME);  
   if (storable == kNotStorable) {
   }
   representationsAttrFn.
addChild(aRepName);
   representationsAttrFn.
addChild(aRepLabel);
   representationsAttrFn.
addChild(aRepType);
   representationsAttrFn.
addChild(aRepData);
   return stat;
}
MStatus AssemblyDefinition::initialize()
 
{
   
   MStatus stat = initRepresentations(
 
      kStorable, aRepresentations, aRepName, aRepLabel, aRepType, aRepData);
   return stat;
}
MStatus AssemblyDefinition::uninitialize()
 
{
   
   RepresentationFactories::iterator i = repFactories.begin();
   for (; i != repFactories.end(); ++i) {
      delete i->second;
   }
}
{
   RepresentationFactories::const_iterator i = repFactories.begin();
   for (; i != repFactories.end(); ++i) {
   }
   return repTypes;
}
bool AssemblyDefinition::registerRepresentationFactory(
   AdskRepresentationFactory* f
)
{
   if (f == 0 ||
       repFactories.find(f->getType().asChar()) != repFactories.end()) {
      return false;
   }
   repFactories[f->getType().asChar()] = f;
   return true;
}
bool AssemblyDefinition::deregisterRepresentationFactory(
)
{
   RepresentationFactories::iterator found = repFactories.find(type.
asChar());
   if (found == repFactories.end()) {
      return false;
   }
   delete found->second;
   repFactories.erase(found);
   return true;
}
 
AssemblyDefinition::AssemblyDefinition() : fActiveRep(0)
{}
AssemblyDefinition::~AssemblyDefinition()
{}
void AssemblyDefinition::getExternalContent(
) const
{
   const unsigned int nbReps = repNames.length();
      return;
   }
   
   
   
   
   
   
   
   
   
   
   const MString entryFormat( 
"^1s[^2s].^3s" );
 
   for (unsigned int i = 0; i < nbReps; ++i) {
      RepresentationPtr rep( representationFactory( repNames[ i ] ) );
      if ( rep.get() == 0 ) {
         continue;
      }
      rep->getExternalContent( repTable );
      if ( repTable.
length() == 0 ) {
 
         continue;
      }
      
      
      
      
              0, unusedKey, unresolvedLocation, resolvedLocation, contextNodeFullName, roles ) !=
         continue;
      }
      plugIndex += i;
      entryName.
format( entryFormat, REPRESENTATIONS_ATTR_UINAME,
                        plugIndex, REPRESENTATION_DATA_ATTR_UINAME );
         entryName, unresolvedLocation, resolvedLocation, contextNodeFullName, roles );
   }
}
void AssemblyDefinition::setExternalContent(
)
{
   const unsigned int nbReps = repNames.length();
      return;
   }
    
   const unsigned int nbEntries = table.
length();
 
   for (unsigned int i = 0; i < nbEntries; ++i) {
      
      
      
      
      
      
      
      
      const int openingBracketIdx = key.
index( 
'[' );
 
      const int closingBracketIdx = key.
index( 
']' );
 
      if ( openingBracketIdx < 0 || closingBracketIdx < 0 ) {
         
         continue;
      }
         key.
substring( openingBracketIdx + 1, closingBracketIdx - 1 ) );
      
      const unsigned int repIdx = repIdxStr.
asUnsigned();
 
      if ( repIdx >= nbReps ) {
         continue;
      }
      std::auto_ptr< MPxRepresentation > rep(
         representationFactory( repNames[ repIdx ] ) );
      if ( rep.get() == 0 ) {
         continue;
      }
      
      
      
      
      rep->setExternalContent( repTable );
      
      
      
      if(repNames[ repIdx ] == oldActive)
      {
        activate(oldActive);
      }
   }
}
MString AssemblyDefinition::createRepresentation(
 
)
{
   
   RepresentationFactories::const_iterator found =
      repFactories.find(type.
asChar());
   if (found == repFactories.end()) {
   }
   const AdskRepresentationFactory* const repFactory = found->second;
   
       representation :
       repFactory->creationName(this, input);
   
   
   }
   
   performCreateRepresentation(
      newRepName,                             
      type,                                   
      repFactory->creationLabel(this, input), 
      repFactory->creationData(this, input)   
   );
   
   return newRepName;
}
bool AssemblyDefinition::inactivateRep()
{
   
      bool returnVal = fActiveRep.get() ? fActiveRep->inactivate(): false;      
      if (!returnVal) {
         return false;
      }
      
      fActiveRep = RepresentationPtr();
   }
   return true;
}
bool AssemblyDefinition::activateRep(
const MString& representation)
 
{
   
      fActiveRep = RepresentationPtr(representationFactory(representation));
      return fActiveRep.get() ?  fActiveRep->activate() : false;
   }
   return true;
}
   
MString AssemblyDefinition::getActive()
 const 
{
   return fActiveRep.get() ? fActiveRep->getName() : 
MString();
 
}
{
   MPlug representationsPlug(thisMObject(), aRepresentations);
 
   for (int i=0; i<static_cast<int>(representationsPlug.numElements()); ++i) {
      MPlug representationPlug = representationsPlug[i];
 
      MPlug namePlug = representationPlug.
child(aRepName);
 
          
          
          break;
      }
      
   }
   
   
   if (status != 0) {
   }
   return representations;
}
{
   return getRepAttrValue(repName, aRepType);
}
{
   return getRepAttrValue(repName, aRepLabel);
}
{
   return getRepAttrValue(repName, aRepData);
}
void AssemblyDefinition::setRepData(
)
{
   setRepAttrValue( repName, aRepData, data );
}
MString AssemblyDefinition::getRepNamespace()
 const 
{
   
}
{
   
   
   
   
   return registeredTypes();
}
MStatus AssemblyDefinition::deleteRepresentation(
const MString& repName)
 
{   
   
   MPlug representationsPlug(thisMObject(), aRepresentations);
 
   const int numElements = static_cast<int>(representationsPlug.numElements());
   static MObject attribs[] = {aRepName, aRepData, aRepLabel, aRepType};
 
   for (int i=0; i<numElements; ++i) 
   {
      MPlug representationPlug = representationsPlug[i];
 
      MPlug namePlug = representationPlug.
child(aRepName);
 
      if (value == repName) {       
         
         
         
         
         for (int j = i + 1 ; j < numElements; j++)
         {          
            for (int k = 0; k < DIMOF(attribs); ++k){
               representationsPlug[j].child(attribs[k]).getValue(value);
               representationsPlug[j-1].child(attribs[k]).setValue(value);               
            }           
         }  
         
         MString cmd(
"removeMultiInstance -b true ");
 
         cmd += representationsPlug[numElements-1].name();
                
         break;
      }
   }
   return status;
}
MStatus AssemblyDefinition::deleteAllRepresentations()
 
{  
   clearRepresentationList();
   MPlug representationsPlug(thisMObject(), aRepresentations);
 
}
) const
{
   MString repType = getRepType(name);
 
      MString repData = getRepData(name);
 
      RepresentationFactories::const_iterator found =
         repFactories.find(repType.
asChar());
      if (found != repFactories.end()) {
         
         
         return found->second->create(
            const_cast<AssemblyDefinition*>(this), name, repData);
      }
   }
   return 0;
}
void AssemblyDefinition::postLoad()
{
   
   const int len = representations.
length();
 
      return;
   }
   
   
   
   
   if (!aFn.canActivate()) {
      return;
   }
   
   
   aFn.activate(representations[0]);
}
MString AssemblyDefinition::getDefaultIcon()
 const 
{
}
void AssemblyDefinition::postConstructor()
{
   
   MPlug iconName = 
self.findPlug(
MString(
"iconName"), 
true, &status);
 
      return;
   }
}
void AssemblyDefinition::clearRepresentationList()
{
   MPlug representationsPlug(thisMObject(), aRepresentations);
 
   for (int i=0; i<static_cast<int>(representationsPlug.numElements()); ++i) {
      representations.
append(representationsPlug[i].name());
   }   
   for (
int i=0; i<static_cast<int>(representations.
length()); ++i) {
 
      MString cmd(
"removeMultiInstance -b true ");
 
      cmd += representations[i];
   }   
}
void AssemblyDefinition::performCreateRepresentation(
)
{
   MPlug representationsPlug(thisMObject(), aRepresentations);
 
   int nbElements = representationsPlug.numElements();
   representationsPlug.selectAncestorLogicalIndex(nbElements, aRepresentations);
   MPlug namePlug = representationsPlug.
child(aRepName);
 
   MPlug labelPlug = representationsPlug.
child(aRepLabel);
 
   
   MPlug typePlug = representationsPlug.
child(aRepType);
 
   MPlug dataPlug = representationsPlug.
child(aRepData);
 
}
MString AssemblyDefinition::getRepAttrValue(
 
) const
{
   }
   MPlug representationsPlug(thisMObject(), aRepresentations);
 
   
   
   const int numElements = static_cast<int>(representationsPlug.numElements());
   for (int i=0; i<numElements; ++i) {
      MPlug representationPlug = representationsPlug[i];
 
      MPlug namePlug = representationPlug.
child(aRepName);
 
      if (name == repName) {
         MPlug dataPlug = representationPlug.
child(repAttr);
 
         break;
      }
   }
   return data;
}
MStatus AssemblyDefinition::setRepAttrValue(
 
)
{
   }
   MPlug representationsPlug(thisMObject(), aRepresentations);
 
   
   
   const int numElements = static_cast<int>(representationsPlug.numElements());
   for (int i=0; i<numElements; ++i) {
      MPlug representationPlug = representationsPlug[i];
 
      MPlug namePlug = representationPlug.
child(aRepName);
 
      if (name == repName) {
         MPlug dataPlug = representationPlug.
child(repAttr);
 
         break;
      }
   }
}
MString AssemblyDefinition::setRepName(
 
)
{
    MStatus s = setRepAttrValue(repName, aRepName, newName);
 
    if (status) *status = s;
    return newName;
}
MStatus AssemblyDefinition::setRepLabel(
 
)
{
   return setRepAttrValue(repName, aRepLabel, label);
}
bool AssemblyDefinition::canRepApplyEdits(
const MString& representation)
 const 
{
      return false;
   }
   
   
   if (getActive() != representation || fActiveRep.get() == 0) {
      RepresentationPtr ptr(representationFactory(representation));
      return (ptr.get() == 0 ? false : ptr->canApplyEdits());
   }
   return fActiveRep->canApplyEdits();
}