
#include"CSetupConfig.h"

#include"../../Maid/Auxiliary/Windows/CShell.h"
#include"../../Maid/Auxiliary/CString.h"
#include"../../Maid/Auxiliary/Debug/CAssert.h"
#include"../MaidUninstaller/SetupGlobal.h"

#include<map>

using namespace Maid;


static const char*	s_TABLE_PROGRAMFILES = "programfiles";
static const char*	s_TABLE_WINDOWS = "windows";
static const char*	s_TABLE_STARTMENU = "startmenu";
static const char*	s_TABLE_DESKTOP = "desktop";

static const char*	s_TABLE_UNINSTALLER = "uninstaller";
static const char*	s_TABLE_UNINSTALLER_COMMAND = "uninstallercommand";
static const char*	s_TABLE_SOURCEFOLDER = "sourcefolder";
static const char*	s_TABLE_TARGETFOLDER = "targetfolder";



static const char* s_XML_MUTEXNAME = "mutexname";
static const char* s_XML_CAPTION   = "caption";
static const char* s_XML_GUID = "guid";
static const char* s_XML_UNINSTALLTITTLE = "uninstalltittle";
static const char* s_XML_TARGETREGISTRY = "targetregistry";
static const char* s_XML_DEFAULTTARGET = "defaultfolder";
static const char* s_XML_LASTEXECUTE = "lastexecute";
static const char* s_XML_LASTEXECUTE_CHECKCOMMENT = "checkcomment";
static const char* s_XML_LASTEXECUTE_EXECUTEPATH = "executepath";
static const char* s_XML_LASTEXECUTE_PARAMETERS = "parameters";
static const char* s_XML_INSTALLTYPE = "installtype";
static const char* s_XML_INSTALLTYPE_INSTALLTYPENAME = "installtypename";
static const char* s_XML_INSTALLTYPE_INSTALLTYPECOMMENT = "installtypecomment";
static const char* s_XML_INSTALLTYPE_COPYFILE = "copyfile";
static const char* s_XML_COPYFILE_DISKNO = "diskno";
static const char* s_XML_COPYFILE_SOURCEPATH = "sourcepath";
static const char* s_XML_COPYFILE_TARGETPATH = "targetpath";
static const char* s_XML_COPYFILE_MD5 = "md5";
static const char* s_XML_SHORTCUT = "shortcut";
static const char* s_XML_SHORTCUT_TARGETOBJECT = "targetobject";
static const char* s_XML_SHORTCUT_CREATEPATH = "createpath";
static const char* s_XML_SHORTCUT_PARAMETERS = "parameters";



void CSetupConfig::Initialize( const mstring& FilePath )
{
	{
		//	固定パスの設定
		const mstring ProgramFiles = GetProgramFilesFolder();
		const mstring Windows   = GetWindowsFolder();
		const mstring StartMenu = GetStartMenuFolder();
		const mstring Desktop   = GetDesktopFolder();

		const mstring Source  = CString::GetDirectory(FilePath);

		AddConvertTable( MAIDTEXT(s_TABLE_PROGRAMFILES), ProgramFiles );
		AddConvertTable( MAIDTEXT(s_TABLE_WINDOWS),      Windows );
		AddConvertTable( MAIDTEXT(s_TABLE_STARTMENU),    StartMenu );
		AddConvertTable( MAIDTEXT(s_TABLE_DESKTOP),      Desktop );

		AddConvertTable( MAIDTEXT(s_TABLE_UNINSTALLER),  Windows + MAIDTEXT("\\") + MAIDTEXT(s_UNINSTALLER_NAME) );

		AddConvertTable( MAIDTEXT(s_TABLE_SOURCEFOLDER),  Source);

	}




	CXMLReader reader;

	reader.Load(FilePath);

	reader.AscendNode();

	while( true )
	{
		if( reader.IsTopNode() ) { break; }
		if( reader.IsEndNode() )
		{
			reader.DescendNode();
			reader.NextNode();
			continue;
		}

		const mstring NodeName = reader.GetNodeName();

		if( NodeName==MAIDTEXT(s_XML_MUTEXNAME) )
		{
			m_MutexName = reader.GetString();
		}
		ef( NodeName==MAIDTEXT(s_XML_CAPTION) )
		{
			m_WindowCaption = reader.GetString();
		}
		ef( NodeName==MAIDTEXT(s_XML_GUID) )
		{
			m_GUID = CString::ToLower(reader.GetString());
		}
		ef( NodeName==MAIDTEXT(s_XML_UNINSTALLTITTLE) )
		{
			m_UninstallTittle = reader.GetString();
		}
		ef( NodeName==MAIDTEXT(s_XML_TARGETREGISTRY) )
		{
			m_TargetRegistry = ConvertText( reader.GetString() );
		}
		ef( NodeName==MAIDTEXT(s_XML_DEFAULTTARGET) )
		{
			m_DefaultTarget = ConvertText(reader.GetString());
		}
		ef( NodeName==MAIDTEXT(s_XML_LASTEXECUTE) )
		{
			CXMLReaderAutoDescend(reader);
			ReadLastExec( reader );
		}
		ef( NodeName==MAIDTEXT(s_XML_INSTALLTYPE) )
		{
			CXMLReaderAutoDescend(reader);
			ReadInstall( reader );
		}
		reader.NextNode();
	}

}



void CSetupConfig::ReadLastExec( CXMLReader& reader )
{
	while( true )
	{
		if( reader.IsEndNode() ) { break; }

		const mstring Name = reader.GetNodeName();

		if( Name==MAIDTEXT(s_XML_LASTEXECUTE_CHECKCOMMENT) )
		{
			m_ExecuteInfo.CheckComment = reader.GetString();
		}
		ef( Name==MAIDTEXT(s_XML_LASTEXECUTE_EXECUTEPATH) )
		{
			m_ExecuteInfo.ExecutePath = reader.GetString();
		}
		ef( Name==MAIDTEXT(s_XML_LASTEXECUTE_PARAMETERS) )
		{
			m_ExecuteInfo.Parameters = reader.GetString();
		}

		reader.NextNode();
	}
}


void CSetupConfig::ReadInstall( CXMLReader& reader )
{
	INSTALLTYPE install;
	while( true )
	{
		if( reader.IsEndNode() ) { break; }

		const mstring Name = reader.GetNodeName();

		if( Name==MAIDTEXT(s_XML_INSTALLTYPE_INSTALLTYPENAME) )
		{
			install.InstallTypeName = reader.GetString();
		}
		ef( Name==MAIDTEXT(s_XML_INSTALLTYPE_INSTALLTYPECOMMENT) )
		{
			install.InstallTypeComment = reader.GetString();
		}
		ef( Name==MAIDTEXT(s_XML_INSTALLTYPE_COPYFILE) )
		{
			CXMLReaderAutoDescend(reader);
			INSTALLTYPE::COPYFILE dat;
			ReadCopyFile( reader, dat );

			install.CopyFileList.push_back(dat);
		}
		ef( Name==MAIDTEXT(s_XML_SHORTCUT) )
		{
			CXMLReaderAutoDescend(reader);
			INSTALLTYPE::SHORTCUT dat;
			ReadShortcut( reader, dat );

			install.ShortcutList.push_back(dat);
		}

		reader.NextNode();
	}

	m_InstallType.push_back(install);
}


void CSetupConfig::ReadCopyFile( CXMLReader& reader, INSTALLTYPE::COPYFILE& dat )
{
	while( true )
	{
		if( reader.IsEndNode() ) { break; }

		const mstring Name = reader.GetNodeName();

		if( Name==MAIDTEXT(s_XML_COPYFILE_DISKNO) )
		{
			dat.DiskNo = reader.GetInteger();
		}
		ef( Name==MAIDTEXT(s_XML_COPYFILE_SOURCEPATH) )
		{
			dat.SrcPath = reader.GetString();
		}
		ef( Name==MAIDTEXT(s_XML_COPYFILE_TARGETPATH) )
		{
			dat.DstPath = reader.GetString();
		}
		ef( Name==MAIDTEXT(s_XML_COPYFILE_MD5) )
		{
			if( reader.GetNodeType()==CXMLReader::NODETYPE_ELEMENT )
			{
				dat.MD5 = CString::ToLower(reader.GetString());
			}
		}

		reader.NextNode();
	}

}



void CSetupConfig::ReadShortcut( CXMLReader& reader, INSTALLTYPE::SHORTCUT& dat )
{
	while( true )
	{
		if( reader.IsEndNode() ) { break; }

		const mstring Name = reader.GetNodeName();

		if( Name==MAIDTEXT(s_XML_SHORTCUT_TARGETOBJECT) )
		{
			dat.TargetObject = reader.GetString();
		}
		ef( Name==MAIDTEXT(s_XML_SHORTCUT_CREATEPATH) )
		{
			dat.CreatePath = reader.GetString();
		}
		ef( Name==MAIDTEXT(s_XML_SHORTCUT_PARAMETERS) )
		{
			if( reader.GetNodeType()==CXMLReader::NODETYPE_ELEMENT )
			{
				dat.Parameters = reader.GetString();
			}
		}
		reader.NextNode();
	}
}



mstring CSetupConfig::GetMutexName()const		{ return m_MutexName; }
mstring CSetupConfig::GetWindowCaption()const	{ return m_WindowCaption; }
mstring CSetupConfig::GetGUID()const				{ return m_GUID; }
mstring CSetupConfig::GetUninstallTittle()const	{ return m_UninstallTittle; }
mstring CSetupConfig::GetTargetRegistry()const{ return m_TargetRegistry; }
mstring CSetupConfig::GetDefaultTarget()const{ return m_DefaultTarget; }

mstring CSetupConfig::GetProgramFilesFolder()const{ return CShell::GetProgramFilesFolder(NULL); }
mstring CSetupConfig::GetWindowsFolder()const	{ return CShell::GetWindowsFolder(); }
mstring CSetupConfig::GetStartMenuFolder()const	{ return CShell::GetProgramMenuFolder(NULL); }
mstring CSetupConfig::GetDesktopFolder()const	{ return CShell::GetDeskTopFolder(NULL); }

mstring CSetupConfig::GetInstallFolder()const	{ return m_InstallFolder; }



CSetupConfig::INSTALLTYPE CSetupConfig::GetInstallType( int no )const
{
	MAID_ASSERT( !(no<(int)m_InstallType.size()), "範囲オーバー" );
	return m_InstallType[no];
}

int			CSetupConfig::GetInstallTypeCount()const
{
	return (int)m_InstallType.size();
}


CSetupConfig::EXECUTEINFO CSetupConfig::GetExecuteInfo()const
{
	return m_ExecuteInfo;
}

void CSetupConfig::SetInstallFolder( const mstring& dir )
{
	m_InstallFolder = dir;

	AddConvertTable( MAIDTEXT(s_TABLE_TARGETFOLDER),  dir );
	AddConvertTable( MAIDTEXT(s_TABLE_UNINSTALLER_COMMAND),  MAIDTEXT("\"") + dir + MAIDTEXT("\\") + MAIDTEXT(s_UNINSTALLERINFONAME) + MAIDTEXT("\"") );


	//	ここで変換テーブルが完成するので,一気に変換する
	for( int i=0; i<(int)m_InstallType.size(); ++i )
	{
		INSTALLTYPE& dat = m_InstallType[i];

		for( int j=0; j<(int)dat.CopyFileList.size(); ++j )
		{
			INSTALLTYPE::COPYFILE& c = dat.CopyFileList[j];
			ConvertTextThis(c.SrcPath);
			ConvertTextThis(c.DstPath);
		}

		for( int j=0; j<(int)dat.ShortcutList.size(); ++j )
		{
			INSTALLTYPE::SHORTCUT& c = dat.ShortcutList[j];
			ConvertTextThis(c.TargetObject);
			ConvertTextThis(c.CreatePath);
			ConvertTextThis(c.Parameters);
		}
	}

	ConvertTextThis(m_ExecuteInfo.ExecutePath);
}

mstring CSetupConfig::ConvertText( const mstring& src )
{
	mstring ret;

	for( int i=0; i<(int)src.length(); ++i )
	{
		unt32 c = src[i];

		if( c!='[' )
		{
			ret += c;
		}else
		{
			mstring name;

			++i;
			for( ; i<(int)src.length(); ++i )
			{
				unt32 c = src[i];
				if( c==']' )
				{
					CANVERTTABLE::iterator ite = m_ConvertTable.find(CString::ToLower(name));

					MAID_ASSERT( ite==m_ConvertTable.end(), MAIDTEXT("変換テーブルが見つかりませんでした ") << name );
					ret += ite->second;
					break;
				}else
				{
					name += c;
				}
			}
		}
	}

	return ret;
}

void CSetupConfig::ConvertTextThis( mstring& t )
{
	t = ConvertText(t);
}

void CSetupConfig::AddConvertTable( const mstring& index, const mstring& data )
{
	m_ConvertTable[index] = data;
}

