/*  $Id: display_window_opengl.h,v 1.33 2004/03/10 23:35:17 mbn Exp $
**
**  ClanLib Game SDK
**  Copyright (C) 2003  The ClanLib Team
**  For a total list of contributers see the file CREDITS.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This library 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
**  Lesser General Public License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*/

#ifndef header_display_window_opengl
#define header_display_window_opengl

#if _MSC_VER > 1000
#pragma once
#endif

#include <map>
#include <stack>

#include "API/Core/System/keep_alive.h"

#include "API/Display/graphic_context.h"
#include "API/Display/pixel_buffer.h"
#include "API/Display/input_device.h"
#include "API/Display/input_context.h"
#include "API/Display/display_window_description.h"

#include "Display/display_window_generic.h"

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>

#include <X11/extensions/xf86vmode.h>
#include <X11/extensions/XInput.h>

#include <GL/glu.h>
#include <GL/glx.h>

class CL_DisplayWindow_OpenGL : public CL_DisplayWindow_Generic, CL_KeepAlive
{
//! Construction:
public:
	CL_DisplayWindow_OpenGL();

	virtual ~CL_DisplayWindow_OpenGL();

//! Attributes:
public:
	//: Returns the width of this window.
	virtual int get_width() const;

	//: Returns the height of this window.
	virtual int get_height() const;

	//: Returns true if fullscreen window.
	virtual bool is_fullscreen() const;

	//: Returns true if window got focus.
	virtual bool has_focus() const;

	//: Returns pixelbuffer interfaces for flipping buffers.
	virtual CL_PixelBuffer &get_buffer(int i);

	//: Returns const versions of the pixelbuffer interfaces.
	virtual const CL_PixelBuffer &get_buffer(int i) const;

	//: Returns the amount of flipping buffers.
	virtual int get_buffer_count() const;

	//: Returns the graphic context of this window.
	virtual CL_GraphicContext *get_gc();

	//: Returns the input context of this window.
	virtual CL_InputContext *get_ic() { return &input_context; }

	//: Returns the maximum size of a surface this displaywindow supports.
	CL_Size get_max_surface_size() const;

	//: Returns the GLX rendering context for this window.
	GLXContext get_context() { return context; }

	//: Returns the X11 display handle.
	static Display *get_display() { return disp; }

	//: Handle to X11 window handle.
	Window get_window() { return window; }

	//: Input context for all input devices associated with this window.
	CL_InputContext input_context;

	//: Input device for the keyboard.
	CL_InputDevice keyboard;

	//: Input device for the mouse.
	CL_InputDevice mouse;

	//: State information about misc key modifiers.
	bool left_ctrl_down, left_alt_down, left_shift_down;
	bool right_ctrl_down, right_alt_down, right_shift_down;

	//: handle of the first created context. Used for sharing
	//: textures and display lists between rendering contexts.
	static GLXContext share_context;

//! Operations:
public:
	//: Set window to fullscreen.
	virtual void set_fullscreen(int width, int height, int bpp, int refresh_rate);

	//: Restore to windowed mode.
	virtual void set_windowed();

	//: Change title on window.
	virtual void set_title(const std::string &title);

	//: Set window position and size.
	virtual void set_position(const CL_Rect &pos);

	//: Set window position.
	virtual void set_position(int x, int y);

	//: Set window size.
	virtual void set_size(int width, int height);

	//: Change the buffer count in the flipping system.
	virtual void set_buffer_count(int flipping_buffers);

	//: Copy a region of the backbuffer to the frontbuffer.
	virtual void update(const CL_Rect &rect);

	//: Flip the backbuffer to front.
	virtual void flip(int interval);

	//: Make system cursor visible over window.
	virtual void show_system_cursor();

	//: Make system cursor invisible over window.
	virtual void hide_system_cursor();

	//: Create a window.
	virtual void create_window(const CL_DisplayWindowDescription &desc);

	//: Called by ClanLib keep alive pump.
	virtual void keep_alive();

	//: Return the X display handle
	virtual Display *get_hwnd();

//! Signals:
public:
	//: Signal emitted when x11 events are to be processed.
	CL_Signal_v1<XEvent &> sig_xevent;

//! Implementation:
private:
        //: Initializes all joysticks
        void setup_joysticks();

        //: Initializes additional USB mice
        void setup_usb_mice();

	//: Signal that a new cursor CL_Sprite is available
	void cursor_changed();

	//: Destroy current window handles.
	void destroy_window();

	//: X Event handler for the window
	void on_xevent(XEvent &event);

	//: True if currently in full screen mode.
	bool fullscreen;

	//: Width and height, if in full screen mode.
	int fullscreen_width, fullscreen_height;

	//: Bits per pixel in the openGL Context.
	//: May not correspond to bit depth on screen
	int glx_bpp;

	//: Saved position of window when going fullscreen. This is the
	//: position the window receives when leaving fullscreen again.
	CL_Rect saved_position;

	// OpenGL compatible gc.
	CL_GraphicContext gc;

	//: OpenGL frame buffer access.
	CL_PixelBuffer buffer_front, buffer_back;
	
	//: GLX rendering context handle.
	GLXContext context;
	
	//: X11 Display handle.
	static Display *disp;

	static int disp_ref_count;

	//: Handle to X11 window.
	Window window;

	//: Attributes used to create window.
	XSetWindowAttributes attributes;
	
	//: Whether we have window focus or not
	bool focus;

	//: Attributes to switch between windowed and fullscreen
	int dotclock;
	XF86VidModeModeInfo old_mode;
	int old_x, old_y;

	//: X Event slot
	CL_Slot slot_xevent;
	
	Cursor system_cursor;
	Cursor hidden_cursor;
	Pixmap cursor_bitmap;
	
};

#endif

