// FWATCH GENERIC

#pragma once

#include <string>

/*!
 * コマンドライン引数を分解します。
 * 引数はヌル文字によって破壊されます。
 * \param lpCmdLine コマンドライン
 * \param argv 引数を格納する配列
 * \param mx 配列の大きさ
 * \return 得られた引数の数
 */
int GetCmdArgs(LPTSTR lpCmdLine, LPTSTR* argv, int mx);


/*!
 * 整数を文字列として返します。
 * 返されるオブジェクトは一時オブジェクトです。
 * \param v_value 整数
 * \return 文字列
 */
tstring IntToString(long v_value) throw();


/*!
 * 引数を文字列に変換して返します。
 * 返されるオブジェクトは一時オブジェクトです。
 * \param v_format フォーマット文字列
 * \return 文字列
 */
tstring ToString(const LPCTSTR v_format, ...) throw();

/*!
 * 引数を文字列に変換して返します。
 * 返されるオブジェクトは一時オブジェクトです。
 * \param v_format フォーマット文字列
 * \return 文字列
 */
tstring ToStringV(const LPCTSTR v_format, va_list marker) throw();

/*!
 * エラーコードを文字列にして返します。
 * \param errcode エラーコード
 * \return エラーメッセージ
 */
tstring ToErrorMessage(DWORD errcode) throw();

/*!
 * 文字列の前後に含まれる空白とタプ、改行コードを取り除きます。
 * 引数は破壊されます。
 * \param buf トリムする文字列(トリム結果でもある。)
 * \return トリムされた文字列
 */
LPTSTR StrTrim(LPTSTR buf);


/*!
 * 文字列の前後に含まれる空白とタプ、改行コードを取り除い文字列を返します。
 * 引数は破壊されません。
 * 返される文字列は一時的オブジェクトです。
 */
tstring StrTrim(const tstring& v_in);


/*!
 * 文字列が指定した末尾で終端することを保障します。
 * 指定した末尾で終端していない文字列は末尾に終端文字列が追加されます。
 * 対象文字列は破壊的に操作されます。
 * 対象文字列はあらかじめ終端文字を追加しても安全な長さが必要です。
 * \param v_str 対象文字列
 * \param v_endStr 終端文字列
 * \param bufsiz バッファサイズ
 */
void EnsureLast(LPTSTR v_str, LPCTSTR v_endStr, size_t bufsiz);


/*!
 * 文字列が指定した末尾で終端することを保障します。
 * 引数は破壊されません。
 * 返される文字列は一時オブジェクトです。
 * \param v_str 文字列
 * \param v_endStr 終端する文字列
 * \return 終端していることが保障された文字列(一時オブジェクト)
 */
tstring EnsureLast(const tstring& v_str, const tstring& v_endStr);

/*!
 * 文字列に非印字文字が含まれる場合はエスケープします。
 * \r/\n/\tと\x00形式をサポートします。
 * 返される文字列は一時オブジェクトです。
 * \return エスケープされた文字列
 */
tstring EscapeUnprintableChars(const tstring& v_str);

/*!
 * 文字列にエスケープが含まれる場合はエスケープ解除します。
 * \r/\n/\tと\x00形式をサポートします。
 * 返される文字列は一時オブジェクトです。
 */
tstring UnescapeUnprintableChars(const tstring& v_str);

/*!
 * 文字列に非印字文字が含まれる場合は置換文字列で置き換えます。
 * 返される文字列は一時オブジェクトです。
 * \param v_str 対象文字列
 * \param v_replace 置き換える文字列
 * \return 置き換えられた文字列
 */
tstring EliminateUnprintableChars(const tstring& v_str, const tstring& v_replace = _T(" "));

/*!
 * パターンマッチを行います。
 * パターン文字には「*」と「?」の特殊文字を含めることができます。
 * 比較対照となる文字列には、この特殊文字を含めることはできません。
 * 「*」は終端を含めた0文字以上のマッチ、「?」は終端以外の任意の1文字とマッチします。
 * 大文字・小文字を区別します。
 * \param v_text 比較対照文字列
 * \param v_pattern パターン
 * \return マッチした場合、true
 */
bool IsMatch(LPCTSTR v_text, LPCTSTR v_pattern);


/*!
 * 文字列から数値を取り出します。
 * 数値として変換できない場合は0となります。
 * \param v_text 文字列
 * \return 数値
 */
int atoi(const tstring& v_text) throw();

/*!
 * この実行ファイルのフルパスを取得します.
 * \return フルパス
 */
tstring GetModuleFileName();

/*!
 * モジュールの実行ファイル名をベースに拡張子を変更したファイルパスを返します。
 * \param ExtName 拡張子
 * \return モジュールの実行ファイル名をベースに拡張子を変更したファイルパス
 */
tstring GetBaseFileNameWithExtention(LPCTSTR ExtName);

/*!
 * 環境変数を取得します.
 * 存在しない場合はfalseを返します.
 * \param name 環境変数名
 * \param value 環境変数の値の格納先(環境変数がない場合は変更なし)
 * \return 存在すればtrue、存在しないければfalse
 */
bool GetEnvironmentVariable(LPCTSTR name, tstring& value);

/*!
 * フルパスから短いパスを取得します.
 * 変換できない場合は引数をそのまま返します.
 * \param path フルパス
 * \return 短いパス
 */
tstring GetShortPathName(const tstring& path);

/*!
 * 文字列から空白区切りの要素を1つ取り出します。
 * 先行する空白はスキップされます。
 * 先頭がダブルクォートで始まっている場合は空白ではなく次のダブルクォートまでが要素となります。
 * 終端まで達した場合は、InfPathは空となり、終端(ヌル文字)のアドレスが返されます。
 * バッファサイズが足りない場合はNULLが返され、GetLastErrorではERROR_INSUFFICIENT_BUFFERが取得されます。
 * \param InfPath 格納先、不要ならばnull
 * \param lpCmdLine 読み取り開始ポインタ、NULLを指定した場合はNULLが返されます。
 * \param bufsiz 格納先バッファのサイズ
 * \return 次の読み取り位置、もしくは終端
 */
LPCTSTR GetToken(LPTSTR InfPath, LPCTSTR lpCmdLine, int bufsiz);


/*!
 * パスの最後の「\」までの文字列を返します。
 * 「\」を含みます。
 * 「\」がない場合は「.」を返します。
 * \param path パス
 * \return ディレクトリのパス、もしくは「.」
 */
tstring GetDirName(const tstring& path);


/*!
 * パスの最後の「\」より後ろの文字列を返します。「\」は含みません。
 * 「\」がない場合は、パスをそのまま返します。
 * \param パス
 * \return ファイル名、もしくはパスそのもの
 */
tstring GetBaseName(const tstring& path);


/*!
 * パスの最後の「\」より後ろ以降で、最後の「.」までの文字列を返します。
 * 「\」がない場合は、最後の「.」までの文字列を返します。
 * \param パス
 * \return ファイルの拡張子を除いたもの、もしくは、ファイル名、もしくはパスそのもの。
 */
tstring GetNameBody(const tstring& path);

/*!
 * 引数absolutePathを引数dirnameを基準とした相対位置として返す。
 * (何らかの原因で変換できなかった場合は絶対パスが、そのまま返される。)
 * \param dirname 基準位置(フォルダ)
 * \param absoluePath ファイルの絶対パス
 */
tstring GetRelativePath(const tstring& dirname, const tstring& absolutePath);

/*!
 * 指定時刻を経過しているか判定する。
 * nowで示す日時が、targetで示す日時 + spanミリ秒以上である場合、true。
 * \param v_now 現在時刻
 * \param v_span 猶予期間
 * \param v_target 対象時間
 */
bool IsExpired(const FILETIME& v_now, DWORD v_span, const FILETIME& v_target);

/*!
 * 文字列中に含まれる大文字を小文字に変換する.
 * 引数が更新されます.
 * \param 文字列(IN/OUT)
 */
void ToLower(tstring& str);
