#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include "SDL.h"
#include "vector.h"             // 2D Vector stuff used for screen coordinates
#include "draw.h"               // 2D Raster Graphics Library used for drawing
#include "blit.h"
#include "bullet.h"
#include "ship.h"               // Spaceship player class
#include "text.h"               // 2D Simple raster text output classes
#include "linklist.h"           // Used for enemy memory management
//#include "mouse.h"              // Mouse driver interface
#include "game.h"               // Main game control

using namespace std;

void game(byte_t *double_buffer, SDL_Surface *screen){
	byte_t 
		RED=	SDL_MapRGB(screen->format,255,  0,  0),
		GREEN=	SDL_MapRGB(screen->format,  0,255,  0),
		BLUE=	SDL_MapRGB(screen->format,  0,  0,255),
		
		YELLOW=	SDL_MapRGB(screen->format,255,255,  0),
		MAGENTA=SDL_MapRGB(screen->format,255,  0,255),
		CYAN=	SDL_MapRGB(screen->format,  0,255,255),
		
		ORANGE=	SDL_MapRGB(screen->format,255,127,  0),
		PINK=	SDL_MapRGB(screen->format,255,  0,127),
		PURPLE=	SDL_MapRGB(screen->format,127,  0,255),
		POWDER=	SDL_MapRGB(screen->format,  0,127,255),
		MARINE=	SDL_MapRGB(screen->format,  0,255,127),
		LIME=	SDL_MapRGB(screen->format,127,255,  0),
		
		BLACK=	SDL_MapRGB(screen->format,  0,  0,  0),
		WHITE=	SDL_MapRGB(screen->format,255,255,255);
	SDL_Event event;
	Uint32 timer=SDL_GetTicks();
	Uint32 ticks=0;
	bool push=false, left=false, right=false;
	int frames=0;
	byte_t rockcolor=31;
        Line l1, l2, l3, l4, l5, l6;
	char charin=0;
	Ship s1;
	int invulnerable=0;
	LinkedList rocks;
	s1.score=0;
	int lastscore=0;
	int level=0;
	Text pause("PAUSE",CENTER-Vector(12,5));
	Text levellabel("LEVEL", Vector(XMAX-80,5));
	Text scorelabel("SCORE:",Vector(XMAX/2-30,5));
	Text gameover("GAME OVER",Vector(XMAX/2-20,YMAX/2-10));
	Text pressanykey("PRESS ANY KEY",Vector(XMAX/2-30,YMAX/2));
	Vector scorepos(XMAX/2+5,5);
	Vector levelpos(XMAX-30,5);
	int turn=0;
	int lives=4;
	bool paused=false;
	Ship extra;
	//mousex();
	//leftclick();
	timer=SDL_GetTicks();
	for(double t=0; charin!='q'; t+=.002*ticks/5){ 
		if(rocks.cleared()){
			level++;
			invulnerable=200;
			for (int i=0; i<level+4; i++)
				rocks.add(Circle(Prand(),Vrand(),20));
		}
		rockcolor=(int(t*256/(2*Pi)))%24+32;
		l1.set(CENTER+f(t), CENTER+g(t));
		l2.set(CENTER+g(t), CENTER+h(t));
		l3.set(CENTER+h(t), CENTER+f(t));
		l4.set(CENTER+f(.5*t)/2, CENTER+g(1.5*t));
		l5.set(CENTER+g(1.5*t), CENTER+h(.5*t));
		l6.set(CENTER+h(.5*t), CENTER+f(.5*t)/2);
		turn=0;
		while(SDL_PollEvent(&event)==1){
			switch(event.type){
				case SDL_KEYDOWN:
					if(event.key.keysym.sym==SDLK_q){
						charin='q';
					}
					if(event.key.keysym.sym==SDLK_UP){
						push=true;
					}
					if(event.key.keysym.sym==SDLK_LEFT){
						left=true;
					}
					if(event.key.keysym.sym==SDLK_RIGHT){
						right=true;
					}
					if(event.key.keysym.sym==SDLK_SPACE){
						s1.shoot();
					}
					if(event.key.keysym.sym==SDLK_p){
						paused=!paused;
					}
					if(event.key.keysym.sym==SDLK_F12){
						SDL_SaveBMP(screen,"asteroids.bmp");
					}
					break;
				case SDL_KEYUP:
					if(event.key.keysym.sym==SDLK_UP){
						push=false;
					}
					if(event.key.keysym.sym==SDLK_LEFT){
						left=false;
					}
					if(event.key.keysym.sym==SDLK_RIGHT){
						right=false;
					}	
			}
		}
		if(left) turn-=ticks;
		if(right) turn+=ticks;
		if(push) s1.push(ticks);
		s1.turn(0.005*turn);
		
		//if (rightclick()) s1.push();
		//if (leftclick()) s1.shoot();
		if(paused){
					pause.draw(POWDER,double_buffer);
					blit0(double_buffer,screen);
		} else {
		s1.fly(ticks);
		rocks.fly(ticks);
		lastscore=s1.score;
		if (!invulnerable)
			rocks.collide(s1);
		else {
			invulnerable-=ticks/5;
			if(0==(ticks/5)) invulnerable--;
			if (invulnerable<0) invulnerable=0;
		}
		if(lastscore!=s1.score)
			if (!(s1.score%ONEUP))
				lives++;
		if (s1.dead()){
			lives--;
			if(lives>=0){
				s1.live();
				s1.set();
				invulnerable=200;
			}
			else charin='q';
		}
		if(t>=32*Pi) t=0;
		l1.draw(GREEN,double_buffer);
		l2.draw(GREEN,double_buffer);
		l3.draw(GREEN,double_buffer);
		l4.draw(BLUE,double_buffer);
		l5.draw(BLUE,double_buffer);
		l6.draw(BLUE,double_buffer);
		draw(rocks,rockcolor,double_buffer);
		if (!((invulnerable/4)%2)) s1.draw(RED,YELLOW,double_buffer);
		scorelabel.draw(POWDER,double_buffer);
		longout(s1.score,scorepos,WHITE,double_buffer);
		levellabel.draw(YELLOW,double_buffer);
		longout(level,levelpos,YELLOW,double_buffer);
		for (int i=0; i<lives; i++){
			extra.set(Vector(10*i+10,9));
			extra.draw(RED,RED,double_buffer);
			if(i>=11) i=lives;
		}
		}
		blit0(double_buffer,screen);		//write buffer to the screen
		memset(double_buffer,0,XMAX*YMAX);	//clear buffer for next frame
		frames++;
		ticks=timer;
		ticks=((timer=SDL_GetTicks())-ticks);
	}
	scorelabel.draw(POWDER,double_buffer);
	longout(s1.score,scorepos,WHITE,double_buffer);
	levellabel.draw(YELLOW,double_buffer);
	longout(level,levelpos,YELLOW,double_buffer);
	gameover.draw(RED,double_buffer);
	pressanykey.draw(MAGENTA,double_buffer);
	blit0(double_buffer,screen);
	while((SDL_PollEvent(&event)!=1)||(event.type!=SDL_KEYDOWN));
	memset(double_buffer,0,XMAX*YMAX);
}

Vector f(double t){
	return Vector(	int(2*cos(t+Pi)*XMAX/4.0),
			int(cos(t/2)*YMAX/2.5)
	);
}

Vector g(double t){
	return Vector(	int(cos(t)*XMAX/4.0),
			int(sin(t)*-YMAX/2.5)
	);
}

Vector h(double t){
	return Vector(	int(2*sin(t+Pi)*XMAX/4.0),
			int(YMAX/2.0*cos(2*t))
	);
}
