/*
Solar Conquest
Copyright (C) 2006 Greg Beaman

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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

using namespace std;

struct Vector
{
	float x;
	float y;
}; 

Vector CreateVector(float x, float y)
{
	Vector v;
	v.x = x;
	v.y = y;
	return v;
}

Vector AddVectors(Vector v1, Vector v2)
{
	Vector v3;
	v3.x = v1.x + v2.x;
	v3.y = v1.y + v2.y;
	return v3;
}

Vector SubtractVectors(Vector v1, Vector v2)
{
	Vector v3;
	v3.x = v1.x - v2.x;
	v3.y = v1.y - v2.y;
	return v3;
}

Vector MultiplyVectors(Vector v1, Vector v2)
{
	Vector v3;
	v3.x = v1.x * v2.x;
	v3.y = v1.y * v2.y;
	return v3;
}

Vector ScaleVector(Vector v1, float scale)
{
	Vector v3;
	v3.x = v1.x * scale;
	v3.y = v1.y * scale;
	return v3;
}

float CapAngle(float angle)
{
	while (angle < -6.28)
		angle += 6.28;
	while (angle > 6.28)
		angle -= 6.28;
	return angle;
}

Vector CapAngles(Vector angles)
{
	Vector v;
	v.x = CapAngle(angles.x);
	v.y = CapAngle(angles.y);
	return v;
}

//floating point version of abs
float absf(float num)
{
	if (num < 0)
		num *= -1;
	return num;
}

float Distance(Vector v1, Vector v2)
{
	float d = sqrt((((v1.x-v2.x)*(v1.x-v2.x))+(v1.y-v2.y)*(v1.y-v2.y)));
	return d;
}

float Distance(float x1, float y1, float x2, float y2)
{
	float d = sqrt((((x1-x2)*(x1-x2))+(y1-y2)*(y1-y2)));
	return d;
}

bool PointInBoxCenter(Vector boxCenter, float width, float height, Vector point)
{
	if ((point.x < boxCenter.x-width) || (point.x > boxCenter.x+width))
		return false;
	if ((point.y < boxCenter.y-height) || (point.y > boxCenter.y+height))
		return false;
	return true;
}

//Wrappers in case lookup tables get used
float ToDegrees(float angle) { return angle * (180/3.14); }
float ToRadians(float angle) { return angle * (3.14/180); }

float GetProperAngle(float radians)
{
	float num = radians;
	while (num >= (3.14*2))
		num -= (3.14*2);
	while (num < 0)
		num = (3.14*2) + num;
	return num;
}
float GetNegativeAngle(float radians)
{
	float num = radians;
	while (num > (3.14))
		num -= (3.14*2);
	return num;
}

float GetSin(float angle) { return sin(angle); }
float GetCos(float angle) { return cos(angle); }

GLenum checkGLError()
{
	GLenum error = glGetError();
#ifdef _DEBUG
	if (error == GL_NO_ERROR)
		return error;
	if (error == GL_INVALID_ENUM)
		return error;
	if (error == GL_INVALID_VALUE)
		return error;
	if (error == GL_INVALID_OPERATION)
		return error;
	if (error == GL_STACK_OVERFLOW)
		return error;
	if (error == GL_STACK_UNDERFLOW)
		return error;
	if (error == GL_OUT_OF_MEMORY)
		return error;
#endif
	return error;
}

bool FileExists(char* fileName)
{
	if (!fileName)
		return false;

	FILE* file;
	file = fopen(fileName,"r");

	if (!file)
		return false;

	fclose(file);
	
	return true;
}

SDL_Surface* LoadBMPImage(char* fileName)
{
	if (!fileName)
		return NULL;

	FILE* file;
	file = fopen(fileName,"r");

	if (!file)
		return NULL;

	fclose(file);
	return SDL_LoadBMP(fileName);
}

float XPixelToTexCoord(int x, float pxWidth)
{
	float rx;
	rx = x * pxWidth;
	return rx;
//	return x;
}

float YPixelToTexCoord(int y, int imgHeight, float pxHeight)
{
	float ry;
	ry = (imgHeight-y) * pxHeight;
//	return ry;
	return y * pxHeight;
}

int lastFpsUpdate = 0;
int frames = 0;
int framesPerSecond = 0;

void UpdateFPS()
{
	frames++;
	if ((SDL_GetTicks()-lastFpsUpdate) >= 1000)
	{
		framesPerSecond = frames;
		frames = 0;
		lastFpsUpdate = SDL_GetTicks();
	}
}

//Just an explenation for some of the funkyness here, there seems to be a difference between Windows gcvt and Unix gcvt, but since we only care about
//the first decimal point in the game speed, the speed is multiplied by 10 and made into an int on save, and multiplied by 0.1 on load. Just fyi.
void LoadGameSettings()
{
	if (!FileExists("settings.dat"))
	{
		g_screenWidth = 640;
		g_screenHeight = 480;
		g_screenDepth = 16;

		g_fullscreen = false;
		g_soundEnabled = true;
		g_gameSpeed = 1.0;
		return;
	}

	ifstream file;
	file.open("settings.dat");

	char txt[MAX_STRING_SIZE];

	file.getline(txt,MAX_STRING_SIZE-2);
	g_screenWidth = atoi(txt);
	file.getline(txt,MAX_STRING_SIZE-2);
	g_screenHeight = atoi(txt);
	file.getline(txt,MAX_STRING_SIZE-2);
	g_screenDepth = atoi(txt);

	file.getline(txt,MAX_STRING_SIZE-2);
	if (atoi(txt) == 1)
		g_fullscreen = true;
	else
		g_fullscreen = false;

	file.getline(txt,MAX_STRING_SIZE-2);
	if (atoi(txt) == 1)
		g_soundEnabled = true;
	else
		g_soundEnabled = false;

	file.getline(txt,MAX_STRING_SIZE-2);
	g_gameSpeed = atof(txt) * 0.1;
}

void SaveGameSettings()
{
	ofstream file;
	file.open("settings.dat");

	char num[MAX_STRING_SIZE];

	sprintf(num,"%d\n%d\n%d\n",g_screenWidth,g_screenHeight,g_screenDepth);
	file.write(num,strlen(num));

	if (g_fullscreen)
		file.write("1\n",strlen("1\n"));
	else
		file.write("0\n",strlen("0\n"));

	if (g_soundEnabled)
		file.write("1\n",strlen("1\n"));
	else
		file.write("0\n",strlen("0\n"));

//	gcvt(g_gameSpeed,3,num);
	int ftoi = (int)(g_gameSpeed*10);
	sprintf(num,"%d\n",ftoi);
	file.write(num,strlen(num));
}