/******************************************************************************
Copyright (C) 2009 Matteo Lucarelli

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.
******************************************************************************/

// OpenGL/FLTK 2D display with zoom, drag, measures and dynamic grid
// NEED: `fltk-config --ldflags --use-gl`

// NOTE: you must call Fl::visual(FL_RGB); before build the object 
//       and Fl::run() of Fl::check() to make it alive

#if !defined(FL_GL2DISPLAY_H_INCLUDED)
#define FL_GL2DISPLAY_H_INCLUDED

#include <FL/Fl.H>
#include <FL/Fl_Gl_Window.H>
#include <FL/gl.h>
#include <FL/Fl_Output.H>
#include <FL/Fl_Box.H>

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// user function to draw the stage content
typedef void Fl_gl2display_drawCB();

// class Fl_gl2display is a plain openGl box with 2D display
class Fl_gl2display : public Fl_Gl_Window {

public:
	
	Fl_gl2display(int X, int Y, int W, int H, Fl_gl2display_drawCB *drawCB);
	virtual ~Fl_gl2display();

	void draw();
	
	// with mouse wheel or right button drag : zoom
	// left button drag: drag
	int handle(int event);
	
	GLdouble getXoffset();
	GLdouble getYoffset();
	GLdouble getScale();
	
	void setXoffset(GLdouble val);
	void setYoffset(GLdouble val);
	void setScale(GLdouble val);
	
	void resize(int X,int Y, int W, int H);
	
	// enable dynamic grid drawing
	// grid size gost from 10^minOrder to 10^maxOrder
	// grid is not drawn if lines distance is less than pixFilter pixels
	void setGrid(int minOrder,int maxOrder,int pixFilter,int baseColor, int stepColor);
	
	void setLabel(Fl_Output* label);
private:

	bool m_doGrid;
	int m_minOrder,m_maxOrder,m_pixFilter;
	int m_baseColor,m_stepColor;

	void enable2D();
	void disable2D();
	
	void drawGrid();
	void refreshLabel();

	Fl_gl2display_drawCB *m_drawCB;
	
	GLdouble m_ScaleFactor;
	GLdouble m_TranslateX;
	GLdouble m_TranslateY;
	
	Fl_Output* m_Label;
};

// class Fl_gl2displayLabel is a box with Fl_gl2display
// and a label that shown grid size and position
class Fl_gl2displayLabel : public Fl_Box {

public:

	Fl_gl2displayLabel(int X, int Y, int W, int H, Fl_gl2display_drawCB *drawCB);
	virtual ~Fl_gl2displayLabel();
	
	GLdouble getXoffset();
	GLdouble getYoffset();
	GLdouble getScale();
	
	void setXoffset(GLdouble val);
	void setYoffset(GLdouble val);
	void setScale(GLdouble val);
		
	void draw();
	
	// see previous class notes	
	void setGrid(int minOrder,int maxOrder,int pixFilter,int baseColor, int stepColor);

private:

	Fl_gl2display *m_Display;
	Fl_Output *m_Label;
	
};

#endif // !defined(FL_GL2DISPLAY_H_INCLUDED)