//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// 汎用引数解析クラス
// 
// Coder  : Atsushi Yamashita (atsushi@webs.to)
// Rights : The OpenSource Definition
//
// use :
// hは引数なし、fは2個の引数を取るという意味
//   Argv cmd(argc, argv, "h", "f2");
//
// オプションはまとめて指定することができるが。パラメータを取るもの
// はトークン内で最も前にあるもの一つだけが有効となる。
// ex. -hfr でfもrもパラメータを取る場合はfのみが有効となる。
// 複数指定したい場合は -f file.txt -r file2.txtとする。
//
// 最初のオプション文字列は？
//   char op = cmd.Option(0);
//
// hの最初のパラメーターは?
//   string param = cmd.Parameter(h, 0);
//
// コンストラクタの引数 :
// argc, argv, 固定長の引数を取るオプション, 可変長の引数を取るオプション
// 固定長の引数ではパラメーターの数は1桁(0〜9)までしか許されません。
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

#if !defined ATS_ARGV_H
#define ATS_ARGV_H

#pragma warning (disable : 4786)

#include <vector>
#include <string>
#include <map>
#include <utility>

namespace ats
{
	class Argv
	{
	protected:
		int m_argc;
		char** m_argv;
		// argvのコピー
		std::vector<std::string> m_str_argv;
		// オプション<char><引数の数><char><引数の数>...
		std::string m_user_option, m_option_list, m_param_option;
		// オプションとパラメーターの連想配列
		std::map<char, std::vector<std::string> > m_user_parameter;
		// m_user〜はユーザーが実際に指定したオプション

		void InitOption();
		int FindParamOption(std::string&);
		int RegistParam(char, int, int);

	public:
		Argv(int argc, char** argv, char* ="", char* ="");
		virtual ~Argv();
		// 単純なアクセス
		virtual const std::string& operator[](const int) const;
		// ユーザーに指定されたオプションに順にアクセス(parameter-number)
		virtual char Option(const int) const;
		// 指定されたオプションの数
		virtual int OptionSize() const;
		// そのオプションは指定されているか？
		virtual bool FindOption(const char);
		// 指定されたオプションのパラメーターにアクセス(option-char, parameter-number)
		virtual std::string Parameter(const char, const int);
		// そのオプションは正確にパラメーターの数が指定されているか？
		virtual bool IsParameter(const char);
		// パラメーターの数を取得(option-char)
		virtual int ParameterSize(const char);
	};
}

#endif // ATS_ARGV_H

