//QT_Spec.h, Copyright (c) 2001-2008 R.Lackner
//
//    This file is part of RLPlot.
//
//    RLPlot 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.
//
//    RLPlot 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 RLPlot; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
#include "rlplot.h"
#include "menu.h"
#include <qapplication.h>
#include <qwidget.h>
#include <qstring.h>
#include <qpen.h>
#include <qpainter.h>
#include <qprinter.h>
#include <qmenubar.h>
#include <qscrollbar.h>
#include <qcstring.h>
#include <qpaintdevicemetrics.h>
#include <qpen.h>
#include <qprinter.h>
#include <qdragobject.h>
#include <qmenubar.h>
#include <qscrollbar.h>
#include <qmessagebox.h>
#include <qpixmap.h>
#include <qfiledialog.h>
#include <qimage.h>
#include <qcursor.h>
#include <qclipboard.h>
#include <qbuffer.h>
#include <qbitmap.h>
#include <qtextstream.h>
#include <qdragobject.h>
#include "TheDialog.h"

#define RLP_PORT	4321		//enable clipboard server
#ifdef RLP_PORT
	#include <sys/socket.h>
	#include <netdb.h>
	#include <pthread.h>
	#include <fcntl.h>
	#include <unistd.h>
	#include <sys/ioctl.h>
	#include <linux/fs.h> 
#endif

bool ProcMenuEvent(int id, QWidget *parent, anyOutput *OutputClass, GraphObj *BaseObj);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class TxtCurBlink:public QObject {
	Q_OBJECT
public:
	TxtCurBlink();
	void Show();
//	void showCopyMark();

protected:
	void timerEvent(QTimerEvent *);

private:
	bool isVis;
	int count;
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// use sockets for to exchange clipboard data
// undefine RLP_PORT to limit clipboard to a single instance

class RLPserver {
public:
	GraphObj *SourceGO;
	bool bValid;

	RLPserver(QObject* parent=0, GraphObj *g=0);
	~RLPserver();
	void CreateThread();
	void SetGO(GraphObj *g);
	char *GetXML();
	char *GetRLP();
	char *GetTXT() {return text_plain; };
	bool ok() {return true;};
#ifdef RLP_PORT
	int Socket() {return sock;};
#endif

private:
	char *text_xml, *text_rlp, *text_plain;
#ifdef RLP_PORT
	pthread_t thread;
	pthread_attr_t thread_attr;
	int sock;
#endif
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class RLPmenu:public QMenuBar {
	Q_OBJECT
public:
	RLPmenu(QWidget *par, anyOutput *o, GraphObj *g);

public slots:
	void doMenuItem(int id);

private:
	anyOutput *OutputClass;
	QWidget *parent;
	GraphObj *BaseObj;

};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// The Qt widget class implementet for RLPlot
class RLPwidget:public QWidget {
	Q_OBJECT

public:
	QScrollBar *HScroll, *VScroll;
	QPixmap *mempic;
	QMenuBar *menu_bar;

	RLPwidget(QWidget *par=0, const char *name=0, anyOutput *o = 0,
		GraphObj *g = 0);
	~RLPwidget();
	void openHistoryFile(int idx);

public slots:
	void hScrollEvent(int pos);
	void vScrollEvent(int pos);
	void cmNOP(){;};
	void cmCopy(){ProcMenuEvent(CM_COPY, this, OutputClass, BaseObj);};
	void cmCut(){ProcMenuEvent(CM_CUT, this, OutputClass, BaseObj);};
	void cmZoomIn(){ProcMenuEvent(CM_ZOOMIN, this, OutputClass, BaseObj);};
	void cmZoomOut(){ProcMenuEvent(CM_ZOOMOUT, this, OutputClass, BaseObj);};
	void cmZoomFit(){ProcMenuEvent(CM_ZOOMFIT, this, OutputClass, BaseObj);};
	void cmPaste();
	void cmUndo(){if(BaseObj) BaseObj->Command(CMD_UNDO, 0L, OutputClass);};
	void cmSave(){ProcMenuEvent(CM_SAVE, this, OutputClass, BaseObj);};
	void cmOpen(){ProcMenuEvent(CM_OPEN, this, OutputClass, BaseObj);};
	void cmPrint(){ProcMenuEvent(CM_PRINT, this, OutputClass, BaseObj);};
	void cmNewInst(){ProcMenuEvent(CM_NEWINST, this, OutputClass, BaseObj);};

protected:
	void paintEvent(QPaintEvent *);
	void resizeEvent(QResizeEvent *);
	void closeEvent(QCloseEvent *);
	void mouseDoubleClickEvent(QMouseEvent *e);
	void mousePressEvent(QMouseEvent *e);
	void mouseReleaseEvent(QMouseEvent *e);
	void mouseMoveEvent(QMouseEvent *e);
	void keyPressEvent(QKeyEvent *e);
	void focusInEvent(QFocusEvent *e);

private:
	QWidget *parent;
	anyOutput *OutputClass;
	GraphObj *BaseObj;
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class DlgWidget:public QWidget {
	Q_OBJECT
public:
	QPixmap *mempic;
	anyOutput *OutputClass;

	DlgWidget(QWidget *par=0, const char *name=0, tag_DlgObj *d = 0, DWORD flags = 0L);
	~DlgWidget();

protected:
	void paintEvent(QPaintEvent *);
	void mouseDoubleClickEvent(QMouseEvent *e);
	void mousePressEvent(QMouseEvent *e);
	void mouseReleaseEvent(QMouseEvent *e);
	void mouseMoveEvent(QMouseEvent *e);
	void keyPressEvent(QKeyEvent *e);
	void focusInEvent(QFocusEvent *e);
	void focusOutEvent(QFocusEvent *e);
	void closeEvent(QCloseEvent *e);
	void timerEvent(QTimerEvent *);

private:
	QWidget *parent;
	tag_DlgObj *dlg;
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class BitMapQT:public anyOutput {
public:
	QWidget *widget;
	QWidget *dlgwidget;
	HatchOut *hgo;
	QPixmap *mempic;
	QImage *image;
	QPen qPen;
	QPainter qPainter;
	QFont qFont;
	void *ShowObj;				//eph_obj*
	void *ShowAnimated;			//copy mark

	BitMapQT(GraphObj *g, QWidget *wi, int vr = 98, int hr = 98);
	BitMapQT(int w, int h, double hr, double vr);
	~BitMapQT();
	bool SetLine(LineDEF *lDef);
	bool SetFill(FillDEF *fill);
	bool SetTextSpec(TextDEF *set);
	virtual bool Erase(DWORD Color);
	virtual bool StartPage() {return true;};
	bool CopyBitmap(int x, int y, anyOutput* src, int sx, int sy,
		int sw, int sh, bool invert);
	bool oGetTextExtent(char *text, int cb, int *width, int *height);
	bool oGetTextExtentW(w_char *text, int cb, int *width, int *height);
	bool oGetPix(int x, int y, DWORD *col);
	bool oDrawIcon(int type, int x, int y);
	bool oCircle(int x1, int y1, int x2, int y2, char* nam = 0L);
	bool oPolyline(POINT * pts, int cp, char *nam = 0L);
	bool oRectangle(int x1, int y1, int x2, int y2, char *nam = 0L);
	bool oSolidLine(POINT *p);
	bool oTextOut(int x, int y, char *txt, int cb);
	bool oTextOutW(int x, int y, w_char *txt, int cb);
	bool oPolygon(POINT *pts, int cp, char *nam = 0L);
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class OutputQT:public BitMapQT {
public:
	QScrollBar *HScroll, *VScroll;
	RLPmenu *menu;

	OutputQT(GraphObj *g);
	OutputQT(DlgWidget *wi);
	~OutputQT();
	bool ActualSize(RECT *rc);
	void Focus(){if(widget){widget->show(); widget->raise();}};
	void Caption(char *txt, bool bModified);
	void MouseCursor(int cid, bool force);
	bool SetScroll(bool isVert, int iMin, int iMax, int iPSize, int iPos);
	bool EndPage();
	void MouseCapture(bool bgrab);
	bool UpdateRect(RECT *rc, bool invert);
	void ShowLine(POINT * pts, int cp, DWORD color);
	void ShowEllipse(POINT p1, POINT p2, DWORD color);
	void ShowInvert(RECT *rec);
	bool SetMenu(int type);
	void CheckMenu(int mid, bool check);
	void FileHistory();
	void CreateNewWindow(GraphObj *g);

private:
	GraphObj *BaseObj;
};

class PrintQT:public anyOutput{
public:
	HatchOut *hgo;
	QPrinter *printer;

	PrintQT(GraphObj *g, char *file);
	~PrintQT();
	bool ActualSize(RECT *rc);
	bool SetLine(LineDEF *lDef);
	bool SetFill(FillDEF *fill);
	bool SetTextSpec(TextDEF *set);
	bool StartPage();
	bool EndPage();
	bool Eject();
	bool oGetTextExtent(char *text, int cb, int *width, int *height);
	bool oGetTextExtentW(w_char *text, int cb, int *width, int *height);
	bool oCircle(int x1, int y1, int x2, int y2, char* nam = 0L);
	bool oPolyline(POINT * pts, int cp, char *nam = 0L);
	bool oRectangle(int x1, int y1, int x2, int y2, char *nam = 0L);
	bool oSolidLine(POINT *p);
	bool oTextOut(int x, int y, char *txt, int cb);
	bool oTextOutW(int x, int y, w_char *txt, int cb);
	bool oPolygon(POINT *pts, int cp, char *nam = 0L);

private:
	QPen qPen;
	QFont qFont;
	QPainter qPainter;
	QWMatrix dxf;
	char *fileName;
	GraphObj *go;
	bool bPrinting;
};

