#include <stdio.h>

#include "config.h"

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_mixer.h"

#include "enum.h"

#include "Engine.h"
#include "Player.h"
#include "Room.h"
#include "Kaos.h"
#include "HyperKaos.h"
#include "TextBox.h"
#include "Scene.h"
#include "Synergy.h"

typedef struct timer Timer;
#include "extern.h"

void bufferData(enum dataChunks chunk)
{
  hasMusic = 0;
  applySurface(0,0, loadingTxt, screen, NULL);
  SDL_Flip(screen);
  printf("Loading map chunk\n");
  switch (chunk){
  case LEVEL1:

#ifdef SOUND_ON
    bgmData[0] = loadBGM("assets/snd/bgm/artificial sun stage (mamon machine mix).mp3");
#endif

    mapBuffer[0] = newRoom("assets/img/backgrounds/blueroom.gif", 10);
    mapBuffer[1] = newRoom("assets/img/backgrounds/redroom.gif", 4);
    mapBuffer[2] = newRoom("assets/img/backgrounds/greenroom.gif", 4);
    mapBuffer[3] = newRoom("assets/img/backgrounds/darkroom.gif", 4);

    addObstacle(mapBuffer[0], 64,92,22,16);
    addFgObj(mapBuffer[0], 64,64,22,55,"assets/img/objects/floatingChips.png", 4, 1, 255);
    addObstacle(mapBuffer[0], 320 - 64 - 22, 92,22,16);
    addFgObj(mapBuffer[0], 320 - 64 - 22, 64, 22, 55, "assets/img/objects/floatingChips.png", 4, 1, 255);

    addWarp(mapBuffer[0], 0,0,8,180, LEVEL1, 1, 304,90);
    addWarp(mapBuffer[0], 312,0,8,180,  LEVEL1, 2, 16,90);
    addWarp(mapBuffer[0], 0,0,320,8,  LEVEL1, 3, 160,164);

    addWarp(mapBuffer[2], 0,0,8,180, LEVEL1, 0, 304,90);
    addWarp(mapBuffer[1], 312,0,8,180, LEVEL1, 0, 16,90);
    addWarp(mapBuffer[3], 0,172,320,8, LEVEL1, 0, 160,16);

    addWarp(mapBuffer[2], 312,0,8,180, LEVEL2,0, 16,165);


    dialogueData[0] = newGTextBox(loadImage("assets/img/portraits/test.gif"));
    addText(dialogueData[0], "I can't help but feel like I'm");
    addText(dialogueData[0], "trapped in the universe...");
    addText(dialogueData[0], "Do you ever feel that way?");
    addText(dialogueData[0], "It's maddening.");
    addText(dialogueData[0], "Let me know if you feel it.");

    dialogueData[1] = newGTextBox(loadImage("assets/img/portraits/kmage.gif"));
    addText(dialogueData[1], "Whoa! You and I look so alike!");

    dialogueData[2] = newTextBox();
    addText(dialogueData[2], "It's a floating computer chip.");
    addText(dialogueData[2], "How it can spin forever");
    addText(dialogueData[2], "without slowing or stopping");
    addText(dialogueData[2], "is a mystery to me...");
    addText(dialogueData[2], "Looks damn cool though!");

    dialogueData[3] = newGTextBox(loadImage("assets/img/portraits/test.gif"));
    addText(dialogueData[3], "Well fine then!");

    dialogueData[4] = newGTextBox(loadImage("assets/img/portraits/test.gif"));
    addText(dialogueData[4], "Thanks buddy.");

    kaosData[0] = newConversation(0);
    kaosData[1] = newErase('t', 2);
    kaosData[2] = newManip(hero, 0, 0);
    kaosData[3] = newConversation(1);
    kaosData[4] = newManip(hero, 0 ,0);
    kaosData[5] = newConversation(2);
    kaosData[6] = newConversation(3);
    kaosData[7] = newConversation(4);
    kaosData[12] = newErase('f', 1);
    kaosData[13] = newErase('o', 1);
    kaosData[14] = newErase('s', 0);

    HyperKaos* choiceBranchA = newHyperKaos(1,0, 0, 0, 0, 0);
    addKaos(choiceBranchA, kaosData[7]);
    addKaos(choiceBranchA, kaosData[2]);
    addTrigger(mapBuffer[3], choiceBranchA);
    choiceBranchA = NULL;

    HyperKaos* choiceBranchB = newHyperKaos(1,0, 0, 0, 0, 0);
    addKaos(choiceBranchB, kaosData[6]);
    addKaos(choiceBranchB, kaosData[2]);
    addTrigger(mapBuffer[3], choiceBranchB);
    choiceBranchB = NULL;

    HyperKaos* destroyChp2 = newHyperKaos(1,0,0,0,0,0);

    addKaos(destroyChp2, kaosData[12]);
    addKaos(destroyChp2, kaosData[13]);
    addKaos(destroyChp2, kaosData[14]);

    Synergy* testSigil = newSynergy(0,'e', 0, 74, 256, 48, destroyChp2);
    addSigil(mapBuffer[0], testSigil);

    destroyChp2 = NULL;
    testSigil = NULL;

    kaosData[8] = newChoice("Let her know?", "Sure thing", "Nope", mapBuffer[3]->eventTriggers[0], mapBuffer[3]->eventTriggers[1]);

    if(notCompleted(3))
    {
      HyperKaos* testTextBox = newHyperKaos(3, 0, 0, 0, 320, 180);
      addKaos(testTextBox, kaosData[4]);
      addKaos(testTextBox, kaosData[0]);
      addKaos(testTextBox, kaosData[1]);
      addKaos(testTextBox, kaosData[8]);

      addTrigger(mapBuffer[3], testTextBox);
      testTextBox = NULL;
    }

    Player* randomDude;
    if (notCompleted(5))
      randomDude = newPlayer("assets/img/characters/kmage.png", -16, -16);
    else
      randomDude = newPlayer("assets/img/characters/kmage.png", 160, 90);


    addPerson(mapBuffer[1], randomDude);
    addObstacle(mapBuffer[1], 152,76,16,22);
    kaosData[9] = newFaceEachother(hero, randomDude);
    kaosData[10] = newTeleport(randomDude, 160, 90, 0);
    kaosData[11] = newErase('t', 0);
    randomDude = NULL;

  if(notCompleted(5))
  {
    HyperKaos* tpDude = newHyperKaos(5, 0, 300, 0, 20, 180);
    addKaos(tpDude, kaosData[10]);
    addKaos(tpDude, kaosData[11]);
    addTrigger(mapBuffer[1],tpDude);
    tpDude = NULL;
  }

    HyperKaos* randomDudeConvo = newHyperKaos(1, 1, 152, 82, 16, 16);
    addKaos(randomDudeConvo, kaosData[3]);
    addKaos(randomDudeConvo, kaosData[9]);
    addKaos(randomDudeConvo, kaosData[2]);
    addTrigger(mapBuffer[1], randomDudeConvo);
    randomDudeConvo = NULL;


    break;

  case LEVEL2:
    mapBuffer[0] = newRoom("assets/img/backgrounds/crystal_path.png", 4);
    addObstacle(mapBuffer[0], 0,0,320,155);
    addObstacle(mapBuffer[0], 0,175,320,10);
    addWarp(mapBuffer[0], 0,155,8,20, LEVEL1, 2, 304, 90);
    addWarp(mapBuffer[0], 312,155,8,20, LEVEL2, 1, 295, 158);

    mapBuffer[1] = newRoom("assets/img/backgrounds/crystal_room.png", 4);
    addObstacle(mapBuffer[1], 0,0,320,115);
    addObstacle(mapBuffer[1], 0,115,180,65);
    addWarp(mapBuffer[1], 312,172,8,8, LEVEL2, 0, 304, 165);
    break;

  case LEVEL3:
    break;
  }
  printf("Loaded map chunk\n");
}

void dataPurge(int a, int b, int c, int d, int e)
{
  int i;
  for (i = 0; i < a; i++)
    deleteRoom(mapData[i]);
  for (i = 0; i < b; i++)
    deleteTextBox(dialogueData[i]);
  for (i = 0; i < c; i++)
    kaosData[i]->destroy(kaosData[i]);

#ifdef SOUND_ON
  for (i = 0; i < d; i++)
    Mix_FreeMusic(bgmData[i]);
  for (i = 0; i < e; i++)
    Mix_FreeChunk(sfxData[i]);
#endif

}

void unloadData(enum dataChunks chunk)
{
  printf("Unloading old map chunk\n");
  switch(chunk)
  {
    case LEVEL1:
      dataPurge(4,5,15,1,0);
      break;
    case LEVEL2:
      dataPurge(2,0,0,0,0);
      break;
    case LEVEL3:
      break;
    }
  printf("Unloaded old map chunk\n");
}

void pushBufferData()
{
  printf("Pushing map buffer\n");
  mapData = mapBuffer;
  mapBuffer = (Room**)malloc(64*sizeof(Room*));

#ifdef SOUND_ON
  if (hasMusic)
    Mix_PlayMusic(bgmData[0], -1);
#endif

  printf("Map buffer clean\n");
}

void pager()
{
  if (thisChunk != nextChunk)
  {

#ifdef SOUND_ON
    if (Mix_PlayingMusic())
    {
      Mix_HaltMusic();
    }
#endif

    unloadData(thisChunk);
    pushBufferData();
    thisChunk=nextChunk;
  }
}