// Geometric Tools, Inc.
// http://www.geometrictools.com
// Copyright (c) 1998-2005.  All Rights Reserved
//
// The Wild Magic Library (WM3) source code is supplied under the terms of
// the license agreement
//     http://www.geometrictools.com/License/WildMagic3License.pdf
// and may not be copied or disclosed except in accordance with the terms
// of that agreement.

#include <Rpc.h>
#include <cassert>
#include <fstream>
#include <iostream>
using namespace std;

//----------------------------------------------------------------------------
void Usage ()
{
    cout << "usage: GenerateVCPROJ projectname" << endl;
    cout << "The output is projectname.vcproj" << endl;
}
//----------------------------------------------------------------------------
char* GetGuidString ()
{
    UUID kGuid;
    RPC_STATUS kStatus = UuidCreate(&kGuid);
    if ( kStatus != RPC_S_OK )
        return 0;

    unsigned char* aucString = 0;
    kStatus = UuidToString(&kGuid,&aucString);
    if ( kStatus != RPC_S_OK || !aucString )
        return 0;

    char* acString = (char*)aucString;
    char* acCopy = new char[strlen(acString)+1];
    strcpy(acCopy,acString);

    RpcStringFree(&aucString);

    return acCopy;
}
//----------------------------------------------------------------------------
bool GenerateProject (const char* acTemplateFile, const char* acExtension,
    const char* acSourceName, char cMajor, char cMinor,
    const char* acRenderer)
{
    char* acGuid = GetGuidString();
    if ( !acGuid )
        return false;

    char acProjectName[512];
    sprintf(acProjectName,"%s%c%c%s",acSourceName,cMajor,cMinor,acRenderer);

    char acDirectory[512];
    sprintf(acDirectory,"%s\\VC%c%c",acRenderer,cMajor,cMinor);

    char acProjectFile[512];
    sprintf(acProjectFile,"%s.%s",acProjectName,acExtension);
    ofstream kOStr(acProjectFile);
    if ( !kOStr )
        return false;

    ifstream kIStr(acTemplateFile);
    if ( !kIStr )
        return false;

    const int iSize = 512;
    char acString[iSize];

    while ( !kIStr.eof() )
    {
        kIStr.getline(acString,iSize);

        char* acSub;
        int iIndex, i;

        acSub = strstr(acString,"FOUNDATIONLIB");
        if ( acSub )
        {
            char* acTmp = acString;
            iIndex = (int)(acSub - acTmp);
            for (i = 0; i < iIndex; i++)
            {
                kOStr << acTmp[i];
            }
            kOStr << "Wm3Foundation" << cMajor << cMinor;
            acSub += strlen("FOUNDATIONLIB");
            acTmp = acSub;

            acSub = strstr(acTmp,"RENDERERLIB");
            iIndex = (int)(acSub - acTmp);
            for (i = 0; i < iIndex; i++)
            {
                kOStr << acTmp[i];
            }
            kOStr << "Wm3" << acRenderer << "Renderer" << cMajor << cMinor;
            acSub += strlen("RENDERERLIB");
            acTmp = acSub;

            acSub = strstr(acTmp,"APPLICATIONLIB");
            iIndex = (int)(acSub - acTmp);
            for (i = 0; i < iIndex; i++)
            {
                kOStr << acTmp[i];
            }
            kOStr << "Wm3" << acRenderer << "Application" << cMajor << cMinor;
            acSub += strlen("APPLICATIONLIB");
            acTmp = acSub;

            acSub = strstr(acTmp,"PROJECTNAME");  // VC6
            if ( acSub )
            {
                iIndex = (int)(acSub - acTmp);
                for (i = 0; i < iIndex; i++)
                {
                    kOStr << acTmp[i];
                }
                kOStr << acProjectName;
                acSub += strlen("PROJECTNAME");
                acTmp = acSub;
            }

            kOStr << acTmp << endl;
            continue;
        }

        acSub = strstr(acString,"PROJECTNAME");
        if ( acSub )
        {
            iIndex = (int)(acSub - acString);
            for (i = 0; i < iIndex; i++)
                kOStr << acString[i];

            kOStr << acProjectName;

            acSub += strlen("PROJECTNAME");
            kOStr << acSub << endl;
            continue;
        }

        acSub = strstr(acString,"VCVERSION");
        if ( acSub )
        {
            iIndex = (int)(acSub - acString);
            for (i = 0; i < iIndex; i++)
                kOStr << acString[i];

            kOStr << cMajor << '.' << cMinor << '0';

            acSub += strlen("VCVERSION");
            kOStr << acSub << endl;
            continue;
        }

        acSub = strstr(acString,"GENERATEDGUID");
        if ( acSub )
        {
            iIndex = (int)(acSub - acString);
            for (i = 0; i < iIndex; i++)
                kOStr << acString[i];

            kOStr << acGuid;

            acSub += strlen("GENERATEGUID");
            kOStr << acSub << endl;
            continue;
        }

        acSub = strstr(acString,"PROJECTDIR");
        if ( acSub )
        {
            iIndex = (int)(acSub - acString);
            for (i = 0; i < iIndex; i++)
                kOStr << acString[i];

            kOStr << acDirectory;

            acSub += strlen("PROJECTDIR");
            kOStr << acSub << endl;
            continue;
        }

        acSub = strstr(acString,"SOURCENAME");
        if ( acSub )
        {
            iIndex = (int)(acSub - acString);
            for (i = 0; i < iIndex; i++)
                kOStr << acString[i];

            kOStr << acSourceName;

            acSub += strlen("SOURCENAME");
            kOStr << acSub << endl;
            continue;
        }

        kOStr << acString << endl;
    }

    kOStr.close();
    kIStr.close();
    delete[] acGuid;
    return true;
}
//----------------------------------------------------------------------------
void GenerateXcodeProject (const char* acProjName)
{
    // open project template for textual substitution
    ifstream kIProj("TemplatePBXPROJ.txt");
    assert( kIProj );

    // open the output project file
    ofstream kOProj("project.pbxproj");
    assert( kOProj );

    // substitute
    const int iSize = 1024;
    char acString[iSize];
    while ( !kIProj.eof() )
    {
        kIProj.getline(acString,iSize);

        char* acSub = strstr(acString,"WM3APPNAME");
        int iIndex, i;
        if ( acSub )
        {
            iIndex = (int)(acSub - acString);
            for (i = 0; i < iIndex; i++)
                kOProj << acString[i];

            kOProj << acProjName;

            acSub += strlen("WM3APPNAME");
            kOProj << acSub << endl;
            continue;
        }

        kOProj << acString << endl;
    }

    kIProj.close();
    kOProj.close();
}
//----------------------------------------------------------------------------
int main (int iQuantity, char** apcArgument)
{
    if ( iQuantity != 2 )
    {
        cout << "Incorrect number of command line arguments." << endl << endl;
        Usage();
        return -1;
    }

    const char* acSourceName = apcArgument[1];

    // VC6.0
    GenerateProject("TemplateDSP.txt","dsp",acSourceName,'6','0',"Dx9");
    GenerateProject("TemplateDSP.txt","dsp",acSourceName,'6','0',"Wgl");

    // VC7.0
    GenerateProject("TemplateVCPROJ.txt","vcproj",acSourceName,'7','0',"Dx9");
    GenerateProject("TemplateVCPROJ.txt","vcproj",acSourceName,'7','0',"Wgl");

    // VC7.1
    GenerateProject("TemplateVCPROJ.txt","vcproj",acSourceName,'7','1',"Wgl");
    GenerateProject("TemplateVCPROJ.txt","vcproj",acSourceName,'7','1',"Dx9");

    // Xcode
    GenerateXcodeProject(acSourceName);

    return 0;
}
//----------------------------------------------------------------------------
