
//#define SFML_STATIC
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>
#include <assert.h>
#include <stdio.h>
#include <string>
using namespace std;

#include "utils.h"
#include "Log.h"
#include "scripting.h"
#include "Game.h"
#include "ScreenLog.h"
#include "settings.h"

int main()
{
    g_log.setFile("ld22.log", false);
    srand( time(NULL) );

    registerScriptStuff();
    loadSettings();

    sf::RenderWindow window;
    if ( g_fullscreen )
        window.Create(sf::VideoMode(g_screenWidth, g_screenHeight, 32), "Alone in the park : iforce2d's LD22", sf::Style::Fullscreen);
    else
        window.Create(sf::VideoMode(g_screenWidth, g_screenHeight, 32), "Alone in the park : iforce2d's LD22", sf::Style::Default);

    // Create a clock for measuring the time elapsed
    sf::Clock stepClock;
    sf::Clock fpsClock;

    glClearColor(0.f, 0.f, 0.f, 0.f);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90.f, 1.f, 1.f, 500.f);

    stepClock.Reset();
    fpsClock.Reset();

    sf::Font MyFont;

    const char* fontfile = "UbuntuMono-R.ttf";
    if (!MyFont.LoadFromFile(fontfile))
        g_log.log(LL_ERROR, "Could not load font file %s", fontfile);
    else
        g_log.log(LL_INFO, "Loaded font file %s", fontfile);

    sf::Text sfText("", MyFont);
    sfText.SetCharacterSize(14);

    int frameNumber = 0;
    int lastFPSFrame = 0;
    string lastFPSDisplay;

    g_screenLog = new ScreenLog();

    g_game = new Game();
    g_game->setViewCenter( b2Vec2(-90,5) );
    g_game->setViewVerticalSpan(11.7f);
    g_game->setup();

    while (window.IsOpened())
    {
        sf::Event event;
        while (window.PollEvent(event))
        {
            if (event.Type == sf::Event::Closed)
                window.Close();

            if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Keyboard::Escape))
                window.Close();

            if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Keyboard::Space)) {
                if ( !g_game->m_started )
                    g_game->setPause(false);
            }

            if (event.Type == sf::Event::Resized) {
                glViewport(0, 0, event.Size.Width, event.Size.Height);
                window.SetView( sf::View( sf::FloatRect(0,0,window.GetWidth(),window.GetHeight()) ) );
            }

            if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Keyboard::R)) {
                loadSettings();
                delete g_game;
                g_game = new Game();
                g_game->setViewCenter( b2Vec2(-90,5) );
                g_game->setViewVerticalSpan(11.7f);
                g_game->setup();
            }
            else if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Keyboard::P)) {
                g_game->togglePause();
            }
            else {
                if (event.Type == sf::Event::KeyPressed)
                    g_game->keyDown(window, event.Key);
                else if (event.Type == sf::Event::KeyReleased)
                    g_game->keyUp(window, event.Key);
                else if (event.Type == sf::Event::MouseButtonPressed)
                    g_game->mouseDown(window, event.MouseButton);
                else if (event.Type == sf::Event::MouseButtonReleased)
                    g_game->mouseUp(window, event.MouseButton);
                else if (event.Type == sf::Event::MouseMoved)
                    g_game->mouseMove(window, event.MouseMove);
                else if ( event.Type == sf::Event::MouseWheelMoved)
                    g_game->mouseWheel(window, event.MouseWheel);
            }
        }

        window.SetActive();

        window.Clear();

        float timePassed = stepClock.GetElapsedTime();
        if (timePassed >= 1000/60.0f) {
            g_game->step();
            frameNumber++;
            stepClock.Reset();
        }
        else
            sf::Sleep(0);

        g_game->renderWorld(window);

        window.SaveGLStates();
        {
            window.SetView( sf::View( sf::FloatRect(0,0,window.GetWidth(),window.GetHeight()) ) );
            g_game->renderOverlay(window, sfText);

            window.SetView( sf::View( sf::FloatRect(0,0,window.GetWidth(),window.GetHeight()) ) );

            //fps counter display
            sfText.SetString( lastFPSDisplay );
            sfText.SetColor( sf::Color(0, 192, 0, 255) );
            sfText.SetPosition(window.GetWidth() - 70, 5);
            sfText.SetCharacterSize(16);
            window.Draw(sfText);

            g_screenLog->render(window, sfText);
        }
        window.RestoreGLStates();

        window.Display();

        //fps counter update
        if ( fpsClock.GetElapsedTime() > 1000 ) {
            char buf[32];
            sprintf(buf, "FPS: %d", frameNumber - lastFPSFrame);
            lastFPSDisplay = string(buf);
            lastFPSFrame = frameNumber;
            fpsClock.Reset();
        }
    }

    DISCARD(g_game);
    DISCARD(g_screenLog);
    cleanupScriptStuff();

    return EXIT_SUCCESS;
}
