#include "util.h"
#include <maya/MAnimControl.h>
#include <maya/MDGModifier.h>
#include <maya/MPlugArray.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnTransform.h>
#include <maya/MFnSet.h>
#include <maya/MItDag.h>
#include <maya/MSelectionList.h>
#include <maya/MStringArray.h>
#include <maya/MObjectArray.h>
#include <maya/MTime.h>
#include <maya/MItDependencyGraph.h>
#include <algorithm>
{
                                        &status);
    {
        MString theError(
"Could not create shading engine: ");
 
        theError += iName;
        return shadingGroup;
    }
    return shadingGroup;
}
{
    
    
    
        return connSG;
    
    itDG.enablePruningOnFilter();
    
    for( ; itDG.isDone()!= true; itDG.next() )
        connSG.
append( itDG.thisNode() );
    return connSG;
}
{
    {
        unsigned int numChild = mFnOld.childCount();
        std::vector<MObject> children;
        children.reserve(numChild);
        for (unsigned int i = 0; i < numChild; i++)
        {
            MObject child = mFnOld.child(i, &status);
 
            {
                children.push_back(child);
            }
            else
            {
                MString theError(
"Failed to get child ");
 
                theError += i;
                theError += " of ";
                theError += mFnOld.name();
                theError += ", status = ";
            }
        }
        {
            for (unsigned int i = 0; i < numChild; i++)
            {
                status = mFnNew.addChild(children[i]);
                {
                    MString theError(
"Failed to add child ");
 
                    theError += i;
                    theError += " of ";
                    theError += mFnOld.name();
                    theError += " to ";
                    theError += name;
                    theError += ", status = ";
                }
            }
        }
    }
    return status;
}
    std::vector<Prop> & iSampledPropList,
    std::size_t iFirstProp)
{
    
    
    std::size_t numProps = iSampledPropList.size();
    for (std::size_t i = iFirstProp; i < numProps; ++i)
    {
        std::string propName;
        if (iSampledPropList[i].mArray.valid())
        {
            propName = iSampledPropList[i].mArray.getName();
        }
        else
        {
            propName = iSampledPropList[i].mScalar.getName();
        }
        
        if (propName == Alembic::AbcGeom::kVisibilityPropertyName)
        {
        }
        else
        {
            dstPlug = iNode.
findPlug(propName.c_str());
        }
        
        if (propName == Alembic::AbcGeom::kVisibilityPropertyName ||
            dstPlug.
partialName(
false, 
false, 
false, 
false, 
false, 
true) == propName.c_str())
        {
            disconnectAllPlugsTo(dstPlug);
        }
    }
}
{
    unsigned int arrayLength = array.
length();
 
    for (unsigned int i = 0; i < arrayLength; i++)
    {
        MPlug srcPlug = array[i];
 
        {
            status = modifier.
doIt();
            {
                theError += srcPlug.
name();
                theError += dstPlug.
name();
                theError += 
MString(
" failed, status = ");
                return status;
            }
        }
    }
}
    std::vector<MDagPath> & dagPathList)
{
    status = objectNames.
split(
' ', theArray);
    {
        unsigned int len = theArray.
length();
 
        for (unsigned int i = 0; i < len; i++)
        {
            status = getDagPathByName(theArray[i], dagPath);
                dagPathList.push_back(dagPath);
            else
            {
                theError += 
MString(
" doesn't exist");
            }
        }
    }
    return status;
}
{
    {
    }
    return status;
}
{
    {
    }
    return status;
}
std::string stripPathAndNamespace(const std::string & iPath)
{
    std::string childName;
    std::size_t lastPath = iPath.rfind('|');
    if (lastPath != std::string::npos)
    {
        childName =  iPath.substr(lastPath + 1);
    }
    else
    {
        childName = iPath;
    }
    std::size_t lastNamespace = childName.rfind(':');
    if (lastNamespace != std::string::npos)
    {
        childName = childName.substr(lastNamespace+1);
    }
    return childName;
}
bool getDagPathByChildName(
MDagPath & ioDagPath, 
const std::string & iChildName)
 
{
    unsigned int numChildren = ioDagPath.
childCount();
 
    std::string strippedName = stripPathAndNamespace(iChildName);
    for (unsigned int i = 0; i < numChildren; ++i)
    {
        std::string name = dagChild.partialPathName().
asChar();
        if (name == iChildName)
        {
            return true;
        }
        {
            if (strippedName == stripPathAndNamespace(name))
            {
                closeMatch = child;
            }
        }
    }
    {
        ioDagPath.
push(closeMatch);
        return true;
    }
    return false;
}
{
    MStatus status = getObjectByName(objName, 
object);
 
    {
            plug = mFn.findPlug(attrName, &status);
    }
    return status;
}
MStatus setPlayback(
double min, 
double max)
 
{
    MTime minTime, maxTime, curTime;
 
    if (max > 0)
    {
    }
    return status;
}
{
    if (getObjectByName(
"initialShadingGroup", initShader) == 
MS::kSuccess &&
 
    {
        set.addMember(dagPath);
    }
    else
    {
        MString theError(
"Error getting adding ");
 
        theError += dagNodeName;
        theError += 
MString(
" to initalShadingGroup.");
    }
}
{
}
{
    status = modifier.
doIt();
    return status;
}
{
    std::string str(filePath.
asChar());
    size_t found;
    found = str.find_last_of("/\\");
    str = str.substr(found+1);
    
    found = str.find_first_of(".");
    str = str.substr(0, found);
    return true;
}
double getWeightAndIndex(double iFrame,
    Alembic::AbcCoreAbstract::TimeSamplingPtr iTime, size_t numSamps,
    Alembic::AbcCoreAbstract::index_t & oIndex,
    Alembic::AbcCoreAbstract::index_t & oCeilIndex)
{
    if (numSamps == 0)
        numSamps = 1;
    std::pair<Alembic::AbcCoreAbstract::index_t, double> floorIndex =
        iTime->getFloorIndex(iFrame, numSamps);
    oIndex = floorIndex.first;
    oCeilIndex = oIndex;
    if (fabs(iFrame - floorIndex.second) < 0.0001)
        return 0.0;
    std::pair<Alembic::AbcCoreAbstract::index_t, double> ceilIndex =
        iTime->getCeilIndex(iFrame, numSamps);
    if (oIndex == ceilIndex.first)
        return 0.0;
    oCeilIndex = ceilIndex.first;
    double alpha = (iFrame - floorIndex.second) /
        (ceilIndex.second - floorIndex.second);
    
    if (fabs(1.0 - alpha) < 0.0001)
    {
        oIndex = oCeilIndex;
        return 0.0;
    }
    return alpha;
}
bool isColorSet(const Alembic::AbcCoreAbstract::PropertyHeader & iHeader,
    bool iUnmarkedFaceVaryingColors)
{
    bool isColor = Alembic::AbcGeom::IC3fGeomParam::matches(iHeader) ||
            Alembic::AbcGeom::IC4fGeomParam::matches(iHeader);
    Alembic::AbcGeom::GeometryScope scope =
        Alembic::AbcGeom::GetGeometryScope(iHeader.getMetaData());
    bool isScoped = (scope == Alembic::AbcGeom::kFacevaryingScope ||
                     scope == Alembic::AbcGeom::kVaryingScope ||
                     scope == Alembic::AbcGeom::kVertexScope);
    return (isColor && isScoped &&
            (iUnmarkedFaceVaryingColors ||
            iHeader.getMetaData().get("mayaColorSet") != ""));
}