#ifndef GLVISORBASE_H
#define GLVISORBASE_H

#include <QGLWidget>
//Added by qt3to4:
#include <QWheelEvent>
#include <QMouseEvent>
#include <Q3PopupMenu>
#include <QKeyEvent>

#include "kryomolcore_export.h"
#include "molecule.h"
#include "quantumparser.h"
#include <qcolor.h>




struct cartesian {GLdouble x; GLdouble y; GLdouble z;};

class Q3PopupMenu;
class QInfoDialog;
//#ifdef _USE_KDE_
#define Printer KPrinter
//#else
//#define Printer QPrinter
//#endif
class QPrinter;
class KPrinter;
class QTimerOpenMenu;
class Q3PopupMenu;



class KRYOMOLCORE_EXPORT CGlVisorBase : public QGLWidget
{
		Q_OBJECT
		//public methods
	public:
		enum GraphMode { WIREFRAME=0, STICKS, CPK, HIGHQUALITY };
		CGlVisorBase ( QWidget* parent=0 );
		CGlVisorBase ( QGLContext* context,QWidget* parent=0 );
		CGlVisorBase ( const QGLFormat& format,QWidget* parent=0 );
		virtual ~CGlVisorBase();
		/** Do Visor initialization*/
		virtual void Initialize();
		/** Set the representation mode */
		void SetGraphMode ( GraphMode mode ) { m_graphmode=mode;}
		/** Get Image, useful for instance for thumbnailing */
		void GetImage ( QImage& img, int w, int h );
		/** Save a snapshot of the file*/
		void SaveSnapshot ( const QString& file, const QString& format );
		/** Print the GL contents rendering a pixmap */
		void Print ( QPrinter* pP );
		/** Return a pointer to the molecule set */
		std::vector<CMolecule>* GetMolecule() { return &m_molecules; }
		/** Return a reference to the molecule set */
		std::vector<CMolecule>& GetMolecules() { return m_molecules; }
		/** Return a const reference to the molecule set */
		const std::vector<CMolecule>& GetMolecules() const { return m_molecules; }
		/** Return a reference to the current molecule in screen*/
		CMolecule& GetCurrentMolecule() { return m_molecule; }
		/** Return a const reference to the current molecule in screen*/
		const CMolecule& GetCurrentMolecule() const { return m_molecule; }
		/**Return a pointer to the quadric*/
		GLUquadricObj* GetQuadric() const { return m_quadric; }
		/** return current point from 0 to N-1 structures*/
		int GetCurrentPoint() const { return m_current; }
		/**Render Text*/
		void RenderText ( const QString& str,int x, int y, int z );
		/**Render Text*/
		void RenderText ( const std::string& str,int x, int y, int z );
		/** Get the font*/
		const QFont& Font() const { return m_glfont; }
		void SetFont ( const QFont& font ) { m_glfont=font; }
//  void Export(const QString& file,const QString& mode);
		/** Get the graphical mode*/
		const GraphMode& GetGraphMode() const { return m_graphmode; } 
	public: //public attributes
		/** Molecule Container*/
		std::vector<CMolecule> m_molecules;
		/** Reference to the molecule currently displayed*/
		CMolecule m_molecule;
		/** An empty molecule to allow initialization of reference*/
		CMolecule dummymolecule;

	public slots: // Public slots
		/** show atom numbering */
		void OnShowNumbers();
		/** go for fullscreen mode */
		void OnFullScreen();
		/** change the background color */
		void OnChangeBackground();
		/** show atom types */
		void OnShowTypes();

	protected: //protected methods
		/** used for convenience*/
		void glVertexC ( const coordinate& c ) { glVertex3f ( c.x,c.y,c.z ); }
		void glVertex4C ( const coordinate& c,float f ) { glVertex4f ( c.x,c.y,c.z,f ); }
		/** Get the atom color */
		void GetMaterialColor ( CAtom &a );
		void GetColor ( CAtom& a );
	protected: //virtual methods
		/** Setup the perspective*/
		void SetupPerspective();
		/** Render 2D controls on the screen*/
		virtual void RenderButtons() {};
		/** Select a 2D control*/
		virtual void selectButton ( const QPoint& ) {};
		/** */
		virtual void initializeGL();
		virtual void resizeGL ( int w, int h );
		virtual void paintGL();
		virtual void wheelEvent ( QWheelEvent* e );

		virtual  void RenderMolecule ( GLenum mode=GL_RENDER );
		void RenderScene ( GLenum mode=GL_RENDER );
		/** OpenGL selection code */
		virtual void OnSelection ( QMouseEvent* ) {};
		/** Render text onto the screen*/
		virtual void RenderScreenText() {};


		virtual void mouseMoveEvent ( QMouseEvent * e );
		virtual void mousePressEvent ( QMouseEvent* e );
		virtual void mouseReleaseEvent ( QMouseEvent* e );
		virtual void mouseDoubleClickEvent ( QMouseEvent* e );
		virtual void keyPressEvent ( QKeyEvent* e );
		/** return a pointer to the basic menu*/
		Q3PopupMenu* GetMenu();

	protected slots: // Protected slots


	protected: //protected atributes
		/** number of the current molecule*/
		int m_current;
		/** 2D controls set*/
		std::vector<QRect> m_screencontrols;
		/** vector with numbers of selected atoms*/
		std::vector<int> m_selectedatoms;
		GLfloat m_aspect;
		/** draw atom numbers on screen */
		bool m_bshownumbers;

		/** transform matrix for trackball rotation*/
		GLfloat* m_transform;

		/** previous cursor point*/
		QPoint m_oldpoint;

	private slots: //private methods
		void OnChangeGraphMode ( int mode );
	private:
		void Init();
	private: //private attributes
		/** show type of the atoms in the screen */
		bool m_bshowtypes;
		/** pointer to the parent window*/
		QWidget* m_parent;
		/** OpenGL quadric object*/
		GLUquadricObj* m_quadric;
		/** background colors*/
		QColor m_bkcolor;
		/** boolean to control full screen mode */
		bool m_bisfull;
		/**  */
		coordinate m_rotationvector;
		double m_scale;
		cartesian m_rotate;
		bool m_rgrabbed;
		bool m_lgrabbed;
		GLfloat m_range;
		GraphMode m_graphmode;
		float m_maxdepth;
		/** popup menu for display settings */

		QTimerOpenMenu* m_optionsmenu;
		Q3PopupMenu* m_rendermenu;
		QFont m_glfont;

	signals:
		void  text ( const QString& );


};


#endif