/***************************************************************************
 *   Copyright (C) 2004-2005 by                                            *
 *     Paolo Sacconier   <axa1981@tin.it>                                  *
 *     Francesco Tamagni <minchiahead@hacari.org>                          *
 *                                                                         *
 *   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, USA.             *
 ***************************************************************************/
#include "video.h"

namespace gillo {

Video::Video(Mode vm)
: mode(WINDOW)
{    
    /* First, initialize SDL's video subsystem. */
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
        /* Failed, exit. */
        throw Error::Video("Video initialization failed", SDL_GetError( ));
    }
	
	this->switchToMode(vm);
	
//     glEnable ( GL_DEPTH_TEST ) ;
	
	/* SSG setup */
	//fntInit () ;
	ssgInit () ;
	ssgModelPath   ( MODEL_PATH ) ;
	ssgTexturePath ( TEX_PATH ) ;
        
	glClearColor ( 0.2f, 0.7f, 1.0f, 1.0f ) ;
	
	glEnable ( GL_DEPTH_TEST ) ;
	
	ssgSetFOV     ( 90.0f, 0.0f ) ;
	ssgSetNearFar ( 0.01f, 700.0f ) ;
	
	sgVec3 avec ;
	sgSetVec3 ( avec, 0.2f, -0.5f, 0.5f ) ;
	ssgGetLight ( 0 ) -> setPosition ( avec ) ;
	sgSetVec3 ( avec, 0.5f, 0.5f, 0.5f ) ;
	ssgGetLight ( 1 ) -> setPosition ( avec ) ;
	ssgGetLight ( 1 ) -> on();
	ssgGetLight ( 1 ) -> setHeadlight(1);
	sgSetVec3 (avec, 0.4f, 0.4f, 0.0f);
	ssgGetLight ( 1 ) -> setColour( GL_DIFFUSE, avec );

//    	ssgGetCurrentContext()->overrideCullface(0);
}


Video::~Video()
{
/*	vector<Viewport*>::iterator i = viewports.begin();
	while (i != viewports.end() ) {
		delete (*i)->getCameraPtr();
		delete *i;
		i++;
	}*/
	SDL_Quit();
	printf("Video(%p): destroyed\n",this);
}

// @todo void Video::addViewport(x, y, dimx, dimy)

void Video::draw(ssgRoot* scene, ssgRoot* alphaScene) {
    glClear  ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // @fixme
	list<Viewport*>::iterator i = viewports.begin();
	while ( i != viewports.end() ) {
// 		printf("VP: %p\n", *i);
		if ((*i)->isVisible()) {
			(*i)->draw(width, height);
			glClear  ( GL_DEPTH_BUFFER_BIT );
			glEnable( GL_CULL_FACE );
			ssgCullAndDraw (scene);
			glDepthMask( GL_FALSE );
			ssgCullAndDraw (alphaScene);
			glDepthMask( GL_TRUE );
		}
		i++;
	}
	overlay.draw(width, height);
	//glFlush();
}

void Video::update(float dt) {
	list<Viewport*>::iterator i = viewports.begin();
	while ( i != viewports.end() ) {
		(*i)->update(dt);
		i++;
	}
    SDL_GL_SwapBuffers();
}

void Video::switchToMode(Mode vm) {
    /* Let's get some video information. */
    const SDL_VideoInfo* info = SDL_GetVideoInfo( );

    if( !info ) {
        /* This should probably never happen. */
		throw Error::Video("Video query failed", SDL_GetError( ) );
    }
    
    int bpp = info->vfmt->BitsPerPixel;
    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1);

	int flags = SDL_OPENGL;
	switch (vm) {
		case FULLSCREEN:
			width = 1024;
			height = 768;
			flags |= SDL_FULLSCREEN;
			break;
		case WINDOW:
			width = 640;
			height = 480;
			break;
		default:
			throw Error::Video("Video mode not allowed", ""); // @todo add new constructor
			break;
	}    
    if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 )
		throw Error::Video("Video mode set failed", SDL_GetError( ) );
	else
		mode = vm;
}

};
