////////////////////////////////////////////////////////////////////////////
// CTaEditDraw クラスのインタフェース宣言
//
////////////////////////////////////////////////////////////////////////////

#if !defined( TAEDITDRAW_H_INCLUDED_ )
#define TAEDITDRAW_H_INCLUDED_

#include "output/gui.h"

#include "TaEdit_std.h"

#include "ScrollInfoPacket.h"
#include "TaEditDoc.h"
#include "ScrollMgr.h"
#include "Cursor.h"
#include "Mouse.h"
#include "GCStorage.h"
#include "GCMgr.h"
#include "XimMgr.h"
#include "TextEdit.h"
#include "DrewLineCash.h"
#include "TEDrawPopup.h"

#include <Dt/Dnd.h>

class CTaEditDraw :
	public CDraw,
	public CScrEventHandler
{
public:
	CTaEditDraw();
	~CTaEditDraw();

	// 構築
	void OnCreate( Widget argWgt, XtPointer user_data );

	// 破壊
	void OnDestroy( Widget argWgt, XtPointer user_data );

	// プロセスが終了される
	void OnExit();

	// ドキュメントが読み込まれた
	void OnReadDocument();

	// スクロールバーのオブジェクトを設定
	void SetScrollMgr( CScrollMgr *argpH, CScrollMgr *argpV );

	// マウス操作
	void OnMouse( Widget w, XEvent *event, Boolean *continue_to_dispatch );

	// マウスポインタの移動
	void OnPointerMotion( Widget w, XEvent *event, Boolean *continue_to_dispatch );

	// タイマイベント
	void OnTimer();

	// テキストの高さを取得
	int GetTextHeight() const;
	int GetTextAscent() const;

	// カーソルを描画
	void DrawCursor( int x, int y ) const;
protected:
	void DrawCursor( int x, int y, Drawable drawable ) const;
public:

	// カレント行の下線を描画
	void DrawCurLineUnderbar( int curline, bool flg ) const;
protected:
	void DrawCurLineUnderbar( int curline, bool flg, Drawable drawable ) const;
public:

	// 文字の幅を取得
	int GetCharWidth( wchar_t c, int xpos ) const;

	// 一番上に描画している行の行番号を取得
	int GetTopLineNum() const;

	// 描画範囲の左端のピクセルの位置を取得
	int GetLeftPixPos() const;

	// ビューに描画できる行数を取得
	int GetViewLineCnt() const;

	// ビューの幅を取得
	int GetViewWidth() const;

	// 縦スクロール
	void ScrollV( int y, bool NeedRedraw );

	// 横スクロール
	void ScrollH( int x, bool NeedRedraw );

	// 画面上のX座標から、左から何文字目かを算出する
	// （pixXはLeftColumnWidthにおいて虚偽のX座標である）
	int XPosToCharNum( int lineY, int pixX ) const;

	// 画面上の座標から、文字位置を算出する
	// （pixXはLeftColumnWidthにおいて虚偽のX座標である）
	T_CurPos PixPosToCurPos( int pixX, int pixY ) const;

	// 画面に何行描画しているかを取得
	// （呼ばれる都度、「描画すべき」行数を計算する）
	int GetDrawedLineCnt() const;

	VClsPtr< CTextEdit > GetTextEditor();	// 編集オブジェクトを取得
	VClsPtr< CCursor > GetCursorInfo();		// カーソル情報管理オブジェクトを取得
	const CCursor* GetCursorInfo() const;

	// 編集後の再描画処理を行う
	void AfterEditRedraw( const ScrollInfoPacket &rScrPacket );

	// 選択範囲の変化後の再描画処理を行う
	void AfterSelRangeRedraw( int argSLine, int argELine );

	// フォーカスの状態を取得
	bool GetForcusState() const;

protected:
	// 入力コールバック
	void OnInput( Widget argWgt, XtPointer user_data );

	// 入力イベント
	void OnKey( Widget w, XEvent *event, Boolean *continue_to_dispatch );

	// 表示
	void OnExpose( Widget argWgt, XtPointer user_data );

	// サイズ変更
	void OnResize( Widget argWgt, XtPointer user_data );

	// フォーカスの出入り
	void OnForcus( Widget w, XEvent *event, Boolean *continue_to_dispatch );

	// マウスの中ボタンの押下
	void OnMouse2Push( XButtonPressedEvent* event );

	// マウスの右ボタンの押下
	void OnMouse3Push( XButtonPressedEvent* event );

	// マウスのスクロールボタンによる上方向へのスクロール
	void OnMouseScrollUp( XButtonPressedEvent* event );

	// マウスのスクロールボタンによる下方向へのスクロール
	void OnMouseScrollDown( XButtonPressedEvent* event );

	// ドロップイベント
	void OnDrop( DtDndTransferCallbackStruct *pCallbackData );

	// スクロールバーが操作された。
	void OnScrValueChange( const CScrollMgr *argpMgr, int value, bool NeedRedraw );

	// 描画領域のサイズを取得
	void GetSize( int *pX, int *pY ) const;

	// 画面（裏面）をクリア
	void ClearBackScreen();

	// 再描画
	void OnRedraw( enumREDRAWTYPE type , int argSLine, int argELine );
	void OnRedraw( enumREDRAWTYPE type );

	// 文字の描画位置情報を再利用して文字列を描画
	void DrawString_ReuseCharInfo( Display *pDisplay, Drawable argDrawable, int XPos, int YPos, const T_LineDataItr_c &rItr, int LineNum, int ViewWidth ) const;

	// 画面の指定された位置に文字列を描画
	void DrawString( Display *pDisplay, Drawable argDrawable, int XPos, int YPos, const T_LineDataItr_c &rItr, int StrSPos, int StrCnt, int LineNum ) const;

	// TABを描画
	void DrawTab( Display *pDisplay, Drawable argDrawable, int s, int e, const CDrawCharPos& rDrawCharPos, int width, int XPos, int YPos, GC ClearGC, GC EditMarkGC ) const;

	// 左側のカラムを描画
	void DrawLeftColumn( Display *pDisplay, Drawable argDrawable, int YPos, const T_LineDataItr_c &rItr, int ColW, int ColCnt ) const;


	// 最初に画面に表示されるときのイベント
	void OnFirstExpose();

	// フォーカスの状態の変化に対するイベントハンドラ
	static void OnForcusEvent( Widget w, XtPointer client_data, XEvent *event, Boolean *continue_to_dispatch );

	// キーボード入力に対するイベントハンドラ
	static void OnKeybordEvent( Widget w, XtPointer client_data, XEvent *event, Boolean *continue_to_dispatch );

	// マウスに対するイベントハンドラ
	static void OnMouseEvent( Widget w, XtPointer client_data, XEvent *event, Boolean *continue_to_dispatch );

	// マウスポインタの移動に対するイベントハンドラ
	static void OnPointerMotionEvent( Widget w, XtPointer client_data, XEvent *event, Boolean *continue_to_dispatch );

	// ドロップされたときのコールバック
	static void OnDropCallback( Widget w, XtPointer client_data, XtPointer callback_data );

protected:
	// ダブルバッファリング用ピックスマップ
	Pixmap BackgndPixmap;

	// 一番上に描画している行
	int numTopLine;

	VClsPtr< CCursor > pCursorInfo;	// カーソル管理オブジェクト
	VClsPtr< CMouse > pMouseInfo;	// マウス管理オブジェクト
	VClsPtr< CGCStorage > pGCStorage;	// GC保持オブジェクト
	VClsPtr< CGCMgr > pGCMgr;	// GC管理オブジェクト
	VClsPtr< CXimMgr > pXimMgr;	// XIM管理オブジェクト
	VClsPtr< CTextEdit > pTextEditor;	// 編集オブジェクト

	int MaxLengthPix;	// もっとも長い行を描画するのに要するピクセル数
	int DrawedLineCnt_hoz;	// 現在画面に何行描画しているか（保存用）
	vector< CDrewLineCash > vDrewLD;	// 現在描画している行に関する情報

	XFontSet fontSet;	// フォントセット
	int TextHeight;	// テキストの高さ
	int TextAscent;	// テキストの上半分の高さ
	int TabWidth;	// タブの幅
	enumTABWIDTHCALCMETHOD TabWidth_CM;	// タブ幅の計算方法
	const wstring *pTabString;	// タブキーで入力される文字

	CScrollMgr *pHScrollMgr;	// 水平スクロールバー
	CScrollMgr *pVScrollMgr;	// 垂直スクロールバー

	bool IsFirstExposed;	// 最初の画面表示が終わったか否か

	bool ForcusState;	// フォーカスの状態
						// フォーカスを得ていれば真

	int LeftColumnWidth;	// 左側に常に確保する空き領域

};

#endif // TAEDITDRAW_H_INCLUDED_

