/*  DS
 *  Copyright (C) Anders Asplund and Joakim Kolsjö 2005
 *	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
 */

#include "hcamera.h"

using namespace std;

namespace DS
{	
	HCamera::HCamera()
	{
		// Set defaults
		m_pHandleAttr->Insert("type", "persp");
		m_pDefaultNodeAttr->Insert("time", "required");
		m_pDefaultNodeAttr->Insert("z", "0");
	}

	void HCamera::Init()
	{
		for(int i = 0; i < (int)m_NodeAttrList.size(); i++)
		{
			Map* pNodeAttr = m_NodeAttrList[i];
			Attrib temp;
			temp.time = atol(pNodeAttr->Get("time"));
			temp.z = atof(pNodeAttr->Get("z"));
			m_attr.push_back(temp);
		}		
		string type = m_pHandleAttr->Get("type");
		if(type == "persp")
			m_bPerspective = true;
		else if(type == "ortho")
			m_bPerspective = false;
		else
			throw Exception("[HCamera::Init]", "Unknown type, allowed: persp or ortho.");
		SetupRange();
	}
	
	void HCamera::Reset()
	{
		m_current = 1;
		m_bProjectionSet = false;
	}
	
	void HCamera::Draw(long time)
	{		
		// Set projection type
		if(!m_bProjectionSet)
		{
			// Perspective
			if(m_bPerspective)
			{
				glMatrixMode(GL_PROJECTION);
				glLoadIdentity();
				gluPerspective(45, (GLdouble)4/3, 1, 100);
    			glMatrixMode(GL_MODELVIEW);
    			glLoadIdentity();
			} else { // Ortographical
				glMatrixMode(GL_PROJECTION);
				glLoadIdentity();
				glOrtho(0, 800, 0, 600, 1, 100);
    			glMatrixMode(GL_MODELVIEW);
    			glLoadIdentity();
			}
			
			m_bProjectionSet = true;			
		}
		
				glShadeModel(GL_SMOOTH);
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LEQUAL);
		
		glClearDepth(1);
		glClearColor(0.0, 0.0, 0.0, 0);
		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_BLEND);
		
		
		// Find current state
		if(m_attr.size() > 2 && m_current < m_attr.size()-1)
			if(time > m_attr[m_current].time)
				m_current++;
				
		float s = (float)(time - m_attr[m_current-1].time)/(m_attr[m_current].time - m_attr[m_current-1].time);
		m_state.z =  m_attr[m_current-1].z + (m_attr[m_current].z-m_attr[m_current-1].z)*s;
			
		glTranslatef(0, 0, -m_state.z);
	}
}
