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

#include <stdio.h>
#include "lang/LangConfig.h"
#include "CmdOption.h"

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

CCmdOption::CCmdOption() :
	IsEnableFileNameFlg( false ),
	IsEnableInitLineFlg( false ),
	IsEnableLangTypeFlg( false ),
	InitLine( 0 ),
	LangType( LANGTYPE_NAN ),
	IsConstructionModeFlg( false ),
	Arg0( "" )
{

}

CCmdOption::~CCmdOption()
{

}

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

// オプションを設定する
void CCmdOption::SetOption( int argc, char *argv[] )
{
	// コマンドラインのオプションを解釈する
	// （この時点では、Xtなどが使用したオプションは全て無くなっている）

	const char *wp;
	int i, j, len;
	const char *pErrMsg = "It failed to resolve path name of process.";
	char buf[ PATH_MAX + 1 ];	// 起動時のコマンドを取得するためのバッファ

	// コマンドに指定されるスイッチ
	const char *pOptStr[] = {
		"/file:",
		"/line:",
		"/syntax:",
		"/standalone",
		"/construction"
	};

	// スイッチの数
	const int OptStrCnt = sizeof( pOptStr ) / sizeof( pOptStr[0] );

	// 各スイッチが指定されたか否か
	bool wStandaloneFlg = false;
	bool wConstructionFlg = false;
	bool *pEnableFlg[] = {
		&IsEnableFileNameFlg,
		&IsEnableInitLineFlg,
		&IsEnableLangTypeFlg,
		&wStandaloneFlg,
		&wConstructionFlg
	};

	if ( argc < 0 ) {
		fprintf( stderr, pErrMsg );
		Arg0 = "";
		return ;
	}

	// argv[0]の引数を待避する
	if ( realpath( argv[0], buf ) == NULL ) {
		fprintf( stderr, pErrMsg );
		Arg0 = argv[0];
	}
	else {
		buf[ PATH_MAX ] = '\0';
		Arg0 = buf;
	}

	// 各引数を順次処理する
	for ( i = 1; i < argc; i++ ) {

		// 使用可能なスイッチと照合する
		for ( j = 0; j < OptStrCnt; j++ ) {
			len = strlen( pOptStr[j] );
			// 使用可能なスイッチに該当するか否か
			if ( !strncasecmp( pOptStr[j], argv[i], len ) )
				break;
		}
		if ( j >= OptStrCnt ) continue;	// 認識できないスイッチ

		// スイッチ名の後に有効な値が指定されているか否か
		if ( strlen( argv[i] ) <= len )
			wp = NULL;
		else
			wp = argv[i] + len;

		// 当該のスイッチが有効であることを示すフラグを設定する
		*(pEnableFlg[j]) = true;

		// 各スイッチ別に値を取得
		switch ( j ) {
		case 0:	// ファイル名
			FileName = wp;
			break;
		case 1:	// 行番号
			InitLine = atoi( wp );
			break;
		case 2:	// 構文強調表示の種別
			LangType = NLangExt::GetLangTypeID_ByLangName( wp );
			break;
		case 3:
			// スタンドアロンモード
			// コンストラクションモードの指定を無効化する
			IsConstructionModeFlg = false;
			break;
		case 4:
			// コンストラクションモード
			// （/standaloneが指定されていた場合、/constructionは無視する）
			if ( !wStandaloneFlg ) IsConstructionModeFlg = true;
		}
	}
}

// ファイル名オプションが有効か否かを取得
bool CCmdOption::IsEnableFileName() const
{
	return IsEnableFileNameFlg;
}

// ファイル名オプションを取得
const string& CCmdOption::GetFileName() const
{
	return FileName;
}

// 行番号オプションが有効か否かを取得
bool CCmdOption::IsEnableInitLine() const
{
	return IsEnableInitLineFlg;
}

// 行番号オプションの値を取得する
int CCmdOption::GetInitLine() const
{
	return InitLine;
}

// 構文強調表示の種別の設定が有効か否か
bool CCmdOption::IsEnableLangType() const
{
	return IsEnableLangTypeFlg;
}

//  構文強調表示の種別のオプションを取得する
enumLANGTYPE CCmdOption::GetLangType() const
{
	if ( IsEnableLangType() )
		return LangType;
	else
		return LANGTYPE_NAN;
}


// argv[0]の値を参照
const string& CCmdOption::GetArg0() const
{
	return Arg0;
}

// サーバと接続するか否か
bool CCmdOption::IsConstructionMode() const
{
	return IsConstructionModeFlg;
}

