#include <irrlicht.h>
#include <IGUIButton.h>
#include "driverChoice.h"
#include <IGUIEnvironment.h>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif

// Define some values that we'll use to identify individual GUI controls.
enum
{
    GUI_ID_NEW_GAME_BUTTON = 101,
    GUI_ID_LOAD_GAME_BUTTON,
    GUI_ID_LOAD_SCENARIO_BUTTON,
    GUI_ID_NET_GAME_BUTTON,
    GUI_ID_SETTINGS_BUTTON,
    GUI_ID_QUIT_BUTTON,
    GUI_ID_LAUNCH_BUTTON,
    GUI_ID_MENU_BUTTON,
    GUI_ID_SETTINGS_SAVE_BUTTON
};
int view_window = 0;
//set up settings

struct SAppContext
{
    IrrlichtDevice* device;
    s32             counter;
    IGUIListBox* listbox;
};

class MyEventReceiver : public IEventReceiver
{
public:
    MyEventReceiver(SAppContext& context) : Context(context) { }

    virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == EET_GUI_EVENT)
        {
            s32 id = event.GUIEvent.Caller->getID();
            IGUIEnvironment* env = Context.device->getGUIEnvironment();

            switch (event.GUIEvent.EventType)
            {
            case EGET_BUTTON_CLICKED:
                switch (id)
                {
                case GUI_ID_QUIT_BUTTON:
                    Context.device->closeDevice();
                    return true;

                case GUI_ID_NEW_GAME_BUTTON:
                {
                    view_window = 1;
                    env->clear();
                    env->addButton(rect<s32>(550, 550, 750, 550 + 32), 0, GUI_ID_LAUNCH_BUTTON,
                        L"Launch!", L"Launch a new game");
                    env->addButton(rect<s32>(300, 550, 500, 550 + 32), 0, GUI_ID_MENU_BUTTON,
                        L"Back", L"Back to main menu");
                }
                return true;

                case GUI_ID_SETTINGS_SAVE_BUTTON:
                {
                }

                case GUI_ID_MENU_BUTTON:
                {
                    view_window = 0;
                    env->clear();
                    env->addButton(rect<s32>(150, 400, 350, 400 + 32), 0, GUI_ID_NEW_GAME_BUTTON,
                        L"New Game", L"Launch a new game");
                    env->addButton(rect<s32>(150, 440, 350, 440 + 32), 0, GUI_ID_LOAD_GAME_BUTTON,
                        L"Load Game", L"Load a saved game");
                    env->addButton(rect<s32>(150, 480, 350, 480 + 32), 0, GUI_ID_LOAD_SCENARIO_BUTTON,
                        L"Load Scenario", L"Loads a prebuilt map");
                    env->addButton(rect<s32>(450, 400, 650, 400 + 32), 0, GUI_ID_NET_GAME_BUTTON,
                        L"Network Game", L"Join a network game");
                    env->addButton(rect<s32>(450, 440, 650, 440 + 32), 0, GUI_ID_SETTINGS_BUTTON,
                        L"Settings", L"Client Settings");
                    env->addButton(rect<s32>(450, 480, 650, 480 + 32), 0, GUI_ID_QUIT_BUTTON,
                        L"Exit", L"Quit");
                }
                return true;

                case GUI_ID_LOAD_SCENARIO_BUTTON:
                {
                    //Context.listbox->addItem(L"Load Game");
                    // There are some options for the file open dialog
                    // We set the title, make it a modal window, and make sure
                    // that the working directory is restored after the dialog
                    // is finished.
                    env->addFileOpenDialog(L"Please choose a scenario map.", true, 0, -1, true);
                    return true;
                }

                case GUI_ID_NET_GAME_BUTTON:
                {
                    //Context.listbox->addItem(L"Window created");
                    Context.counter += 30;
                    if (Context.counter > 200)
                        Context.counter = 0;

                    IGUIWindow* window = env->addWindow(
                        rect<s32>(100 + Context.counter, 100 + Context.counter, 350 + Context.counter, 200 + Context.counter),
                        false, // modal?
                        L"Network Game");

                    env->addStaticText(L"This Feature doesn't work yet .Please close me",
                        rect<s32>(20, 35, 230, 50),
                        true, // border?
                        false, // wordwrap?
                        window);

                }
                return true;

                case GUI_ID_SETTINGS_BUTTON:
                {
                    //Context.listbox->addItem(L"Window created");
                    Context.counter += 30;
                    if (Context.counter > 200)
                        Context.counter = 0;

                    IGUIWindow* window = env->addWindow(
                        rect<s32>(100 + Context.counter, 100 + Context.counter, 350 + Context.counter, 200 + Context.counter),
                        false, // modal?
                        L"Client Settings");

                    env->addStaticText(L"This Feature doesn't work yet .Please close me",
                        rect<s32>(20, 35, 230, 50),
                        true, // border?
                        false, // wordwrap?
                        window);
                }
                return true;

                case GUI_ID_LOAD_GAME_BUTTON:
                {
                    //Context.listbox->addItem(L"Load Game");
                    // There are some options for the file open dialog
                    // We set the title, make it a modal window, and make sure
                    // that the working directory is restored after the dialog
                    // is finished.
                    env->addFileOpenDialog(L"Please choose a save file.", true, 0, -1, true);
                    return true;
                }

                case GUI_ID_LAUNCH_BUTTON:
                {
                    view_window = 2;
                    env->clear();
                    env->addButton(rect<s32>(550, 550, 750, 550 + 32), 0, GUI_ID_MENU_BUTTON,
                        L"Back", L"Back to main menu");
                    /*
                    //Context.listbox->addItem(L"Window created");
                    Context.counter += 30;
                    if (Context.counter > 200)
                        Context.counter = 0;

                    IGUIWindow* window = env->addWindow(
                        rect<s32>(100 + Context.counter, 100 + Context.counter, 350 + Context.counter, 200 + Context.counter),
                        false, // modal?
                        L"Launch Game");

                    env->addStaticText(L"This Feature doesn't work yet .Please close me",
                        rect<s32>(20, 35, 230, 50),
                        true, // border?
                        false, // wordwrap?
                        window);
                    */
                }
                return true;

                default:
                    return false;
                
                }
                break;

            case EGET_FILE_SELECTED:
            {
                // show the model filename, selected in the file dialog
                IGUIFileOpenDialog* dialog =
                    (IGUIFileOpenDialog*)event.GUIEvent.Caller;
                //Context.listbox->addItem(dialog->getFileName());
            }
            break;

            default:
                break;
            }
        }

        return false;
    }

private:
    SAppContext& Context;
};

int main()
{
    // ask user for driver
    video::E_DRIVER_TYPE driverType = driverChoiceConsole();
    if (driverType == video::EDT_COUNT)
        return 1;

    // create device

    IrrlichtDevice* device = createDevice(driverType,
        core::dimension2d<u32>(800, 600), 64, false, false, true);

    if (device == 0)
        return 1; // could not create selected driver.

    device->setWindowCaption(L"Irrlicht Engine - Freeciv Client Test");
    //set up enviroment
    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* env = device->getGUIEnvironment();
    //load images
    ITexture* bg = driver->getTexture("client/bg.png");
    ITexture* intro = driver->getTexture("client/intro.png");
    //set up map rendering
    ITexture* map = 0;
    ICameraSceneNode* camera = 0;
    map = driver->addRenderTargetTexture(core::dimension2d<u32>(510, 300), "RTT1");
    camera = smgr->addCameraSceneNode(0, core::vector3df(0, 0, 50),
        core::vector3df(0, 0, 0));
    //set up fonts
    gui::IGUIFont* font = device->getGUIEnvironment()->getBuiltInFont();
    gui::IGUIFont* font2 =
        device->getGUIEnvironment()->getFont("client/fonthaettenschweiler.bmp");
    IGUISkin* skin = env->getSkin();
    if (font2)
        skin->setFont(font);
    //set up the main menu buttons
    env->addButton(rect<s32>(150, 400, 350, 400 + 32), 0, GUI_ID_NEW_GAME_BUTTON,
        L"New Game", L"Launch a new game");
    env->addButton(rect<s32>(150, 440, 350, 440 + 32), 0, GUI_ID_LOAD_GAME_BUTTON,
        L"Load Game", L"Load a saved game");
    env->addButton(rect<s32>(150, 480, 350, 480 + 32), 0, GUI_ID_LOAD_SCENARIO_BUTTON,
        L"Load Scenario", L"Loads a prebuilt map");
    env->addButton(rect<s32>(450, 400, 650, 400 + 32), 0, GUI_ID_NET_GAME_BUTTON,
        L"Network Game", L"Join a network game");
    env->addButton(rect<s32>(450, 440, 650, 440 + 32), 0, GUI_ID_SETTINGS_BUTTON,
        L"Settings", L"Client Settings");
    env->addButton(rect<s32>(450, 480, 650, 480 + 32), 0, GUI_ID_QUIT_BUTTON,
        L"Exit", L"Quit");

    // Store the appropriate data in a context structure.
    SAppContext context;
    context.device = device;
    context.counter = 0;

    int lastFPS = 0;

    // Then create the event receiver, giving it that context structure.
    MyEventReceiver receiver(context);

    // And tell the device to use our custom event receiver.
    device->setEventReceiver(&receiver);

    // create test earth
    ISceneNode* earth = 0;
    IAnimatedMesh* earthMesh = smgr->getMesh("client/earth.x");
    if (earthMesh)
    {
        //perform various task with the mesh manipulator
        scene::IMeshManipulator* manipulator = smgr->getMeshManipulator();

        // create mesh copy with tangent informations from original earth.x mesh
        scene::IMesh* tangentSphereMesh =
            manipulator->createMeshWithTangents(earthMesh->getMesh(0));

        // scale the mesh by factor 10
        core::matrix4 m;
        m.setScale(core::vector3df(20, 20, 20));
        manipulator->transform(tangentSphereMesh, m);

        earth = smgr->addMeshSceneNode(tangentSphereMesh);

        earth->setPosition(core::vector3df(0, 0, 0));

        earth->setMaterialTexture(0,
            driver->getTexture("client/earth.jpg"));

        // load heightmap, create normal map from it and set it
        /*video::ITexture* earthNormalMap = driver->getTexture("client/earthbump.jpg");
        if (earthNormalMap)
        {
            driver->makeNormalMapTexture(earthNormalMap, 20.0f);
            earth->setMaterialTexture(1, earthNormalMap);
            earth->setMaterialType(video::EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA);
        }
        */

        // adjust material settings
        earth->setMaterialFlag(video::EMF_FOG_ENABLE, true);

        // add rotation animator
        scene::ISceneNodeAnimator* anim =
            smgr->createRotationAnimator(core::vector3df(0, 0.1f, 0));
        earth->addAnimator(anim);
        anim->drop();

        // drop mesh because we created it with a create.. call.
        tangentSphereMesh->drop();
    }

    // add white light
    smgr->addLightSceneNode(0, core::vector3df(-50, 0, 25),
        video::SColorf(1.0f, 1.0f, 1.0f));

    // set ambient light
    smgr->setAmbientLight(video::SColor(0, 60, 60, 60));

    //set up video quality settings
    driver->getMaterial2D().TextureLayer[0].BilinearFilter = true;
    driver->getMaterial2D().AntiAliasing = video::EAAM_FULL_BASIC;
    while (device->run() && driver)
    {
        if (device->isWindowActive())
        {
            u32 time = device->getTimer()->getTime();

            driver->beginScene(true, true, video::SColor(255, 0, 0, 0));
            // draw background
            driver->draw2DImage(bg, core::position2d<s32>(0, 0));
            if (view_window == 0)
            {
                // draw intro image
                driver->draw2DImage(intro, core::position2d<s32>(145, 50));
                //draw buttons
                env->drawAll();

                // draw some other text
                if (font2)
                    font2->draw(L"Welcome to the experimental Irrlicht engine 3D client for freeciv.",
                        core::rect<s32>(250, 20, 650, 80),
                        video::SColor(255, 0, 0, 0));


            }
            if (view_window == 1)
            {
                // draw background and splash
                driver->draw2DImage(bg, core::position2d<s32>(0, 0));
                //draw buttons
                env->drawAll();

                // draw some other text
                if (font2)
                    font2->draw(L"This is the new game page.",
                        core::rect<s32>(20, 20, 650, 80),
                        video::SColor(255, 0, 0, 0));

            }
            if (view_window == 2)
            {
                //render map
                //set up camera
                driver->setRenderTarget(map, true, true, SColor(0, 0, 0, 0));
                smgr->setActiveCamera(camera);
                smgr->drawAll();
                driver->setRenderTarget(0, true, true, 0);
                // draw background and map
                driver->draw2DImage(bg, core::position2d<s32>(0, 0));
                driver->draw2DImage(map, core::position2d<s32>(145, 50));
                //draw buttons
                env->drawAll();

                // draw some other text
                if (font2)
                    font2->draw(L"This is the game page.",
                        core::rect<s32>(20, 20, 650, 80),
                        video::SColor(255, 0, 0, 0));
                int fps = driver->getFPS();

                if (lastFPS != fps)
                {
                    core::stringw str = L"Irrlicht Engine - Freeciv Client Test [";
                    str += driver->getName();
                    str += "] FPS:";
                    str += fps;

                    device->setWindowCaption(str.c_str());
                    lastFPS = fps;
                }

            }
            driver->endScene();
        }
    }

    device->drop();

    return 0;
}