/*-----------------------------------------------------------------------------

  File        : odykill.cpp

  Description : Simple shoot-em-up game featuring the Robotvis/Odyssee Team !

  Author      : David Tschumperlé

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  --------------------------------------------------------------------------*/

#include "../CImg.h"
// The lines below are not necessary in your own code, it simply allows 
// the source compilation with compilers that do not respect the C++ standart.
#if ( defined(_MSC_VER) && _MSC_VER<=1200 ) || defined(__DMC__)
#define std
#endif

int main(int argc,char **argv) {

  std::fprintf(stderr," - Load graphics...Please wait... \n");
  cimg_library::CImg<unsigned char> graphics[21] = {
    cimg_library::CImg<unsigned char>("img/tomato.png"),
    cimg_library::CImg<unsigned char>("img/heart.png"),
    cimg_library::CImg<unsigned char>("img/dynamite.png"),
    cimg_library::CImg<unsigned char>("img/brain.png"),
    cimg_library::CImg<unsigned char>("img/cdrom.png"),
    cimg_library::CImg<unsigned char>("img/enemy.png"),
    cimg_library::CImg<unsigned char>("img/enemy2.png"),
    cimg_library::CImg<unsigned char>("img/enemy3.png"),
    cimg_library::CImg<unsigned char>("img/enemy4.png"),
    cimg_library::CImg<unsigned char>("img/enemy5.png"),
    cimg_library::CImg<unsigned char>("img/enemy6.png"),
    cimg_library::CImg<unsigned char>("img/enemy7.png"),
    cimg_library::CImg<unsigned char>("img/enemy8.png"),
    cimg_library::CImg<unsigned char>("img/enemy9.png"),
    cimg_library::CImg<unsigned char>("img/enemy10.png"),
    cimg_library::CImg<unsigned char>("img/enemy11.png"),
    cimg_library::CImg<unsigned char>("img/enemy12.png"),
    cimg_library::CImg<unsigned char>("img/enemy13.png"),
    cimg_library::CImg<unsigned char>("img/enemy14.png"),
    cimg_library::CImg<unsigned char>("img/enemy15.png"),
    cimg_library::CImg<unsigned char>("img/enemy16.png"),
  };
  cimg_library::CImg<> masks[21];

/*-----------------------------

  Menu principal

  -------------------------------*/

  cimg_library::CImg<unsigned char> back0(640,480,1,3);
  cimg_library::CImg<unsigned char> title("img/title.jpg");
  cimg_library::CImg<unsigned char> choose("img/choose.png");
  unsigned char wcolor[3] = {255,255,255};
  back0.fill(0);
  back0.draw_image(title,back0.width/2-title.width/2,30);
  back0.draw_image(choose,back0.width/2-choose.width/2,120);
  cimg_library::CImgDisplay *disp = back0.new_display("OdyKill",0,3);

  while(!disp->button) {
    back0.fill(0);
    back0.draw_image(title,back0.width/2-title.width/2,50);
    back0.draw_image(choose,back0.width/2-choose.width/2,150);

    for (int k=0; k<5; k++) {
      cimg_library::CImg<unsigned char> tmp = graphics[k].get_resize(100,100);
      if (!((disp->mousex-40)/110==k && disp->mousey>200 && disp->mousey<300)) tmp/=2;
      back0.draw_image(tmp,40+k*110,200);
    }
    disp->resize(*disp).display(back0,200,300);
  }

  int weapon = 0;
  if (disp->mousey>200 && disp->mousey<300) { weapon = (disp->mousex-40)/110; }

/*---------------------------------

  Go !

  --------------------------------*/

  cimg_library::CImg<unsigned char> background("img/background.jpg");
  background.resize(back0.width,back0.height);
  background/=2.5;
  for (int k=0; k<21; k++) {
    graphics[k].resize(k<5?32:164,k<5?32:164);
    cimg_library::CImg<> tmp(graphics[k].width,graphics[k].height,1,1);
    cimg_mapXY(tmp,x,y) tmp(x,y)  = (graphics[k](x,y,0)==255 && graphics[k](x,y,1)==255 && graphics[k](x,y,2)==255)?0.0f:1.0f;
    masks[k]=tmp;
  }

  cimg_library::CImg<unsigned char> canvas(background);
  int n = 5+((int)(200*cimg_library::cimg::rand())%16);
  cimg_library::CImg<unsigned char> tomato = graphics[weapon], enemy = graphics[n];
  cimg_library::CImg<> m_tomato = masks[weapon], m_enemy = masks[n];

  double angle=0;
  int tomato_x=0,tomato_y=0,shooted=0;
  double enemy_x=-1000, enemy_y=-1000, enemy_z=-1000, tomato_z = 0, vx = 0, vy = 0, vz = 0, va = 0;
  double speed = cimg_option("-speed",10.0,"Speed");
  int timeleft = 2000, score = 0;
  cimg_library::CImg<unsigned char> r_enemy;

// Main loop
  while(timeleft && !disp->closed && disp->key!=cimg_library::cimg::keyESC && disp->key!=cimg_library::cimg::keyQ) {
    timeleft--;

// Handle object motion
    if (tomato_z>0) {
      tomato_z+=0.07; tomato_y -= (int)(20*std::cos(cimg_library::cimg::PI/7 + tomato_z*cimg_library::cimg::PI));
      if (tomato_z>=1) { tomato_z=0; tomato_x = disp->mousex; tomato_y = disp->mousey; }
    }
    if (!shooted) {
      enemy_x +=vx;
      enemy_y +=vy;
      enemy_z +=vz;
    }
    else {
      va = 10;
      enemy_y += vy;
      vy += 5;
      tomato_z = 0;
      if (enemy_y>5*canvas.height/4) {
        shooted = 0;
        int n = 5 + ((int)(200*cimg_library::cimg::rand())%16);
        enemy = graphics[n];
        m_enemy = masks[n];
        enemy_x=cimg_library::cimg::crand()*1e8; enemy_y=cimg_library::cimg::crand()*1e8; enemy_z=cimg_library::cimg::crand()*1e8;
        va = angle = 0;
      }
    }

    if (enemy_x<0) { enemy_x=0; vx = speed*cimg_library::cimg::crand(); }
    if (enemy_x>canvas.width) { enemy_x=canvas.width; vx = speed*cimg_library::cimg::crand(); }
    if (enemy_y<0) { enemy_y=0; vy = speed*cimg_library::cimg::crand(); }
    if (!shooted && enemy_y>canvas.height) { enemy_y=canvas.height; vy = speed*cimg_library::cimg::crand(); }
    if (enemy_z<0.1) { enemy_z = 0.1; vz = speed*0.01*cimg_library::cimg::crand(); }
    if (enemy_z>0.7) { enemy_z = 0.7; vz = speed*0.01*cimg_library::cimg::crand(); }
    angle+=va;

// Handle mouse interaction
    if (!disp->button) {
      if (tomato_z==0) {
        tomato_x = disp->mousex; tomato_y = disp->mousey;
      }
    } else tomato_z +=0.01;

// Detect shooting
    if (std::fabs(tomato_z-enemy_z)<0.1) {
      if (tomato_x>enemy_x-r_enemy.width/2 && tomato_x<enemy_x+r_enemy.width/2 &&
      tomato_y>enemy_y-r_enemy.height/2 && tomato_y<enemy_y+r_enemy.height/2) {
        score++;
        shooted = 1;
      }
    }

// Draw into canvas
    canvas = background;
    r_enemy = enemy.get_resize((int)(8+enemy.width*(1-enemy_z)),(int)(8+enemy.height*(1-enemy_z)),-100,-100);
    cimg_library::CImg<> rm_enemy = m_enemy.get_resize(r_enemy.width,r_enemy.height);
    cimg_library::CImg<unsigned char> r_tomato  = tomato.get_resize((int)(8+tomato.width*(1-tomato_z)),(int)(8+tomato.height*(1-tomato_z)),-100,-100);
    cimg_library::CImg<> rm_tomato = m_tomato.get_resize(r_tomato.width,r_tomato.height);
    if (angle!=0) { r_enemy.rotate((float)angle,0); rm_enemy.rotate((float)angle,0); cimg_mapXY(r_enemy,x,y) r_enemy(x,y,0) = (r_enemy(x,y,0)+255)/2; }
    r_enemy*=(1-(enemy_z-0.1)/1.6);
    r_tomato*=(1-tomato_z/1.6);
    rm_enemy*=(1-(enemy_z-0.1)/1.6);

    if (enemy_z>tomato_z) {
      canvas.draw_image(r_enemy,rm_enemy,(int)(enemy_x-r_enemy.width/2),(int)(enemy_y-r_enemy.height/2));
      if (tomato_x>=0) canvas.draw_image(r_tomato,rm_tomato,tomato_x-r_tomato.width/2,tomato_y-r_tomato.height/2);
    }
    else {
      if (tomato_x>=0) canvas.draw_image(r_tomato,rm_tomato,tomato_x-r_tomato.width/2,tomato_y-r_tomato.height/2);
      canvas.draw_image(r_enemy,rm_enemy,(int)(enemy_x-r_enemy.width/2),(int)(enemy_y-r_enemy.height/2));
    }
    canvas.draw_text(1,1,wcolor,NULL,1,"\r Time left %d, Score = %d",timeleft,score);
    disp->resize(*disp).display(canvas).wait(50);
  }

  delete disp;
  std::fprintf(stderr,"\n\n YOUR SCORE : %d\n\n\n",score);

  exit(0);
  return 0;
}
