#include "CMain.hpp"
#include "CDisplay.hpp"
#include "Interaction.hpp"
#include "CMenu.hpp"
#include "Quests.hpp"

CMenu menu;

static int key_up = 0;
static int key_down = 0;
static int key_alt = 0;


CMenu::CMenu()
{
	choice = 0;
	inventory = 0;

    done = false;
    
}

CMenu::~CMenu()
{
}

void CMenu::Init()
{
  	status_screen = load_bitmap("./data/status.tga", NULL);
	selector = load_bitmap("./data/selector.bmp", NULL);
	menuchoice_screen = load_bitmap("./data/menuchoice.bmp", NULL);
	inventorymenuchoice_screen = load_bitmap("./data/invchoice.bmp", NULL);
	inventory_screen = load_bitmap("./data/status.tga", NULL);
    choice_bmp = load_bitmap("./data/choice.bmp", NULL);
    item_type = load_bitmap("./data/items.bmp", NULL);
}

void CMenu::DisplayStatus(/*CPlayer or CNPC*/)
{
  
	clear_keybuf();
	done = false;

	do{
//			if(key[KEY_LCONTROL] || key[KEY_RCONTROL]) done = true;

        if(inventory == 0)
        {
            player[App.selected_pc].UpdateStats();
   			masked_blit( status_screen, Display.GetSurface(), 0, 0, 0, 0, status_screen->w, status_screen->h);
            textprintf_ex(Display.GetSurface(), font, 70, 72,  makecol(0,0,0), -1, "Str %d", player[App.selected_pc].str);
            textprintf_ex(Display.GetSurface(), font, 70, 86,  makecol(0,0,0), -1, "Wis %d", player[App.selected_pc].wis);
            textprintf_ex(Display.GetSurface(), font, 70, 100, makecol(0,0,0), -1, "Con %d", player[App.selected_pc].con);
            textprintf_ex(Display.GetSurface(), font, 70, 114, makecol(0,0,0), -1, "Cha %d", player[App.selected_pc].chr);
            textprintf_ex(Display.GetSurface(), font, 70, 128, makecol(0,0,0), -1, "Int %d", player[App.selected_pc].intell);
            // blank line
            textprintf_ex(Display.GetSurface(), font, 70, 156, makecol(128,128,0), -1, "HP %d(%d)", player[App.selected_pc].hp,player[App.selected_pc].max_hp);
            textprintf_ex(Display.GetSurface(), font, 70, 170, makecol(0,0,128), -1, "Mana %d(%d)", player[App.selected_pc].mana,player[App.selected_pc].max_mana);
            
            textprintf_ex(Display.GetSurface(), font, 45, 190, makecol(255,255,0), -1, "Gold %d", player[0].gold); // remember the players share the gold
            textprintf_ex(Display.GetSurface(), font, 45, 200, makecol(0,0,0), -1,"Experience %d", player[App.selected_pc].exp);
            textprintf_ex(Display.GetSurface(), font, 45, 210, makecol(0,0,0), -1, "Armor Class %d (the higher the better)", player[App.selected_pc].ac);
            textprintf_ex(Display.GetSurface(), font, 45, 220, makecol(0,0,0), -1, "Damage %d", player[App.selected_pc].dam);

 int tnl = level_table[player[App.selected_pc].level+1]-player[App.selected_pc].exp;
 if(player[App.selected_pc].level+1 <= MAX_LEVEL && tnl > 0)
            textprintf_ex(Display.GetSurface(), font, 45, 230, makecol(0,0,0), -1, "Experience needed for next level: %d", tnl);
 else if(player[App.selected_pc].level+1 <= MAX_LEVEL && tnl <= 0)
            textprintf_ex(Display.GetSurface(), font, 45, 230, makecol(255,0,0), -1, "Experience needed for next level: You may level!");
            
            textprintf_ex(Display.GetSurface(), font, 15, 7, makecol(0,0,0), -1, "Name: %s", player[App.selected_pc].name.c_str());

        	StatusSelection();
        }
        
        else if(inventory == 1)
        {
            player[App.selected_pc].UpdateInventory();
   			DisplayInventory(true);//masked_blit( inventory_screen, Display.GetSurface(), 0, 0, 0, 0, status_screen->w, status_screen->h);
        }
        
        else if(inventory == 2)
        {
             player[App.selected_pc].UpdateInventory();
             DisplayInventory(false);
             InteractInventory();

        }


            blit( Display.GetSurface(), screen, 0,0, 0,0, screen->w, screen->h);
            clear(Display.GetSurface());
	}while(!done);

    //hack
	remove_keyboard();
	install_keyboard();
	
}

void CMenu::StatusSelection()
{
   

    update_key(KEY_UP, &key_up);
    update_key(KEY_DOWN, &key_down);
    update_key(KEY_RCONTROL, &key_rctrl);
    update_key(KEY_LCONTROL, &key_lctrl);
    update_key(KEY_ALT, &key_alt);



if(inventory == 0)
	masked_blit( menuchoice_screen, Display.GetSurface(), 0, 0, screen->w/2-menuchoice_screen->w/2, 400, menuchoice_screen->w, menuchoice_screen->h);
	
	masked_stretch_blit( selector, Display.GetSurface(), 0, 0, selector->w, selector->h,  screen->w/2-menuchoice_screen->w/2+120, 411+choice*14, 9,9);
    if(key_up == 1 && choice > 0 ) choice --;
    if(key_down == 1 && choice < 2 ) choice ++;
    
    // Inventory
    if( (choice == 0 && key_rctrl == 1) || (choice == 0 && key_lctrl == 1) )
    {
        inventory^=1; // toggle
    }

    // Next Character
   if(CHECK_BIT(quest.quest_bit, QUEST_RECRUIT_FEMALE))
    if( (choice == 1 && key_rctrl == 1) || (choice == 1 && key_lctrl == 1) )
    {
        App.selected_pc ^= 1; // toggle!
    }

    // Exit
    if( (choice == 2 && key_rctrl == 1) || (choice == 2 && key_lctrl == 1) || key_alt == 1 )
    {
      done = true;
      inventory = 0;
      choice = 0;
    }
  
}

void CMenu::DisplayInventory(bool control)
{
	masked_blit( inventory_screen, Display.GetSurface(), 0, 0, 0, 0, inventory_screen->w, inventory_screen->h);
	player[App.selected_pc].UpdateEquip();
    textprintf_ex(Display.GetSurface(), font, screen->w/2-50, screen->h/2-90, makecol(0,0,0), -1, "Head: %s", player[App.selected_pc].equip[WEAR_HEAD].name.c_str());
    textprintf_ex(Display.GetSurface(), font, screen->w/2-50, screen->h/2-80, makecol(0,0,0), -1, "Arms: %s", player[App.selected_pc].equip[WEAR_ARM].name.c_str());
    textprintf_ex(Display.GetSurface(), font, screen->w/2-50, screen->h/2-70, makecol(0,0,0), -1, "Legs: %s", player[App.selected_pc].equip[WEAR_LEG].name.c_str());
    textprintf_ex(Display.GetSurface(), font, screen->w/2-50, screen->h/2-60, makecol(0,0,0), -1, "Ring: %s", player[App.selected_pc].equip[WEAR_RING].name.c_str());
    textprintf_ex(Display.GetSurface(), font, screen->w/2-50, screen->h/2-50, makecol(0,0,0), -1, "Weapon: %s", player[App.selected_pc].equip[WEAR_WEAPON].name.c_str());

    textprintf_ex(Display.GetSurface(), font, screen->w/2-50, screen->h/2-30, makecol(0,0,0), -1, "Inventory: ");
    for(int i = 0; i<MAX_INV; ++i)
    {
    if(player[App.selected_pc].inv[i].id!=0)
    {
      masked_blit(item_type, Display.GetSurface(), 0, player[App.selected_pc].inv[i].type*8, screen->w/2-50, screen->h/2-20+i*10, 8, 8);
      if(player[App.selected_pc].inv[i].equipped)
         textprintf_ex(Display.GetSurface(), font, screen->w/2-40, screen->h/2-20+i*10, makecol(0,0,0), -1, "%d. %s (equipped)", i, player[App.selected_pc].inv[i].name.c_str());
      else
         textprintf_ex(Display.GetSurface(), font, screen->w/2-40, screen->h/2-20+i*10, makecol(0,0,0), -1, "%d. %s", i, player[App.selected_pc].inv[i].name.c_str());
    }
    else
         textprintf_ex(Display.GetSurface(), font, screen->w/2-40, screen->h/2-20+i*10, makecol(0,0,0), -1, "%d. ", i);

    }

    textprintf_ex(Display.GetSurface(), font, screen->w/2-50, screen->h/2-20+MAX_INV*10, makecol(0,0,0), -1, "Exit");


if(control)
{
/*    static int key_up = 0;
    static int key_down = 0;
    static int key_rctrl = 0;
    static int key_lctrl = 0;
*/
    update_key(KEY_UP, &key_up);
    update_key(KEY_DOWN, &key_down);
    update_key(KEY_RCONTROL, &key_rctrl);
    update_key(KEY_LCONTROL, &key_lctrl);
    update_key(KEY_ALT, &key_alt);
    
    if(key_up == 1 && choice > 0 ) choice --;
    if(key_down == 1 && choice < MAX_INV ) choice ++;
    masked_stretch_blit( selector, Display.GetSurface(), 0, 0, selector->w, selector->h,  screen->w/2-75, screen->h/2-20+choice*10, 9,9);
    

    if( (choice == MAX_INV && key_rctrl == 1) || (choice == MAX_INV && key_lctrl == 1) || key_alt == 1 )
    {
        done = true;
        choice = 0;
        inventory = 0;
    }
    else if( key_rctrl == 1 || key_lctrl == 1 )
    {
         if(player[App.selected_pc].inv[choice].id != 0)
         {
              inventory = 2;
              selected_item = choice;
              choice = 0;
              //readkey();
              //while(keypressed()) {}
//              remove_keyboard();
//              install_keyboard();
         }
    }
    

}
}


void CMenu::InteractInventory()
{
/*
    static int key_up = 1;
    static int key_down = 1;
    static int key_rctrl = 1;
    static int key_lctrl = 1;
*/
    update_key(KEY_UP, &key_up);
    update_key(KEY_DOWN, &key_down);
    update_key(KEY_RCONTROL, &key_rctrl);
    update_key(KEY_LCONTROL, &key_lctrl);
    update_key(KEY_ALT, &key_alt);

    if(key_up == 1 && choice > 0 ) choice --;
    if(key_down == 1 && choice < 3 ) choice ++;

   
    
    DisplayItemInfo(player[App.selected_pc].inv[selected_item].id);

    // Wear
    if((choice == 0 && key_rctrl == 1) || (choice == 0 && key_lctrl == 1))
    {
        // TODO: Remove 1st arg -- unnec. see DropObject for example
        player[App.selected_pc].WearObject(player[App.selected_pc].inv[selected_item].id, selected_item);
        player[App.selected_pc].UpdateInventory();
        player[App.selected_pc].UpdateEquip();
    }

    // Give to other playa
    if((choice == 1 && key_rctrl == 1) || (choice == 1 && key_lctrl == 1))
    {
          bool swapped = false;
      if( CHECK_BIT(quest.quest_bit, QUEST_RECRUIT_FEMALE))
      {
          for(int i = 0; i<MAX_INV; ++i)
          {
            if(player[App.selected_pc^1].inv[i].id == 0 && !swapped)
            {
//                // unequip item
                  if( player[App.selected_pc].inv[selected_item].equipped == true)
                  {
                       player[App.selected_pc].RemoveObject(selected_item);
                  }

              
                player[App.selected_pc^1].inv[i].id = player[App.selected_pc].inv[selected_item].id;
                player[App.selected_pc].inv[selected_item].id = 0;
                swapped = true;
                player[App.selected_pc].UpdateEquip();
                player[App.selected_pc].UpdateInventory();
                return;
            }

          }

          if(!swapped)
          {
            Talk("The other player's inventory is full!", "");
          }
       }
    }

    // Drop
    if((choice == 2 && key_rctrl == 1) || (choice == 2 && key_lctrl == 1))
    {
        player[App.selected_pc].DropObject(selected_item);
    }
    
    // Back
    if((choice == 3 && key_rctrl == 1) || (choice == 3 && key_lctrl == 1))
    {
         inventory = 1;
         selected_item = 0;
         choice = 0;
 
    }
    
    if(key_alt == 1)
    {
         inventory = 1;
         selected_item = 0;
         choice = 0;
    }

    masked_blit( inventorymenuchoice_screen, Display.GetSurface(), 0, 0, 200, 400, menuchoice_screen->w, menuchoice_screen->h);
       textprintf_ex(Display.GetSurface(), font, 315, 408, makecol(255,255,255), -1, "Wear");
       textprintf_ex(Display.GetSurface(), font, 315, 418, makecol(255,255,255), -1, "Give to Other PC");
       textprintf_ex(Display.GetSurface(), font, 315, 428, makecol(255,255,255), -1, "Drop");
       textprintf_ex(Display.GetSurface(), font, 315, 438, makecol(255,255,255), -1, "Back");
	masked_stretch_blit( selector, Display.GetSurface(), 0, 0, selector->w, selector->h,  300, 405+choice*10, 9,9);


}


void CMenu::DisplayItemInfo(int id)
{
 if(id!=0)
 {
   textprintf_ex(Display.GetSurface(), font, 15, screen->h/2-50, makecol(255,255,255), -1, "Information:");
   textprintf_ex(Display.GetSurface(), font, 35, screen->h/2-30, makecol(255,255,255), -1, "Name: %s", player[App.selected_pc].list[id-1].name.c_str());
   textprintf_ex(Display.GetSurface(), font, 35, screen->h/2-20, makecol(255,255,255), -1, "Damage: %d", player[App.selected_pc].list[id-1].dam);
   textprintf_ex(Display.GetSurface(), font, 35, screen->h/2-10, makecol(255,255,255), -1, "Armour: %d", player[App.selected_pc].list[id-1].ac);
   
  if(player[App.selected_pc].list[id-1].type == WEAR_HEAD )
   textprintf_ex(Display.GetSurface(), font, 35, screen->h/2-0, makecol(255,255,255), -1, "Type: Head Armor");
  else if(player[App.selected_pc].list[id-1].type == WEAR_ARM )
   textprintf_ex(Display.GetSurface(), font, 35, screen->h/2-0, makecol(255,255,255), -1, "Type: Arm Armor");
  else if(player[App.selected_pc].list[id-1].type == WEAR_LEG )
   textprintf_ex(Display.GetSurface(), font, 35, screen->h/2-0, makecol(255,255,255), -1, "Type: Leg Armor");
  else if(player[App.selected_pc].list[id-1].type == WEAR_RING )
   textprintf_ex(Display.GetSurface(), font, 35, screen->h/2-0, makecol(255,255,255), -1, "Type: Rings");
  else if(player[App.selected_pc].list[id-1].type == WEAR_WEAPON )
   textprintf_ex(Display.GetSurface(), font, 35, screen->h/2-0, makecol(255,255,255), -1, "Type: Weapon");
  else if(player[App.selected_pc].list[id-1].type == TYPE_USABLE )
   textprintf_ex(Display.GetSurface(), font, 35, screen->h/2-0, makecol(255,255,255), -1, "Type: Other(usable)");
  else
   textprintf_ex(Display.GetSurface(), font, 35, screen->h/2-0, makecol(255,255,255), -1, "Type: Other");
 }
}

bool CMenu::Choice(BITMAP *savescreen)
{
//    key_space = 1;
 //   simulate_keypress(KEY_SPACE);
BITMAP *test = savescreen;
    choice = 0;
    bool done = false;
    do{
      update_key(KEY_UP, &key_up);
      update_key(KEY_DOWN, &key_down);
      update_key(KEY_SPACE, &key_space);
      if(key_up == 1 && choice > 0) choice --;
      if(key_down == 1 && choice < 1) choice ++;

     if(key_space == 1 && choice == 0)
     {
     // If it looks right, it is right!
        remove_keyboard();
        install_keyboard();
        return true;
     }
     if(key_space == 1 && choice == 1)
     {
        remove_keyboard();
        install_keyboard();
        return false;
     }
            // Draw the map as a background!
     //		map.DrawMap(0, player[App.selected_pc].cam.x, player[App.selected_pc].cam.y); // Walls
      //  	map.DrawMapTrans(1, player[App.selected_pc].cam.x, player[App.selected_pc].cam.y); // Overlap
     blit(savescreen, Display.GetSurface(), 0, 0, 0, 0, screen->w, screen->h);
	 masked_blit(choice_bmp, Display.GetSurface(), 0, 0, screen->w/2+100, screen->h/2+50, choice_bmp->w, choice_bmp->h);
     textprintf_ex(Display.GetSurface(), font, screen->w/2+100+45, screen->h/2+50+15, makecol(255,255,255), -1, "Yes");
     textprintf_ex(Display.GetSurface(), font, screen->w/2+100+45, screen->h/2+50+30, makecol(255,255,255), -1, "No");
     masked_stretch_blit( selector, Display.GetSurface(), 0, 0, selector->w, selector->h,   screen->w/2+100+30, screen->h/2+62+choice*15, 9,9);

     blit(Display.GetSurface(), screen, 0, 0, 0, 0, screen->w, screen->h);
     clear_bitmap(Display.GetSurface());
    }while(!done);
}

// I get the feeling this should be somewhere else...
bool CMenu::ClericChoice(BITMAP *savescreen)
{
    BITMAP *test = savescreen;
    choice = 0;
    bool done = false;
    do{
      update_key(KEY_UP, &key_up);
      update_key(KEY_DOWN, &key_down);
      update_key(KEY_SPACE, &key_space);
      if(key_up == 1 && choice > 0) choice --;
      if(key_down == 1 && choice < 1) choice ++;

     if(key_space == 1 && choice == 0)
     {
        // If it looks right, it is right!
        remove_keyboard();
        install_keyboard();
        return true;
     }
     if(key_space == 1 && choice == 1)
     {
        remove_keyboard();
        install_keyboard();
        return false;
     }
            // Draw the map as a background!
     //		map.DrawMap(0, player[App.selected_pc].cam.x, player[App.selected_pc].cam.y); // Walls
      //  	map.DrawMapTrans(1, player[App.selected_pc].cam.x, player[App.selected_pc].cam.y); // Overlap
     blit(savescreen, Display.GetSurface(), 0, 0, 0, 0, screen->w, screen->h);
	 masked_blit(choice_bmp, Display.GetSurface(), 0, 0, screen->w/2+100, screen->h/2+50, choice_bmp->w, choice_bmp->h);
     textprintf_ex(Display.GetSurface(), font, screen->w/2+100+45, screen->h/2+50+15, makecol(0,0,0), -1, "Leave");
     textprintf_ex(Display.GetSurface(), font, screen->w/2+100+45, screen->h/2+50+30, makecol(255,0,0), -1, "Save");

     masked_stretch_blit( selector, Display.GetSurface(), 0, 0, selector->w, selector->h,   screen->w/2+100+30, screen->h/2+62+choice*15, 9,9);

     blit(Display.GetSurface(), screen, 0, 0, 0, 0, screen->w, screen->h);
     clear_bitmap(Display.GetSurface());
    }while(!done);
}

bool CMenu::TrainerChoice(BITMAP *savescreen)
{
    BITMAP *test = savescreen;
    choice = 0;
    int select_pc = 0;
    
    bool done = false;
    do{
      update_key(KEY_UP, &key_up);
      update_key(KEY_DOWN, &key_down);
      update_key(KEY_SPACE, &key_space);
      if(key_up == 1 && choice > 0) choice --;
      if(key_down == 1 && choice < 1) choice ++;

     if(key_space == 1 && choice == 0)
     {
        remove_keyboard();
        install_keyboard();
        return true;
     }
     if(key_space == 1 && choice == 1)
     {
        remove_keyboard();
        install_keyboard();
     if(player[select_pc].level+1 <= MAX_LEVEL)
        if( player[select_pc].exp >= level_table[player[select_pc].level+1])
        {
            Talk("", "You gained a level! Your HP has increased by 4, Your Damage has increased by 1!");
            player[select_pc].max_hp+=4;
            player[select_pc].hp = player[select_pc].max_hp;
            player[select_pc].base_dam+=1;
            player[select_pc].level++;
        }
        
        else
        {
            Talk("", "You don't have enough experience to level yet!");
        }
        return false;
     }
     
     if(key[KEY_RIGHT] && CHECK_BIT(quest.quest_bit, QUEST_RECRUIT_FEMALE))
     {
      select_pc^=1;
      while(key[KEY_RIGHT]) {}
     }
     
     if(key[KEY_LEFT] && CHECK_BIT(quest.quest_bit, QUEST_RECRUIT_FEMALE))
     {
      select_pc^=1;
      while(key[KEY_LEFT]) {}
     }
     
     // Draw the map as a background!
     //		map.DrawMap(0, player[App.selected_pc].cam.x, player[App.selected_pc].cam.y); // Walls
     //  	map.DrawMapTrans(1, player[App.selected_pc].cam.x, player[App.selected_pc].cam.y); // Overlap
     blit(savescreen, Display.GetSurface(), 0, 0, 0, 0, screen->w, screen->h);
	 masked_blit(choice_bmp, Display.GetSurface(), 0, 0, screen->w/2+100, screen->h/2+50, choice_bmp->w, choice_bmp->h);
     textprintf_ex(Display.GetSurface(), font, screen->w/2+100+25, screen->h/2+50+15, makecol(0,0,0), -1, "Training for: %s", player[select_pc].name.c_str());
       textprintf_ex(Display.GetSurface(), font, screen->w/2+100+45, screen->h/2+50+30, makecol(0,0,0), -1, "(right/left changes)");
       
     textprintf_ex(Display.GetSurface(), font, screen->w/2+100+45, screen->h/2+50+45, makecol(0,0,0), -1, "Leave");
     textprintf_ex(Display.GetSurface(), font, screen->w/2+100+45, screen->h/2+50+60, makecol(255,0,0), -1, "Level Up!");

     masked_stretch_blit( selector, Display.GetSurface(), 0, 0, selector->w, selector->h,   screen->w/2+100+30, screen->h/2+92+choice*15, 9,9);

     blit(Display.GetSurface(), screen, 0, 0, 0, 0, screen->w, screen->h);
     clear_bitmap(Display.GetSurface());
    }while(!done);
}


void CMenu::ShowBattleStatus(bool isplayer, int id)
{
// Name, HP/Mana, Damage, Level, Exp(player only),

masked_blit(choice_bmp, screen, 0, 0, screen->w/2+100, screen->h/2+50, choice_bmp->w, choice_bmp->h);
if(!isplayer)
{
    textprintf_ex(screen, font,  screen->w/2+120, screen->h/2+60,  makecol(0,0,0), -1, "%s", map.npc[id].name.c_str());
    textprintf_ex(screen, font,  screen->w/2+120, screen->h/2+70,  makecol(0,0,0), -1, "HP %d", map.npc[id].hp);
    textprintf_ex(screen, font,  screen->w/2+120, screen->h/2+80,  makecol(0,0,0), -1, "Mana %d", map.npc[id].mana);
    textprintf_ex(screen, font,  screen->w/2+120, screen->h/2+90,  makecol(0,0,0), -1, "Damage %d", map.npc[id].dam);
    textprintf_ex(screen, font,  screen->w/2+120, screen->h/2+100,  makecol(0,0,0), -1, "Level %d", map.npc[id].level);
}
else
{
    textprintf_ex(screen, font,  screen->w/2+110, screen->h/2+60,  makecol(0,0,0), -1, "%s", player[id].name.c_str());
    textprintf_ex(screen, font,  screen->w/2+110, screen->h/2+70,  makecol(0,0,0), -1, "HP %d(%d)", player[id].hp, player[id].max_hp);
    textprintf_ex(screen, font,  screen->w/2+110, screen->h/2+80,  makecol(0,0,0), -1, "Mana %d(%d)",  player[id].mana, player[id].max_mana);
    textprintf_ex(screen, font,  screen->w/2+110, screen->h/2+90,  makecol(0,0,0), -1, "Level %d, Exp %d", player[id].level, player[id].exp);
    textprintf_ex(screen, font,  screen->w/2+110, screen->h/2+100,  makecol(0,0,0), -1, "Dam %d", player[id].dam);
}


 //   clear_bitmap(Display.GetSurface());
}
