/*******************************************************************************
  TPI - flexible but useless plug-in framework.
  Copyright (C) 2002-2009 Silky

  This library is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free
  Software Foundation; either version 2.1 of the License, or (at your option)
  any later version.

  This library is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
  for more details.

  You should have received a copy of the GNU Lesser General Public License along
  with this library; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

  $Id: library.cpp 266 2010-03-01 02:28:53Z sirakaba $
*******************************************************************************/

//******************************************************************************
//    Includes
//******************************************************************************

#include "library.h"

//******************************************************************************
//    Functions
//******************************************************************************

wxString ProcessBoolLoop(bool b, wxString szCommandLine, size_t * nPos, wxString szVal, bool fIf)
{
	wxString szCommandLineSend;
	size_t i = * nPos;
	for (i++; i < szCommandLine.Len() && szCommandLine[i] != (fIf ? wxT('|') : wxT('}')); i++)
	{
		if (fIf ? b : ! b)
		{
			szCommandLineSend += szCommandLine[i] == wxT('#') ? szVal : szCommandLine[i];
		}
	}
	* nPos = i;
	return szCommandLineSend;
}

wxString ProcessBool(bool b, wxString szCommandLine, size_t * nPos, wxString szVal = wxEmptyString)
{
	wxString szCommandLineSend;
	size_t i = * nPos;
	if (szCommandLine[++i] == wxT('{'))
	{
		// 条件判別。
		szCommandLineSend += ProcessBoolLoop(b, szCommandLine, & i, szVal, true);
		szCommandLineSend += ProcessBoolLoop(b, szCommandLine, & i, szVal, false);
	}
	else
	{
		// bool値を返却。
		szCommandLineSend += b ? wxT('1') : wxT('0');
		i--;
	}
	* nPos = i;
	return szCommandLineSend;
}

wxString MakeCommandLineSend(wxString szCommandLine, wxString szArcName, TPI_SWITCHES * swInfo, wxArrayString asFiles, wxString szResponceFileName)
{
	// コマンドライン変数を差し替え。
	wxString szCommandLineSend;
	for (size_t i = 0; i < szCommandLine.Len(); i++)
	{
		if (szCommandLine[i] == wxT('%'))
		{
			// 変数解析開始。
			switch ((wxChar) szCommandLine[++i])
			{
			case wxT('%'):
				// 特殊文字。
				szCommandLineSend += szCommandLine[i];
				break;
			case wxT('9'):
				switch ((wxChar) szCommandLine[++i])
				{
				// 0: 書庫名
				// 1: 出力先
				// 2: レスポンスファイル
				// 3: ファイルリスト
				// 4: 圧縮レベル
				// 5: リカバリーレコード
				// 6: コメント
				case wxT('0'): szCommandLineSend += szArcName; break;
				case wxT('1'): szCommandLineSend += swInfo->fnDestinationDirectory.GetPathWithSep(); break;
				case wxT('2'): szCommandLineSend += szResponceFileName; break;
				case wxT('3'):
					for (size_t j = 0; j < asFiles.GetCount(); j++)
					{
						szCommandLineSend += wxT("\"") + asFiles[j] + wxT("\" ");
					}
					break;
				case wxT('4'): szCommandLineSend += wxString::Format(wxT("%d"), swInfo->nCompressLevel); break;
				case wxT('5'): szCommandLineSend += wxString::Format(wxT("%d"), swInfo->nRecoveryRecord); break;
				case wxT('6'): szCommandLineSend += swInfo->szComment; break;
				}
				break;
			case wxT('a'):
				switch ((wxChar) szCommandLine[++i])
				{
				// 0: パスを有効にするか
				// 1: SFXを作成するか
				// 2: Solid圧縮
				// 3: MM最適化
				// 4: ヘッダ暗号化
				// 5: パスワード
				// 6: キーファイル
				// 7: 分割サイズ
				// 8: ヘッダ圧縮
				case wxT('0'): szCommandLineSend += ProcessBool(swInfo->fStoreDirectoryPathes,  szCommandLine, & i); break;
				case wxT('1'): szCommandLineSend += ProcessBool(swInfo->fMakeSFX,               szCommandLine, & i); break;
				case wxT('2'): szCommandLineSend += ProcessBool(swInfo->fSolid,                 szCommandLine, & i); break;
				case wxT('3'): szCommandLineSend += ProcessBool(swInfo->fMMOptimize,            szCommandLine, & i); break;
				case wxT('4'): szCommandLineSend += ProcessBool(swInfo->fEncryptHeader,         szCommandLine, & i); break;
				case wxT('5'): szCommandLineSend += ProcessBool(! swInfo->szPassword.IsEmpty(), szCommandLine, & i, swInfo->szPassword); break;
				case wxT('6'): szCommandLineSend += ProcessBool(! swInfo->szKeyFile.IsEmpty(),  szCommandLine, & i, swInfo->szKeyFile); break;
				case wxT('7'): szCommandLineSend += ProcessBool(swInfo->nSplitSize != 0,        szCommandLine, & i, wxString::Format(wxT("%d"), swInfo->nSplitSize)); break;
				case wxT('8'): szCommandLineSend += ProcessBool(swInfo->fCompressHeader,        szCommandLine, & i); break;
				}
				break;
			}
		}
		else
		{
			szCommandLineSend += szCommandLine[i];
		}
	}

	return szCommandLineSend;
}

wxString MakeResponceFile(wxArrayString asFiles, bool bQuote)
{
	wxFile fListFile;
	wxString szFileName = wxFileName::CreateTempFileName(wxT("__listfile"), & fListFile);
	if (szFileName.IsEmpty())
	{
		return wxEmptyString;
	}

	// ファイルリスト書き込み処理。
	if (asFiles.IsEmpty())
	{
		fListFile.Write(wxT("*"));
	}
	else
	{
		// 毎回引用符で括って処理する。
		for (size_t i = 0; i < asFiles.GetCount(); i++)
		{
			// 最後に改行があると動作がおかしくなる場合がある模様。
			if (i != 0)
			{
#ifdef __WINDOWS__
				fListFile.Write(wxT("\r\n"));
#else
				fListFile.Write(wxT("\n"));
#endif
			}
			fListFile.Write((bQuote ? wxT("\"") : wxEmptyString) + asFiles[i] + (bQuote ? wxT("\"") : wxEmptyString));
		}
	}
	fListFile.Close();

	return szFileName;
}

wxString MB2String(const char * sz)
{
	return wxString(sz, wxConvLibc);
}

wxString UTF82String(const char * sz)
{
	return wxString(sz, wxConvUTF8);
}

wxString WC2String(const wchar_t * sz)
{
	return wxString(sz);
}
