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

#include <stdlib.h>
#include "CmdOpt.h"
#include <assert.h>

#define SWITCH_CHAR '-'

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

CCmdOpt::CCmdOpt() :
	FileName( "" ),
	LineNumber( 1 ),
	LangType( "" ),
	StandAlone( false ),
	StopSvrByForce( false ),
	CmdType( CT_FILE_OPEN )
{

}

CCmdOpt::~CCmdOpt()
{

}

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

// 初期化
// 処理の継続が不可能な場合は偽を返す
bool CCmdOpt::Initialize( int argc, char *argv[] )
{
	int i;

	if ( argc <= 1 ) return true;

	// 最初の引数がスイッチでなければ、[file][-s]の形式
	if ( argv[1][0] != SWITCH_CHAR ) {
		if ( argc >= 4 ) return help( argv[0] );
		if ( argc == 3 ) {
			// スタンドアロンモード
			if ( strcmp( argv[2], "-s" ) ) return help( argv[0] );
			StandAlone = true;
		}
		FileName = argv[1];	// ファイル名
		CmdType = CT_FILE_OPEN;
		return true;
	}

	if ( !strcmp( argv[1], "-h" ) ) return help( argv[0] );

	if ( !strcmp( argv[1], "-b" ) ) {
		// サーバのブートのみ
		if ( argc >= 3 ) return help( argv[0] );
		CmdType = CT_BOOT_SERVER;
		return true;
	}

	if ( !strcmp( argv[1], "-k" ) ) {
		// サーバの停止
		if ( argc >= 3 ) return help( argv[0] );
		CmdType = CT_STOP_SERVER;
		StopSvrByForce = false;
		return true;
	}

	if ( !strcmp( argv[1], "-K" ) ) {
		// サーバの強制停止
		if ( argc >= 3 ) return help( argv[0] );
		CmdType = CT_STOP_SERVER;
		StopSvrByForce = true;
		return true;
	}

	// ファイルを開く
	CmdType = CT_FILE_OPEN;
	i = 1;
	while ( i < argc ) {
		if ( !strcmp( argv[i], "-f" ) ) {
			// ファイル名
			// -fの次の引数は（強制的に）ファイル名と見なす。
			// -fの後に何もなかったら、ファイル名は省略された物と見なす。
			if ( i >= argc - 1 ) {
				FileName = "";
				i++;
			}
			else {
				FileName = argv[i+1];
				i += 2;
			}
		}
		else if ( !strcmp( argv[i], "-l" ) ) {
			// 行番号
			// -lの後には行番号が必要
			if ( i >= argc - 1 ) return help( argv[0] );
			LineNumber = atoi( argv[i+1] );
			i += 2;
		}
		else if ( !strcmp( argv[i], "-t" ) ) {
			// 構文種別
			// -tの後には構文種別が必要
			if ( i >= argc - 1 ) return help( argv[0] );
			LangType = argv[i+1];
			i += 2;
		}
		else if ( !strcmp( argv[i], "-s" ) ) {
			// スタンドアロンモード
			StandAlone = true;
			i++;
		}
		else {
			// エラー
			return help( argv[0] );
		}
	}

	return true;
}

// コマンドのオプションを表示する
bool CCmdOpt::help( const char *cmd )
{
	string CmdName;
	int len;
	int i;

	assert( cmd );

	// 画面に表示するコマンド名を決定する
	len = strlen( cmd );
	if ( len == 0 ) {
		CmdName = "TaEditClient";
	}
	else {
		for ( i = len - 1; i >= 0 && cmd[i] != '/'; i-- );
		if ( i < 0 )
			CmdName = cmd;
		else
			CmdName = cmd + i + 1;
	}

	fprintf( stderr, "%s : Syuhitu Client\n", CmdName.c_str() );
	fprintf( stderr, "\tCommand Option\n" );
	fprintf( stderr, "\t %s [file] [ -s ]\n", CmdName.c_str() );
	fprintf( stderr, "\t %s -f file [ -l line ] [ -t syntax ] [ -s ]\n", CmdName.c_str() );
	fprintf( stderr, "\t %s -h\n", CmdName.c_str() );
	fprintf( stderr, "\t %s -b\n", CmdName.c_str() );
	fprintf( stderr, "\t %s -k\n", CmdName.c_str() );
	fprintf( stderr, "\t %s -K\n", CmdName.c_str() );
	fprintf( stderr, "\t-s : Stand alone mode.\n" );	
	fprintf( stderr, "\t-l : Cursor position.\n" );	
	fprintf( stderr, "\t-t : Syntax mode.\n" );	
	fprintf( stderr, "\t-h : Show this message.\n" );	
	fprintf( stderr, "\t-b : Boot server only.\n" );
	fprintf( stderr, "\t-k : Stop server.\n" );
	fprintf( stderr, "\t-k : Stop server by force.\n" );
	return false;
}

// フラグを解析する
int CCmdOpt::RecognizeFlg( int argc, char *argv[], const char *pFlg )
{
	int i;

	for ( i = 0; i < argc; i++ ) {
		if ( strcmp( argv[i], pFlg ) == 0 )
			return i;
	}
	return i;
}

// コマンドの種別を取得
CMDTYPE CCmdOpt::GetCmdType() const
{
	return CmdType;
}

const string& CCmdOpt::GetFileName() const
{
	return FileName;
}

int CCmdOpt::GetLineNumber() const
{
	return LineNumber;
}

const string& CCmdOpt::GetLangType() const
{
	return LangType;
}

bool CCmdOpt::GetStandAlone() const
{
	return StandAlone;
}

bool CCmdOpt::GetStopSvrByForce() const
{
	return StopSvrByForce;
}

