#include <stdio.h>
#include <allegro5/allegro.h>

const int SCREEN_W = 640;
const int SCREEN_H = 480;
const float FPS = 60;
const int paddle_height = 96;
const int paddle_width = 16;
const int bouncer_size = 16;

enum MYKEYS {
    KEY_UP, KEY_DOWN, KEY_W, KEY_S
};

int main(int argc, char **argv)
{
    ALLEGRO_DISPLAY *display = NULL;
    ALLEGRO_EVENT_QUEUE *event_queue = NULL;
    ALLEGRO_TIMER *timer = NULL;
    ALLEGRO_BITMAP *right_paddle = NULL;
    ALLEGRO_BITMAP *left_paddle = NULL;
    ALLEGRO_BITMAP *bouncer = NULL;

    float right_paddle_x = (SCREEN_W * 4/5) - (paddle_width / 2.0);
    float right_paddle_y = (SCREEN_H / 2.0) - (paddle_height / 2.0);
    
    float left_paddle_x = (SCREEN_W * 1/5) - (paddle_width / 2.0); 
    float left_paddle_y = (SCREEN_H / 2.0) - (paddle_height / 2.0);
    
    float bouncer_x = SCREEN_W / 2.0 - bouncer_size / 2.0;
    float bouncer_y = SCREEN_H / 2.0 - bouncer_size / 2.0;
    float bouncer_dx = 4.0, bouncer_dy = -4.0;
    
    bool key[4] = {false, false, false, false };
    bool redraw = true;
    bool doexit = false;
    
    if(!al_init()) {
	fprintf(stderr, "failed to initialized allegro\n");
	return -1;
    }
    
    if(!al_install_keyboard()) {
	fprintf(stderr, "failed to install keyboard\n");
	return -1;
    }
    
    //initialize display (w, h)
    display = al_create_display(SCREEN_W, SCREEN_H);
    if(!display) {
	fprintf(stderr, "failed to create display\n");
	return -1;
    }
    
    timer = al_create_timer(1.0/FPS);
    if(!timer) {
	fprintf(stderr, "failed to create timer\n");
	return -1;
    }
    
    right_paddle = al_create_bitmap(paddle_width, paddle_height);
    if(!right_paddle) {
	fprintf(stderr, "failed to create right paddle bitmap\n");
	return -1;
    }
    
    left_paddle = al_create_bitmap(paddle_width, paddle_height);
    if(!left_paddle) {
	fprintf(stderr, "failed to create left paddle bitmap\n");
	return -1;
    }
    bouncer = al_create_bitmap(bouncer_size, bouncer_size);
    if(!bouncer) {
	fprintf(stderr, "failed to create bouncer bitmap\n");
	return -1;
    }
    
    al_set_target_bitmap(left_paddle);
    al_clear_to_color(al_map_rgb (0,255,0));
    
    al_set_target_bitmap(right_paddle);
    al_clear_to_color(al_map_rgb (0,255,0));
    
    al_set_target_bitmap(bouncer);
    al_clear_to_color(al_map_rgb (0,0,255));
    
    al_set_target_bitmap(al_get_backbuffer(display));
    
    event_queue = al_create_event_queue();
    if(!event_queue) {
	fprintf(stderr, "failed to create event queue\n");
	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_start_timer(timer);
    
    while(!doexit)
    {
	ALLEGRO_EVENT ev;
	
	al_wait_for_event(event_queue, &ev);
	
	if(ev.type == ALLEGRO_EVENT_TIMER) {
	    
	    //logic for moving the paddles on input
	    if(key[KEY_UP] && right_paddle_y >= 4.0) {
		right_paddle_y -= 4.0;
	    }
	    
	    if(key[KEY_DOWN] && right_paddle_y <= SCREEN_H - paddle_height - 4.0){
		right_paddle_y += 4.0;
	    }
	    
	    if(key[KEY_W] && left_paddle_y >= 4.0) {
		left_paddle_y -= 4.0;
	    }
	    
	    if(key[KEY_S] && left_paddle_y <= SCREEN_H - paddle_height - 4.0){
		left_paddle_y += 4.0;
	    }
	    
	    //logic for the bouncer
	    if(bouncer_x < 0 || bouncer_x > SCREEN_W - bouncer_size) {
		bouncer_dx = -bouncer_dx;
	    }
	    
	    if(bouncer_y < 0 || bouncer_y > SCREEN_H - bouncer_size) {
		bouncer_dy = -bouncer_dy;
	    }
	    
	     if(bouncer_x == left_paddle_x + (paddle_width / 2.0) || bouncer_x == right_paddle_x - (paddle_width / 2.0)) {
		bouncer_dx = -bouncer_dx;
	    }
	
	    
	    bouncer_x += bouncer_dx;
	    bouncer_y += bouncer_dy;
	    
	    redraw = true;
	}
	
	else 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_W:
		    key[KEY_W] = true;
		    break;
		    
		case ALLEGRO_KEY_S:
		    key[KEY_S] = true;
		    break;
	    }
	}
	
	else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
	    switch(ev.keyboard.keycode) {
		case ALLEGRO_KEY_UP:
		    key[KEY_UP] = false;
		    break;
		    
		case ALLEGRO_KEY_DOWN:
		    key[KEY_DOWN] = false;
		    break;
		    
		case ALLEGRO_KEY_W:
		    key[KEY_W] = false;
		    break;
		    
		case ALLEGRO_KEY_S:
		    key[KEY_S] = false;
		    break;
		
		case ALLEGRO_KEY_ESCAPE:
		    doexit = true;
		    break;
	    }
	}
	
	if(redraw && al_is_event_queue_empty(event_queue)) {
	    redraw = false;
	    
	    al_clear_to_color(al_map_rgb(0,0,0));
	    
	    al_draw_bitmap(right_paddle, right_paddle_x, right_paddle_y, 0);
	    al_draw_bitmap(left_paddle, left_paddle_x, left_paddle_y, 0);
	    al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0);
	    
	    al_flip_display();
	}
    }
    
    al_destroy_bitmap(bouncer);
    al_destroy_bitmap(right_paddle);
    al_destroy_bitmap(left_paddle);
    al_destroy_timer(timer);
    al_destroy_display(display);
    al_destroy_event_queue(event_queue);
    
    return 0;
}