//////////////////////////////////////////////////////////////////////
//																	//
//		LINEEDIT CTRL, modification by Ratah						//
//		lova.tahina@hotmail.fr										//
//		Phone +33626984844     										//
//		Fevr 2011, FRANCE											//
//																	//
//////////////////////////////////////////////////////////////////////



#ifndef _MyLineEditCtrl_LineEditCtrl_h_
#define _MyLineEditCtrl_LineEditCtrl_h_

#include <CtrlLib/CtrlLib.h>

using namespace Upp;


class AdvLineEdit : public TextCtrl {
public:
	virtual bool   Key(dword key, int count);
	virtual void   Paint(Draw& w);
	virtual void   LeftDown(Point p, dword flags);
	virtual void   RightDown(Point p, dword flags);
	virtual void   LeftRepeat(Point p, dword keyflags);
	virtual void   LeftDouble(Point p, dword keyflags);
	virtual void   LeftTriple(Point p, dword keyflags);
	virtual void   LeftUp(Point p, dword flags);
	virtual void   LeftDrag(Point p, dword flags);
	virtual void   MouseMove(Point p, dword flags);
	virtual void   MouseWheel(Point, int zdelta, dword);
	virtual Image  CursorImage(Point, dword);
	virtual void   DragAndDrop(Point p, PasteClip& d);
	virtual void   DragRepeat(Point p);
	virtual void   DragLeave();
	virtual void   Layout();
	virtual void   RefreshLine(int i);
	
	Vector<int> FindWordOccurence(WString& line, WString& word);

protected:
	virtual void  SetSb();
	virtual void  PlaceCaret(int newcursor, bool sel = false);

public:

	virtual bool IsSelection();
	Vector<int> m_vNbCarParLigne; // contient le nbre de caract par ligne
	void alimNbCarParLigne();
	
	bool isBlockSelection, isBlockActive;
	int hcursor;
	Point m_CursorTL, m_CursorBR;
	Callback WhenAltPressed;

	void SelectBlock();
	void GetCursorTLPos();
	void GetCursorBRPos();
	
	struct selectionSpeciale : Moveable<selectionSpeciale> 
	{
		int r1;
		int r2;
		int c1;
		int c2;
		
		Color cfond;	
		Color cborder;
		
		bool show;
	};
	
	Vector<selectionSpeciale> m_vss;
	
	void AddSelection(int r1, int r2, int c1, int c2, Color& cfond, Color& cborder, bool isShowen);
	void PaintSelection(Draw& w, int y, int wcaract, int hcaract, int r1, int r2, int c1, int c2, int scx, int scy, Color cfond, Color cborder);
	void PaintSelection(Draw& w, int y, int wcaract, int hcaract, int scx, int scy, Vector<selectionSpeciale>& vss);
	
	struct Highlight : Moveable<Highlight> {
		Color paper;
		Color ink;
		Font  font;
		wchar chr;

		bool operator==(const Highlight& h) const
		     { return paper == h.paper && ink == h.ink && font == h.font; }
	};

	struct EditPos : Moveable<EditPos> {
		int sby;
		int cursor;

		void Serialize(Stream& s);
		void Clear()                      { sby = 0; cursor = 0; }
		EditPos()                         { Clear(); }
	};

protected:
	virtual void  HighlightLine(int line, Vector<Highlight>& h, int pos);
	virtual void  NewScrollPos();

	ScrollBars       sb;
	int              gcolumn;
	int              mpos;


	Font             font;
	CharFilter       filter;
	int              tabsize;
	int              bordercolumn;
	Color            bordercolor;
	bool             nohbar;
	bool             showtabs;
	bool             cutline;
	bool             overwrite;
	Scroller         scroller;
	Point            caretpos;

	void   Paint0(Draw& w);

	void   AlignChar();

	void   MovePage(int dir, bool sel);

	void   PlaceCaret0(Point p);
	int    PlaceCaretNoG(int newcursor, bool sel = false);

	void   PlaceBlockCaret(Point p);
	void   PlaceCaretBlock(Point p);
	int    PlaceCaretNoGBlock(int newcursor, bool sel = false);
	
	void   Scroll();
	void   SetHBar();
	Rect   DropCaret();
	void   RefreshDropCaret();

	struct RefreshDraw;

public:
	Size   GetFontSize() const;
	int    GetGPos(int ln, int cl) const;
	int    GetMousePos(Point p) const;
	Point  GetColumnLine(int pos) const;
	int    GetColumnLinePos(Point pos) const  { return GetGPos(pos.y, pos.x); }
	Point  GetIndexLine(int pos) const;
	int    GetIndexLinePos(Point pos) const;

	void   ScrollUp()                         { sb.LineUp(); }
	void   ScrollDown()                       { sb.LineDown(); }

	Rect   GetLineScreenRect(int line) const;

	void   TopCursor(int lines = 0);
	void   CenterCursor();

	void   MoveUpDown(int n, bool sel = false);

	void   MoveLeft(bool sel = false);
	void   MoveRight(bool sel = false);
	void   MoveUp(bool sel = false);
	void   MoveDown(bool sel = false);
	void   MovePageUp(bool sel = false);
	void   MovePageDown(bool sel = false);
	void   MoveHome(bool sel = false);
	void   MoveEnd(bool sel = false);
	void   MoveTextBegin(bool sel = false);
	void   MoveTextEnd(bool sel = false);

	bool   InsertChar(dword key, int count = 1, bool canoverwrite = false);
	void   DeleteChar();
	void   Backspace();
	void   DeleteLine();
	void   CutLine();

	Point   GetScrollPos() const              { return sb; }
	Size    GetPageSize()                     { return sb.GetPage(); }
	void    SetScrollPos(Point p)             { sb.Set(p); }

	EditPos GetEditPos() const;
	void    SetEditPos(const EditPos& pos);
	void    SetEditPosSb(const AdvLineEdit::EditPos& pos);

	void    ScrollIntoCursor();

	Point   GetCaretPoint() const             { return caretpos; }

	void    Clear();

	void    OverWriteMode(bool o = true)      { overwrite = o; PlaceCaret(cursor, false); }
	bool    IsOverWriteMode() const           { return overwrite; }

	void    RefreshChars(bool (*predicate)(int c));

	AdvLineEdit& TabSize(int n);
	int       GetTabSize() const              { return tabsize; }
	AdvLineEdit& BorderColumn(int col, Color c = SColorFace());
	AdvLineEdit& SetFont(Font f);
	Font      GetFont() const                 { return font; }
	AdvLineEdit& NoHorzScrollbar(bool b = true)  { nohbar = b; ScrollIntoCursor(); return *this; }
	AdvLineEdit& ShowTabs(bool st = true)        { showtabs = st; Refresh(); return *this; }
	bool      IsShowTabs() const              { return showtabs; }
	AdvLineEdit& WithCutLine(bool b)             { cutline = b; return *this; }
	AdvLineEdit& NoCutLine()                     { return WithCutLine(false); }
	AdvLineEdit& SetFilter(int (*f)(int c))      { filter = f; return *this; }
	
	AdvLineEdit& SetScrollBarStyle(const ScrollBar::Style& s)   { sb.SetStyle(s); return *this; }

	typedef AdvLineEdit CLASSNAME;

	AdvLineEdit();
	virtual ~AdvLineEdit();
	
};	
	

#endif
