#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");


	// Count the total number of vertices per mesh.
	int* meshCounts = new int[msModel_GetMeshCount(pModel)];
	int totalVtxCount = 0;
	
	for (int ii = 0; ii < msModel_GetMeshCount(pModel); ++ii)
	{
        msMesh *pMesh = msModel_GetMeshAt (pModel, ii);
		meshCounts[ii] = msMesh_GetVertexCount (pMesh);
		totalVtxCount += meshCounts[ii];
	}

	// Count the total number of triangles per mesh.
	int* triCounts = new int[msModel_GetMeshCount(pModel)];
	int totalTriCount = 0;
	
	for (int ii = 0; ii < msModel_GetMeshCount(pModel); ++ii)
	{
        msMesh *pMesh = msModel_GetMeshAt (pModel, ii);
		triCounts[ii] = msMesh_GetTriangleCount (pMesh);
		totalTriCount += triCounts[ii];
	}





	// Print the total number of vertices.
    fprintf (file, "%d\n", totalVtxCount);
	fprintf (file, "#\n# Vertex Definitions\n#\n");


	// Define all the vertices.
	int verticesSoFar = 0;
    for (int i = 0; i < msModel_GetMeshCount (pModel); i++)
    {
		fprintf(file, "# mesh %d\n", i);
        msMesh *pMesh = msModel_GetMeshAt (pModel, i);
        msMesh_GetName (pMesh, szName, MS_MAX_NAME);

        for (int 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);

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

	// Print the total number of triangles

		fprintf (file, "#\n# Number of triangles\n#\n");
        fprintf (file, "%d\n", totalTriCount);
		fprintf (file, "#\n# Triangle definitions\n#\n");


	// Define all the triangles.
	int trianglesPrinted = 0;
    int prevMeshCounts = 0;

    for (int i = 0; i < msModel_GetMeshCount (pModel); i++)
    {
        msMesh *pMesh = msModel_GetMeshAt (pModel, i);
        msMesh_GetName (pMesh, szName, MS_MAX_NAME);

		prevMeshCounts += ((i == 0) ? 0 : meshCounts[i-1]);

		fprintf(file, "# mesh %d, previous mesh counts %d\n", i, prevMeshCounts);
        for (int j = 0; j < msMesh_GetTriangleCount (pMesh); j++)
        {
            msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, j);

			word nIndices[3];
            msTriangle_GetVertexIndices (pTriangle, nIndices);

			fprintf(file, "# (vertices 2 and 3 flipped from milkshape) %d: ", trianglesPrinted++);
            				for (int k = 0; k < 3; ++k)
				{
					msVertex *pVertex = msMesh_GetVertexAt (pMesh, nIndices[k]);
					msVec3 Vertex;
					msVec2 uv;

					msVertex_GetVertex (pVertex, Vertex);
					msVertex_GetTexCoords (pVertex, uv);
		// we print them in inverted order to fix orientation.
					fprintf (file, "(%f, %f, %f) ",
						Vertex[0], Vertex[1], Vertex[2]
						);
				}
				fprintf (file, "\n");


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

        }
    }

 

    fclose (file);

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

    return 0;
}
