#include "meshMapUtils.h"
#include "meshReorderCmd.h"
#include <maya/MArgList.h>
#include <maya/MDagPathArray.h>
#include <maya/MFnMesh.h>
#include <maya/MFnMeshData.h>
#include <maya/MFnNumericData.h>
#include <maya/MIOStream.h>
#include <maya/MItSelectionList.h>
#include <maya/MItMeshVertex.h>
#include <maya/MPlug.h>
#include <maya/MString.h>
meshReorderCommand::meshReorderCommand()
{
    fClampedArray = NULL;
    fRepArray = NULL;
    fColorArrays = NULL;
    fVertexColorArrays = NULL;
    fColorIdsArrays = NULL;
    fUArrays = NULL;
    fVArrays = NULL;
    fUVIdsArrays = NULL;
}
meshReorderCommand::~meshReorderCommand()
{
    resetColorsUVsMemory();
}
void* meshReorderCommand::creator()
{
    return new meshReorderCommand;
}
{
    {
        displayError("3 vertices must be specified");
    }
    int argIdx = 0;
    for (unsigned int j = 0; j < 3; j++)
    {
        {
            displayError( "Can't parse arg");
            return stat;
        }
        {
            err = arg + ": no such component";
            displayError(err);
        }
        if (selectionIt.isDone ())
        {
            err = arg + ": not a component";
            displayError (err);
        }
        if( selectionIt.getDagPath (selectedPath[j], selectedComponent[j]) != 
MStatus::kSuccess )
 
        {
            displayError( "Can't get path for");
            return stat;
        }
        {
            err = arg + ": Invalid type!  Only a mesh or its transform can be specified!";
            displayError (err);
        }
        argIdx++;
    }
    if( ( stat = meshMapUtils::validateFaceSelection( selectedPath, selectedComponent, &fFaceIdxSrc, &fFaceVtxSrc ) ) != 
MStatus::kSuccess )
 
    {
        displayError("Selected vertices don't define a unique face on source mesh");
        return stat;
    }
    fDagPathSrc = selectedPath[0];
    return stat;
}
{
    {
        displayError ("Error parsing arguments");
        return stat;
    }
    return redoIt();
}
MStatus meshReorderCommand::redoIt()
 
{
    unsigned i;
    MFnMesh theMesh( fDagPathSrc, &stat );
 
    {
        displayError(" MFnMesh creation");
        return stat;
    }
    
    MPlug   historyPlug = theMesh.findPlug(
"inMesh", 
true);
 
        displayError("The mesh has history. Its geometry cannot be modified.");
    }
    {
        displayError(" MFnMesh getPoints");
        return stat;
    }
    
    MIntArray           faceTraversal( theMesh.numPolygons(), false );
 
    MIntArray cvMapping(theMesh.numVertices(), -1);
 
    MIntArray cvMappingInverse(theMesh.numVertices(), -1);
 
    
    
    
    stat = meshMapUtils::traverseFace( fDagPathSrc, fFaceIdxSrc, fFaceVtxSrc[0], fFaceVtxSrc[1], faceTraversal,
                    cvMapping, cvMappingInverse, 
                    newPolygonCounts, newPolygonConnects, 
                    origVertices, newVertices );
    {
        displayError(" could not process all the mesh faces.");
        return stat;
    }
    
    
    fVertices.copy(origVertices);
    while(!polyIter.isDone()) 
    {
        fPolygonCounts.append(polyIter.polygonVertexCount());
        for(i = 0; i < polyIter.polygonVertexCount(); i++)
        {
            fPolygonConnects.append(polyIter.vertexIndex(i));
        }
    }
    theMesh.getColorSetNames(fColorSetNames);
    int numColorSets = fColorSetNames.length();
    fColorIdsArrays = 
new MIntArray[numColorSets];
    collectColorsUVs(theMesh, false);
    stat = theMesh.createInPlace( newVertices.
length(), newPolygonCounts.
length(), newVertices, newPolygonCounts, newPolygonConnects );
    {
        displayError(" MFnMesh::createInPlace failed.");
        fCVMapping.clear();
        fCVMappingInverse.clear();
        fVertices.clear();
        fPolygonCounts.clear();
        fPolygonConnects.clear();
        delete [] fColorArrays;  fColorArrays = NULL;
        delete [] fColorIdsArrays;fColorIdsArrays = NULL;
        
        resetColorsUVsMemory();
        return stat;
    }
    
    numDataFn.
setData( 0.0f, 0.0f, 0.0f );
    MPlug tweaks = depFn.findPlug(
"pnts");
 
    tweaks.getExistingArrayAttributeIndices( tweakIndices );
    unsigned int numTweaks = (
unsigned int) tweakIndices.
length();
 
    for( i = 0; i < numTweaks; i++ )
    {
    }
    assignColorsUVs(theMesh, cvMapping, cvMappingInverse, false);
    
    fCVMapping = cvMapping;
    fCVMappingInverse = cvMappingInverse;
    return stat;
}
MStatus meshReorderCommand::undoIt()
 
{
    fColorSetNames.clear();
    theMesh.getColorSetNames(fColorSetNames);
    collectColorsUVs(theMesh, true);
    stat = theMesh.createInPlace( fVertices.length(), fPolygonCounts.length(), fVertices, fPolygonCounts, fPolygonConnects );
    assignColorsUVs(theMesh, fCVMappingInverse, fCVMapping, true);
    fCVMapping.clear();
    fCVMappingInverse.clear();
    fVertices.clear();
    fPolygonCounts.clear();
    fPolygonConnects.clear();
    delete [] fColorArrays;  fColorArrays = NULL;
    delete [] fColorIdsArrays;fColorIdsArrays = NULL;
    return stat;
}
void meshReorderCommand::collectColorsUVs(
MFnMesh &theMesh, 
bool isUndo)
 
{
    int i;
    
    int numColorSets = fColorSetNames.length();
    fClampedArray = new bool[numColorSets];
    for (i = 0; i < numColorSets; i++)
    {
        
        
        
        if(!isUndo) {
            theMesh.
getColors(fColorArrays[i], &(fColorSetNames[i]));
            unsigned nth = 0;
            fColorIdsArrays[i].setLength(theMesh.
numColors(fColorSetNames[i]));
            while(!polyIter.isDone()) 
            {
                for(unsigned j = 0; j < polyIter.polygonVertexCount(); j++)
                {
                    unsigned polygonIdx = polyIter.
index();
 
                    int colorId;
                    theMesh.
getColorIndex(polygonIdx, j, colorId, &(fColorSetNames[i]));
                    fColorIdsArrays[i][nth] = colorId;
                    nth++;
                }
                polyIter.next();
            }
        }
    }
    
    int numUVSets = fUVSetNames.length();
    for (i = 0; i < numUVSets; i++) 
    {
        unsigned nth = 0;
        fUVIdsArrays[i].setLength(fVertices.length());
        while(!polyIter.isDone()) 
        {
            for(unsigned j = 0; j < polyIter.polygonVertexCount(); j++)
            {
                fUVIdsArrays[i][vertexIdx] = uvIds[nth];
                nth++;
            }
            polyIter.next();
        }
        theMesh.
getUVs(fUArrays[i], fVArrays[i], &(fUVSetNames[i]));
    }
}
{
    int i;
    
    int numColorSets = fColorSetNames.length();
    for (i = 0; i < numColorSets; i++) 
    {
        
        if (fColorSetNames[i] != defaultColorSetName)
        {
            theMesh.
createColorSet(fColorSetNames[i], NULL, fClampedArray[i], fRepArray[i]);
        }
        if (fVertexColorArrays[i].length() > 0 && fVertexColorArrays[i].length() == fVertices.length())
        {
            
            
            
            if(!isUndo) 
            {
                theMesh.
setVertexColors(fVertexColorArrays[i], colorMapping, NULL, fRepArray[i]);
            } else {
                theMesh.
setColors(fColorArrays[i], NULL, fRepArray[i]);
                theMesh.
assignColors(fColorIdsArrays[i], &(fColorSetNames[i]));
            }
        }
    }
    
    int numUVSets = fUVSetNames.length();
    for (i = 0; i < numUVSets; i++) 
    {
        
        if (fUVSetNames[i] != defaultUVSetName)
        {
        }
        if (fUArrays[i].length() > 0 && fUArrays[i].length() == fVArrays[i].length())
        {
            theMesh.
setUVs(fUArrays[i], fVArrays[i], &(fUVSetNames[i]));
            while(!polyIter.isDone()) 
            {
                for(unsigned j = 0; j < polyIter.polygonVertexCount(); j++)
                {
                    unsigned polygonIdx = polyIter.
index();
 
                    unsigned vertexIdx = polyIter.vertexIndex(j);
                    int uvId = fUVIdsArrays[i][uvMapping[vertexIdx]];
                }
                polyIter.next();
            }
        }
    }
    resetColorsUVsMemory();
}
void meshReorderCommand::resetColorsUVsMemory()
{
    if (fClampedArray != NULL) 
    {
        delete [] fClampedArray; 
        fClampedArray = NULL;
    }
    if (fRepArray != NULL)
    {
        delete [] fRepArray;
        fRepArray = NULL;
    }
    if (fVertexColorArrays != NULL)
    {
        delete [] fVertexColorArrays;
        fVertexColorArrays = NULL;
    }
    if (fUArrays != NULL)
    {
        delete [] fUArrays;
        fUArrays = NULL;
    }
    if (fVArrays != NULL)
    {
        delete [] fVArrays;
        fVArrays = NULL;
    }
    if (fUVIdsArrays != NULL)
    {
        delete [] fUVIdsArrays;
        fUVIdsArrays = NULL;
    }
    fColorSetNames.clear();
    fUVSetNames.clear();
}