// Add Python installations at the given root to the supplied map.
//
void Installer::iterPython(HKEY root, map<wstring, wstring> &pyInstalls) {
	RegistryKey key;
	if ( key.open(root, PY_ROOT ) ) {
		RegistryKey installPath;
		vector<wstring> children;
		key.enumChildren(RegistryKey::EnumKeys, children);
		for ( vector<wstring>::const_iterator i = children.begin(); i != children.end(); i++ ) {
			const wstring &version = *i;
			wstring installPathName = PY_ROOT;
			installPathName += L'\\';
			installPathName += version;
			installPathName += L"\\InstallPath";
			if ( installPath.open(root, installPathName ) ) {
				pyInstalls.insert(make_pair(version, installPath.getValueAsString(L"")));
			}
		}
	}
}
// Populate the lists of installed software for display in the drop-downs.
//
Installer::Installer(void) :
	m_vsSelect(-1), m_pySelect(-1), m_iseSelect(-1), m_x64(det64()),
	m_hdlUseable(false), m_linkName(L"makestuff-base")
{
	RegistryKey key;

	// See if Windows SDK v7.1 is installed
	if ( key.open(HKEY_LOCAL_MACHINE, SDK_ROOT) ) {
		wstring target = L"\"";
		target += key.getValueAsString(L"InstallationFolder");
		m_vsInstalls.push_back(
			VSInstall(
				L"sdk7.1.x86",
				L"Windows SDK v7.1 C/C++ Compiler (x86)",
				target + L"Bin\\SetEnv.cmd\" /x86&&set MACHINE=x86&&"
			)
		);
		if ( m_x64 ) {
			m_vsInstalls.push_back(
				VSInstall(
					L"sdk7.1.x64",
					L"Windows SDK v7.1 C/C++ Compiler (x64)",
					target + L"Bin\\SetEnv.cmd\" /x64&&set MACHINE=x64&&"
				)
			);
		}
	}

	// See which versions (if any) of Visual Studio are installed
	if ( key.open(HKEY_LOCAL_MACHINE, VS_ROOT) ) {
		const wstring baseName = L"Visual Studio ";
		vector<wstring> children;
		key.enumChildren(RegistryKey::EnumValues, children);
		for ( vector<wstring>::const_iterator i = children.begin(); i != children.end(); i++ ) {
			const wstring &version = *i;
			const int majorVersion = getMajorVersion(i->c_str());
			const wstring thisName = baseName + version;
			wstring thisTarget = L"\"";
			thisTarget += key.getValueAsString(version);
			m_vsInstalls.push_back(
				VSInstall(
					L"vs" + version + L".x86",
					thisName + L" C/C++ Compiler (x86)",
					thisTarget + L"VC\\vcvarsall.bat\" x86&&set MACHINE=x86&&"
				)
			);
			if ( m_x64 && majorVersion > 10 ) {
				// 64-bit compilers are only available after VS2010, and realistically only on Windows x64.
				m_vsInstalls.push_back(
					VSInstall(
						L"vs" + version + L".x64",
						thisName + L" C/C++ Compiler (x64)",
						thisTarget + L"VC\\vcvarsall.bat\" x86_amd64&&set MACHINE=x64&&"
					)
				);
			}
		}
	}

	// See which versions (if any) of Python are installed
	map<wstring, wstring> pyInstalls;
	iterPython(HKEY_CURRENT_USER, pyInstalls);
	iterPython(HKEY_LOCAL_MACHINE, pyInstalls);
	for ( map<wstring, wstring>::const_iterator i = pyInstalls.begin(); i != pyInstalls.end(); i++ ) {
		m_pyInstalls.push_back(
			make_pair(
				i->first,
				i->second
			)
		);
	}

	// See which versions (if any) of Xilinx ISE are installed
	if ( key.open(HKEY_CURRENT_USER, ISE_ROOT) ) {
		const wstring baseName = L"Xilinx ISE ";
		vector<wstring> children;
		key.enumChildren(RegistryKey::EnumKeys, children);
		for ( vector<wstring>::const_iterator i = children.begin(); i != children.end(); i++ ) {
			const wstring &version = *i;
			const wstring thisName = baseName + version;
			const wstring thisTarget = grandParent(
				key.getValueAsString(
					version +
					L"\\Project Navigator\\Project Manager\\Preferences\\PlanAheadBinDirUserVal"
				)
			) + (m_x64 ? L"\\ISE\\bin\\nt64" : L"\\ISE\\bin\\nt");
			m_iseInstalls.push_back(
				make_pair(version, thisTarget)
			);
		}
	}
}