int main() {
  bool menu = true;
  char pontuacao[100];
  char vida[100];
  ALLEGRO_COLOR  font_color;
  ALLEGRO_FONT *font,*font2;
  ALLEGRO_AUDIO_STREAM *musica = NULL;
  
  camera *cam = camera_inicializa(0);
  if(!cam)
    erro("erro na inicializacao da camera\n");
  int x = 0, y =  0;
  int largura = cam->largura;
  int altura = cam->altura;
  int fps = 0,tempo = 5;
  int ndisco = 9;
 
  if(!al_init())
    erro("erro na inicializacao do allegro\n");

  if(!al_init_image_addon())
    erro("erro na inicializacao do adicional de imagem\n");

  al_init_font_addon();
  al_init_ttf_addon();

    font_color = al_map_rgb(0, 0, 0);
    
    font = al_load_ttf_font("Fontes/Blokletters-Viltstift.ttf", 20, 0);
    font2 = al_load_ttf_font("Fontes/Blokletters-Viltstift.ttf", 50, 0);
    


  if(!al_init_primitives_addon())
    erro("erro na inicializacao do adicional de primitivas\n");

  ALLEGRO_TIMER *timer = al_create_timer(1.0 / FPS);
  if(!timer)
    erro("erro na criacao do relogio\n");

  ALLEGRO_DISPLAY *display = al_create_display(2 * largura,altura);
  if(!display)
    erro("erro na criacao da janela\n");

  ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue();
  if(!queue)
    erro("erro na criacao da fila\n");

   if (!al_install_audio())
    {
        fprintf(stderr, "Falha ao inicializar áudio.\n");
        return false;
    }
 
    if (!al_init_acodec_addon())
    {
        fprintf(stderr, "Falha ao inicializar codecs de áudio.\n");
        return false;
    }
    if (!al_reserve_samples(1))
    {
        fprintf(stderr, "Falha ao alocar canais de áudio.\n");
        return false;
    }

  musica = al_load_audio_stream("Audio/elementary.ogg", 4, 1024);
  if(!musica)
        erro("Erro na alocação da musica de fundo\n");

  al_attach_audio_stream_to_mixer(musica, al_get_default_mixer());
  al_set_audio_stream_playing(musica, true);

  al_register_event_source(queue, al_get_timer_event_source(timer));
  al_register_event_source(queue, al_get_display_event_source(display));

  al_start_timer(timer);
  
  unsigned char ***matriz = camera_aloca_matriz(cam);
  ALLEGRO_BITMAP *buffer = al_get_backbuffer(display);
  ALLEGRO_BITMAP *fundo = al_load_bitmap("Imagens/Elementary2.png");

  if(!fundo)
    erro("erro ao carregar Elementary.png");

  ALLEGRO_BITMAP *esquerda = al_create_sub_bitmap(buffer, 0, 0, largura, altura);
  ALLEGRO_BITMAP *direita = al_create_sub_bitmap(buffer, largura, 0, largura, altura);

  /**********/
  Disco *discos[9];
  bool perdeu = false;
  carregarDiscos(discos);
  int pontos=0,velo = 1;
  int aux1 = 1;
  int vidas = 10;
  int ultimoDisco = 0;
  int distance = 0;
  int desenhar = 0;
  int terminar = 0;
  al_set_target_bitmap(esquerda);
  al_draw_bitmap(fundo,0,0,0);
  while(1) {

    ALLEGRO_EVENT event;

    al_wait_for_event(queue, &event);

    switch(event.type) {
    case ALLEGRO_EVENT_TIMER:
      desenhar = 1;
      break;
    case ALLEGRO_EVENT_DISPLAY_CLOSE:
      terminar = 1;
      break;
   
    }

    if(terminar)
      break;

    if(desenhar && al_is_event_queue_empty(queue)) {
      desenhar = 0;
      camera_atualiza(cam);
      mediana(cam);
      /**********/
      al_set_target_bitmap(esquerda);
      al_draw_bitmap(fundo,0,0,0);
      
      if(!menu){
        while(aux1 <= ndisco){
          if(discos[aux1]->status == false){
            if(distance > 50 || ultimoDisco==0  ){
              printf("%d\n",aux1 );
              al_draw_bitmap(discos[aux1]->elemento,discos[aux1]->pos_x,discos[aux1]->pos_y,0);
              discos[aux1]->status = true;
              distance = 0;
              ultimoDisco = aux1;
              break;
            }else
             aux1++;
          }else{
              discos[aux1]->pos_y+=(10+velo);
              al_draw_bitmap(discos[aux1]->elemento,discos[aux1]->pos_x,discos[aux1]->pos_y,0);
            aux1++;
              
            }
        }
        distance = discos[ultimoDisco]->pos_y;
        for(aux1 = 1;aux1<ndisco;aux1++){
          if(discos[aux1]->pos_x >= x-30 && discos[aux1]->pos_x <= x+30 && discos[aux1]->pos_y >= y-30 &&  discos[aux1]->pos_y <= y+30){
            if(discos[aux1]->tipo == 2){ // Tipo do fogo(Necessario para vencer o jogo)
            pontos +=10;
            velo += 1;
            discos[aux1]->pos_x = rand()%9 * 55;
            discos[aux1]->pos_y = 0;
            discos[aux1]->status = false;
          }else if(discos[aux1]->tipo == 1){ //Tipo da agua(Perde o jogo se destruir esse disco)
            discos[aux1]->pos_x = rand()%9 * 55;
            discos[aux1]->pos_y = 0;
            discos[aux1]->status = false;
            al_flip_display();
            vidas--;
          }else if(discos[aux1]->tipo == 3){//Tipo planta(Aumenta velocidade de queda das peças)
            velo *= 2;
            discos[aux1]->pos_x = rand()%9 * 55;
            discos[aux1]->pos_y = 0;
            discos[aux1]->status = false;
          }

        }else if( discos[aux1]->pos_y > 480){
          if(discos[aux1]->tipo == 2){ //Tipo da agua e Planta(Não perde se deixar cair)
               discos[aux1]->pos_x = rand()%9 * 55;
            discos[aux1]->pos_y = 0;
            discos[aux1]->status = false;
            al_flip_display();
            vidas--;
          }else{
            discos[aux1]->pos_x = rand()%9 * 55;
            discos[aux1]->pos_y = 0;
            discos[aux1]->status = false;
          }
        }
      }

        aux1 = 1;
      sprintf(pontuacao,"PONTUAÇÃO: %d",pontos);
      al_draw_text(font, al_map_rgb(255, 255, 255), 50, 5, 0,pontuacao);
       sprintf(vida,"VIDAS: %d",vidas);
      al_draw_text(font, al_map_rgb(255, 255, 255), 300, 5, 0,vida);
      al_flip_display();

      }
       if(perdeu){
        al_draw_text(font2, al_map_rgb(255, 0, 0), 50, 100, 0,"PONTUAÇÃO FINAL");
        sprintf(pontuacao,"%d",pontos);
        al_draw_text(font2, al_map_rgb(255, 0, 0), 250, 170, 0,pontuacao);
        al_flip_display();
        al_rest(3);
        break;
      }
       
      if(vidas == 0){
        perdeu = true;
      }

      if(menu){
        if(abrirJogo(x,y,&fps,&tempo,font,font2, font_color)){
          fundo = al_load_bitmap("Imagens/galaxia.png");
          menu = false;
        }
      }
      cameraRastreia(cam,&x,&y);
   

      al_set_target_bitmap(direita);
      camera_copia(cam, cam->quadro, direita);
      al_flip_display();
    }
  }
  al_destroy_bitmap(direita);
  al_destroy_bitmap(fundo);
  al_destroy_bitmap(esquerda);
  camera_libera_matriz(cam, matriz);
int fri = 9;
while(fri != 0){
  free(discos[fri]);
  fri--;

}


  al_stop_timer(timer);

  al_unregister_event_source(queue, al_get_display_event_source(display));
  al_unregister_event_source(queue, al_get_timer_event_source(timer));

  al_destroy_event_queue(queue);
  al_destroy_display(display);
  al_destroy_timer(timer);
  al_destroy_audio_stream(musica);
  al_shutdown_primitives_addon();
  al_shutdown_image_addon();
  al_uninstall_system();

  camera_finaliza(cam);

  return EXIT_SUCCESS;
}
int main() {
  camera *cam = camera_inicializa(0);
  if(!cam)
    erro("nao foi possivel inicializar camera");

  int largura = cam->largura;
  int altura = cam->altura;

  if(!al_init())
    erro("nao foi possivel inicializar allegro");

  if(!al_init_primitives_addon())
    erro("nao foi possivel inicializar adicional de primitivas");

  if(!al_init_image_addon())
    erro("nao foi possivel inicializar a adicional de imagem ");

  ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue();
  if(!queue)
    erro("nao foi possivel criar fila de eventos");

  ALLEGRO_DISPLAY *display = al_create_display(2 * largura, altura * 2);
  if(!display)
    erro("nao foi possivel criar janela");

  al_register_event_source(queue, al_get_display_event_source(display));

  ALLEGRO_TIMER *timer = al_create_timer(1.0 / FPS);
  if(!timer)
    erro("nao foi possivel criar relogio");

  al_register_event_source(queue, al_get_timer_event_source(timer));

  /**********/

  unsigned char ***matriz = camera_aloca_matriz(cam);
  unsigned char ***anterior;

  ALLEGRO_COLOR cor = al_map_rgb_f(0, 0, 1);

  ALLEGRO_BITMAP *buffer = al_get_backbuffer(display);

  ALLEGRO_BITMAP *esquerda = al_create_sub_bitmap(buffer, 0, 0, largura, altura);

  ALLEGRO_BITMAP *direita = al_create_sub_bitmap(buffer, largura, 0, largura, altura);

  ALLEGRO_BITMAP * baixo = al_create_sub_bitmap(buffer, largura/2, altura, largura, altura);

  sniper = al_load_bitmap("semi.png");

  /**********/

  int continuar = 1;
  int atualizar = 0;

  al_start_timer(timer);

  while(continuar) {
    ALLEGRO_EVENT event;

    al_wait_for_event(queue, &event);

    switch(event.type) {
    case ALLEGRO_EVENT_DISPLAY_CLOSE:
      continuar = 0;
      break;
    case ALLEGRO_EVENT_TIMER:
      atualizar = 1;
      break;
    }

    if(atualizar && al_is_event_queue_empty(queue)) {
      camera_atualiza(cam);

      /**********/

      int cy = 0;
      int cx = 0;
      int cn = 0;

      for(int y = 0; y < altura; y++)
        for(int x = 0; x < largura; x++) {
          float r = (cam->quadro[y][x][0]) / 255;
          float g = (cam->quadro[y][x][1]) / 255;
          float b = (cam->quadro[y][x][2]) / 255;

          /*if(compara_imagem(cam, matriz, anterior)) {
            cy += y;
            cx += x;
            cn += 1;

            matriz[y][x][0] = 255;
            matriz[y][x][1] = 255;
            matriz[y][x][2] = 255;
          }
          else {
            matriz[y][x][0] = 0;
            matriz[y][x][1] = 0;
            matriz[y][x][2] = 0;
          }
        }
        */

      anterior = compara_imagem(cam, matriz, anterior);
        //int x1 = cx / cn;
        //int y1 = cy / cn;
        
      /**********/
      }
      camera_copia(cam, cam->quadro, esquerda);
      camera_copia(cam, matriz, direita);
      camera_copia(cam, anterior, baixo);   
      if(cn > 0){
        //al_draw_circle(cx / cn, cy / cn, 120, cor, 1);
        //al_draw_bitmap(sniper, cx / cn, cy / cn, 120);
        // SNIPER al_draw_bitmap(sniper, cx / cn - 400, cy / cn - 300, 120);
        

      camera_copia(cam, cam->quadro, direita);

      /**********/

      al_flip_display();

      atualizar = 0;
    }
  }
}
  al_stop_timer(timer);

  /**********/

  al_destroy_bitmap(direita);

  al_destroy_bitmap(esquerda);

  camera_libera_matriz(cam, matriz);

  /**********/

  al_unregister_event_source(queue, al_get_timer_event_source(timer));
  al_destroy_timer(timer);

  al_unregister_event_source(queue, al_get_display_event_source(display));
  al_destroy_display(display);

  al_destroy_event_queue(queue);
  al_shutdown_primitives_addon();
  al_uninstall_system();

  camera_finaliza(cam);

  return EXIT_SUCCESS;


}
bool inicializar()
{
    //INICIALIZAR ADD ONS DO ALLEGRO
    if (!al_init())
    {
        fprintf(stderr, "Falha ao inicializar a Allegro.\n");
        return false;
    }

    al_init_font_addon();

    if (!al_init_ttf_addon())
    {
        fprintf(stderr, "Falha ao inicializar add-on allegro_ttf.\n");
        return false;
    }

    if (!al_init_primitives_addon())
    {
        fprintf(stderr, "Falha ao inicializar add-on allegro_primitives.\n");
        return false;
    }

    if (!al_init_image_addon())
    {
        fprintf(stderr, "Falha ao inicializar add-on allegro_image.\n");
        return false;
    }

    if (!al_install_keyboard())
    {
        fprintf(stderr, "Falha ao inicializar o teclado.\n");
        return false;
    }

    timer = al_create_timer(1.0 / 60);
    if(!timer)
        erro("erro na criacao do relogio\n");

    fila_eventos = al_create_event_queue();

    if (!fila_eventos)
    {
        fprintf(stderr, "Falha ao criar fila de eventos.\n");
        al_destroy_display(janela);
        return false;
    }

    cam = camera_inicializa(0);
    if(!cam)
        erro("erro na inicializacao da camera\n");

    largura = cam->largura;
    altura = cam->altura;

    timer = al_create_timer(1.0 / 60);
    if(!timer)
        erro("erro na criacao do relogio\n");

    display = al_create_display(2 * largura, altura);
    if(!display)
        erro("erro na criacao da janela\n");

    al_register_event_source(fila_eventos, al_get_timer_event_source(timer));
    al_register_event_source(fila_eventos, al_get_display_event_source(display));

    

    matriz = camera_aloca_matriz(cam);
    cor = al_map_rgb_f(0, 0, 1);
    buffer = al_get_backbuffer(display);
    esquerda = al_create_sub_bitmap(buffer, 0, 0, largura, altura);
    direita = al_create_sub_bitmap(buffer, largura, 0, largura, altura);


    /*
    janela = al_create_display(800, 600);

    if (!janela)
    {
        fprintf(stderr, "Falha ao criar janela.\n");
        return false;
    }

    al_set_window_title(janela, "Allegro");

    
    */
    /* JOYSTICK COMENTADO
    if(!al_install_joystick())
    {
        fprintf(stderr, "falha ao inicializar joystick!\n");
    }

    al_reconfigure_joysticks();

    joystick = al_get_joystick(al_get_num_joysticks()-1);

    al_register_event_source(fila_eventos  , al_get_joystick_event_source());
    */

    //INICIALIZAR VARIAVEIS
    teste = al_load_bitmap("../img/pika.png");



    if (!teste)
    {
        fprintf(stderr, "erro no pikachu.\n");
        return false;
    }

    //REGISTRAR EVENTOS
   // al_register_event_source(fila_eventos, al_get_keyboard_event_source());
   // al_register_event_source(fila_eventos, al_get_display_event_source(janela));

    return true;
}
int main() {
  //inicialização
  camera *cam = camera_inicializa(0);
  if(!cam)
    erro("erro na inicializacao da camera\n");

  int largura = cam->largura;
  int altura = cam->altura;

  if(!al_init())
    erro("erro na inicializacao do allegro\n");

  if(!al_init_image_addon())
    erro("erro na inicializacao do adicional de imagem\n");

  if(!al_init_primitives_addon())
    erro("erro na inicializacao do adicional de primitivas\n");

  ALLEGRO_TIMER *timer = al_create_timer(1.0 / FPS);
  if(!timer)
    erro("erro na criacao do relogio\n");

  ALLEGRO_DISPLAY *display = al_create_display(largura, altura);
  if(!display)
    erro("erro na criacao da janela\n");

  ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue();
  if(!queue)
    erro("erro na criacao da fila\n");

  al_register_event_source(queue, al_get_timer_event_source(timer));
  al_register_event_source(queue, al_get_display_event_source(display));

  al_start_timer(timer);

  /**********/

  unsigned char ***matriz = camera_aloca_matriz(cam);
  int ***background = alocaHsvMatriz(cam->largura, cam->altura);

  fila *f = aloca();

  //cor para desenhar o círculo
  ALLEGRO_COLOR cor = al_map_rgb_f(0, 0, 1);

  ALLEGRO_BITMAP *buffer = al_get_backbuffer(display);

  //tela exibindo img normal
  ALLEGRO_BITMAP *esquerda = al_create_sub_bitmap(buffer, 0, 0, largura, altura);

  //tela mostrando como o computador enxerga
  //ALLEGRO_BITMAP *direita = al_create_sub_bitmap(buffer, largura/2, 0, largura/2, altura/2);
  ALLEGRO_BITMAP *silhueta = al_create_bitmap(largura, altura);

  /**********/
  srand(time(NULL));
  int desenhar = 0;
  int terminar = 0;

  int cycle = 0;
  int hitx = rand() % (largura);
  int hity = rand() % (altura);

  int x, y;

  float cyr, cxr, cnr, lastCx, lastCy;

  int r, g, b, r2, g2, b2;

  int h, s, v, h2, s2, v2;
  int fh, fs, fv;

  int dh, ds, dv;
  int tempH;

  int token;

  double value;
  int dist;

  al_rest(1);

  for(y = 0; y < altura; y++)
    for(x = 0; x < largura; x++){
      rgbToHsv(cam->quadro[y][x][0], cam->quadro[y][x][1], cam->quadro[y][x][2], 
        &background[y][x][0], &background[y][x][1], &background[y][x][2]);

      if(background[y][x][0] > 180){
        background[y][x][0] -= 360;
        background[y][x][0] = -background[y][x][0];
      }
        
    }

  al_rest(1);

  for(y = 0; y < altura; y++)
    for(x = 0; x < largura; x++){
      rgbToHsv(cam->quadro[y][x][0], cam->quadro[y][x][1], cam->quadro[y][x][2], 
        &fh, &fs, &fv);

      if(fh > 180){
        fh -= 360;
        fh = -fh;
      }

      background[y][x][0] += fh;
      background[y][x][0] /=2;

      background[y][x][1] += fs;
      background[y][x][1] /=2;
      
      background[y][x][2] += fv;
      background[y][x][2] /=2;  
    }

  //gameloop
  while(1) {
    ALLEGRO_EVENT event;

    al_wait_for_event(queue, &event);

    switch(event.type) {
    case ALLEGRO_EVENT_TIMER:
      desenhar = 1;

      break;

    case ALLEGRO_EVENT_DISPLAY_CLOSE:
      terminar = 1;
      break;

    default:
      printf("evento desconhecido\n");
    }

    if(terminar)
      break;

    //interpretar img e realizar transformações
    printf("%d\n", al_is_event_queue_empty(queue));
    if(desenhar && al_is_event_queue_empty(queue)) {
      desenhar = 0;
      camera_atualiza(cam);

      /**********/

      int bx, by, bn;

      cyr = 0;
      cxr = 0;
      cnr = 0;

      for(y = 0; y < altura; y++){
        for(x = 0; x < largura; x++){
          //Espada
          r = cam->quadro[y][x][0];
          g = cam->quadro[y][x][1];
          b = cam->quadro[y][x][2];

          rgbToHsv(r, g, b, &h, &s, &v);

          if(h < 15 || h > 345)
            if(s > 75 && v > 75){
              cyr += y;
              cxr += x;
              cnr++;
            }

          //Silhueta (REFINAR!!!)
          if(h > 180)
            tempH = -(h - 360);

          else
            tempH = h;

          dh = tempH - background[y][x][0];
          if(dh < 0)
            dh = -dh;

          ds = s - background[y][x][1];
          if(ds < 0)
            ds = -ds;

          dv = v - background[y][x][2];
          if(dv < 0)
            dv = -dv;

          //dh > 15 && ds > 10 para tirar a interfencia de iluminacao, mas gera mtuiro ruido
          //ds > 25 é o mais preciso, mas sofre de interferencia de iluminacao
          if(dv > 25){
            //valores para teste!
            matriz[y][x][0] = 37;
            matriz[y][x][1] = 50;
            matriz[y][x][2] = 248;
          }

          else{
            matriz[y][x][0] = 0;
            matriz[y][x][1] = 0;
            matriz[y][x][2] = 0;
          }

          //Escudo
          if(h < 135 && h > 105 && s > 50 && v > 75){
            by += y;
            bx += x;
            bn++;

            matriz[y][x][0] = 0;
            matriz[y][x][1] = 255;
            matriz[y][x][2] = 0;
          }
        }
      }

     /*for(y = 1; y < altura-1; y++)
        for(x = 1; x < largura-1; x++){
          token = 4;

          if(255 != matriz[y+1][x][0])
            token--;
          if(255 != matriz[y-1][x][0])
            token--;
          if(255 != matriz[y][x+1][0])
            token--;
          if(255 != matriz[y][x-1][0])
            token--;

          if(token == 0){
            matriz[y][x][0] = 0;
            matriz[y][x][1] = 0;
            matriz[y][x][2] = 0;
          }*/

      cycle++;
      if(cycle > 50 && bn > 0){
        value = (pow(hitx - (bx / 2 /bn), 2) + pow(hity - (by / 2 / bn), 2));
        dist = sqrt(value) - 7;

        if(dist < 100 && dist > -100 && bn > 0)
          printf("block!\n");

        else{
          if(matriz[hity][hitx][0] == 255)
            printf("hit\n");

          else
            printf("miss\n");
        }

        cycle = 0;
        hitx = rand() % (largura/2);
        hity = rand() % (altura/2);
      }

      /**********/
      camera_copia(cam, cam->quadro, esquerda);

      //Copia img editada na img direita
      camera_copia(cam, matriz, silhueta);
      //cor para teste!
      al_convert_mask_to_alpha(silhueta, al_map_rgb(37, 50, 248));
      al_draw_bitmap(silhueta, 0, 0, 0);
      /**********/

      if(bn > 0)
        al_draw_circle(bx / bn, by / bn, 100, al_map_rgb(0, 0, 255), 1);

      if(cycle >= 40){
        if(cycle < 48){
          al_draw_circle(hitx, hity, 15, al_map_rgb(0, 0, 255), 30);
          al_draw_circle(hitx + largura, hity, 6, al_map_rgb(0, 0, 255), 3);
        }

        else
          al_draw_circle(hitx, hity, 15, al_map_rgb(255, 0, 0), 30);
      }

      if(cnr > 10){
        lastCx = cxr / cnr;
        lastCy = cyr / cnr;

        al_draw_circle(lastCx, lastCy, 100, al_map_rgb(255, 0, 0), 1);

        insere(f, lastCx, lastCy);
      }

      else
        insere(f, lastCx, lastCy);

      if(f->count > 10)
          retira(f);

      drawAtk(f);

      al_flip_display();
    }
  }

  /**********/

  libera(f);

  al_destroy_bitmap(silhueta);

  al_destroy_bitmap(esquerda);

  camera_libera_matriz(cam, matriz);
  liberaHsvMatriz(background, cam->largura, cam->altura);

  /**********/

  al_stop_timer(timer);

  al_unregister_event_source(queue, al_get_display_event_source(display));
  al_unregister_event_source(queue, al_get_timer_event_source(timer));

  al_destroy_event_queue(queue);
  al_destroy_display(display);
  al_destroy_timer(timer);

  al_shutdown_primitives_addon();
  al_shutdown_image_addon();
  al_uninstall_system();

  camera_finaliza(cam);

  return EXIT_SUCCESS;
}