/*    Zonic the Hog.  A silly Sonic-like game written for Speedhack 2007
 *    Copyright (c) 2007 Steven Wallace / Chedda Cheeze
 *    email: steven.t.wallace @ gmail. com
 *
 *    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.
 *
 *    You should have received a copy of the GNU General Public License along
 *    with this program; if not, write to the Free Software Foundation, Inc.,
 *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
 
#include "Game.h"
#include <allegro.h>
#include <alleggl.h>
#include "main.h"
#include "Level.h"
#include <math.h>
#include "Cutscene.h"
#include "Menu.h"
#include "fudgefont.h"


Game::Game() {
	//Restart();
	levels[0] = levels[1] = levels[2] = false;
}




bool Game::Update(float dt) {
	timer += dt;
	
	
	vector<int>::const_iterator it;
	for(it=keys->begin(); it!=keys->end(); it++) {
		switch(*it) {
		case KEY_ESC:
			Pause();
			toProcess.clear();
			//toProcess.push_back(this);
			toProcess.push_back(&menu);
			return true;
			break;
		
		}
	}

	if(player.UpdatePig(dt)) return true;
	if(farmer.UpdateAI(dt)) return true;
	level->UpdateApples(dt);
	

	// Ensure camera is on the piggy
	int SCREEN_W4 = SCREEN_W/4;
	int SCREEN_H3 = SCREEN_H/3;
	
	if(player.GetX() - SCREEN_W4 < cx) {
		cx = (int)player.GetX() - SCREEN_W4;
		if(cx < 0) cx = 0;
	}
	else if(player.GetX() - SCREEN_W4*3 > cx) {
		cx = (int)player.GetX() - SCREEN_W4*3;
		if(cx > level->GetWidthInPixels() - SCREEN_W) cx = level->GetWidthInPixels() - SCREEN_W;
	}

	if(player.GetY() - SCREEN_H3 < cy) {
		cy = (int)player.GetY() - SCREEN_H3;
	}
	else if((int)player.GetY() - SCREEN_H3*2 > cy) cy = (int)player.GetY() - SCREEN_H3*2;
	
	
	return false;
}	



void Game::DrawFarmerLocator() {
	if(farmer.IsOnScreen(cx,cy)) return;
	glPushMatrix();
	glTranslatef(SCREEN_W/2, SCREEN_H/5, 0);
	float yDist = player.GetY() - farmer.GetY();
	float xDist = player.GetX() - farmer.GetX();
	float angle = atan(yDist/xDist) * 180 / M_PI;
	float dist2 = yDist*yDist + xDist*xDist;
	if(farmer.GetX() > player.GetX()) angle += 180;
	glRotatef(angle, 0, 0, 1);
	dist2 = SQUEEZE(0.5, sqrt(dist2)*0.0005, 3);
	glScalef(dist2, 1, 1);
	glColor3f(0,0,0);
	
	/*if(allegro_gl_get(AGL_ACC_ALPHA_DEPTH) > 4) {
		glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
		glEnable(GL_BLEND);
		glEnable(GL_POLYGON_SMOOTH);
		glDisable(GL_DEPTH_TEST);
	}*/

	glBegin(GL_QUADS);
		glVertex2i(-16, -8);
		glVertex2i(-16,  8);
		glVertex2i( 16,  8);
		glVertex2i( 16, -8);
	glEnd();
	
	glBegin(GL_TRIANGLES);
		glVertex2i( -14, -12);
		glVertex2i( -14,  12);
		glVertex2i( -32,   0);
	glEnd();
	//glDisable(GL_POLYGON_SMOOTH);
	
	glPopMatrix();
}



void Game::Draw(BITMAP *buffer) {
	level->Draw(buffer, cx, cy);
	player.Draw(buffer, cx, cy);
	farmer.Draw(buffer, cx, cy);
	
	/*
	// Debug info
	#ifdef _DEBUG
	textprintf_ex(buffer, font, 0, 0, 0, -1, "x=%0.0f  y=%0.0f", player.GetX(), player.GetY());
	textprintf_ex(buffer, font, 0,10, 0, -1, "dx=%0.0f  dy=%0.0f", player.GetDX(), player.GetDY());
	textprintf_ex(buffer, font, 0,20, 0, -1, "cx=%d  cy=%d", cx, cy);
	textprintf_ex(buffer, font, 0,30, 0, -1, "h=%d  theta=%0.0f", level->GetHeight((int)player.GetX()), player.GetAngle());
	#endif
	*/
	
	// Status: timer and food
	glDisable(GL_TEXTURE_2D);
	DrawFarmerLocator();
	
	my_color(0,0,0);
	my_print(fMenu, 24, 24, FALSE, "%d:%02d.%02.0f", (int)timer/60, ((int)timer)%60, (timer - (int)timer) * 100);
	my_print(fMenu, 24, 48, FALSE, "Score: %d", player.GetScore());
	
	my_print_right(fMenu, SCREEN_W - 72, 24,  "Apples:");
	my_print_right(fMenu, SCREEN_W - 24, 24,  "%d", player.GetItem(ITEM_APPLE));
	my_print_right(fMenu, SCREEN_W - 72, 48,  "Bananas:");
	my_print_right(fMenu, SCREEN_W - 24, 48,  "%d", player.GetItem(ITEM_BANANA));
	my_print_right(fMenu, SCREEN_W - 72, 72,  "Carrots:");
	my_print_right(fMenu, SCREEN_W - 24, 72,  "%d", player.GetItem(ITEM_CARROT));
	my_print_right(fMenu, SCREEN_W - 72, 96,  "Eggs:");
	my_print_right(fMenu, SCREEN_W - 24, 96,  "%d", player.GetItem(ITEM_EGG));
}




void Game::Restart() {
	printf("Loading level...\n");
	char temp[16];
	snprintf(temp,16,"level%02d.map", levelNumber);
	level->Load(temp);
	cx = cy = 0;
	paused = false;
	player.Restart();
	farmer.Restart();
	timer = 0.0;
}



void Game::NextLevel() {
	toProcess.clear();
	levels[levelNumber] = true;
	
	int i;
	bool found = false;
	for(i=0; i<3; i++) if(levels[i] == false) { levelNumber = i; found = true; break; }
	if(!found) {
		levelNumber = 3;
		toProcess.push_back(&cutscene);
	}
	else toProcess.push_back(&game);
	Restart();
}


void Game::NewGame() {
	Restart();
	levels[0] = levels[1] = levels[2] = false;
	player.NewGame();
}


