#ifndef GL_WINDOW_H
#define GL_WINDOW_H

/* gltest - small OpenGL tearing test program
 * Copyright (C) 2012-2013 Ralf Jung <post@ralfj.de>
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <X11/Xlib.h>

/** Abstracts the GL binding API away */
class GLBackend {
public:
	/** Create a GL window class, but does not do anything */
	GLBackend() {}
	/** Fre all resources */
	virtual ~GLBackend() {}
	
	/** Initialize GL backend, choose visual configuration and return the ID */
	virtual VisualID initialize(Display *display) = 0;
	
	/** create a GL context for the given window */
	virtual void createContext(Window window) = 0;
	
	/** Swap back and front buffers */
	virtual void swapBuffers() const = 0;
	
	/** Set the swap interval */
	virtual void setSwapInterval(int i) const = 0;
};

/** A window to render GL stuff in */
class GLWindow {
public:
	GLWindow(Display *display, GLBackend *backend) //!< Create the window class, but do not open it. Taks ownership of the backend and the X connection.
	 : display(display), backend(backend), window(0) {}
	virtual ~GLWindow();

	void open(unsigned int width, unsigned int height) { if (!window) create(width, height); }
	void close();
	void setFullscreen(bool fullscreen);
	bool getFullscreen(void) { return fullscreen; }
	
	int getWidth() { return width; }
	int getHeight() { return height; }

	void exec();

protected:
	const GLBackend * getBackend() { return backend; }

	virtual void initGL() = 0;
	virtual void resizeGL(unsigned int width, unsigned int height) = 0;
	virtual void renderGL() = 0;
	virtual void handleKeyPress(KeySym key) = 0;
	 
private:
	void create(unsigned int width, unsigned int height);

	Display *display;
	GLBackend *backend;
	Window window;
	int width, height;
	bool fullscreen;
};

#endif
