#include <allegro.h>

double max(double a, double b)
{
if (a>b) return a;
return b;
}

double min(double a, double b)
{
if (a<b) return a;
return b;
}

class ball
{
public:
  double x,y;
  double sx,sy;
  BITMAP *p;
  ball (double _x, double _y, double _sx, double _sy)
  {
    x = _x;
    y = _y;
    sx = _sx;
    sy = _sy;
    p = load_bmp("ball.bmp",NULL);
  }

  void draw(BITMAP *where)
  {
   draw_sprite(where,p,x,y);
  }

  void move()
  {
   x+=sx;
   y+=sy;
  }
};

class pad
{
  public:
  bool human;
  char *name;
  int x,y;
  int score;
  BITMAP *p;

  pad(int _x, int _y, char *n, bool h=false)
  {
   human = h;
   score = 0;
   x = _x;
   y = _y;
   name = new char[strlen(n)+1];
   strcpy(name,n);
   p = load_bmp("pad.bmp",NULL);   
  }

  void draw(BITMAP *where)
  {
   draw_sprite(where,p,x,y);
  }
  
};
ball *b1;
pad *p1;
pad *p2;
BITMAP *back;

void draw_all()
{
 clear_to_color(back,makecol(0,0,0));
 b1->draw(back);
 p1->draw(back);
 p2->draw(back);
 textprintf(back,font,0,290,makecol(255,255,255),"%s: %i",p1->name,p1->score);
 textprintf(back,font,0,300,makecol(255,255,255),"%s: %i",p2->name,p2->score);
 blit(back,screen,0,0,0,0,800,600);
}

bool square_collision(ball *bl, pad *pd)
{
    double x11 = bl->x;
    double y11 = bl->y;
    double x12 = bl->x+bl->p->w;
    double y12 = bl->y+bl->p->h;

    double x21 = pd->x;
    double y21 = pd->y;
    double x22 = pd->x+pd->p->w;
    double y22 = pd->y+pd->p->h;

    bool fits_by_x = true;
    bool fits_by_y = true;

    if ((x11<x21)&&(x12<x21)) fits_by_x=false;
    if ((x11>x22)) fits_by_x=false;

    if ((y11<y21)&&(y12<y21)) fits_by_y=false;
    if ((y11>y22)) fits_by_y=false;

    return fits_by_x&&fits_by_y;
}

void collide(ball *b, pad *pl1, pad *pl2)
{
 if (pl1->x>800-pl1->p->w) pl1->x=800-pl1->p->w;
 if (pl1->x<0) pl1->x=0;
 if (pl2->x>800-pl2->p->w) pl2->x=800-pl2->p->w;
 if (pl2->x<0) pl2->x=0;

 if (b->x>800-b->p->w) b->sx=-b->sx;
 if (b->x<0) b->sx=-b->sx;

 if (square_collision(b, pl1)) b->sy=-b->sy;
 if (square_collision(b, pl2)) b->sy=-b->sy;
}

void victory()
{
 int winner = 0;
 if (b1->y>600) winner = 1;
 if (b1->y<0) winner = 2;
 if (winner==0) return;
 if (winner==1) p1->score++;
 if (winner==2) p2->score++;
 b1->x=400;
 b1->y=300;
 b1->sx=3;
 b1->sy=3;
}

void ai(pad *p,ball *b)
{
 if (b->x<p->x+p->p->w/2) p->x-=3;
 if (b->x>p->x+p->p->w/2) p->x+=3;
}

int main()
{
 allegro_init();
 install_keyboard();
 set_color_depth(16);
 set_gfx_mode(GFX_VESA3,800,600,0,0);
 back = create_bitmap(800,600);
 b1 = new ball(400,300,3,-3);
 p1 = new pad(400,0,"Player One",true);
 p2 = new pad(400,550,"Player Two");
 set_keyboard_rate(1,1);
 while(true)
 {
  draw_all();
  if (keypressed())
  {
   int k = readkey();
   if (k>>8 == KEY_ESC) break;
   if (key[KEY_LEFT]) p1->x-=10;
   if (key[KEY_RIGHT]) p1->x+=10;
   if (key[KEY_Q]) p2->x-=10;
   if (key[KEY_W]) p2->x+=10;
  }
  b1->move();
  if (!p1->human) ai(p1,b1);
  if (!p2->human) ai(p2,b1);
  collide(b1,p1,p2);
  victory();
 }
 set_gfx_mode(GFX_TEXT,800,600,0,0);
}
