#include "assemblyReference.h"
#include "sceneAssemblyStrings.h"
#include "assemblyReferenceInitialRep.h"
#include <maya/MPxRepresentation.h>
#include <maya/MFnAssembly.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnCompoundAttribute.h>
#include <maya/MFnContainerNode.h>
#include <maya/MObjectArray.h>
#include <maya/MFileIO.h>
#include <maya/MGlobal.h>
#include <maya/MNamespace.h>
#include <maya/MExternalContentInfoTable.h>
#include <maya/MExternalContentLocationTable.h>
#include <cassert>
#include <iostream>             
using namespace std;            
namespace {
const char* const ICON_NAME = "out_assemblyReference.png";
const MString DEFINITION_FILE_ATTR_UINAME( 
"definition" );
 
const MString DEFINITION_FILE_ATTR_SHORTNAME( 
"def" );
 
bool isAssemblyDefinition(
MObject& obj)
 
{
   
   
   
   return fn.
typeId() == AssemblyDefinition::id;
 
}
}
const MTypeId AssemblyReference::id(0x580000b1);
 
const MString AssemblyReference::typeName(
"assemblyReference");
 
MObject AssemblyReference::aDefnFile;
 
MObject AssemblyReference::aRepNamespace;
 
MObject AssemblyReference::aRepresentations;
 
MObject AssemblyReference::aRepName;
 
MObject AssemblyReference::aRepLabel;
 
MObject AssemblyReference::aRepType;
 
MObject AssemblyReference::aRepData;
 
MObject AssemblyReference::aInitialRep;
 
void* AssemblyReference::creator()
{
   return new AssemblyReference;
}
MStatus AssemblyReference::initialize()
 
{
   
   
   
   
   MStatus stat = initRepresentations(
 
      kNotStorable, aRepresentations, aRepName, aRepLabel, aRepType, aRepData);
   aDefnFile = defnFileAttrFn.
create(
      DEFINITION_FILE_ATTR_UINAME, DEFINITION_FILE_ATTR_SHORTNAME,
   
   
   
   
   return stat;
}
MStatus AssemblyReference::uninitialize()
 
{
}
AssemblyReference::AssemblyReference() 
    : BaseNode()
    , fDefnFile()
    , fUseDefnFileAttrib(true)
    , fInitialRep(NULL)
    , fUpdatingRepNamespace(false)
{}
AssemblyReference::~AssemblyReference()
{
    
    
    assert(NULL == fInitialRep);
}
MString AssemblyReference::createRepresentation(
 
)
{
    
    if (status != NULL) {
    }
}
void AssemblyReference::getExternalContent(
) const
{
   
   
   
}
void AssemblyReference::setExternalContent(
)
{
   
   
   
   
   if ( !table.
getLocation( DEFINITION_FILE_ATTR_UINAME, location ) ) {
 
      return;
   }
   MPlug defnPlug(thisMObject(), aDefnFile);
 
   defnPlug.setValue(location);
}
{
   
   
   
   
   
}
void AssemblyReference::copyInternalData(
MPxNode* srcNode)
 
{
    assert(dynamic_cast<AssemblyReference*>(srcNode) != 0);
    AssemblyReference* srcAssembly = static_cast<AssemblyReference*>(srcNode);
    fDefnFile           = srcAssembly->fDefnFile;
    fUseDefnFileAttrib  = srcAssembly->fUseDefnFileAttrib;
    fDefnFileCacheEntry = srcAssembly->fDefnFileCacheEntry;
}
bool AssemblyReference::setInternalValueInContext(
)
{
    if (plug == aDefnFile ) {
        
        
        
        
            return false;
        }
        
        
        fUseDefnFileAttrib = false;
        
        
        
        aFn.postLoad();    
        fUseDefnFileAttrib = true;      
    }
    else if( plug == aRepNamespace && !fUpdatingRepNamespace) {
        
        
        
        
        
        
        
        
        
        
        
        
        
        {
            return false;
        }
        
        }
        
        
        
            return false;
        }
            
        }
        if (validNewNS != newNS)
        {
            
            newNS = validNewNS;
            nonConstHandle->
set(newNS);
        }
        
                
                
                
                
                nonConstHandle->
set(oldNS);
            }
        }
   }
   return false;
}
void AssemblyReference::beforeSave()
{
   
   
   
   
   
   assemblyReferenceInitialRep saveRep;
   saveRep.writer(thisMObject()); 
}
MString AssemblyReference::getInitialRep(
const MObject &assembly, 
bool& hasInitialRep, 
MStatus* status)
 const 
{
    
    
    if (fInitialRep)
    {
        return fInitialRep->getInitialRep(assembly, hasInitialRep);
    }  
    
}
void AssemblyReference::postLoad()
{
   
   clearRepresentationList();
   
   
   MString defnFile = getDefinitionFile();
 
      
      
      aFn.activate("");
      return;
   }
   
   
   
   
   
   AssemblyDefinitionFileCache& cache =
       AssemblyDefinitionFileCache::getInstance();
   fDefnFileCacheEntry = cache.get(defnFile);
   if (!fDefnFileCacheEntry) {
       const bool fileIgnoreVersion =
       
           defnFile, NULL , false ,
           NULL , fileIgnoreVersion);
           definitionError(rAssemblyDefnImportError);
           return;
       }
       
       
       
       
       
       
       
       
       clearRepresentationList();
       
       
       
       status = contFn.getMembers(members);
           definitionError(rAssemblyDefnNotFoundError);
           return;
       }
       
       
       
       const int nbMembers = 
static_cast<int>(members.
length());
 
       int found = nbMembers;
       int nbFound = 0;
       for (int i=0; i<nbMembers; ++i) {
           if (isAssemblyDefinition(members[i])) {
               found = i;
               ++nbFound;
           }
       }
       if (found==nbMembers) {
           definitionError(rAssemblyDefnNotFoundError);
           return;
       }
       else if (nbFound > 1) {
           definitionError(rMultAssemblyDefnFoundError);
           return;
       }
       
       
       MStringArray defnRepresentations = defnFn.getRepresentations(&status);
 
       const int nbReps = defnRepresentations.
length();
 
           const AssemblyDefinition* defn =
               dynamic_cast<AssemblyDefinition*>(defnFn.userNode());
           
           assert(defn != 0);
           AssemblyDefinitionFileCache::RepCreationArgsList repCreationArgsList;
           for (int i=0; i<nbReps; ++i) {
               const MString repName = defnRepresentations[i];
 
               repCreationArgsList.push_back(
                   AssemblyDefinitionFileCache::RepresentationCreationArgs(
                       repName,
                       defn->getRepType(repName),
                       defn->getRepLabel(repName),
                       defn->getRepData(repName)));
           }
           fDefnFileCacheEntry = cache.
insert(defnFile, repCreationArgsList);
       }
   
       
           return;
       }
   }
   
   
   
   const AssemblyDefinitionFileCache::RepCreationArgsList& repCreationArgslist =
       fDefnFileCacheEntry->getRepCreationArgsList();
   {
       AssemblyDefinitionFileCache::RepCreationArgsList::const_iterator it  =
           repCreationArgslist.begin();
       AssemblyDefinitionFileCache::RepCreationArgsList::const_iterator end =
           repCreationArgslist.end();
       for (;it != end; ++it) {
           performCreateRepresentation(
               it->getName(), it->getType(), it->getLabel(), it->getData());
       }
   }
   
   
   
   
   if(!aFn.isTopLevel())
   {
       MPlug repNamespacePlug(thisMObject(), aRepNamespace);
 
       repNamespacePlug.setLocked(true);
   }
   
   
   if (!aFn.canActivate()) {
      return;
   }
   
   
   
   
   
   
   
   
   
   
   assert(fInitialRep == NULL);
   if (aFn.isTopLevel())
   {
       fInitialRep = new assemblyReferenceInitialRep();
       fInitialRep->reader(thisMObject());
   }
   
   if (!repCreationArgslist.empty()) {
       
       
       
       
       bool hasInitialRep = false;
       MString initialRep = aFn.getInitialRep(hasInitialRep);       
 
       if (!hasInitialRep)
       {
           
           
           initialRep = repCreationArgslist.front().getName();
       }
       
       
       aFn.activate(initialRep);
   }
   
   if (fInitialRep)
   {
       fInitialRep->
clear(thisMObject());
       delete fInitialRep;
       fInitialRep = NULL;
   }
}
MString AssemblyReference::getDefaultIcon()
 const 
{
}
MString AssemblyReference::getDefinitionFile()
 const 
{
   if (fUseDefnFileAttrib) {
      MPlug defnPlug(thisMObject(), aDefnFile);
 
      defnPlug.getValue(defnFile);
   }
   return defnFile;
}
{
   
   
   const MString defnFile = getDefinitionFile();
 
   errorString.
format(errorString, defnFile, contFn.name());
   contFn.clear();
}
MStatus AssemblyReference::deleteRepresentation(
const MString& repName)
 
{    
   
}
MStatus AssemblyReference::deleteAllRepresentations()
 
{  
   
}
MString AssemblyReference::getRepNamespace()
 const 
{
    MPlug repNamespacePlug(thisMObject(), aRepNamespace);
 
    repNamespacePlug.getValue(repNamespaceStr);
       
    if ( !repNamespaceStr.
length() ) {
 
        
            
        
        repNamespacePlug.setValue(repNamespaceStr);
    }
   
   
   
   assert ( repNamespaceStr.
length() > 0 );
   return repNamespaceStr;
}
void AssemblyReference::updateRepNamespace( 
const MString& repNamespace )
 
{
   MPlug repNamespacePlug(thisMObject(), aRepNamespace);
 
   repNamespacePlug.getValue(repCurrentNamespaceStr);
   bool prevVal = fUpdatingRepNamespace;
   fUpdatingRepNamespace = true;
   
   repNamespacePlug.setValue(repNamespace);
   
   fUpdatingRepNamespace = prevVal;
}
bool AssemblyReference::supportsEdits() const
{
    
    return true;
}