#include "GL_widget3.h"


Context* GLwidget3::getContext(void)
{
	return this->qContext;
}
void GLwidget3::setApp( AbstractAPP* app )
{
	this->app=app;
}
void GLwidget3::setAssistant( UiAssistant *uiAssistant )
{
	this->uiAssistant = uiAssistant;
}

bool GLwidget3::isInitialized(void)
{
	return this->initialized;
}

GLwidget3::GLwidget3(QWidget *parent): QGLWidget(QGLFormat(QGL::SampleBuffers), parent), oneSecondTimer(this)
{
	this->initialized = false;

	this->uiAssistant= NULL;
	this->app=NULL;

	this->setFocusPolicy(Qt::StrongFocus);	

	this->qContext = new QContext( const_cast<QGLContext*> ( this->context() ));

	this->oneSecondTimer.start(1000);

	QObject::connect( &this->oneSecondTimer, SIGNAL(timeout()), this, SLOT(oneSecondTimeout()) );
}

void GLwidget3::oneSecondTimeout()
{
	if (this->app !=NULL)
	{
		this->app->setFps( loop );
	}
	this->loop=0;
}
void GLwidget3::updateGL()
{
	++this->loop;
	if (this->app != NULL)
	{
		this->app->refresh();
		this->paintGL();
	}
}
void GLwidget3::keyPressEvent( QKeyEvent *e)
{
	if (this->app != NULL)
	{
		this->app->keyPressEvent( e->key() );
	}

	if (e->key()==Qt::Key_F11) //SCREENSHOT
	{
		QImage screenShot=this->grabFrameBuffer(false);
		screenShot.save("screenshot.png");
	}

	emit keyPressEventSignal( e );
}
void GLwidget3::keyReleaseEvent( QKeyEvent *e)
{
	if (this->app != NULL)
	{
		this->app->keyReleaseEvent( e->key() );
	}

	emit keyReleaseEventSignal( e );
}

void GLwidget3::wheelEvent( QWheelEvent *e )
{
	if (this->app != NULL)
	{
		this->app->mouseWheelEvent( e->delta() );
	}

	emit wheelEventSignal( e );
}

void GLwidget3::mouseReleaseEvent( QMouseEvent *e )
{
	if (this->app != NULL)
	{
		switch ( e->button() )
		{
			case Qt::LeftButton:
				this->app->mouseReleaseEvent( Mouse::LEFT );
			break;
			case Qt::RightButton:
				this->app->mouseReleaseEvent( Mouse::RIGHT );
			break;
			case Qt::MidButton:
				this->app->mouseReleaseEvent( Mouse::MIDDLE );
			break;
			default:
				//ignore
			break;
		}

	}

	emit mouseReleaseEventSignal(e);
}
void GLwidget3::mousePressEvent( QMouseEvent *e )
{
	if (this->app != NULL)
	{
		switch ( e->button() )
		{
			case Qt::LeftButton:
				this->app->mousePressEvent( Mouse::LEFT );
			break;
			case Qt::RightButton:
				this->app->mousePressEvent( Mouse::RIGHT );
			break;
			case Qt::MidButton:
				this->app->mousePressEvent( Mouse::MIDDLE );
			break;
			default:
				//ignore
			break;
		}


	}

	emit mousePressEventSignal(e);
}
void GLwidget3::mouseMoveEvent( QMouseEvent *e )
{
	if (this->app != NULL)
	{
		this->app->mouseMoveEvent( e->x(), e->y() );
	}

	emit mouseMoveEventSignal(e);
}

void GLwidget3::initializeGL(void)
{
	try
	{
		this->makeCurrent();

		GLeeInit(); //inicializace vsech ruznych ARB a EXT rozsireni pro OpenGL
		glEnable(GL_MULTISAMPLE_ARB);	//AntiAliasing 
		glClearColor(0, 0, 0, 0);
		glClearDepth(1.0);				// Enables Clearing Of The Depth Buffer
		glDepthFunc(GL_LEQUAL);				// The Type Of Depth Test To Do
		glEnable(GL_DEPTH_TEST);			// Enables Depth Testing
		glShadeModel(GL_SMOOTH);			// Enables Smooth Color Shading
		glViewport( 0, 0, SCREEN_WIDTH_RES, SCREEN_HEIGHT_RES);
		glMatrixMode(GL_PROJECTION);// Zvolí projekční matici
		glLoadIdentity();// Reset matice
		gluPerspective(45.0f, (float) SCREEN_WIDTH_RES / (float) SCREEN_HEIGHT_RES , 2.0 , 1000.0 );// Výpočet perspektivy
		glMatrixMode(GL_MODELVIEW);// Zvolí matici Modelview
		glLoadIdentity();// Reset matice

		if ( this->app != NULL )
		{
			this->app->init();
		}
		else
		{
			cerr <<"Warning: null pointer application - application ignored." << endl;
		}

		this->initialized = true;
		this->doneCurrent();
	}
	catch( exception &e)
	{
		KODIAK_ERROR<<"Application initialization failed. Aplication name: " + app->getApplicationName() + ", reason: " + e.what();
	}
}
 


void GLwidget3::focusOutEvent( QFocusEvent *e )
{
	emit lostFocusSignal();
}

void GLwidget3::paintGL(void)
{
	this->makeCurrent();

	if ( this->app != NULL )
	{
		this->app->run();
	}

	emit this->refresh();	//WARNING: it is important to emit the signal AFTER the APP::RUN was done for expected functionality!!!

	this->doneCurrent();
}


