#include "GL_widget2.h"
#include <QDateTime>
#include "math\SupportFunctions.h"

Context* GLwidget2::getContext(void)
{
	return this->qContext;
}
void GLwidget2::setApp( AbstractAPP* app )
{
	if ( app!= NULL )
	{
		app->myWidget = this;
		this->app=app;
	}
}

void GLwidget2::forceInitialize(void)
{
	this->initialized = false;
	this->initializeGL();
}
bool GLwidget2::isInitialized(void)
{
	return this->initialized;
}

GLwidget2::GLwidget2( QWidget * parent , const QGLWidget * shareWidget , Qt::WindowFlags f ): QGLWidget(QGLFormat(QGL::SampleBuffers), parent, shareWidget, f) , oneSecondTimer(this)
//GLwidget2::GLwidget2(QWidget *parent): QGLWidget(QGLFormat(QGL::SampleBuffers), parent), oneSecondTimer(this)
{
	this->initialized = false;
	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 GLwidget2::oneSecondTimeout()
{
	if (this->app !=NULL)
	{
		this->app->setFps( loop );
	}
	this->loop=0;
}
void GLwidget2::updateGL()
{
	++this->loop;
	if (this->app != NULL)
	{
		//cout<<this->app->getApplicationName()<<endl;
		this->app->refresh();
		this->paintGL();
	}
}
void GLwidget2::keyPressEvent( QKeyEvent *e)
{
	if (this->app != NULL)
	{
		this->app->keyPressEvent( e->key() );
	}

	if (e->key()==Qt::Key_F10) //SCREENSHOT
	{
		QImage screenShot=this->grabFrameBuffer(false);
		
		QTime time = QTime::currentTime();
		string timeString = intToString( time.msec() );

		string screenshotName =  ("screenshot_"+ timeString +".png") ;
		//cout<<"New screenshot created with name: "<<screenshotName<<endl;
		screenShot.save( screenshotName.c_str() );
	}

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

	emit keyReleaseEventSignal( e );
}

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

	emit wheelEventSignal( e );
}

void GLwidget2::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 GLwidget2::mousePressEvent( QMouseEvent *e )
{
	if (this->app != NULL)
	{
		this->app->mouseMoveEvent( e->x(), e->y() );

		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 GLwidget2::mouseMoveEvent( QMouseEvent *e )
{
	if (this->app != NULL)
	{
		this->app->mouseMoveEvent( e->x(), e->y() );
	}

	emit mouseMoveEventSignal(e);
}

void GLwidget2::initializeGL(void)
{
	if ( ! this->initialized )
	{
		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, 640, 480);
			glMatrixMode(GL_PROJECTION);// Zvolí projekční matici
			glLoadIdentity();// Reset matice
			gluPerspective(45.0f, (float) 640 / (float) 480 , 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 <<"GL_Widget2: Warning: null pointer application - application ignored." << endl;
			}

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

		emit initializationEventSignal();
	}
}
 


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

void GLwidget2::paintGL(void)
{
	// WARNING:
	//makeCurrent is called automatic according to Qt documentation
	//( but without explicit call it is not working correct!!! )

	if ( this->app != NULL )
	{
		this->makeCurrent();
			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();
	}
}


