#include <maya/MIOStream.h>
#include "apiMeshData.h"
#include "apiMeshIterator.h"
#include <api_macros.h>
#include <maya/MFnSingleIndexedComponent.h>
#include <maya/MArgList.h>
#define kDblQteChar             "\""
#define kSpaceChar              "   "
#define kWrapString             "\n\t\t"
#define kVertexKeyword          "v"
#define kNormalKeyword          "vn"
#define kTextureKeyword         "vt"
#define kFaceKeyword            "face"
#define kUVKeyword              "uv" 
const MTypeId apiMeshData::id( 0x80777 );
 
const MString apiMeshData::typeName( 
"apiMeshData" );
 
apiMeshData::apiMeshData() : fGeometry( NULL )
{
    fGeometry = new apiMeshGeom;
}
apiMeshData::~apiMeshData()
{
    if ( NULL != fGeometry ) {
        delete fGeometry;
        fGeometry = NULL;
    }
}
{
    if ( ! readVerticesASCII(argList,index) ) {
    }
    else if ( ! readNormalsASCII(argList,++index) ) {
    }
    else if ( ! readFacesASCII(argList,++index) ) {
    } 
    else if ( ! readUVASCII(argList,index) ) { 
    }
    
    
}
MStatus apiMeshData::readBinary( istream& , 
unsigned  )
 
{
}
MStatus apiMeshData::writeASCII( ostream& out )
 
{
    if ( ! writeVerticesASCII(out) ) {
    }
    else if ( ! writeNormalsASCII(out) ) {
    }
    else if ( ! writeFacesASCII(out) ) {
    }
    writeUVASCII(out); 
}
MStatus apiMeshData::writeBinary( ostream&  )
 
{
}
void apiMeshData::copy ( 
const MPxData& other )
 
{
    *fGeometry = *(((const apiMeshData &)other).fGeometry);
}
MTypeId apiMeshData::typeId() const
 
{
    return apiMeshData::id;
}
{
    return apiMeshData::typeName;
}
void * apiMeshData::creator()
{
    return new apiMeshData;
}
                                            bool useComponents)
{
    apiMeshGeomIterator * result = NULL;
    if ( useComponents ) {
        result = new apiMeshGeomIterator( fGeometry, componentList );
    }
    else {
        result = new apiMeshGeomIterator( fGeometry, component );
    }
    return result;
}
                                            bool useComponents,
                                            bool ) const
{
    apiMeshGeomIterator * result = NULL;
    if ( useComponents ) {
        result = new apiMeshGeomIterator( fGeometry, componentList );
    }
    else {
        result = new apiMeshGeomIterator( fGeometry, component );
    }
    return result;
}
bool apiMeshData::updateCompleteVertexGroup( 
MObject & component ) 
const 
{
    
    
    
    
    if ( stat && (NULL != fGeometry) && (fnComponent.isComplete()) ) {
    
        int maxVerts ;
        fnComponent.getCompleteData( maxVerts );
        int numVertices = fGeometry->vertices.length();
        if ( (numVertices > 0) && (maxVerts != numVertices) ) {
            
            
            
            fnComponent.setCompleteData( numVertices );
            return true;
        }
    }
    return false;
}
MStatus apiMeshData::writeUVASCII( ostream &out )
 
{
    int uvCount = fGeometry->uvcoords.uvcount(); 
    int faceVertexCount = fGeometry->uvcoords.faceVertexIndex.length();
    if ( uvCount > 0 ) { 
        out << "\n"; 
        out << kWrapString; 
        out << kDblQteChar << kUVKeyword << kDblQteChar
            << kSpaceChar << uvCount << kSpaceChar << faceVertexCount; 
        int i; 
        float u, v; 
        for ( i = 0; i < uvCount; i ++ ) { 
            fGeometry->uvcoords.getUV( i, u, v ); 
            out << kWrapString; 
            out << u << kSpaceChar; 
            out << v << kSpaceChar; 
        }
        const MIntArray &fvl = fGeometry->uvcoords.faceVertexIndex; 
 
        for ( i = 0; i < faceVertexCount; i ++ ) { 
            out << kWrapString; 
            out << fvl[i] << kSpaceChar; 
        }
    }
}
MStatus apiMeshData::writeVerticesASCII( ostream& out )
 
{
    int vertexCount = fGeometry->vertices.length();
    out << "\n";
    out << kWrapString;
    out << kDblQteChar << kVertexKeyword << kDblQteChar
        << kSpaceChar << vertexCount;
    for ( int i=0; i<vertexCount; i++ ) {
        vertex = fGeometry->vertices[i];
        out << kWrapString;
        out << vertex[0] << kSpaceChar;
        out << vertex[1] << kSpaceChar;
        out << vertex[2];
    }
}
MStatus apiMeshData::writeNormalsASCII( ostream& out )
 
{
    int normalCount = fGeometry->normals.
length();
 
    out << "\n";
    out << kWrapString;
    out << kDblQteChar << kNormalKeyword << kDblQteChar
        << kSpaceChar << normalCount;
    for ( int i=0; i<normalCount; i++ ) {
        normal = fGeometry->normals[i];
        out << kWrapString;
        out << normal[0] << kSpaceChar;
        out << normal[1] << kSpaceChar;
        out << normal[2];
    }
}
MStatus apiMeshData::writeFacesASCII( ostream& out )
 
{
    int numFaces = fGeometry->face_counts.length();
    int vid = 0;
    for ( int f=0; f<numFaces; f++ )
    {
        int faceVertexCount = fGeometry->face_counts[f];
        out << "\n";
        out << kWrapString;
        out << kDblQteChar << kFaceKeyword << kDblQteChar
            << kSpaceChar << faceVertexCount;
        out << kWrapString;
        for ( int v=0; v<faceVertexCount; v++ )
        {
            out << fGeometry->face_connects[vid] << kSpaceChar;
            vid++;
        }
    }
}
                                        unsigned& index )
{
    int vertexCount = 0;
    result = argList.
get( index, geomStr );
    if ( result && (geomStr == kVertexKeyword) ) {
        result = argList.
get( ++index, vertexCount );
        
        for ( int i=0; i<vertexCount; i++ )
        {
            if ( argList.
get( ++index, vertex ) ) {
 
                fGeometry->vertices.append( vertex );
            }
            else {
            }
        }
    }
    return result;
}
                                       unsigned& index )
{
    int normalCount = 0;
    result = argList.
get( index, geomStr );
    if ( result && (geomStr == kNormalKeyword) ) {
        result = argList.
get( ++index, normalCount );
        for ( int i=0; i<normalCount; i++ )
        {
            if ( argList.
get( ++index, normal ) ) {
 
                fGeometry->normals.append( normal );
            }
            else {
            }
        }
    }
    return result;
}
                                  unsigned &index )
{
    double u, v; 
    int fvi; 
    int faceVertexListCount = 0; 
    int uvCount; 
    
    fGeometry->uvcoords.reset(); 
    if ( argList.
get(index,uvStr) && (uvStr == kUVKeyword) ) { 
 
        result = argList.
get( ++index, uvCount ); 
        if ( result ) { 
            result = argList.
get( ++index, faceVertexListCount ); 
        }
        int i; 
        for ( i = 0; i < uvCount && result; i ++ ) { 
            if ( argList.
get( ++index, u ) && argList.
get( ++index, v ) ) { 
 
                fGeometry->uvcoords.append_uv( (float)u, (float)v );
            } else { 
            }
        }
        
        for ( i = 0; i < faceVertexListCount && result; i++ ) { 
            if ( argList.
get( ++index, fvi ) ) { 
 
                fGeometry->uvcoords.faceVertexIndex.append( fvi ); 
            } else { 
            }
        }
    }
    
    return result; 
}
                                     unsigned& index )
{
    int faceCount = 0;
    int vid;
    while( argList.
get(index,geomStr) && (geomStr == kFaceKeyword) )
 
    {
        result = argList.
get( ++index, faceCount );
        fGeometry->face_counts.append( faceCount );
        for ( int i=0; i<faceCount; i++ )
        {
            if ( argList.
get( ++index, vid ) ) {
 
                fGeometry->face_connects.append( vid );
            }
            else {
            }
        }
        index++;
    }
    fGeometry->faceCount = fGeometry->face_counts.length();
    return result;
}