#include<iostream>

#include<stdlib.h>
#include<stdio.h>
#include<list>
#include<iterator>

#include"NAVE.h"
//#include"ENEMIGO.h"
#include"PROYECTIL.h"
//#include"GLOBALES.h"

#include <allegro5/allegro.h>
//#include <allegro5/allegro_image.h>
//#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_audio.h>
#include <allegro5/allegro_acodec.h>

#define FPS   60

using namespace std;

const int ANCHURA_DISPLAY = 900;
const int ALTURA_DISPLAY  = 600;


const float sizeNAVEX = 50.0;
const float sizeNAVEY = 38.0;

const float sizePROYECTILVerticalX = 13.0;
const float sizePROYECTILVerticalY = 65.0;

const int sizeENEMIGOX = 50;
const int sizeENEMIGOY = 40;

enum TECLAS {
   KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,
   KEY_W, KEY_S, KEY_A, KEY_D, KEY_SPACE
};

// Prototipos

void CambioEstado(int &estado, int nuevoEstado);

int PROYECTILs = 0;
int PROYECTILs_destruidas = 0;
int asteroides = 0;
int asteroides_destruidos = 0;
int asteroides_perdidos = 0;

int main(){

   //==============================================
   //SHELL VARIABLES
   //==============================================
   bool gameOver = false;
   bool redraw = false;

   float gameTime = 0;
   int frames = 0;
   int gameFPS = 0;

   //Input input;

   NAVE* nave = NULL;

   list<PROYECTIL* > balas;
   list<PROYECTIL* >::iterator iterBalas;
   list<ENEMIGO2* > enemigos;
   list<ENEMIGO2* >::iterator iterEnemigos;

   nave = new NAVE(ANCHURA_DISPLAY/2, ALTURA_DISPLAY/2, sizeNAVEX, sizeNAVEY);


   ALLEGRO_DISPLAY *display = NULL;
   ALLEGRO_EVENT_QUEUE *event_queue = NULL;
   //ALLEGRO_KEYBOARD_STATE keyState;
   ALLEGRO_TIMER *timer = NULL;
   ALLEGRO_BITMAP *miNAVE = NULL;
   ALLEGRO_BITMAP *disparoVertical = NULL;
   ALLEGRO_BITMAP *disparoHorizontal = NULL;
   ALLEGRO_BITMAP *marco   = NULL;
   ALLEGRO_BITMAP *ENEMIGO = NULL;
   ALLEGRO_FONT *font18;
   ALLEGRO_SAMPLE_INSTANCE *temazoInstance;
   ALLEGRO_SAMPLE *shot = NULL;
   ALLEGRO_SAMPLE *boom = NULL;
   ALLEGRO_SAMPLE *song = NULL;

   bool key[9] = { false, false, false, false, false, false, false, false, false };

   if(!al_init())
   {
      fprintf(stderr, "failed to initialize allegro!\n");
      return -1;
   }

   if(!al_install_keyboard()) {
      fprintf(stderr, "failed to initialize the keyboard!\n");
      return -1;
   }
   if(!al_init_image_addon())
   {
      fprintf(stderr, "failed to create image addon!\n");
      return -1;
   }

   al_init_font_addon();
   al_init_ttf_addon();
   al_init_primitives_addon();
   al_install_audio();
   al_init_acodec_addon();

   timer = al_create_timer(1.0 / FPS);
   if(!timer) {
      fprintf(stderr, "failed to create timer!\n");
      return -1;
   }

   display = al_create_display(ANCHURA_DISPLAY, ALTURA_DISPLAY);
   if(!display) {
      fprintf(stderr, "failed to create display!\n");
      al_destroy_timer(timer);
      return -1;
   }

   miNAVE  = al_load_bitmap("NAVE.png");
   marco = al_load_bitmap("starBG.png");
   font18 = al_load_font("Arcade_Classic.ttf", 28, 0);
   ENEMIGO = al_load_bitmap("asteroide1.png");
   disparoVertical = al_load_bitmap("Rayo_Ik1_Vertical.png");

   disparoHorizontal = al_load_bitmap("Rayo_Ik1_Horizontal.png");
   if(!disparoHorizontal)
   {
       cout << "Imposible cargar imagen!";
       return -1;
   }

   if(!marco) {
      fprintf(stderr, "failed to create NAVE bitmap!\n");
      al_destroy_display(display);
      al_destroy_timer(timer);
      return -1;
   }

   al_clear_to_color(al_map_rgb(255, 0, 255));

   event_queue = al_create_event_queue();
   if(!event_queue) {
      fprintf(stderr, "failed to create event_queue!\n");
      al_destroy_bitmap(miNAVE);
      al_destroy_display(display);
      al_destroy_timer(timer);
      return -1;
   }

   al_register_event_source(event_queue, al_get_display_event_source(display));

   al_register_event_source(event_queue, al_get_timer_event_source(timer));

   al_register_event_source(event_queue, al_get_keyboard_event_source());

   al_clear_to_color(al_map_rgb(0,0,0));


   al_flip_display();
   al_reserve_samples(15);

   shot = al_load_sample("Toko1.ogg");
   if(!shot)
   cout << "NO SHOT!!";
   boom = al_load_sample("Granada1.ogg");
   if(!boom)
   cout << "NO BOOM!!";
   song = al_load_sample("Maid.ogg");
   if(!song)
   cout << "NO SONG!!";

   temazoInstance = al_create_sample_instance(song);
   al_set_sample_instance_playmode(temazoInstance, ALLEGRO_PLAYMODE_LOOP);

   al_attach_sample_instance_to_mixer(temazoInstance, al_get_default_mixer());

   al_start_timer(timer);

   //vector<int> teclas;
   //teclas.push_back(ALLEGRO_KEY_ESCAPE);

    while(!gameOver)
    {
          // Movimiento personaje principal

          ALLEGRO_EVENT ev;
          al_wait_for_event(event_queue, &ev);
          //al_get_keyboard_state(&keyState);

          /*if(input.TeclaPulsada(ev, teclas))
                gameOver = true;*/
          if(ev.type == ALLEGRO_EVENT_TIMER)
          {
             redraw = true;

			 //UPDATE FPS===========
			 frames++;
			 if(al_current_time() - gameTime >= 1)
			 {
			 	gameTime = al_current_time();
			 	gameFPS = frames;
				frames = 0;
			 }
             if(key[KEY_UP])
             {
                nave->moverArriba(ALTURA_DISPLAY);
             }

             if(key[KEY_DOWN])
             {
                nave->moverAbajo(ALTURA_DISPLAY);
             }

             if(key[KEY_LEFT]) {
                nave->moverIzquierda();
             }

             if(key[KEY_RIGHT]) {
                nave->moverDerecha(ANCHURA_DISPLAY);
             }
          }
          if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
             break;
          }
          else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
          {
             switch(ev.keyboard.keycode)
             {
                case ALLEGRO_KEY_UP:
                   key[KEY_UP] = true;

                   break;

                case ALLEGRO_KEY_DOWN:
                   key[KEY_DOWN] = true;


                   break;

                case ALLEGRO_KEY_LEFT:
                   key[KEY_LEFT] = true;


                   break;

                case ALLEGRO_KEY_RIGHT:
                   key[KEY_RIGHT] = true;


                   break;
                case ALLEGRO_KEY_W:
                    key[KEY_W] = true;
                     balas.push_back(new PROYECTIL( nave->x + 18,  nave->y - 72, sizePROYECTILVerticalX, sizePROYECTILVerticalY ));
                     al_play_sample(shot, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);
                     PROYECTILs++;
                     break;

                /*case ALLEGRO_KEY_S:
                    key[KEY_S] = true;
                     Balas.push_back(new PROYECTIL(NAVE->x + 18, NAVE->y + 41, sizePROYECTILVerticalX, sizePROYECTILVerticalY ));
                     PROYECTILs++;
                     break;*/

                case ALLEGRO_KEY_SPACE:
                {
                    key[KEY_SPACE] = true;
                    break;
                }
             }
          }
          else if(ev.type == ALLEGRO_EVENT_KEY_UP)
          {
             switch(ev.keyboard.keycode)
             {
                case ALLEGRO_KEY_ESCAPE:

                   gameOver = true;
                   break;
                case ALLEGRO_KEY_UP:
                   key[KEY_UP] = false;

                   break;

                case ALLEGRO_KEY_DOWN:
                   key[KEY_DOWN] = false;

                   break;

                case ALLEGRO_KEY_LEFT:
                   key[KEY_LEFT] = false;

                   break;

                case ALLEGRO_KEY_RIGHT:
                   key[KEY_RIGHT] = false;

                   break;

                case ALLEGRO_KEY_W:
                    key[KEY_W] = false;

                     break;

                case ALLEGRO_KEY_S:
                    key[KEY_S] = false;

                     break;

                case ALLEGRO_KEY_A:
                    key[KEY_A] = false;

                     break;

                case ALLEGRO_KEY_D:
                    key[KEY_D] = false;

                     break;

                case ALLEGRO_KEY_SPACE:
                    key[KEY_SPACE] = false;

                    break;
            }
         }

         //-----------------------------------------------
         // RENDER
         //-----------------------------------------------

         if(redraw && al_is_event_queue_empty(event_queue))
         {
             redraw = false;

             al_clear_to_color(al_map_rgb(0, 0, 5));

             al_draw_bitmap(marco, 0, 0, 0);
              nave->pintar(miNAVE, nave->x,  nave->y);

             if(rand() % 100 + 50 == 75)
             {
               enemigos.push_back(new ENEMIGO2(ANCHURA_DISPLAY, sizeENEMIGOX, sizeENEMIGOY));
                asteroides++;
             }
             for(iterEnemigos = enemigos.begin(); iterEnemigos != enemigos.end(); iterEnemigos++)
             {
                 (*iterEnemigos)->fuera(ALTURA_DISPLAY);
                  nave->colision(iterEnemigos);
                 if((*iterEnemigos)->GetestaVivo())
                 (*iterEnemigos)->pintar(ENEMIGO, (*iterEnemigos)->GetX(), (*iterEnemigos)->GetY());
                 else
                 {
                    delete(*iterEnemigos);
                    iterEnemigos = enemigos.erase(iterEnemigos);
                    asteroides_perdidos++;
                 }
             }

             for(iterBalas = balas.begin(); iterBalas != balas.end(); iterBalas++)
             {
                 if(KEY_W)
                 {
                    (*iterBalas)->pintarArriba(disparoVertical, ((*iterBalas)->GetX()), ((*iterBalas)->GetY()));

                 }
             }

             //------------------------------
             // COLISIONES
             //------------------------------

                 for(iterBalas = balas.begin(); iterBalas != balas.end(); iterBalas++)
                 {
                     if((*iterBalas)->GetVida())
                     {
                        for(iterEnemigos = enemigos.begin(); iterEnemigos != enemigos.end(); iterEnemigos++)
                        {
                            if((*iterEnemigos)->GetestaVivo())
                            {
                                if((*iterBalas)->colision(iterBalas, iterEnemigos))
                                {
                                    delete(*iterBalas);
                                    iterBalas = balas.erase(iterBalas);
                                    PROYECTILs_destruidas++;

                                    delete(*iterEnemigos);
                                    iterEnemigos = enemigos.erase(iterEnemigos);
                                    asteroides_destruidos++;
                                    nave->puntos++;
                                    al_play_sample(boom, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);
                                    if(!boom)
                                        cout << "NO BOOM!";
                                    cout << "HE llegado";
                                }
                            }

                            else if((*iterBalas)->fuera(iterBalas, ALTURA_DISPLAY, ANCHURA_DISPLAY))
                            {
                                delete (*iterBalas);
                                iterBalas = balas.erase(iterBalas);
                                PROYECTILs_destruidas++;
                            }
                         } // End for(enemigos...
                      } // End if(iterPROYECTILsVert...
                   } // End for(iterPROYECTILsVert...

             al_draw_textf(font18, al_map_rgb(255, 255, 255), 5, 5, 0, "PROYECTILs disparadas =  %i ", PROYECTILs);
             al_draw_textf(font18, al_map_rgb(255, 255, 255), 5, 30, 0, "Asteroides destruidos = %i" , asteroides_destruidos);
             al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 55, 0, "Puntos  = %i" , nave->puntos);
             al_draw_textf(font18, al_map_rgb(255, 255, 255), 5, 80, 0, "Asteroides perdidos = %i" , asteroides_perdidos);
             al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 105, 0, "FPS: %i", gameFPS);	//display FPS on screen
             al_draw_textf(font18, al_map_rgb(255, 255, 255), 5, 555, 0, "NAVE.X = %i" , nave->x);
             al_draw_textf(font18, al_map_rgb(255, 255, 255), 5, 580, 0, "NAVE.Y = %i" , nave->y);

          } // End if(redraw....
          al_flip_display();
    } // End While

    al_destroy_bitmap(miNAVE);
    al_destroy_bitmap(disparoVertical);
    al_destroy_bitmap(disparoHorizontal);
    al_destroy_bitmap(marco);
    al_destroy_bitmap(ENEMIGO);
    al_destroy_sample(song);
    al_destroy_sample(boom);
    al_destroy_sample(shot);
    al_destroy_timer(timer);
    al_destroy_event_queue(event_queue);
    al_destroy_display(display);

    return 0;
}
