/*
	This file is part of Floculate.
	Copyright (C) 2008  Bill Whitacre

	Floculate 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 3 of the License, or
	(at your option) any later version.

	Floculate 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, see <http://www.gnu.org/licenses/>.
*/

#include "ortho.h"
#if defined(_MSC_VER)||defined(__WIN32__)
#	include <windows.h>
#endif

#if defined(__APPLE__)
#	include <OpenGL/gl.h>
#else
#	include <GL/gl.h>
#endif

static rat_ortho_mode projmode;
static unsigned int rx,ry;
static unsigned int vx,vy;

void rat_ortho_set_mode(rat_ortho_mode mode)
{
	projmode=mode;
}

rat_ortho_mode rat_ortho_get_mode()
{
	return projmode;
}

void rat_ortho_set_res(unsigned int x,unsigned int y)
{
	rx=x;
	ry=y;
}

void rat_ortho_set_virtual_res(unsigned int x,unsigned int y)
{
	vx=x;
	vy=y;
}

void rat_ortho_get_res(unsigned int *x,unsigned int *y)
{
	*x=rx;
	*y=ry;
}

void rat_ortho_get_virtual_res(unsigned int *x,unsigned int *y)
{
	*x=vx;
	*y=vy;
}

void rat_ortho_push()
{
	int vp[4];

	// Set up the ortho variables
	if ((int)projmode<2) glGetIntegerv(GL_VIEWPORT,vp);
	
	// Save a copy of the projection matrix so that we can restore it
	// when it's time to do 3D rendering again.
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();

	// Set up the orthographic projection
	switch (projmode)
	{
	case rat_ortho_vp_vres:
		vp[2]=vx;
		vp[3]=vy;
	case rat_ortho_vp:
		break;
	case rat_ortho_res_vres:
		vp[0]=0;
		vp[1]=0;
		vp[2]=vx;
		vp[3]=vy;
		break;
	case rat_ortho_res:
		vp[0]=0;
		vp[1]=0;
		vp[2]=rx;
		vp[3]=ry;
		break;
	}

	if ((int)projmode>1) glViewport(0,0,rx,ry);
	glOrtho(vp[0],vp[0]+vp[2],vp[1]+vp[3],vp[1],-1,1);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	glMatrixMode(GL_TEXTURE);
	glPushMatrix();
	glLoadIdentity();

	// Make sure depth testing and lighting are disabled for 2D rendering until
	// we are finished rendering in 2D
	glPushAttrib(GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT|GL_ENABLE_BIT);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);
	glEnable(GL_BLEND);
}

void rat_ortho_pop()
{
	glPopAttrib();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_TEXTURE);
	glPopMatrix();
}
