/*
 *  Pong
 *
 *  Created by Remi Bernotavicius on 12/4/08.
 *  Copyright (c) 2008 __MyCompanyName__. All rights reserved.
 */

#include <allegro.h>
#include <math.h>

#define paddle_width 10
#define paddle_height 50
#define screen_width 640
#define screen_height 400
#define ball_speed 70
#define ball_size 6
#define paddle_speed 15
#define dashed_frequency 20.00

#define UP 0
#define CENTER 1
#define DOWN 2

//left side
int yl = ((screen_height / 2) - (paddle_height/2))*paddle_speed;
int points_l = 0;
int direction_l = CENTER;

//right side
int yr = ((screen_height / 2) - (paddle_height/2))*paddle_speed;
int points_r = 0;
int direction_r = CENTER;

//ball
int bx = (screen_width / 2)*ball_speed;
int by = (screen_height / 2)*ball_speed;
int angle = 30;
int i_speed = 5;

int rest_counter = 0;

void gatherInput()
{
  if(key[KEY_DOWN] && yr < (screen_height - paddle_height)*paddle_speed)
  {
    yr++;
    direction_r = DOWN;
  }
  else if(key[KEY_UP] && yr > 0)
  {
    yr--;
    direction_r = UP;
  }
  else
  {
    direction_r = CENTER;
  }
  
  if(key[KEY_Z] && yl < (screen_height - paddle_height)*paddle_speed)
  {
    yl++;
    direction_l = DOWN;
  }
  else if(key[KEY_A] && yl > 0)
  {
    yl--;
    direction_l = UP;
  }
  else
  {
    direction_l = CENTER;
  }
}


int main(int argc, const char *argv[])
{
  allegro_init();
  install_keyboard();
  
  if (set_gfx_mode(GFX_AUTODETECT, screen_width, screen_height, 0, 0)) {
    allegro_message("Error setting 320x200x8 gfx mode:\n%s\n", allegro_error);
    return -1;
  }
  
  //Title Screen
  textprintf_centre_ex(screen, font, screen_width/2, 100, makecol(255, 255, 255), -1, "Pong!");
  textprintf_centre_ex(screen, font, screen_width/2, 120, makecol(255, 255, 255), -1, "By Remi Bernotavicius");
  textprintf_centre_ex(screen, font, screen_width/2, 140, makecol(255, 255, 255), -1, "Press Space Bar to Start");
  
  
  while(!key[KEY_SPACE])
  {
    if(key[KEY_ESC])
      return 0;
  }
  
  BITMAP* buffer = create_bitmap(screen_width, screen_height);
  
  while(!key[KEY_ESC])
  {
    gatherInput();
    clear_to_color(buffer, 0);
    
    //score
    textprintf_centre_ex(buffer, font, screen_width/4, 10, makecol(255, 255, 255), -1, "%d", points_l);
    textprintf_centre_ex(buffer, font, screen_width*(3.00/4.00), 10, makecol(255, 255, 255), -1, "%d", points_r);
    
    //dashed line
    float f;
    for(f = 1.00;f < dashed_frequency;f +=2.00)
      line(buffer, screen_width/2, -10 + screen_height - (screen_height*(f/dashed_frequency)) + (screen_height*(1.00/dashed_frequency)), screen_width/2, -10 + screen_height - (screen_height*(f/dashed_frequency)), makecol(255, 255, 255));
    
    //left paddle
    rectfill(buffer, 10, yl/paddle_speed, 10+paddle_width, (yl/paddle_speed)+paddle_height, makecol(255, 255, 255));
    //right paddle
    rectfill(buffer, screen_width - 10 - paddle_width, yr/paddle_speed, screen_width - 10, (yr/paddle_speed)+paddle_height, makecol(255, 255, 255));
    
    while(angle > 360)
      angle -= 360;
    while(angle < -360)
      angle += 360;
    
    
    if(rest_counter == 0)
    {
    bx+=cos(angle*M_PI/180)*i_speed;
    by+=sin(angle*M_PI/180)*i_speed;
    }
    else
    {
      rest_counter--;
    }
    
    circlefill(buffer, bx/ball_speed, by/ball_speed, ball_size, makecol(250, 250, 250));
    
    //collision detection
    if((by/ball_speed) > screen_height - ball_size)
    {
      angle *= -1;
      by = (screen_height - ball_size)*ball_speed;
    }
    else if((by/ball_speed) < ball_size)
    {
      angle *= -1;
      by = ball_size * ball_speed;
    }
    
    if((bx/ball_speed) > (screen_width - 10 - paddle_width - ball_size))
    {
      if((by / ball_speed) > ((yr/paddle_speed) - ball_size) && (by / ball_speed) < (((yr/paddle_speed) + paddle_height) + ball_size))
      {
        //If the ball hit the right paddle
        
        angle *= -1;
        angle += 180;
        if(direction_r == UP)
        {
          angle += 30*sin(angle*M_PI/180);
          i_speed -= 2*sin(angle*M_PI/180);
        }
        else if(direction_r == DOWN)
        {
          angle -= 30*sin(angle*M_PI/180);
          i_speed += 2*sin(angle*M_PI/180);
        }
        bx = (screen_width - 10 - paddle_width - ball_size)*ball_speed;
      }
      else
      {
        //If the ball went off the screen on the right
        
        points_l++;
        bx = (screen_width/2)*ball_speed;
        by = (screen_height/2)*ball_speed;
        angle = 30;
        i_speed = 5;
        rest_counter = 3000;
      }
    }
    else if((bx/ball_speed) < 10 + paddle_width + ball_size)
    {
      if((by / ball_speed) > ((yl/paddle_speed) - ball_size) && (by / ball_speed) < (((yl/paddle_speed) + paddle_height) + ball_size))
      {
        //If the ball hit the left paddle
        
        angle *= -1;
        angle += 180;
        
        if(direction_l == UP)
        {
          angle -= 30*sin(angle*M_PI/180);
          i_speed -= 2*sin(angle*M_PI/180);
        }
        else if(direction_l == DOWN)
        {
          angle += 30*sin(angle*M_PI/180);
          i_speed += 2*sin(angle*M_PI/180);
        }
        
        bx = (10 + paddle_width + ball_size)*ball_speed;
      }
      else
      {
        //If the ball went off the screen on the left
        
        points_r++;
        bx = (screen_width/2)*ball_speed;
        by = (screen_height/2)*ball_speed;
        angle = 150;
        i_speed = 5;
        rest_counter = 3000;
      }
    }
    
    blit(buffer, screen, 0, 0, 0, 0, screen_width, screen_height);
    
  }
  
  
  return 0;
}
END_OF_MAIN();