#include "stdafx.h"
#include "msPlugInImpl.h"
#include "msLib.h"

#include <time.h>
#include <stdio.h>


BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}



cMsPlugIn*
CreatePlugIn ()
{
    return new cPlugIn ();
}



cPlugIn::cPlugIn ()
{
    strcpy (szTitle, "Chaotic(R) 3D ASCII...");
}



cPlugIn::~cPlugIn ()
{
}



int
cPlugIn::GetType ()
{
    return cMsPlugIn::eTypeExport;
}



const char*
cPlugIn::GetTitle ()
{
    return szTitle;
}


int
cPlugIn::Execute (msModel *pModel)
{
    if (!pModel)
        return -1;

    //
    // check, if we have something to export
    //
    if (msModel_GetMeshCount (pModel) == 0)
    {
        ::MessageBox (NULL, "The model is empty!  Nothing exported!", "Chaotic(R) 3D ASCII Export", MB_OK | MB_ICONWARNING);
        return 0;
    }

    //
    // choose filename
    //
    OPENFILENAME ofn;
    memset (&ofn, 0, sizeof (OPENFILENAME));
    
    char szFile[MS_MAX_PATH];
    char szFileTitle[MS_MAX_PATH];
    char szDefExt[32] = "txt";
    char szFilter[128] = "MilkShape 3D ASCII Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0";
    szFile[0] = '\0';
    szFileTitle[0] = '\0';

    ofn.lStructSize = sizeof (OPENFILENAME);
    ofn.lpstrDefExt = szDefExt;
    ofn.lpstrFilter = szFilter;
    ofn.lpstrFile = szFile;
    ofn.nMaxFile = MS_MAX_PATH;
    ofn.lpstrFileTitle = szFileTitle;
    ofn.nMaxFileTitle = MS_MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
    ofn.lpstrTitle = "Export MilkShape 3D ASCII";

    if (!::GetSaveFileName (&ofn))
        return 0;

    //
    // export
    //
    FILE *file = fopen (szFile, "wt");
    if (!file)
        return -1;

    int i, j;
    char szName[MS_MAX_NAME];

//    fprintf (file, "// MilkShape 3D ASCII\n\n");
	fprintf (file, "# Exported using Chaotic(R) Milkshape 3D ASCII Exporter.\n");



	struct tm *newtime;
	time_t aclock;

	time( &aclock );   // Get time in seconds
	newtime = localtime( &aclock );   // Convert time to struct tm form 

	fprintf (file, "# %s", asctime(newtime));
	fprintf (file, "#\n#\n");
    //fprintf (file, "Frames: %d\n", msModel_GetTotalFrames (pModel));
    //fprintf (file, "Frame: %d\n\n", msModel_GetFrame (pModel));
    //fprintf (file, "Meshes: %d\n", msModel_GetMeshCount (pModel));
	fprintf (file, "# Number of vertices\n#\n");
    for (i = 0; i < msModel_GetMeshCount (pModel); i++)
    {
        msMesh *pMesh = msModel_GetMeshAt (pModel, i);
        msMesh_GetName (pMesh, szName, MS_MAX_NAME);

      //  fprintf (file, "\"%s\" %d %d\n", szName, msMesh_GetFlags (pMesh), msMesh_GetMaterialIndex (pMesh));

        //
        // vertices
        //
        fprintf (file, "%d\n", msMesh_GetVertexCount (pMesh));
		fprintf (file, "#\n# Vertex Definitions\n#\n");
        for (j = 0; j < msMesh_GetVertexCount (pMesh); j++)
        {
            msVertex *pVertex = msMesh_GetVertexAt (pMesh, j);
            msVec3 Vertex;
            msVec2 uv;

            msVertex_GetVertex (pVertex, Vertex);
            msVertex_GetTexCoords (pVertex, uv);
#if 0
            fprintf (file, "%d %f %f %f %f %f %d\n",
                msVertex_GetFlags (pVertex),
                Vertex[0], Vertex[1], Vertex[2],
                uv[0], uv[1],
                msVertex_GetBoneIndex (pVertex)
                );
#endif


            fprintf (file, "%f %f %f 0 1 0\n",
                Vertex[0], Vertex[1], Vertex[2]
                );
        }

        //
        // vertex normals
        //
		fprintf (file, "#\n# Number of triangles\n#\n");
        fprintf (file, "%d\n", msMesh_GetVertexNormalCount (pMesh));
		fprintf (file, "#\n# Triangle definitions\n#\n");
        for (j = 0; j < msMesh_GetVertexNormalCount (pMesh); j++)
        {
            msVec3 Normal;
            msMesh_GetVertexNormalAt (pMesh, j, Normal);
           // fprintf (file, "%f %f %f\n", Normal[0], Normal[1], Normal[2]);
        }

        //
        // triangles
        //
        //fprintf (file, "%d\n", msMesh_GetTriangleCount (pMesh));
        for (j = 0; j < msMesh_GetTriangleCount (pMesh); j++)
        {
            msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, j);
            
            word nIndices[3];
            msTriangle_GetVertexIndices (pTriangle, nIndices);
            
#if 0
            fprintf (file, "%d %d %d %d %d %d %d %d\n",
                msTriangle_GetFlags (pTriangle),
                nIndices[0], nIndices[1], nIndices[2],
                pTriangle->nNormalIndices[0], pTriangle->nNormalIndices[1], pTriangle->nNormalIndices[2],
                msTriangle_GetSmoothingGroup (pTriangle)
                );
#endif

            fprintf (file, "%d %d %d\n",
                nIndices[0], nIndices[1], nIndices[2]
                );

        }
    }

    //
    // materials
    //
#if 0
    fprintf (file, "\nMaterials: %d\n", msModel_GetMaterialCount (pModel));
    for (i = 0; i < msModel_GetMaterialCount (pModel); i++)
    {
        msMaterial *pMaterial = msModel_GetMaterialAt (pModel, i);
        msMaterial_GetName (pMaterial, szName, MS_MAX_NAME);
        fprintf (file, "\"%s\"\n", szName);

        msVec4 vec4;
        msMaterial_GetAmbient (pMaterial, vec4);
        fprintf (file, "%f %f %f %f\n", vec4[0], vec4[1], vec4[2], vec4[3]);
        msMaterial_GetDiffuse (pMaterial, vec4);
        fprintf (file, "%f %f %f %f\n", vec4[0], vec4[1], vec4[2], vec4[3]);
        msMaterial_GetSpecular (pMaterial, vec4);
        fprintf (file, "%f %f %f %f\n", vec4[0], vec4[1], vec4[2], vec4[3]);
        msMaterial_GetEmissive (pMaterial, vec4);
        fprintf (file, "%f %f %f %f\n", vec4[0], vec4[1], vec4[2], vec4[3]);
        fprintf (file, "%f\n", msMaterial_GetShininess (pMaterial));
        fprintf (file, "%f\n", msMaterial_GetTransparency (pMaterial));

        char szTexture[MS_MAX_PATH];
        msMaterial_GetDiffuseTexture (pMaterial, szTexture, MS_MAX_PATH);
        fprintf (file, "\"%s\"\n", szTexture);
        msMaterial_GetAlphaTexture (pMaterial, szTexture, MS_MAX_PATH);
        fprintf (file, "\"%s\"\n", szTexture);
    }

    //
    // bones
    //
    fprintf (file, "\nBones: %d\n", msModel_GetBoneCount (pModel));
    for (i = 0; i < msModel_GetBoneCount (pModel); i++)
    {
        msBone *pBone = msModel_GetBoneAt (pModel, i);
        msBone_GetName (pBone, szName, MS_MAX_NAME);
        fprintf (file, "\"%s\"\n", szName);
        msBone_GetParentName (pBone, szName, MS_MAX_NAME);
        fprintf (file, "\"%s\"\n", szName);
        msVec3 Position, Rotation;
        msBone_GetPosition (pBone, Position);
        msBone_GetRotation (pBone, Rotation);
        fprintf (file, "%d %f %f %f %f %f %f\n",
            msBone_GetFlags (pBone),
            Position[0], Position[1], Position[2],
            Rotation[0], Rotation[1], Rotation[2]
            );

        fprintf (file, "%d\n", msBone_GetPositionKeyCount (pBone));
        for (j = 0; j < msBone_GetPositionKeyCount (pBone); j++)
        {
            msPositionKey *pKey = msBone_GetPositionKeyAt (pBone, j);
            //fprintf (file, "Time: %f, Position Key: %f %f %f\n",
            fprintf (file, "%f %f %f %f\n",
                pKey->fTime, pKey->Position[0], pKey->Position[1], pKey->Position[2]
                );
        }

        fprintf (file, "%d\n", msBone_GetRotationKeyCount (pBone));
        for (j = 0; j < msBone_GetRotationKeyCount (pBone); j++)
        {
            msRotationKey *pKey = msBone_GetRotationKeyAt (pBone, j);
            //fprintf (file, "Time: %f, Rotation Key: %f %f %f\n",
            fprintf (file, "%f %f %f %f\n",
                pKey->fTime, pKey->Rotation[0], pKey->Rotation[1], pKey->Rotation[2]
                );
        }
    }
#endif

    fclose (file);

    // dont' forget to destroy the model
    msModel_Destroy (pModel);

    return 0;
}
