/*
   Copyright (C) 1999-2006 Id Software, Inc. and contributors.
   For a list of contributors, see the accompanying CONTRIBUTORS file.

   This file is part of GtkRadiant.

   GtkRadiant 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.

   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
   Camera plugin for GtkRadiant
   Copyright (C) 2002 Splash Damage Ltd.
 */

#include "camera.h"

CRenderer::CRenderer() {

	refCount = 1;

	m_bHooked = FALSE;

	Register();
	Initialize();
}

CRenderer::~CRenderer() {
	if ( m_bHooked ) {
		UnRegister();
	}
}

void CRenderer::Register() {
	g_QglTable.m_pfnHookGL2DWindow( this );
	g_QglTable.m_pfnHookGL3DWindow( this );
	m_bHooked = TRUE;
}

void CRenderer::UnRegister() {
	if ( g_QglTable.m_nSize ) {
		g_QglTable.m_pfnUnHookGL2DWindow( this );
		g_QglTable.m_pfnUnHookGL3DWindow( this );
	}
	m_bHooked = FALSE;
}

void CRenderer::Initialize() {

}

void CRenderer::Draw2D( VIEWTYPE vt ) {

	g_QglTable.m_pfn_qglPushAttrib( GL_ALL_ATTRIB_BITS );
	g_QglTable.m_pfn_qglPushMatrix();

	switch ( vt )
	{
	case XY:
		break;
	case XZ:
		g_QglTable.m_pfn_qglRotatef( 270.0f, 1.0f, 0.0f, 0.0f );
		break;
	case YZ:
		g_QglTable.m_pfn_qglRotatef( 270.0f, 1.0f, 0.0f, 0.0f );
		g_QglTable.m_pfn_qglRotatef( 270.0f, 0.0f, 0.0f, 1.0f );
		break;
	}

	CCamera *cam = firstCam;
	while ( cam ) {
		cam->GetCam()->draw( ( ( Listener && cam == g_pCurrentEditCam ) ? true : false ) );
		cam = cam->GetNext();
	}

	g_QglTable.m_pfn_qglPopMatrix();
	g_QglTable.m_pfn_qglPopAttrib();
}

void CRenderer::Draw3D() {
	// FIXME: really need a mainloop callback from the editor core
	static long start;
	static float cycle;
	static long msecs;
	static long current;

	if ( g_iPreviewRunning ) {
		if ( g_iPreviewRunning == 1 ) {
			start = Q_QGetTickCount();
			GetCurrentCam()->GetCam()->startCamera( start );
			cycle = GetCurrentCam()->GetCam()->getTotalTime();
			msecs = (long)( cycle * 1000 );
			current = start;
			g_iPreviewRunning = 2;
		}

		if ( current < start + msecs ) {
			float fov;
			vec3_t origin = {0.0f, 0.0f, 0.0f}, dir = {0.0f, 0.0f, 0.0f}, angles;

			GetCurrentCam()->GetCam()->getCameraInfo( current, &origin[0], &dir[0], &fov );
			VectorSet( angles, asin( dir[2] ) * 180 / 3.14159, atan2( dir[1], dir[0] ) * 180 / 3.14159, 0 );
			g_CameraTable.m_pfnSetCamera( origin, angles );
			current = Q_QGetTickCount();
		}
		else {
			g_iPreviewRunning = 0;
			GetCurrentCam()->GetCam()->setRunning( false );
			g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
		}
	}

	g_QglTable.m_pfn_qglPushAttrib( GL_ALL_ATTRIB_BITS );

	CCamera *cam = firstCam;
	while ( cam ) {
		cam->GetCam()->draw( ( ( Listener && cam == g_pCurrentEditCam ) ? true : false ) );
		cam = cam->GetNext();
	}

	if ( g_iPreviewRunning ) {
		int x, y, width, height, i;
		float degInRad;

		g_CameraTable.m_pfnGetCamWindowExtents( &x, &y, &width, &height );

		// setup orthographic projection mode
		g_QglTable.m_pfn_qglMatrixMode( GL_PROJECTION );
		g_QglTable.m_pfn_qglLoadIdentity();
		g_QglTable.m_pfn_qglDisable( GL_DEPTH_TEST );
		g_QglTable.m_pfn_qglOrtho( 0, (float)width, 0, (float)height, -100, 100 );
		g_QglTable.m_pfn_qglMatrixMode( GL_MODELVIEW );

		g_QglTable.m_pfn_qglLoadIdentity();
		g_QglTable.m_pfn_qglColor3f( 1.f, 1.f, 1.f );
		g_QglTable.m_pfn_qglBegin( GL_LINE_LOOP );
		g_QglTable.m_pfn_qglVertex2f( 10, 10 );
		g_QglTable.m_pfn_qglVertex2f( 40, 10 );
		g_QglTable.m_pfn_qglVertex2f( 40, 25 );
		g_QglTable.m_pfn_qglVertex2f( 10, 25 );
		g_QglTable.m_pfn_qglEnd();

		g_QglTable.m_pfn_qglBegin( GL_LINE_LOOP );
		for ( i = 0; i < 360; i += 60 ) {
			degInRad = i * ( 3.14159265358979323846 / 180.f );
			g_QglTable.m_pfn_qglVertex2f( 18 + cos( degInRad ) * 5, 18 + sin( degInRad ) * 5 );
		}
		g_QglTable.m_pfn_qglEnd();

		degInRad = ( 360 - ( ( current - start ) % 360 ) ) * ( 3.14159265358979323846 / 180.f );
		g_QglTable.m_pfn_qglBegin( GL_LINES );
		g_QglTable.m_pfn_qglVertex2f( 18, 18 );
		g_QglTable.m_pfn_qglVertex2f( 18 + cos( degInRad ) * 5, 18 + sin( degInRad ) * 5 );
		g_QglTable.m_pfn_qglVertex2f( 32, 18 );
		g_QglTable.m_pfn_qglVertex2f( 32 + cos( degInRad ) * 5, 18 + sin( degInRad ) * 5 );
		g_QglTable.m_pfn_qglEnd();

		g_QglTable.m_pfn_qglBegin( GL_LINE_LOOP );
		for ( i = 0; i < 360; i += 60 ) {
			degInRad = i * ( 3.14159265358979323846 / 180.f );
			g_QglTable.m_pfn_qglVertex2f( 32 + cos( degInRad ) * 5, 18 + sin( degInRad ) * 5 );
		}
		g_QglTable.m_pfn_qglEnd();

		g_QglTable.m_pfn_qglBegin( GL_LINES );
		g_QglTable.m_pfn_qglVertex2f( 40, 22 );
		g_QglTable.m_pfn_qglVertex2f( 52, 31 );
		g_QglTable.m_pfn_qglVertex2f( 40, 13 );
		g_QglTable.m_pfn_qglVertex2f( 52, 4 );
		g_QglTable.m_pfn_qglEnd();
	}

	g_QglTable.m_pfn_qglPopAttrib();
}
