/*
 * Copyright (c) 2005-2006 Tom N Harris.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Tom N Harris <telliamed@whoopdedo.org>.
 *
 */

#ifndef SETUP_INSTALLER_H
#define SETUP_INSTALLER_H

#include <string>
#include <vector>
#include <ext/hash_map>
#include <ext/hash_set>
#include "string_hash_fun.h"

#include "win32.h"
#include "cString.h"
#include "Thread.h"

#include "InstallInfo.h"

namespace __gnu_cxx
{
template<>
struct hash<Setup::InstallTarget*>
{
	std::size_t operator()(const Setup::InstallTarget* __p) const
		{ return reinterpret_cast<std::size_t>(__p); };
};
};


namespace Setup
{

class ProgressPage;

class Installer
{

	typedef __gnu_cxx::hash_map<std::string,InstallSoftware> SoftList;
	typedef __gnu_cxx::hash_map<std::string,InstallTarget> TargList;
	typedef __gnu_cxx::hash_set<InstallTarget*> TargSet;
	typedef __gnu_cxx::hash_set<InstallFile> FileSet;
	typedef __gnu_cxx::hash_set<InstallDir> DirSet;

class CopierThread : public Thread
{
public:
	CopierThread(Installer& __i, ProgressPage& __p)
		: Thread(),
		  m_installer(__i), m_progress(__p)
	{
	}

protected:
	virtual void run();

private:
	Installer& m_installer;
	ProgressPage& m_progress;
	String m_backupfile;
	FILETIME m_starttime;

	void process(String const&, FileSet const*, FileSet const*, DirSet const*, unsigned int, LPCTSTR);
	void cleanup(String const&, FileSet const*, DirSet const*);
	void cancel();

	int BackupError(String const& dest);
	int CopyFileError(InstallFile const&, String const&);
	int CopyDirError(InstallDir const&, String const&);
	int UpdateInstallCfgError(String const&);
};

public:
	Installer();
	~Installer();

	std::size_t numSofts() const
		{ return m_visiblesofts.size(); };
	const InstallSoftware* getSoft(std::size_t __n) const
		{ return m_visiblesofts.at(__n); };
	const InstallTarget* getTarget(std::string const& __id) const;

	void Reset();
	void AddInstall(std::string const& targ_id);
	void SetDestDirectory(int game, String const& dir);
	bool PreCollectFiles(HWND);
	bool CollectFiles(HWND);
	Thread* CopyFiles(ProgressPage&);

	int InstallGames() const
		{ return m_installgames; };

	bool LoadFromRdf(const char*);

private:
	InstallTarget* _getTarget(std::string const& __id);
	void _AddInstall(std::string const& targ_id, int game);

	SoftList m_softs;
	TargList m_targs;

	String m_destT1;
	String m_destT2;
	String m_destSS2;

	std::vector<InstallSoftware*> m_visiblesofts;
	String m_backupname;

	int m_installgames;
	TargSet m_installs;

	DirSet* m_dirsT1;
	FileSet* m_filesT1;
	FileSet* m_backupT1;
	DirSet* m_dirsT2;
	FileSet* m_filesT2;
	FileSet* m_backupT2;
	DirSet* m_dirsSS2;
	FileSet* m_filesSS2;
	FileSet* m_backupSS2;

	unsigned int m_installcfgT1;
	unsigned int m_installcfgT2;
	unsigned int m_installcfgSS2;

	//CopierThread * m_copier;

	enum OverwriteFileAction
	{
		OverwriteFileKeep,
		OverwriteFileReplace,
		OverwriteFileCancel
	};

	OverwriteFileAction PromptDuplicateFile(HWND, String const&, String const&, String const&);
	OverwriteFileAction PromptReadOnlyFile(HWND, String const&, String const&);
	void PromptDirOverFile(HWND, String const&, String const&);
	void PromptFileOverDir(HWND, String const&, String const&);
};

};

#endif 
