#include "gamestates.h"
#include "jgame.h"
#include "jfile.h"
#include "jinput.h"
#include "jdraw.h"
#include "jaudio.h"
#include <string>
#include <SDL2/SDL.h>

#define DIAPO_ESPERAR		0
#define DIAPO_FADEIN		1
#define DIAPO_SHOW		    2
#define DIAPO_PRINT		    3
#define DIAPO_MUSICA		4
#define DIAPO_FADEOUT		5
#define DIAPO_FADEMUSIC	    6

namespace gamestate
{
    namespace sequence
    {
        int num_diapositives = 0;
        char *sequence_file = nullptr;
        char *sfpointer = nullptr;
        uint32_t wait_until = 0;

        uint8_t getByte()
        {
            return *(sequence_file++);
        }

        uint16_t getWord()
        {
            return getByte() + (getByte() << 8);
        }

        std::string getString()
        {
            uint8_t tamanyCadena = getByte();
            char filename[256];
            for (int i=0; i<tamanyCadena; i++) filename[i] = getByte();
            filename[tamanyCadena] = '\0';
            return std::string(filename);
        }

        void drawPic(std::string filename)
        {
            draw::surface *pic = draw::loadSurface(filename);
            draw::setSource(pic);
            draw::loadPalette(filename);
            draw::draw(0, 0, 320, 200, 0, 0);
            draw::freeSurface(pic);
        }

        void drawText(const int x, const int y, const uint8_t color, std::string text)
        {
            draw::surface *pic = draw::loadSurface("fuente2.gif");
            draw::setSource(pic);
            draw::setTrans(0);
            draw::setPaletteEntry(64, 255, 255, 255);
            draw::setPaletteEntry(65, 255, 0, 0);
            draw::setPaletteEntry(66, 0, 255, 0);
            draw::setPaletteEntry(67, 0, 0, 255);
            draw::setPaletteEntry(68, 0, 0, 0);
            draw::swapcol(1, color+64);
            draw::swapcol(2, 68);
            const int len = text.length();
            for (int i=0;i<len;++i)
            {
                char chr = text[i];
                draw::draw(x+i*7, y, 6, 6, (int(chr)-32)*7, 0);
            }
            draw::setTrans(255);
            draw::restorecol(1);
            draw::restorecol(2);
            draw::freeSurface(pic);
            draw::render();
        }

        bool loop()
        {
            if ( (wait_until > 0) && (SDL_GetTicks() < wait_until) )
            {
                if (!draw::isfading() && (input::anyKeyPressed() || input::mouseBtn(1))) {
                    wait_until=0;
                    if (input::keyPressed(SDL_SCANCODE_ESCAPE)) num_diapositives=0;
                } else {
                    draw::render();
                    return true;
                }
            }
            if (num_diapositives==0) {
                gamestate::menu::init();
                free(sfpointer);
                return true;
            }

            const char tipo_diapositiva = *(sequence_file++);
            switch ( tipo_diapositiva )
            {
                case DIAPO_ESPERAR:
                {
                    const uint16_t time = getWord();
                    wait_until = SDL_GetTicks() + time;
                    printf("- Esperar(%i)\n", time);
                    break;
                }
                case DIAPO_FADEIN:
                {
                    std::string filename = getString();
                    drawPic(filename);
                    draw::fadein();
                    draw::render();
                    wait_until = SDL_GetTicks() + 500;
                    printf("- FadeIn('%s')\n", filename.c_str());
                    break;
                }
                case DIAPO_SHOW:
                {
                    std::string filename = getString();
                    drawPic(filename);
                    draw::render();
                    printf("- Show('%s')\n", filename.c_str());
                    break;
                }
                case DIAPO_PRINT:
                {
                    const uint16_t x = getWord();
                    const uint16_t y = getWord();
                    const uint8_t col = getByte();
                    std::string text = getString();
                    drawText(x, y, col, text);
                    printf("- Print(%i, %i, %i, '%s')\n", x, y, col, text.c_str());
                    break;
                }
                case DIAPO_MUSICA:
                {
                    std::string filename = getString();
                    audio::playMusic(audio::loadMusic(filename));
                    printf("- PlayMusic('%s')\n", filename.c_str());
                    break;
                }
                case DIAPO_FADEOUT:
                {
                    draw::fadeout();
                    wait_until = SDL_GetTicks() + 500;
                    printf("- FadeOut()\n");
                    break;
                }
                case DIAPO_FADEMUSIC:
                    draw::fadeout();
                    audio::fadeoutMusic();
                    wait_until = SDL_GetTicks() + 500;
                    printf("- FadeOutMusic()\n");
                    break;
            }
            num_diapositives--;
            return true;
        }

        void init()
        {
            draw::setTrans(255);
            const int fase = game::getConfig("fase");
            std::string filename;

            switch (fase)
            {
                case -1: filename = "seqIN.seq"; break;
                case  0: filename = "seq00.seq"; break;
                case  5: filename = "seq05.seq"; break;
                case 10: filename = "seq10.seq"; break;
                case 15: filename = "seq15.seq"; break;
                case 20: filename = "seq20.seq"; break;
                case 25: filename = "seq25.seq"; break;
                case 30: filename = "seq30.seq"; break;
            }

            int filesize;
            sequence_file = file::getFileBuffer(filename, filesize);
            sfpointer = sequence_file;
            num_diapositives = *(sequence_file++);

            game::setState(&gamestate::sequence::loop);
        }
    }
}
