////////////////////////////////////////////////////////////////////////////
// CGCMgr クラスのインプリメンテーション
//
////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include "GCMgr.h"

using namespace NLangExt;
using namespace NNabikiVClsPtr;

////////////////////////////////////////////////////////////////////////////
// 構築/破棄
////////////////////////////////////////////////////////////////////////////

CGCMgr::CGCMgr() :
	wgtDraw( NULL ),
	pTxtColorMgr( NULL ),
	pStorage( NULL )
{
}

CGCMgr::~CGCMgr()
{

}

////////////////////////////////////////////////////////////////////////////
// メソッド
////////////////////////////////////////////////////////////////////////////

// GCの構築
// （pTCMはNULLの可能性がある）
bool CGCMgr::CreateGC(
	Widget argpDraw,
	VClsPtr< CConfigInfo > pConf,
	const NLangExt::CTxtColorMgr *pTCM,
	VClsPtr< CGCStorage > argStorage
)
{
	int i;
	int ExInfoColumnCnt = pConf->GetExInfoColumnCount();
	GC wGC;
	Pixel fg;
	Pixel bg;

	wgtDraw = argpDraw;
	pTxtColorMgr = pTCM;
	pStorage = argStorage;

	// 通常のテキストの描画用
	fg = pConf->RefNormalTextF_Color();
	bg = pConf->RefNormalTextB_Color();
	if ( !pStorage->CreateGC( GCID_FAILED_TEXT, wgtDraw, fg, bg ) )
		return false;

	// テキスト描画用ＧＣ
	if ( pTCM ) {
		int cnt = pTCM->GetColorCount();
		for ( int i = 0; i < cnt; i++ ) {
			fg = pTCM->GetColor( i );
			bg = pConf->RefNormalTextB_Color();
			pStorage->CreateGC( GCID_TEXT | i, wgtDraw, fg, bg );
		}
	}

	// Tab文字の描画用ＧＣ
	fg = pConf->RefNormalTextB_Color();
	bg = pConf->RefNormalTextF_Color();
	if ( !pStorage->CreateGC( GCID_TAB, wgtDraw, fg, bg ) )
		return false;

	// 選択されたTabの描画用ＧＣ
	fg = pConf->RefSelectedTextB_Color();
	bg = pConf->RefSelectedTextF_Color();
	if ( !pStorage->CreateGC( GCID_SELTAB, wgtDraw, fg, bg ) )
		return false;

	// 選択されたテキストの描画用
	fg = pConf->RefSelectedTextF_Color();
	bg = pConf->RefSelectedTextB_Color();
	if ( !pStorage->CreateGC( GCID_SELTEXT, wgtDraw, fg, bg ) )
		return false;

	// 画面の消去用ＧＣ
	fg = pConf->RefBackgroundColor();
	bg = pConf->RefBackgroundColor();
	if ( !pStorage->CreateGC( GCID_CLEAR, wgtDraw, fg, bg ) )
		return false;

	// カーソル描画用ＧＣ
	fg = pConf->RefCursorColor();
	bg = pConf->RefCursorColor();
	if ( !pStorage->CreateGC( GCID_CURSOR, wgtDraw, fg, bg ) )
		return false;
	wGC = pStorage->GetGC( GCID_CURSOR );
	XSetFunction( XtDisplay( argpDraw ), wGC, GXxor );	// カーソルはXORで描画

	// 左側の各カラムを描画するためのＧＣ
	for ( i = 0; i < ExInfoColumnCnt; i++ ) {
		fg = pConf->RefExInfoColumnColor( i );
		bg = pConf->RefBackgroundColor();
		if ( !pStorage->CreateGC( GCID_INFOCOL | i, wgtDraw, fg, bg ) )
			return false;
	}

	// 左側のカラムを区切る線を描画するためのＧＣ
	fg = pConf->RefSeparatorLineColor();
	bg = pConf->RefBackgroundColor();
	if ( !pStorage->CreateGC( GCID_LEFTCOL_SEPA, wgtDraw, fg, bg ) )
		return false;

	// カレントの行の下線を描画するためのＧＣ
	fg = pConf->RefCurLineUnderBar_Color();
	bg = pConf->RefBackgroundColor();
	pStorage->CreateGC( GCID_UNDERBAR, wgtDraw, fg, bg );

	// 編集記号を描画するためのＧＣ
	fg = pConf->RefEditMark_Color();
	bg = pConf->RefBackgroundColor();
	pStorage->CreateGC( GCID_EDITMARK, wgtDraw, fg, bg );

	return true;
}

// テキスト描画用GCを取得
GC CGCMgr::GetTextDrawGC( unsigned char c, bool IsSelected, bool IsTab ) const
{
	GC wGC;
	int ID;

	if ( !IsTab ) {
		if ( IsSelected )
			return pStorage->GetGC( GCID_SELTEXT );
		else {
			if ( !pTxtColorMgr )
				return pStorage->GetGC( GCID_FAILED_TEXT );

			// 指定された文字の色を描画するGCを検索
			ID = GCID_TEXT | pTxtColorMgr->TranseToIdx( c );
			wGC = pStorage->GetGC( ID );

			// 見つかればそれを返す。無ければデフォルトの奴を返す
			if ( wGC ) return wGC;
			return pStorage->GetGC( GCID_FAILED_TEXT );
		}
	}
	else {
		if ( IsSelected )
			return GetSelTabGC();
		else
			return GetTabGC();
	}
}

// Tab文字描画用GCを取得
GC CGCMgr::GetTabGC() const
{
	return pStorage->GetGC( GCID_TAB );
}

GC CGCMgr::GetSelTabGC() const
{
	return pStorage->GetGC( GCID_SELTAB );
}

// 背景消去用GCの取得
GC CGCMgr::GetClearGC() const
{
	return pStorage->GetGC( GCID_CLEAR );
}

// カーソル描画用GCの取得
GC CGCMgr::GetCursorGC() const
{
	return pStorage->GetGC( GCID_CURSOR );
}

GC CGCMgr::GetExInfoColumnGC( int idx ) const
{
	return pStorage->GetGC( GCID_INFOCOL | idx );
}

GC CGCMgr::GetLeftColumnSeparatorGC() const
{
	return pStorage->GetGC( GCID_LEFTCOL_SEPA );
}

GC CGCMgr::GetCurLineUnderBarGC() const
{
	return pStorage->GetGC( GCID_UNDERBAR );
}

GC CGCMgr::GetEditMarkGC() const
{
	return pStorage->GetGC( GCID_EDITMARK );
}
