// LineData.cpp: LineData クラスのインプリメンテーション
//
//////////////////////////////////////////////////////////////////////


#include "LineData.h"
#include "DrawCharPos.h"
#include "TaEditDraw.h"
#include "TaEditShell.h"

//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////

CLineData::CLineData()
{
	int i;
	VClsPtr< CConfigInfo > pConf = m_TaEditShell->GetConfigInfo();
	ExtendInfo.resize( pConf->GetExInfoColumnCount(), false );
	clock_gettime( CLOCK_HIGHRES, &ModifiedTime );
	vIro.push_back( 0 );	// 文字列長が0でも色情報は1文字必要である。
	
}

CLineData::CLineData( const CLineData &r ) :
	vIro( r.vIro ), vMoji( r.vMoji )
{
	clock_gettime( CLOCK_HIGHRES, &ModifiedTime );
	ExtendInfo = r.ExtendInfo;
}

CLineData::CLineData( const wchar_t *pStr )
{
	vMoji = pStr;
	vIro.swap( vector< unsigned char >( vMoji.length() + 1, 0 ) );
	VClsPtr< CConfigInfo > pConf = m_TaEditShell->GetConfigInfo();
	ExtendInfo.resize( pConf->GetExInfoColumnCount(), false );
	clock_gettime( CLOCK_HIGHRES, &ModifiedTime );
}

CLineData::~CLineData()
{

}

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

// 挿入
void CLineData::push_back( TA_CHAR c )
{
	vMoji += c.moji;
	// 色情報は最後から2番目への挿入となる
	vIro.insert( vIro.begin() + vIro.size() - 1, c.iro );
	OnUpdate();
}

TA_CHAR CLineData::operator []( size_t idx ) const
{
	assert( idx >= 0 && idx < vMoji.size() );
	return TA_CHAR( vMoji[ idx ], vIro[ idx ] );
}

unsigned char CLineData::getIro( int idx ) const
{
	// 末尾の改行コードの色情報へのアクセスを許す
	assert( idx >= 0 && idx < vIro.size() );
	return vIro[idx];
}

void CLineData::setIro( int idx, unsigned char c )
{
	// 末尾の改行コードの色情報へのアクセスを許す
	assert( idx >= 0 && idx < vIro.size() );
	vIro[idx] = c;
	clock_gettime( CLOCK_HIGHRES, &ModifiedTime );
}

void CLineData::set( size_t idx, TA_CHAR c )
{
	assert( idx >= 0 && idx < vMoji.size() );
	vMoji[ idx ] = c.moji;
	vIro[ idx ] = c.iro;
	OnUpdate();
}

size_t CLineData::length() const
{
	return vMoji.length();
}

const wstring& CLineData::getString() const
{
	return vMoji;
}

const CLineData& CLineData::operator =( const CLineData &r )
{
	vIro = r.vIro;
	vMoji = r.vMoji;
	OnUpdate();
	return (*this);
}

void CLineData::clear()
{
	vIro.clear();
	vIro.push_back( 0 );	// 改行コードの分
	vMoji = L"";
	OnUpdate();
}

// 文字を挿入し間隔を確保する
// 詰められる文字は不定
bool CLineData::InsertBlank( size_t pos, size_t length )
{
	if ( vMoji.length() < pos ) return false;
	if ( length <= 0 ) return true;	// 挿入すべき文字列長が0ならばなにもしない

	vMoji.insert( pos, length, L' ' );
	vIro.insert( vIro.begin() + pos, length, 0 );

	OnUpdate();
	return true;
}

// 指定された範囲の文字を削除する
void CLineData::Delete( size_t s, size_t e )
{
	vIro.erase( vIro.begin() + s, vIro.begin() + e );
	vMoji.erase( vMoji.begin() + s, vMoji.begin() + e );
	OnUpdate();
}

// 最後に更新された時間を取得
const CTimeSpec& CLineData::GetModifiedTime() const
{
	return ModifiedTime;
}

// 描画位置情報が利用可能か否か
bool CLineData::IsEnableDrawCharPos() const
{
	return DrawCharPos.GetIsEnable();
}

// 各文字の描画位置を参照
const CDrawCharPos& CLineData::GetDrawCharPos() const
{
	return DrawCharPos;
}

// 描画位置を更新
bool CLineData::UpdateDrawCharPos( const CTaEditDraw *pDraw ) const
{
	int i;
	unsigned int XPos = 0;

	if ( DrawCharPos.GetIsEnable() ) return true;

	DrawCharPos.Clear();
	for ( i = 0; i < vMoji.length(); i++ ) {
		DrawCharPos.AddChar( XPos );
		XPos += pDraw->GetCharWidth( vMoji[i], XPos );
	}
	DrawCharPos.SetRightXPos( XPos );

	DrawCharPos.SetIsEnable( true );	// 描画位置情報は有効になった
	return true;
}

// 更新された
void CLineData::OnUpdate()
{
	clock_gettime( CLOCK_HIGHRES, &ModifiedTime );	// 更新時間を設定
	DrawCharPos.Clear();
	DrawCharPos.SetIsEnable( false );	// 描画位置情報は無効になった
}

// 拡張情報の取得
bool CLineData::GetExtendInfo( int idx ) const
{
	assert( idx >= 0 && idx < ExtendInfo.size() );
	return ExtendInfo[idx];
}

// 拡張情報の設定
void CLineData::SetExtendInfo( int idx, bool f )
{
	assert( idx >= 0 && idx < ExtendInfo.size() );
	ExtendInfo[idx] = f;
	clock_gettime( CLOCK_HIGHRES, &ModifiedTime );
}

