#include "cache.h"
#include "scenes.h"
#include "globals.h"
#include "mymath.h"
#include "mykeyboard.h"
#include "frames.h"
#include "drawfx.h"
#include "gui.h"
#include "map.h"


ALLEGRO_BITMAP *main_menu_background;

GuiButton *menu_options[2];

float ActualIndex=0;


std::string title_map_name;

bool ShowTitleMapName;

int SceneChange=0;


class LevelBit {
  public:
    int index;
    float x, y, rw, rh, trw, trh, opacity;
    ALLEGRO_BITMAP *bit;
    std::string real_name;

    float text_opacity;

    LevelBit(std::string rn, ALLEGRO_BITMAP *b, int in) {real_name = rn; bit=b; index=in;rw = RSW(170);rh = RSH(170);trw=rw; trh=rh;}

    void Update() {
      float dist;
      dist = (index-ActualIndex)/3.0;
      opacity = 1.0 - (mabs(dist))*1.5;
      x = SCREEN_W/2+(dist*RSW(400.0));
      y = RSH(300);

      if (trw != rw) rw += ((trw-rw)/8) * DeltaTime;
      if (trh != rh) rh += ((trh-rh)/8) * DeltaTime;

      if (inside_rect(mouse_x, mouse_y, x-rw/2, y-rh/2, x+rw/2, y+rh/2)) {
        trw = RSW(170);
        trh = RSH(170);
        opacity *= 1.4;
        ShowTitleMapName = true;
        cursor = cursor_hand;
        title_map_name = real_name;
        if (Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_LCLICK]) {
          ActualLevel = index;
          SceneChange = SCENE_GAME;
          BlackFadeDir = 0.02;
        }
      }
      else {
        trw = RSW(160) * (1.0-mabs(dist)*0.8);
        trh = RSH(160) * (1.0-mabs(dist)*0.8);
      }

      if (opacity < 0.1) opacity=0.1;
      if (opacity > 1) opacity=1.0;
    }

    void Draw() {
      OPACITY_BLEND(opacity);
      DRAW_TRANSFORMED(bit, x, y, rw, rh, 0, 0);
      NORMAL_BLEND;
    }
};

std::deque<LevelBit *> level_bits;


float title_opacity=0;


void GScene_Menu::draw() {
  al_clear_to_color(al_map_rgb_f(0, 0, 0));


  DRAW_TRANSFORMED(main_menu_background, SCREEN_W/2, SCREEN_H/2, SCREEN_W, SCREEN_H, 0, 0);

  for (int i=0; i!=2; i+=1) menu_options[i]->draw();

  std::deque<LevelBit *>::iterator it;
  for (it=level_bits.begin(); it!=level_bits.end(); it+=1) {
    (*it)->Draw();
  }


  if (title_opacity > 0) {
    OPACITY_BLEND(title_opacity);
    score_font->Print(title_map_name, SCREEN_W/2-score_font->Width(title_map_name)/2+2, RSH(75)+2, al_map_rgba_f(0,0,0, title_opacity));
    score_font->Print(title_map_name, SCREEN_W/2-score_font->Width(title_map_name)/2, RSH(75), al_map_rgba_f(1,1,1, title_opacity));
    NORMAL_BLEND;
  }


  if (BlackFade != 0) {
    al_draw_filled_rectangle(0, 0, SCREEN_W, SCREEN_H, al_map_rgba_f(0, 0, 0, BlackFade));
  }


  float rw, rh;
  rw = RSW(al_get_bitmap_width(cursor));
  rh = RSH(al_get_bitmap_height(cursor));

  Vec2D last_pos;
  last_pos = Vec2D(mick_x, mick_y);
  DrawTransformedMotionBlur(cursor, mouse_x+rw/2, mouse_y+rh/2, rw, rh, 0, 0, last_pos);

  al_flip_display();
}



void GScene_Menu::update() {
  ShowTitleMapName= false;

  cursor = cursor_normal;

  UpdateGlobalZoomFactor();
  poll_my_keyboard();
  UpdateDelta();

  if (inside_rect(mouse_x, mouse_y, SCREEN_W/2-RSW(262), RSH(200), SCREEN_W/2+RSW(238), RSH(385))) {
    ActualIndex -= ((float)(SCREEN_W/2-mouse_x)/(float)(SCREEN_W/2)) * 0.15;

    if (ActualIndex < 0) ActualIndex=0;
    if (ActualIndex > MaximumAchievedLevel-1) ActualIndex=MaximumAchievedLevel-1;

    std::deque<LevelBit *>::iterator it;
    for (it=level_bits.begin(); it!=level_bits.end(); it+=1) {
      (*it)->Update();
    }
  }

  if (ShowTitleMapName) {
    title_opacity += 0.05 * DeltaTime;
  }
  else {
    title_opacity -= 0.05 * DeltaTime;
  }

  if (title_opacity > 1.0) title_opacity=1.0;
  if (title_opacity < 0.0) title_opacity=0.0;


  BlackFade += BlackFadeDir*DeltaTime;
  if (BlackFade < 0) BlackFade=0;
  if (BlackFade > 1) {
    BlackFade=1;
    if (SceneChange != 0) Scene = SceneChange;
  }

  for (int i=0; i!=2; i+=1) menu_options[i]->update();

  FramesUpdated+=1;
}


void MenuHiscores() {
  SceneChange = SCENE_HISCORES;
  BlackFadeDir = 0.02;
}

void MenuCredits() {
  SceneChange = SCENE_END;
  BlackFadeDir = 0.02;
}

void MenuQuit() {
  SceneChange=-1;
  BlackFadeDir = 0.02;
}


bool MenuCreated=0;

void create_menu() {
  if (MenuCreated) return;
  MenuCreated=1;
  main_menu_background = al_load_bitmap("Graphics/GUI/MenuBackground.png");
  for (int i=0; i!=2; i+=1) {
    GuiButton *gb;
    void (*func) ();
    gb = new GuiButton();
    func = NULL;

    if (i == 0) func = &MenuHiscores;
    if (i == 1) func = &MenuQuit;

    gb->init(SCREEN_W/2-RSW(200/2), RSH(500) + RSH(125)*i, RSW(200), RSH(100), func, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
    gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
    gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
    GuiElement *gt;
    gt = new GuiElement();
    gt->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h());

    if (i==0)  gb->set_shortcut(ALLEGRO_KEY_H);
    if (i==1)  gb->set_shortcut(ALLEGRO_KEY_ESCAPE);

    if (i==0) gt->set_base_bit(load_cache_bitmap("Graphics/GUI/ButtonHiscores.png"));
    if (i==1) gt->set_base_bit(load_cache_bitmap("Graphics/GUI/ButtonQuit.png"));

    gb->set_element(gt);
    menu_options[i] = gb;
  }

  title_opacity =0;

  level_bits.clear();
  for (int i=0; i!=MaximumAchievedLevel; i+=1) {
    level_bits.push_back(new LevelBit(GetRealMapName(GameLevels[i]), al_load_bitmap(("Maps/" + GameLevels[i]+ ".png").c_str()), i));
    level_bits[i]->Update();
  }
}


void GScene_Menu::main() {
  ChangeGlobalMusic(music_menu);

  SceneChange=0;

  BlackFade=1.0;
  BlackFadeDir=-0.02;

  create_menu();
  al_start_timer(timer);
  ResetDelta();
  update();
  while (Scene == SCENE_MENU) {
    ALLEGRO_EVENT event;
    al_wait_for_event(queue, &event);
    if (event.type == ALLEGRO_EVENT_TIMER) {
      draw();
      update();
    }
  }
  DrawLoadingScreen();
}
