/* -*- mia-c++ -*-
 *
 * This file is part of viewitgui - a library and program for the
 * visualization of 3D data sets. 
 *
 * Copyright (c) Leipzig, Madrid 1999-2013 Mirco Hellmann, Gert Wollny
 *
 * viewitgui 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 3 of the License, or
 * (at your option) any later version.
 *
 * viewitgui 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 viewitgui; if not, see <http://www.gnu.org/licenses/>.
 */


#ifndef _WINSCENE_HH
#  include "WinScene_glade.hh"
#  define _WINSCENE_HH

#include <iostream>
#include <cstdlib>

#include <gtkglmm.h>
#include <gtkmm.h>


#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif


#include <viewit/glviewer.hh>
#include "SignalHandler.hh"

///////////////////////////////////////////////////////////////////////////////
//
//  Frame buffer configuration utilities.
//
///////////////////////////////////////////////////////////////////////////////

struct GLConfigUtil
{
  static void print_gl_attrib(const Glib::RefPtr<const Gdk::GL::Config>& glconfig,
                              const char* attrib_str,
                              int attrib,
                              bool is_boolean,
			      std::ostream &bstream);

  static void examine_gl_attrib(const Glib::RefPtr<const Gdk::GL::Config>& glconfig,
				std::ostream &bstream);
};



///////////////////////////////////////////////////////////////////////////////
//
// Simple OpenGL scene.
//
///////////////////////////////////////////////////////////////////////////////
class WinScene;
class SimpleGLScene : public Gtk::GL::DrawingArea
{
	friend class WinScene;
private:
	bool handle_key(int key);
	
	// OpenGL frame buffer attributes
	Glib::RefPtr<Gdk::GL::Config>	glconfig;
	bool GL_init(const Glib::RefPtr< Gdk::Screen > & screen);
	
	PGLViewer m_glview; 


public:
	SimpleGLScene(const Glib::RefPtr< Gdk::Screen > & screen, PGLViewer glview);
	~SimpleGLScene();
	
	// Invalidate whole window.
	void invalidate() {
		Gtk::Allocation allocation = get_allocation();
		get_window()->invalidate_rect(allocation, false);
	}
	
	// Update window synchronously (fast).
	void update()
	{ get_window()->process_updates(false); }


protected:
	virtual void on_realize();
	virtual void on_unrealize();
	virtual bool on_configure_event(GdkEventConfigure* event);
	virtual bool on_expose_event(GdkEventExpose* event);
	virtual bool on_unmap_event(GdkEventAny* event);
	virtual bool on_visibility_notify_event(GdkEventVisibility* event);
	virtual bool on_idle();

	virtual bool on_button_press_event(GdkEventButton* event);
	virtual bool on_button_release_event(GdkEventButton* event);
	virtual bool on_motion_notify_event(GdkEventMotion* event);

protected:
	// idle signal connection:
	sigc::connection m_ConnectionIdle;
	
	void idle_add();
	void idle_remove();
	void detach();
};


///////////////////////////////////////////////////////////////////////////////
//
// The application class.
//
///////////////////////////////////////////////////////////////////////////////

class WinScene : public WinScene_glade
{
	friend class SimpleGLScene;
	
public:
	WinScene(const Glib::RefPtr< Gdk::Screen > & screen, PGLViewer glview);
	~WinScene();
	
	void				repaint();
	void				on_WinScene_detach();
	void				on_WinScene_resize(unsigned int width, unsigned int height); 
	
	void				on_WinScene_press_key(ViewitKeyTypes key);
	void				on_WinScene_set_visibility(bool visible);
	
	// store size and position in the config file
	// code should be inserted into dtor 
	void				save_state();
	
protected:
	
	// signal handlers:
	bool					on_WinScene_delete_event(GdkEventAny *ev);
	bool					on_WinScene_key_press_event(GdkEventKey* event);	
	void on_realize(); 

protected:
	// member widgets:
	Gtk::VBox m_VBox;
	SimpleGLScene m_SimpleGLScene;
	const Glib::RefPtr< Gdk::Screen > & m_screen; 
};


#endif
