#include "SDL.h"
#include "SDL_opengl.h"
#include <iostream>

#include "util.h"
#include "coordinate.h"



namespace PRJID {
void error() {
   GLenum errorcode;
   const GLubyte *errorstring;


   if ((errorcode= glGetError()) != GL_NO_ERROR) {
      errorstring = gluErrorString(errorcode);
      std::cerr << "GL_ERROR: " << errorstring << std::endl;
   }

}

void ortho2d(float dx,float dy) {
	//disable stuff
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);


	// change projection to ortho 
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0.0,dx,dy,0.0);

	// back to mv and push
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
}

void ortho2d_off() {
	//enable stuff
	glEnable(GL_LIGHTING);
	glEnable(GL_DEPTH_TEST);


	// pop projection matrix
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();


	// pop mv matrix
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
}

void screenshot(int w,int h,unsigned int t) {
	Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    rmask = 0xff000000;
    gmask = 0x00ff0000;
    bmask = 0x0000ff00;
    amask = 0x000000ff;
#else
    rmask = 0x000000ff;
    gmask = 0x0000ff00;
    bmask = 0x00ff0000;
    amask = 0xff000000;
#endif
	SDL_Surface *my;
	my=SDL_CreateRGBSurface( SDL_SWSURFACE, w,h, 32, rmask, gmask, bmask, amask);
	glReadBuffer(GL_FRONT);
	glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, my->pixels);
	std::ostringstream sstr;
	if (t==0) t=time(NULL);
	sstr << SHORTNAME << "_screenshot_" << t << ".bmp";
	SDL_SaveBMP(my,sstr.str().c_str());
}


C3f unproject(int x, int y) {
	GLint viewport[4];
	GLdouble modelview[16];
	GLdouble projection[16];
	GLdouble winX, winY;
	GLfloat winZ;
	GLdouble posX, posY, posZ;

	glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
	glGetDoublev( GL_PROJECTION_MATRIX, projection );
	glGetIntegerv( GL_VIEWPORT, viewport );

	winX = (GLdouble)x;
	winY = (GLdouble)viewport[3] - (GLdouble)y;
	glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

	gluUnProject( winX, winY,(GLdouble) winZ, modelview, projection, viewport, &posX, &posY, &posZ);

	return C3f((float)posX, (float)posY, (float)posZ);
}

float destdegree(C3f p1,C3f p2) {
   static const float radtodeg = 180/M_PI;
   float opp;
   opp=(float)(p1.z-p2.z);

   float a,b;
   a=float(p1.x-p2.x);
   b=float(p1.z-p2.z);
   a*=a;
   b*=b;

   float hyp=sqrtf(a+b);

   float sinalpha=opp/hyp;

   float deg;
   deg=asinf(sinalpha)*radtodeg;
	if (p2.x<p1.x) {
		deg=180.0f+deg*-1;
	}
	if (deg<0) deg+=360;
   return deg;
}

void bar(C3 start,C3 size) {
   glBegin(GL_QUADS);
   glVertex2i(start.x,start.y);
   glVertex2i(start.x,start.y+size.y);
   glVertex2i(start.x+size.x,start.y+size.y);
   glVertex2i(start.x+size.x,start.y);
   glEnd();
}

void crosshair() {
	static GLuint dl=0;
	if (dl!=0) { glCallList(dl); return; }
	dl = glGenLists(1);
	glNewList(dl,GL_COMPILE_AND_EXECUTE);


   C3 center;
   center.x=320;
   center.y=240;
   int size=10;
   int d=4;

	glColor3ub(250,250,250);


	glBegin(GL_LINES);
		glVertex2i(center.x,center.y-size-d);
		glVertex2i(center.x,center.y-d);
	glEnd();
	glBegin(GL_LINES);
		glVertex2i(center.x,center.y+size+d);
		glVertex2i(center.x,center.y+d);
	glEnd();
	glBegin(GL_LINES);
		glVertex2i(center.x-size-d,center.y);
		glVertex2i(center.x-d,center.y);
	glEnd();
	glBegin(GL_LINES);
		glVertex2i(center.x+size+d,center.y);
		glVertex2i(center.x+d,center.y);
	glEnd();

	glEndList();
}

void menu_bg() {
	glPushMatrix();
	glScalef(640,480,0);
	glBegin(GL_QUADS);


	glColor3ub(30,40,250);
	glVertex2i(0,0);
	glColor3ub(60,80,250);
	glVertex2i(0,1);

	glColor3ub(30,40,150);
	glVertex2i(1,1);

	glColor3ub(20,30,130);
	glVertex2i(1,0);

	glEnd();
	glPopMatrix();


}

void lockmouse(){
	SDL_ShowCursor(SDL_DISABLE);
	SDL_WM_GrabInput(SDL_GRAB_ON);
}
void unlockmouse(){
	SDL_ShowCursor(SDL_ENABLE);
	SDL_WM_GrabInput(SDL_GRAB_OFF);
}
void togglemouselock() {
	if (ismouselocked()) {
		unlockmouse();
	} else {
		lockmouse();
	}
}

bool ismouselocked() {
	if (SDL_ShowCursor(SDL_QUERY)==SDL_DISABLE) { return true; }
	return false;
}

Uint32 took_;
void took_on() {
	took_=SDL_GetTicks();
}
void took_off() {
	std::cout << "took: " << SDL_GetTicks()-took_ << std::endl;

}

} //namespace
