////////////////////////////////////////////////////////////////////////////////
//
// Ogre3D project wizard
//
// TODO: make it work with both available SDKs: MinGW & MSVS
//
////////////////////////////////////////////////////////////////////////////////

// globals
OgrePath <- _T("");
// we have two possible types of OGRE SDK installation:
// 1) Source distribution
//    : identical configuration for both linux and windows (except link libs)
// 2) Pre-made SDK
//    : in windows, small changes
//    : in linux we use pkg-config for setting up everything
// This var is true for 1, false for 2.
OgreIsSource <- false;

function BeginWizard()
{
    // intro text
    local intro_msg = _("Welcome to the new OGRE project wizard!\n\n") +
                      _("This wizard will guide you to create a new project\nusing the OGRE 3D rendering engine.\n\n") +
                      _("When you're ready to proceed, please click \"Next\"...");

    // "select OGRE path" text
    local ogrepath_descr = _("Please select the location of OGRE on your computer.\n") +
                           _("This is the top-level folder where OGRE was installed\n(unpacked).\n") +
                           _("To help you, this folder must contain the subfolders\n\"include\" and \"lib\".\n") +
                           _("If you have setup an environment variable named\nOGRE_HOME, it will automatically be used below.");

    // source or SDK?
    local sdk_descr = _("OGRE might exist on your system as a source package\n(you built it yourself), or as a pre-made SDK which you installed.\n\n") +
                      _("It is important for this wizard to know which SDK type is\ninstalled so that it can setup your project properly.");

    // choices
    local sdk_choices =  _("I have a folder with the OGRE source code;I have installed a pre-made OGRE SDK");

    // compilers: GCC and MSVC for windows, GCC for linux
    local compilers = PLATFORM == PLATFORM_MSW
                        ? _T("gcc*;msv*")
                        : _T("gcc*");

    Wizard.AddInfoPage(_T("OgreIntro"), intro_msg);
    Wizard.AddProjectPathPage();
    Wizard.AddGenericSingleChoiceListPage(_T("OgreSDKType"), sdk_descr, sdk_choices, OgreIsSource ? 0 : 1);
    Wizard.AddGenericSelectPathPage(_T("OgrePath"), ogrepath_descr, _("Please select OGRE's location:"), _T("$(OGRE_HOME)"));
    Wizard.AddCompilerPage(_T(""), compilers, true, true);
}

////////////////////////////////////////////////////////////////////////////////
// OGRE SDK's type
////////////////////////////////////////////////////////////////////////////////

function OnGetNextPage_OgreSDKType()
{
    // for pre-made SDK under linux, skip OGRE path selection
    // we will use pkg-config for this ;)
    OgreIsSource = Wizard.GetListboxSelection(_T("lstSelections")) == 0;
    if (PLATFORM != PLATFORM_MSW && !OgreIsSource)
        return _T("CompilerPage");

    return _T("OgrePath");
}

////////////////////////////////////////////////////////////////////////////////
// OGRE's compiler
////////////////////////////////////////////////////////////////////////////////

function OnGetPrevPage_CompilerPage()
{
    // for pre-made SDK under linux, skip OGRE path selection
    // we will use pkg-config for this ;)
    if (PLATFORM != PLATFORM_MSW && !OgreIsSource)
        return _T("OgreSDKType");

    return _T("OgrePath");
}

////////////////////////////////////////////////////////////////////////////////
// OGRE's path page
////////////////////////////////////////////////////////////////////////////////

function OnLeave_OgrePath(fwd)
{
    if (fwd)
    {
        local dir         = Wizard.GetTextControlValue(_T("txtFolder")); // txtFolder is the text control in GenericSelectPathPage
        local dir_nomacro = ReplaceMacros(dir);
        if ((OgreIsSource && !IO.FileExists(dir_nomacro + _T("/OgreMain/include/Ogre.h"))) ||
            (!OgreIsSource && !IO.FileExists(dir_nomacro + _T("/include/Ogre.h"))))
        {
            ShowError(_("The path you entered seems valid, but this wizard\ncan't locate OGRE's files in it..."));
            return false;
        }

        OgrePath = dir;
    }
    return true;
}

// return the files this project contains
function GetFilesDir()
{
    return _T("ogre/files");
}

// setup the already created project
function SetupProject(project)
{
    // set project options

    // Windows platform
    if (PLATFORM == PLATFORM_MSW)
    {
        if (!OgreIsSource) // SDK
        {
//            project.AddIncludeDir(OgrePath + _T("/stlport/stlport"));
            project.AddIncludeDir(OgrePath + _T("/include"));
            project.AddIncludeDir(OgrePath + _T("/samples/include"));
            project.AddIncludeDir(OgrePath + _T("/samples/refapp/include"));
            project.AddLibDir(OgrePath + _T("/lib"));
//            project.AddCompilerOption(_T("-D_STLP_NO_CUSTOM_IO"));
//            project.AddCompilerOption(_T("-D_STLP_USE_DYNAMIC_LIB"));
        }

        project.AddCompilerOption(_T("-mthreads"));
        project.AddCompilerOption(_T("-fmessage-length=0"));
        project.AddCompilerOption(_T("-fexceptions"));
        project.AddCompilerOption(_T("-fident"));
        project.AddCompilerOption(_T("-DWIN32"));
        project.AddCompilerOption(_T("-D_WINDOWS"));
//        project.AddLinkLib(_T("opengl32"));
//        project.AddLinkLib(_T("gdi32"));
//        project.AddLinkLib(_T("user32"));
//        project.AddLinkLib(_T("kernel32"));

        // help the linker
        project.AddLinkerOption(_T("-Wl,--enable-runtime-pseudo-reloc"));
        project.AddLinkerOption(_T("-Wl,--enable-auto-image-base"));
        project.AddLinkerOption(_T("-Wl,--add-stdcall-alias"));
        project.AddLinkerOption(_T("-mthreads"));
    }
    else
    {
        if (!OgreIsSource) // SDK
        {
            project.AddCompilerOption(_T("`pkg-config --cflags OGRE`"));
            project.AddLinkerOption(_T("`pkg-config --libs OGRE`"));
        }
        project.AddLinkLib(_T("GL"));
    }

    if (OgreIsSource) // source: common for windows and linux
    {
        project.AddIncludeDir(OgrePath + _T("/OgreMain/include"));
        project.AddIncludeDir(OgrePath + _T("/Samples/Common/include"));
        // lib dirs are different based on Debug/Release targets
    }

    // enable compiler warnings (project-wide)
    WarningsOn(project, Wizard.GetCompilerID());
    // enable C++ exceptions (project-wide)
    CppExceptionsOn(project, Wizard.GetCompilerID());

    // Debug
    local target = project.GetBuildTarget(Wizard.GetDebugName());
    if (!IsNull(target))
    {
        target.SetTargetType(ttConsoleOnly); // ttConsoleOnly: console for debugging

        if (OgreIsSource)
            target.SetWorkingDir(OgrePath + _T("/Samples/Common/bin/Debug"));
        else if (PLATFORM == PLATFORM_MSW)
            target.SetWorkingDir(OgrePath + _T("/bin/Debug"));
        project.AddLibDir(OgrePath + _T("/bin/Debug"));
        // TODO: linux package contains samples?

        if (target.GetWorkingDir().Matches(_T("")))
            target.SetOutputFilename(target.SuggestOutputFilename());
        else
            target.SetOutputFilename(target.GetWorkingDir() + wxFILE_SEP_PATH + target.SuggestOutputFilename());
//        target.SetOutputFilename(Wizard.GetDebugOutputDir() + Wizard.GetProjectName() + DOT_EXT_EXECUTABLE);

        if (PLATFORM == PLATFORM_MSW)
        {
            target.AddLinkLib(_T("OgreMain_d"));
            target.AddLinkLib(_T("OIS_d"));

            target.AddCompilerOption(_T("-D_DEBUG"));
//            // windows SDK uses STLport
//            if (!OgreIsSource)
//            {
//                target.AddCompilerOption(_T("-D_STLP_DEBUG"));
//                target.AddLinkLib(_T("stlportstlg.5.0"));
//            }
        }
        else
        {
            target.AddLinkLib(_T("OgreMain"));
            target.AddLinkLib(_T("OIS"));
        }

        if (OgreIsSource)
            target.AddLibDir(OgrePath + _T("/OgreMain/lib/Debug"));

        // enable generation of debugging symbols for target
        DebugSymbolsOn(target, Wizard.GetCompilerID());
    }
    // Release
    target = project.GetBuildTarget(Wizard.GetReleaseName());
    if (!IsNull(target))
    {
        target.SetTargetType(ttExecutable); // ttExecutable: no console

        if (OgreIsSource)
            target.SetWorkingDir(OgrePath + _T("/Samples/Common/bin/Release"));
        else if (PLATFORM == PLATFORM_MSW)
            target.SetWorkingDir(OgrePath + _T("/bin/Release"));
        project.AddLibDir(OgrePath + _T("/bin/Release"));
        // TODO: linux package contains samples?

        if (target.GetWorkingDir().Matches(_T("")))
            target.SetOutputFilename(target.SuggestOutputFilename());
        else
            target.SetOutputFilename(target.GetWorkingDir() + wxFILE_SEP_PATH + target.SuggestOutputFilename());
//        target.SetOutputFilename(Wizard.GetReleaseOutputDir() + Wizard.GetProjectName() + DOT_EXT_EXECUTABLE);

        target.AddLinkLib(_T("OgreMain"));
        target.AddLinkLib(_T("OIS"));
        if (PLATFORM == PLATFORM_MSW)
        {
            target.AddCompilerOption(_T("-DNDEBUG"));
//            // windows SDK uses STLport
//            if (!OgreIsSource)
//                target.AddLinkLib(_T("stlport.5.0"));
        }
        if (OgreIsSource)
            target.AddLibDir(OgrePath + _T("/OgreMain/lib/Release"));

        // enable optimizations for target
        OptimizationsOn(target, Wizard.GetCompilerID());
    }

    return true;
}
