#include "openglwindow.h"

#include <QCoreApplication>
#include <QOpenGLContext>
#include <QOpenGLPaintDevice>
#include <QPainter>
#include <qopenglext.h>


OpenGLWindow::OpenGLWindow(QWindow * parent): QWindow(parent) {
	setFlags(flags() | Qt::FramelessWindowHint);
	setSurfaceType(QWindow::OpenGLSurface);
	QSurfaceFormat format = QSurfaceFormat::defaultFormat();
#ifdef QT_OPENGL_ES_2
	format.setRenderableType(QSurfaceFormat::OpenGLES);
#else
	if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
		format.setVersion(4, 3);
		format.setProfile(QSurfaceFormat::CoreProfile);
	}
#endif
	format.setDepthBufferSize(24);
	format.setSamples(8);
	setFormat(format);
}


void OpenGLWindow::renderLater() {
	requestUpdate();
}


bool OpenGLWindow::event(QEvent * event) {
	switch (event->type()) {
	case QEvent::UpdateRequest: renderNow(); return true;
	default: return QWindow::event(event);
	}
}


void OpenGLWindow::exposeEvent(QExposeEvent * event) {
	if (isExposed()) renderNow();
}


void OpenGLWindow::setVSync(bool on) {
	QSurfaceFormat f = requestedFormat();
	if (on) {
		if (f.swapInterval() != 1) {
			f.setSwapInterval(1);
			setFormat(f);
			format_change = true;
		}
	} else {
		if (f.swapInterval() != 0) {
			f.setSwapInterval(0);
			setFormat(f);
			format_change = true;
		}
	}
}


bool OpenGLWindow::getVSync() const {
	return (requestedFormat().swapInterval() == 1);
}


int OpenGLWindow::pixelWidth() const {
	return devicePixelRatio() * width();
}


int OpenGLWindow::pixelHeight() const {
	return devicePixelRatio() * height();
}


QSize OpenGLWindow::pixelSize() const {
	return QSize(pixelWidth(), pixelHeight());
}


// void OpenGLWindow::setSamples(int samples) {
//	QSurfaceFormat f = requestedFormat();
//	if (f.samples() != samples) {
//		f.setSamples(samples);
//		setFormat(f);
//		format_change = true;
//	}
// }


// int OpenGLWindow::getSamples() const {
//	return requestedFormat().samples();
// }


void OpenGLWindow::renderNow() {
	if (!isExposed()) return;
	bool needsInitialize = false;
	if (!m_context || format_change) {
		if (m_context) delete m_context;
		m_context = new QOpenGLContext(this);
		m_context->setFormat(requestedFormat());
		m_context->create();
		needsInitialize = true;
		format_change   = false;
	}
	m_context->makeCurrent(this);
	if (needsInitialize) {
		initializeOpenGLFunctions();
		initialize();
	}
	render();
	m_context->swapBuffers(this);
	frame_cnt++;
}
