#ifndef _Sauklaue_Sauklaue_h
#define _Sauklaue_Sauklaue_h
#include "Schrift_Editor/Schrift_Editor.h"
#include "Text_Editor/text_editor.h"

#include <CtrlLib/CtrlLib.h>
#include <PdfDraw/PdfDraw.h>
#include <Painter/Painter.h>

using namespace Upp;
#define LAYOUTFILE <Sauklaue/Sauklaue.lay>
#include <CtrlCore/lay.h>

#define IMAGECLASS SauklaueImg
#define IMAGEFILE  <Sauklaue/Sauklaue.iml>
#include <Draw/iml.h>
#define MM_MOVINGRECT	  0x0001
#define MM_SIZINGRECT	  0x0002
#define MM_MOVETOBASELINE 0x0004
#define MM_MOVELINEUP	  0x0008
#define MM_MOVELINEUP1L	  0x0010
#define MM_SIZINGSCHRIFT  0x0100
#define MM_SIZINGBLOCKED  0x0200
#define MM_RESTRICTVERT	  0x0400
#define MM_RESTRICTHORZ	  0x0800
#define MM_RESTRICTSNAP	  0x1000
#define MM_SELECTRECT	  0xFF00


const double PI  =3.141592653589793238462;

typedef struct _Trans
{
	int slant;
	int shift;
	int stretchx;
	int stretchy;
} Trans_t, *Trans_ptr_t;

struct options: MoveableAndDeepCopyOption<options> {
	int writer;
	int Featherwidth;
	int Featherturn;
	int Penwidth;
	Color Pencolor;
	Color Feathercolor;
	Trans_t Trans;
	
	void Copy(const options& src) {
		this->writer = src.writer;
		this->Featherwidth = src.Featherwidth;
		this->Featherturn = src.Featherturn;
		this->Penwidth = src.Penwidth;
		this->Pencolor = src.Pencolor;
		this->Feathercolor = src.Feathercolor;
		this->Trans = src.Trans;
	}
	options()
	{
		writer = 0;
		Featherwidth = 10;
		Featherturn = -45;
		Feathercolor = LtBlue();
		Penwidth = 2;
		Pencolor = Blue();
		Trans.slant = 0;
		Trans.shift = 0;
		Trans.stretchx = 0;	
		Trans.stretchy = 0;
	}
	options(const options& op, int){Copy(op);}
	
	void Serialize(Stream& stream)
	{
		stream % writer % Featherwidth % Featherturn % Penwidth % Pencolor % Feathercolor
				% Trans.slant % Trans.shift % Trans.stretchx % Trans.stretchy;
	}

	String ToString() const
	{
		String str;
		str << "writer = "<<writer;
		str <<"\nFeatherwidth = "<<Featherwidth <<" Feathercolor = "<<Feathercolor;
		str <<"\nPenwidth = "<<Penwidth << " Pencolor = "<<Pencolor;
		str <<"\nTrans {slant = "<<Trans.slant <<", shift = "<<Trans.shift <<", stretchx = "<<Trans.stretchx <<", stretchy = "<<Trans.stretchy <<"}\n"; 

	}
	void Xmlize(XmlIO& xml)
	{
		xml
			("writer", writer)
			("Featherwidth",Featherwidth)
			("Feathercolor",Feathercolor)
			("Penwidth",Penwidth)
			("Pencolor",Pencolor)
			("Trans_slant",Trans.slant)
			("Trans_shift",Trans.shift)
			("Trans_stretchx",Trans.stretchx)
			("Trans_stretchy",Trans.stretchy)
		;
	}
};

struct wordrect: MoveableAndDeepCopyOption<wordrect>  {
	Rect r;
	String s;
	int option_index;
	Vector<Vector<Grapoint> > vgrap;
	
	void Copy(const wordrect& src) {
		this->r = src.r;
		this->s = src.s;
		this->option_index = src.option_index;
		this->vgrap <<= src.vgrap;
	}
	wordrect(){s = ""; option_index = 0;}
	wordrect(const wordrect& wr, int) {Copy(wr);}
	
	void Serialize(Stream& stream)
	{
		stream % r % s % option_index % vgrap;
	}

	String ToString() const
	{
		String str;
		str << "r = " << r << ", text = \"" << s << "\" Options_Index:" << option_index << "\nGrapheme:";
		for(int i = 0; i < vgrap.GetCount(); i++)
		{
			str << "\n" <<i << ". ";
			for (int j = 0; j < vgrap[i].GetCount(); j++)
				str << ' ' << vgrap[i][j];
		}
		return str;
	}
	void Xmlize(XmlIO& xml)
	{
		xml
		("rectangle",r)
		("text",s)
		("option_index",option_index)
		("Grapheme",vgrap)
		;
	}
};
struct Docu
{
	int	TopMargin;	
	int	LeftMargin;	
	int Textheight;
	int Interline;
	int Paper;
	double m_default;
	Schrift schrift;
	String text_buf;
	Vector<wordrect> vwordrect;
	Vector<options> voptions;
	
	void Serialize(Stream& s)
	{
		s % TopMargin % LeftMargin % Textheight % Interline % Paper % m_default;
		s % schrift % text_buf % vwordrect % voptions;
	}
	
	String ToString() const
	{
		String s;
		s << "TopMargin = " << TopMargin << ", LeftMargin = "<< LeftMargin << ", Textheight = " << Textheight << ", Interline = "<< Interline;
		s << schrift << text_buf;
		for(int i = 0; i < vwordrect.GetCount(); i++)
		{
			s << "\nWord " <<i << ": " << vwordrect[i];
		}
		return s;
	}
	void Xmlize(XmlIO& xml)
	{
		xml
		("TopMargin",TopMargin)
		("LeftMargin",LeftMargin)
		("Textheight",Textheight)
		("Interline",Interline)
		("Paper",Paper)
		("m_default",m_default)
		("Schrift",schrift)
		("text_buf",text_buf)
		("options",voptions)
		("Wordrects",vwordrect)
		;
	}
};
class Sauklaue : public TopWindow {
public:
	typedef Sauklaue CLASSNAME;
	Sauklaue();
	virtual void Close() {
		delete this;
	}
	virtual void   Layout();
	void Serialize(Stream& s);

protected  :
// Program Parameters
	int	TopMargin;	
	int	LeftMargin;	
	int Textheight;
	int height;
	int Interline;
	double m_default;
	int Paper;
	bool A4Limit;
	bool Baselines;
	bool BasedGraphems;
	bool ShowDots;
	bool ShowFrames;
// End Program Parameters
	MenuBar		menu;
	StatusBar   status;
	ToolBar     toolbar;
	Size		drawing_size;
	Size		view_size;
	String 		filename;
	String 		name;
	Docu 		doc;
	Schrift_Editor * pschrifted;
	TextEditor * ptext;
	HelpWindow * phelp;
	
	ScrollBars scroll;
	void    Scroll();
	
	virtual void LeftDown(Point p, dword keyflags);
	virtual void RightDown(Point p, dword keyflags);
	void Popup(Bar& bar);
	virtual void Paint(Draw& w);
//	Image DrawGraphemes( const Rect& r,Vector<Grapoint>& grap);
//	Drawing DrawGraphemes( const Rect& r,Vector<Grapoint>& grap);
	Painting DrawGraphemes( const Rect& r,Vector<Vector<Grapoint> >& vgrap, struct options& opt, bool isgui = false);
	void DrawGraphemes( Draw& w, const Rect& r,Vector<Vector<Grapoint> >& vgrap, struct options& opt);
	Painting MakePainting(Size ims);
	void Do_FramesDots(Draw& w, Rect& r,Vector<Vector<Grapoint> >& vgrap);
	void Do_Drawing(Draw & w, Size drs, bool isgui = false);
	void ScaleWordRect(Rect& r, double scale);
	Vector<Vector<Grapoint> >  Analyse_Word(String& ins, WString& missing, double& xoff);
	void Analyse();
	void ReAnalyseText();
	void DoRefresh();
	void SchriftRefresh();
	void TextDif();
	void SchriftDif();
	void SetBar();
	void File(Bar& bar);
	void Edit(Bar& bar);
	void Save4undo();
	void EditUndo();
	void EditRedo();
	void EditCut();
	void EditCopy();
	void EditPaste();
	void FileBar(Bar& bar);
	void Change(Bar& bar);
	void New_Doc();
	void Open_Doc();
	void Save_Doc();
	void SaveAs_Doc();
	void Load();
	void OpenXML_Doc();
	void SaveAsXML_Doc();
	void Exit();
	void Pdf();
	void SavePainting();
	void SavePNG();
	void Rita();
	void About();
	void AboutMenu(Bar& bar);
	void MainMenu(Bar& bar);
	void MainBar(Bar& bar);
	void Launch(Bar& bar);
	void Launch_Schrift_Editor();
	void Launch_TextEditor();
	void Launch_HelpWindow();
	void HideHelp();
	void Options();
	void ExtSel();
	void ProgParams();
	void AppWord();
	void MoveRect();
	void SnapRect();
	void RestrictRect(Rect& r);
	void SizeRect();
	void Normalize();
	void DoTransformation(Rect& r,Vector<Vector<Grapoint> >& vg, Trans_t trans);
	int  Handle_Optionsets(Vector<int>& vseli);	
	void DrawingSize();
	
private:
	Vector <int> vselrect;
	bool IsModified;
	bool text_modified;
	bool schrift_modified;
	String prev_text;
	Rect rstart;
	int lastGap;
	int undoIndex;
	int undoPossible;
	int redoPossible;
	unsigned int mousemode;
	unsigned int lastmousemode;
	String docdir;
	String Xmldocdir;
	String pdfdir;
	String pngdir;
	String pntdir;
};

#endif
