/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "windows.h" // this must be first to define GetCurrentDirectory
#include <assert.h>
#include "cmGlobalVisualStudio7Generator.h"
#include "cmGeneratedFileStream.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
#include "cmake.h"
#include <cmsys/Encoding.hxx>

cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
  const std::string& platformName)
{
  this->IntelProjectVersion = 0;
  this->DevEnvCommandInitialized = false;
  this->MasmEnabled = false;

  if (platformName.empty())
    {
    this->DefaultPlatformName = "Win32";
    }
  else
    {
    this->DefaultPlatformName = platformName;
    }
}

cmGlobalVisualStudio7Generator::~cmGlobalVisualStudio7Generator()
{
  free(this->IntelProjectVersion);
}

// Package GUID of Intel Visual Fortran plugin to VS IDE
#define CM_INTEL_PLUGIN_GUID "{B68A201D-CB9B-47AF-A52F-7EEC72E217E4}"

const char* cmGlobalVisualStudio7Generator::GetIntelProjectVersion()
{
  if(!this->IntelProjectVersion)
    {
    // Compute the version of the Intel plugin to the VS IDE.
    // If the key does not exist then use a default guess.
    std::string intelVersion;
    std::string vskey = this->GetRegistryBase();
    vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
    cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
                                     cmSystemTools::KeyWOW64_32);
    unsigned int intelVersionNumber = ~0u;
    sscanf(intelVersion.c_str(), "%u", &intelVersionNumber);
    if(intelVersionNumber >= 11)
      {
      // Default to latest known project file version.
      intelVersion = "11.0";
      }
    else if(intelVersionNumber == 10)
      {
      // Version 10.x actually uses 9.10 in project files!
      intelVersion = "9.10";
      }
    else
      {
      // Version <= 9: use ProductVersion from registry.
      }
    this->IntelProjectVersion = strdup(intelVersion.c_str());
    }
  return this->IntelProjectVersion;
}

void cmGlobalVisualStudio7Generator
::EnableLanguage(std::vector<std::string>const &  lang,
                 cmMakefile *mf, bool optional)
{
  mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
  mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
  if(!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
    {
    mf->AddCacheDefinition(
      "CMAKE_CONFIGURATION_TYPES",
      "Debug;Release;MinSizeRel;RelWithDebInfo",
      "Semicolon separated list of supported configuration types, "
      "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
      "anything else will be ignored.",
      cmCacheManager::STRING);
    }

  // Create list of configurations requested by user's cache, if any.
  this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
  this->GenerateConfigurations(mf);

  // if this environment variable is set, then copy it to
  // a static cache entry.  It will be used by
  // cmLocalGenerator::ConstructScript, to add an extra PATH
  // to all custom commands.   This is because the VS IDE
  // does not use the environment it is run in, and this allows
  // for running commands and using dll's that the IDE environment
  // does not know about.
  const char* extraPath = cmSystemTools::GetEnv("CMAKE_MSVCIDE_RUN_PATH");
  if(extraPath)
    {
    mf->AddCacheDefinition
      ("CMAKE_MSVCIDE_RUN_PATH", extraPath,
       "Saved environment variable CMAKE_MSVCIDE_RUN_PATH",
       cmCacheManager::STATIC);
    }

}

//----------------------------------------------------------------------------
void cmGlobalVisualStudio7Generator::FindMakeProgram(cmMakefile* mf)
{
  this->cmGlobalVisualStudioGenerator::FindMakeProgram(mf);
  mf->AddDefinition("CMAKE_VS_DEVENV_COMMAND",
                    this->GetDevEnvCommand().c_str());
}

//----------------------------------------------------------------------------
std::string const& cmGlobalVisualStudio7Generator::GetDevEnvCommand()
{
  if(!this->DevEnvCommandInitialized)
    {
    this->DevEnvCommandInitialized = true;
    this->DevEnvCommand = this->FindDevEnvCommand();
    }
  return this->DevEnvCommand;
}

//----------------------------------------------------------------------------
std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand()
{
  std::string vscmd;
  std::string vskey = this->GetRegistryBase() + ";InstallDir";
  if(cmSystemTools::ReadRegistryValue(vskey.c_str(), vscmd,
                                      cmSystemTools::KeyWOW64_32))
    {
    cmSystemTools::ConvertToUnixSlashes(vscmd);
    vscmd += "/";
    }
  vscmd += "devenv.com";
  return vscmd;
}

//----------------------------------------------------------------------------
const char* cmGlobalVisualStudio7Generator::ExternalProjectType(
  const char* location)
{
  std::string extension = cmSystemTools::GetFilenameLastExtension(location);
  if (extension == ".vbproj")
    {
    return "F184B08F-C81C-45F6-A57F-5ABD9991F28F";
    }
  else if (extension == ".csproj")
    {
    return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC";
    }
  else if (extension == ".fsproj")
    {
    return "F2A71F9B-5D33-465A-A702-920D77279786";
    }
  else if (extension == ".vdproj")
    {
    return "54435603-DBB4-11D2-8724-00A0C9A8B90C";
    }
  else if (extension == ".dbproj")
    {
    return "C8D11400-126E-41CD-887F-60BD40844F9E";
    }
  else if (extension == ".wixproj")
    {
    return "930C7802-8A8C-48F9-8165-68863BCCD9DD";
    }
  else if (extension == ".pyproj")
    {
    return "888888A0-9F3D-457C-B088-3A5042F75D52";
    }
  return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942";
}
//----------------------------------------------------------------------------
void cmGlobalVisualStudio7Generator::GenerateBuildCommand(
  std::vector<std::string>& makeCommand,
  const std::string& makeProgram,
  const std::string& projectName,
  const std::string& /*projectDir*/,
  const std::string& targetName,
  const std::string& config,
  bool /*fast*/,
  std::vector<std::string> const& makeOptions)
{
  // Select the caller- or user-preferred make program, else devenv.
  std::string makeProgramSelected =
    this->SelectMakeProgram(makeProgram, this->GetDevEnvCommand());

  // Ignore the above preference if it is msbuild.
  // Assume any other value is either a devenv or
  // command-line compatible with devenv.
  std::string makeProgramLower = makeProgramSelected;
  cmSystemTools::LowerCase(makeProgramLower);
  if(makeProgramLower.find("msbuild") != std::string::npos)
    {
    makeProgramSelected = this->GetDevEnvCommand();
    }

  makeCommand.push_back(makeProgramSelected);

  makeCommand.push_back(std::string(projectName) + ".sln");
  std::string realTarget = targetName;
  bool clean = false;
  if ( realTarget == "clean" )
    {
    clean = true;
    realTarget = "ALL_BUILD";
    }
  if(clean)
    {
    makeCommand.push_back("/clean");
    }
  else
    {
    makeCommand.push_back("/build");
    }

  if(!config.empty())
    {
    makeCommand.push_back(config);
    }
  else
    {
    makeCommand.push_back("Debug");
    }
  makeCommand.push_back("/project");

  if (!realTarget.empty())
    {
    makeCommand.push_back(realTarget);
    }
  else
    {
    makeCommand.push_back("ALL_BUILD");
    }
  makeCommand.insert(makeCommand.end(),
                     makeOptions.begin(), makeOptions.end());
}

///! Create a local generator appropriate to this Global Generator
cmLocalGenerator *cmGlobalVisualStudio7Generator::CreateLocalGenerator()
{
  cmLocalVisualStudio7Generator *lg =
    new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS7);
  lg->SetExtraFlagTable(this->GetExtraFlagTableVS7());
  lg->SetGlobalGenerator(this);
  return lg;
}

//----------------------------------------------------------------------------
std::string const& cmGlobalVisualStudio7Generator::GetPlatformName() const
{
  if(!this->GeneratorPlatform.empty())
    {
    return this->GeneratorPlatform;
    }
  return this->DefaultPlatformName;
}

//----------------------------------------------------------------------------
bool cmGlobalVisualStudio7Generator::SetSystemName(std::string const& s,
                                                   cmMakefile* mf)
{
  mf->AddDefinition("CMAKE_VS_INTEL_Fortran_PROJECT_VERSION",
                    this->GetIntelProjectVersion());
  return this->cmGlobalVisualStudioGenerator::SetSystemName(s, mf);
}

//----------------------------------------------------------------------------
bool cmGlobalVisualStudio7Generator::SetGeneratorPlatform(std::string const& p,
                                                          cmMakefile* mf)
{
  if(this->GetPlatformName() == "x64")
    {
    mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
    }
  else if(this->GetPlatformName() == "Itanium")
    {
    mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE");
    }
  mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName().c_str());
  return this->cmGlobalVisualStudioGenerator::SetGeneratorPlatform(p, mf);
}

void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf)
{
  // process the configurations
  const char* ct
    = this->CMakeInstance->GetCacheDefinition("CMAKE_CONFIGURATION_TYPES");
  if ( ct )
    {
    std::vector<std::string> argsOut;
    cmSystemTools::ExpandListArgument(ct, argsOut);
    for(std::vector<std::string>::iterator i = argsOut.begin();
        i != argsOut.end(); ++i)
      {
      if(std::find(this->Configurations.begin(),
                   this->Configurations.end(),
                   *i) == this->Configurations.end())
        {
        this->Configurations.push_back(*i);
        }
      }
    }
  // default to at least Debug and Release
  if(this->Configurations.size() == 0)
    {
    this->Configurations.push_back("Debug");
    this->Configurations.push_back("Release");
    }

  // Reset the entry to have a semi-colon separated list.
  std::string configs = this->Configurations[0];
  for(unsigned int i=1; i < this->Configurations.size(); ++i)
    {
    configs += ";";
    configs += this->Configurations[i];
    }

  mf->AddCacheDefinition(
    "CMAKE_CONFIGURATION_TYPES",
    configs.c_str(),
    "Semicolon separated list of supported configuration types, "
    "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
    "anything else will be ignored.",
    cmCacheManager::STRING);
}

void cmGlobalVisualStudio7Generator::Generate()
{
  // first do the superclass method
  this->cmGlobalVisualStudioGenerator::Generate();

  // Now write out the DSW
  this->OutputSLNFile();
  // If any solution or project files changed during the generation,
  // tell Visual Studio to reload them...
  if(!cmSystemTools::GetErrorOccuredFlag())
    {
    this->CallVisualStudioMacro(MacroReload);
    }
}

void cmGlobalVisualStudio7Generator
::OutputSLNFile(cmLocalGenerator* root,
                std::vector<cmLocalGenerator*>& generators)
{
  if(generators.size() == 0)
    {
    return;
    }
  this->CurrentProject = root->GetMakefile()->GetProjectName();
  std::string fname = root->GetMakefile()->GetStartOutputDirectory();
  fname += "/";
  fname += root->GetMakefile()->GetProjectName();
  fname += ".sln";
  cmGeneratedFileStream fout(fname.c_str());
  fout.SetCopyIfDifferent(true);
  if(!fout)
    {
    return;
    }
  this->WriteSLNFile(fout, root, generators);
  if (fout.Close())
    {
    this->FileReplacedDuringGenerate(fname);
    }
}

// output the SLN file
void cmGlobalVisualStudio7Generator::OutputSLNFile()
{
  std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
  for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
    {
    this->OutputSLNFile(it->second[0], it->second);
    }
}


void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
  std::ostream& fout,
  OrderedTargetDependSet const& projectTargets)
{
  // loop over again and write out configurations for each target
  // in the solution
  for(OrderedTargetDependSet::const_iterator tt =
        projectTargets.begin(); tt != projectTargets.end(); ++tt)
    {
    cmTarget const* target = *tt;
    if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
      {
      continue;
      }
    const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
    if(expath)
      {
      std::set<std::string> allConfigurations(this->Configurations.begin(),
                                              this->Configurations.end());
      const char* mapping = target->GetProperty("VS_PLATFORM_MAPPING");
      this->WriteProjectConfigurations(
        fout, target->GetName().c_str(), target->GetType(),
        allConfigurations, mapping ? mapping : "");
      }
    else
      {
      const std::set<std::string>& configsPartOfDefaultBuild =
        this->IsPartOfDefaultBuild(projectTargets, target);
      const char *vcprojName =
        target->GetProperty("GENERATOR_FILE_NAME");
      if (vcprojName)
        {
        this->WriteProjectConfigurations(fout, vcprojName, target->GetType(),
                                         configsPartOfDefaultBuild);
        }
      }
    }
}


void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
    std::ostream& fout,
    cmLocalGenerator* root,
    OrderedTargetDependSet const& projectTargets)
{
  VisualStudioFolders.clear();

  for(OrderedTargetDependSet::const_iterator tt =
        projectTargets.begin(); tt != projectTargets.end(); ++tt)
    {
    cmTarget const* target = *tt;
    if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
      {
      continue;
      }
    bool written = false;

    // handle external vc project files
    const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
    if(expath)
      {
      std::string project = target->GetName();
      std::string location = expath;

      this->WriteExternalProject(fout,
                                 project.c_str(),
                                 location.c_str(),
                                 target->GetProperty("VS_PROJECT_TYPE"),
                                 target->GetUtilities());
      written = true;
      }
    else
      {
      const char *vcprojName =
        target->GetProperty("GENERATOR_FILE_NAME");
      if(vcprojName)
        {
        cmMakefile* tmf = target->GetMakefile();
        std::string dir = tmf->GetStartOutputDirectory();
        dir = root->Convert(dir.c_str(),
                            cmLocalGenerator::START_OUTPUT);
        if(dir == ".")
          {
          dir = ""; // msbuild cannot handle ".\" prefix
          }
        this->WriteProject(fout, vcprojName, dir.c_str(),
                           *target);
        written = true;
        }
      }

    // Create "solution folder" information from FOLDER target property
    //
    if (written && this->UseFolderProperty())
      {
      const char *targetFolder = target->GetProperty("FOLDER");
      if (targetFolder)
        {
        std::vector<cmsys::String> tokens =
          cmSystemTools::SplitString(targetFolder, '/', false);

        std::string cumulativePath = "";

        for(std::vector<cmsys::String>::iterator iter = tokens.begin();
            iter != tokens.end(); ++iter)
          {
          if(!iter->size())
            {
            continue;
            }

          if (cumulativePath.empty())
            {
            cumulativePath = "CMAKE_FOLDER_GUID_" + *iter;
            }
          else
            {
            VisualStudioFolders[cumulativePath].insert(
              cumulativePath + "/" + *iter);

            cumulativePath = cumulativePath + "/" + *iter;
            }

          this->CreateGUID(cumulativePath.c_str());
          }

        if (!cumulativePath.empty())
          {
          VisualStudioFolders[cumulativePath].insert(target->GetName());
          }
        }
      }
    }
}


void cmGlobalVisualStudio7Generator::WriteTargetDepends(
    std::ostream& fout,
    OrderedTargetDependSet const& projectTargets
    )
{
  for(OrderedTargetDependSet::const_iterator tt =
        projectTargets.begin(); tt != projectTargets.end(); ++tt)
    {
    cmTarget const* target = *tt;
    if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
      {
      continue;
      }
    cmMakefile* mf = target->GetMakefile();
    const char *vcprojName =
      target->GetProperty("GENERATOR_FILE_NAME");
    if (vcprojName)
      {
      std::string dir = mf->GetStartDirectory();
      this->WriteProjectDepends(fout, vcprojName,
                                dir.c_str(), *target);
      }
    }
}

//----------------------------------------------------------------------------
// Write a SLN file to the stream
void cmGlobalVisualStudio7Generator
::WriteSLNFile(std::ostream& fout,
               cmLocalGenerator* root,
               std::vector<cmLocalGenerator*>& generators)
{
  // Write out the header for a SLN file
  this->WriteSLNHeader(fout);

  // Collect all targets under this root generator and the transitive
  // closure of their dependencies.
  TargetDependSet projectTargets;
  TargetDependSet originalTargets;
  this->GetTargetSets(projectTargets, originalTargets, root, generators);
  OrderedTargetDependSet orderedProjectTargets(projectTargets);

  this->WriteTargetsToSolution(fout, root, orderedProjectTargets);

  bool useFolderProperty = this->UseFolderProperty();
  if (useFolderProperty)
    {
    this->WriteFolders(fout);
    }

  // Write out the configurations information for the solution
  fout << "Global\n"
       << "\tGlobalSection(SolutionConfiguration) = preSolution\n";

  int c = 0;
  for(std::vector<std::string>::iterator i = this->Configurations.begin();
      i != this->Configurations.end(); ++i)
    {
    fout << "\t\tConfigName." << c << " = " << *i << "\n";
    c++;
    }
  fout << "\tEndGlobalSection\n";
  // Write out project(target) depends
  fout << "\tGlobalSection(ProjectDependencies) = postSolution\n";
  this->WriteTargetDepends(fout, orderedProjectTargets);
  fout << "\tEndGlobalSection\n";

  if (useFolderProperty)
    {
    // Write out project folders
    fout << "\tGlobalSection(NestedProjects) = preSolution\n";
    this->WriteFoldersContent(fout);
    fout << "\tEndGlobalSection\n";
    }

  // Write out the configurations for all the targets in the project
  fout << "\tGlobalSection(ProjectConfiguration) = postSolution\n";
  this->WriteTargetConfigurations(fout, orderedProjectTargets);
  fout << "\tEndGlobalSection\n";

  // Write out global sections
  this->WriteSLNGlobalSections(fout, root);

  // Write the footer for the SLN file
  this->WriteSLNFooter(fout);
}

//----------------------------------------------------------------------------
void cmGlobalVisualStudio7Generator::WriteFolders(std::ostream& fout)
{
  const char *prefix = "CMAKE_FOLDER_GUID_";
  const std::string::size_type skip_prefix = strlen(prefix);
  std::string guidProjectTypeFolder = "2150E333-8FDC-42A3-9474-1A3956D46DE8";
  for(std::map<std::string,std::set<std::string> >::iterator iter =
    VisualStudioFolders.begin(); iter != VisualStudioFolders.end(); ++iter)
    {
    std::string fullName = iter->first;
    std::string guid = this->GetGUID(fullName.c_str());

    cmSystemTools::ReplaceString(fullName, "/", "\\");
    if (cmSystemTools::StringStartsWith(fullName.c_str(), prefix))
      {
      fullName = fullName.substr(skip_prefix);
      }

    std::string nameOnly = cmSystemTools::GetFilenameName(fullName);

    fout << "Project(\"{" <<
      guidProjectTypeFolder << "}\") = \"" <<
      nameOnly << "\", \"" <<
      fullName << "\", \"{" <<
      guid <<
      "}\"\nEndProject\n";
    }
}

//----------------------------------------------------------------------------
void cmGlobalVisualStudio7Generator::WriteFoldersContent(std::ostream& fout)
{
  for(std::map<std::string,std::set<std::string> >::iterator iter =
    VisualStudioFolders.begin(); iter != VisualStudioFolders.end(); ++iter)
    {
    std::string key(iter->first);
    std::string guidParent(this->GetGUID(key.c_str()));

    for(std::set<std::string>::iterator it = iter->second.begin();
        it != iter->second.end(); ++it)
      {
      std::string value(*it);
      std::string guid(this->GetGUID(value.c_str()));

      fout << "\t\t{" << guid << "} = {" << guidParent << "}\n";
      }
    }
}

//----------------------------------------------------------------------------
std::string
cmGlobalVisualStudio7Generator::ConvertToSolutionPath(const char* path)
{
  // Convert to backslashes.  Do not use ConvertToOutputPath because
  // we will add quoting ourselves, and we know these projects always
  // use windows slashes.
  std::string d = path;
  std::string::size_type pos = 0;
  while((pos = d.find('/', pos)) != d.npos)
    {
    d[pos++] = '\\';
    }
  return d;
}

// Write a dsp file into the SLN file,
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmGlobalVisualStudio7Generator::WriteProject(std::ostream& fout,
                               const std::string& dspname,
                               const char* dir, cmTarget const& target)
{
   // check to see if this is a fortran build
  const char* ext = ".vcproj";
  const char* project =
    "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
  if(this->TargetIsFortranOnly(target))
    {
    ext = ".vfproj";
    project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
    }

  fout << project
       << dspname << "\", \""
       << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
       << dspname << ext << "\", \"{"
       << this->GetGUID(dspname) << "}\"\nEndProject\n";

  UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
  if(ui != this->UtilityDepends.end())
    {
    const char* uname = ui->second.c_str();
    fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
         << uname << "\", \""
         << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
         << uname << ".vcproj" << "\", \"{"
         << this->GetGUID(uname) << "}\"\n"
         << "EndProject\n";
    }
}



// Write a dsp file into the SLN file,
// Note, that dependencies from executables to
// the libraries it uses are also done here
void
cmGlobalVisualStudio7Generator
::WriteProjectDepends(std::ostream& fout,
                      const std::string& dspname,
                      const char*, cmTarget const& target)
{
  int depcount = 0;
  std::string dspguid = this->GetGUID(dspname);
  VSDependSet const& depends = this->VSTargetDepends[&target];
  for(VSDependSet::const_iterator di = depends.begin();
      di != depends.end(); ++di)
    {
    const char* name = di->c_str();
    std::string guid = this->GetGUID(name);
    if(guid.size() == 0)
      {
      std::string m = "Target: ";
      m += target.GetName();
      m += " depends on unknown target: ";
      m += name;
      cmSystemTools::Error(m.c_str());
      }
    fout << "\t\t{" << dspguid << "}." << depcount << " = {" << guid << "}\n";
    depcount++;
    }

  UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
  if(ui != this->UtilityDepends.end())
    {
    const char* uname = ui->second.c_str();
    fout << "\t\t{" << this->GetGUID(uname) << "}.0 = {" << dspguid << "}\n";
    }
}


// Write a dsp file into the SLN file, Note, that dependencies from
// executables to the libraries it uses are also done here
void cmGlobalVisualStudio7Generator
::WriteProjectConfigurations(
  std::ostream& fout, const std::string& name, cmTarget::TargetType,
  const std::set<std::string>& configsPartOfDefaultBuild,
  const std::string& platformMapping)
{
  const std::string& platformName =
    !platformMapping.empty() ? platformMapping : this->GetPlatformName();
  std::string guid = this->GetGUID(name);
  for(std::vector<std::string>::iterator i = this->Configurations.begin();
      i != this->Configurations.end(); ++i)
    {
    fout << "\t\t{" << guid << "}." << *i
         << ".ActiveCfg = " << *i << "|" << platformName << "\n";
      std::set<std::string>::const_iterator
        ci = configsPartOfDefaultBuild.find(*i);
      if(!(ci == configsPartOfDefaultBuild.end()))
      {
      fout << "\t\t{" << guid << "}." << *i
           << ".Build.0 = " << *i << "|" << platformName << "\n";
      }
    }
}



// Write a dsp file into the SLN file,
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmGlobalVisualStudio7Generator::WriteExternalProject(std::ostream& fout,
                               const std::string& name,
                               const char* location,
                               const char* typeGuid,
                               const std::set<std::string>&)
{
  fout << "Project("
       << "\"{"
       << (typeGuid ? typeGuid : this->ExternalProjectType(location))
       << "}\") = \""
       << name << "\", \""
       << this->ConvertToSolutionPath(location) << "\", \"{"
       << this->GetGUID(name)
       << "}\"\n";
  fout << "EndProject\n";
}



void cmGlobalVisualStudio7Generator
::WriteSLNGlobalSections(std::ostream& fout,
                         cmLocalGenerator* root)
{
  bool extensibilityGlobalsOverridden = false;
  bool extensibilityAddInsOverridden = false;
  const cmPropertyMap& props = root->GetMakefile()->GetProperties();
  for(cmPropertyMap::const_iterator itProp = props.begin();
      itProp != props.end(); ++itProp)
    {
    if(itProp->first.find("VS_GLOBAL_SECTION_") == 0)
      {
      std::string sectionType;
      std::string name = itProp->first.substr(18);
      if(name.find("PRE_") == 0)
        {
        name = name.substr(4);
        sectionType = "preSolution";
        }
      else if(name.find("POST_") == 0)
        {
        name = name.substr(5);
        sectionType = "postSolution";
        }
      else
        continue;
      if(!name.empty())
        {
        if(name == "ExtensibilityGlobals" && sectionType == "postSolution")
          extensibilityGlobalsOverridden = true;
        else if(name == "ExtensibilityAddIns" && sectionType == "postSolution")
          extensibilityAddInsOverridden = true;
        fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
        std::vector<std::string> keyValuePairs;
        cmSystemTools::ExpandListArgument(itProp->second.GetValue(),
                                          keyValuePairs);
        for(std::vector<std::string>::const_iterator itPair =
            keyValuePairs.begin(); itPair != keyValuePairs.end(); ++itPair)
          {
          const std::string::size_type posEqual = itPair->find('=');
          if(posEqual != std::string::npos)
            {
            const std::string key =
              cmSystemTools::TrimWhitespace(itPair->substr(0, posEqual));
            const std::string value =
              cmSystemTools::TrimWhitespace(itPair->substr(posEqual + 1));
            fout << "\t\t" << key << " = " << value << "\n";
            }
          }
        fout << "\tEndGlobalSection\n";
        }
      }
    }
  if(!extensibilityGlobalsOverridden)
    fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n"
         << "\tEndGlobalSection\n";
  if(!extensibilityAddInsOverridden)
    fout << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
         << "\tEndGlobalSection\n";
}



// Standard end of dsw file
void cmGlobalVisualStudio7Generator::WriteSLNFooter(std::ostream& fout)
{
  fout << "EndGlobal\n";
}


// ouput standard header for dsw file
void cmGlobalVisualStudio7Generator::WriteSLNHeader(std::ostream& fout)
{
  fout << "Microsoft Visual Studio Solution File, Format Version 7.00\n";
}

//----------------------------------------------------------------------------
std::string
cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target)
{
  std::string pname = target->GetName();
  pname += "_UTILITY";
  std::string fname = target->GetMakefile()->GetStartOutputDirectory();
  fname += "/";
  fname += pname;
  fname += ".vcproj";
  cmGeneratedFileStream fout(fname.c_str());
  fout.SetCopyIfDifferent(true);
  this->CreateGUID(pname.c_str());
  std::string guid = this->GetGUID(pname.c_str());

  fout <<
    "<?xml version=\"1.0\" encoding = \""
    << this->Encoding() << "\"?>\n"
    "<VisualStudioProject\n"
    "\tProjectType=\"Visual C++\"\n"
    "\tVersion=\"" << this->GetIDEVersion() << "0\"\n"
    "\tName=\"" << pname << "\"\n"
    "\tProjectGUID=\"{" << guid << "}\"\n"
    "\tKeyword=\"Win32Proj\">\n"
    "\t<Platforms><Platform Name=\"Win32\"/></Platforms>\n"
    "\t<Configurations>\n"
    ;
  for(std::vector<std::string>::iterator i = this->Configurations.begin();
      i != this->Configurations.end(); ++i)
    {
    fout <<
      "\t\t<Configuration\n"
      "\t\t\tName=\"" << *i << "|Win32\"\n"
      "\t\t\tOutputDirectory=\"" << *i << "\"\n"
      "\t\t\tIntermediateDirectory=\"" << pname << ".dir\\" << *i << "\"\n"
      "\t\t\tConfigurationType=\"10\"\n"
      "\t\t\tUseOfMFC=\"0\"\n"
      "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n"
      "\t\t\tCharacterSet=\"2\">\n"
      "\t\t</Configuration>\n"
      ;
    }
  fout <<
    "\t</Configurations>\n"
    "\t<Files></Files>\n"
    "\t<Globals></Globals>\n"
    "</VisualStudioProject>\n"
    ;

  if(fout.Close())
    {
    this->FileReplacedDuringGenerate(fname);
    }
  return pname;
}

std::string cmGlobalVisualStudio7Generator::GetGUID(const std::string& name)
{
  std::string guidStoreName = name;
  guidStoreName += "_GUID_CMAKE";
  const char* storedGUID =
    this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str());
  if(storedGUID)
    {
    return std::string(storedGUID);
    }
  cmSystemTools::Error("Unknown Target referenced : ",
                       name.c_str());
  return "";
}


void cmGlobalVisualStudio7Generator::CreateGUID(const std::string& name)
{
  std::string guidStoreName = name;
  guidStoreName += "_GUID_CMAKE";
  if(this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()))
    {
    return;
    }
  std::string ret;
  UUID uid;
  unsigned short *uidstr;
  UuidCreate(&uid);
  UuidToStringW(&uid,&uidstr);
  ret = cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(uidstr));
  RpcStringFreeW(&uidstr);
  ret = cmSystemTools::UpperCase(ret);
  this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(),
                                     ret.c_str(), "Stored GUID",
                                     cmCacheManager::INTERNAL);
}

std::vector<std::string> *cmGlobalVisualStudio7Generator::GetConfigurations()
{
  return &this->Configurations;
};

//----------------------------------------------------------------------------
void cmGlobalVisualStudio7Generator
::GetDocumentation(cmDocumentationEntry& entry)
{
  entry.Name = cmGlobalVisualStudio7Generator::GetActualName();
  entry.Brief = "Generates Visual Studio .NET 2002 project files.";
}

//----------------------------------------------------------------------------
void
cmGlobalVisualStudio7Generator
::AppendDirectoryForConfig(const std::string& prefix,
                           const std::string& config,
                           const std::string& suffix,
                           std::string& dir)
{
  if(!config.empty())
    {
    dir += prefix;
    dir += config;
    dir += suffix;
    }
}

std::set<std::string>
cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
  OrderedTargetDependSet const& projectTargets, cmTarget const* target)
{
  std::set<std::string> activeConfigs;
  // if it is a utilitiy target then only make it part of the
  // default build if another target depends on it
  int type = target->GetType();
  if (type == cmTarget::GLOBAL_TARGET)
    {
    return activeConfigs;
    }
  if(type == cmTarget::UTILITY && !this->IsDependedOn(projectTargets, target))
    {
    return activeConfigs;
    }
  // inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
  for(std::vector<std::string>::iterator i = this->Configurations.begin();
      i != this->Configurations.end(); ++i)
    {
    const char* propertyValue =
      target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str());
    if(cmSystemTools::IsOff(propertyValue))
      {
      activeConfigs.insert(*i);
      }
    }
  return activeConfigs;
}

bool
cmGlobalVisualStudio7Generator
::IsDependedOn(OrderedTargetDependSet const& projectTargets,
               cmTarget const* targetIn)
{
  for (OrderedTargetDependSet::const_iterator l = projectTargets.begin();
       l != projectTargets.end(); ++l)
    {
    cmTarget const& target = **l;
    TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
    if(tgtdeps.count(targetIn))
      {
      return true;
      }
    }
  return false;
}

//----------------------------------------------------------------------------
static cmVS7FlagTable cmVS7ExtraFlagTable[] =
{
  // Precompiled header and related options.  Note that the
  // UsePrecompiledHeader entries are marked as "Continue" so that the
  // corresponding PrecompiledHeaderThrough entry can be found.
  {"UsePrecompiledHeader", "YX", "Automatically Generate", "2",
   cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
  {"PrecompiledHeaderThrough", "YX", "Precompiled Header Name", "",
   cmVS7FlagTable::UserValueRequired},
  {"UsePrecompiledHeader", "Yu", "Use Precompiled Header", "3",
   cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
  {"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "",
   cmVS7FlagTable::UserValueRequired},
  {"WholeProgramOptimization", "LTCG", "WholeProgramOptimization", "true", 0},

  // Exception handling mode.  If no entries match, it will be FALSE.
  {"ExceptionHandling", "GX", "enable c++ exceptions", "true", 0},
  {"ExceptionHandling", "EHsc", "enable c++ exceptions", "true", 0},
  // The EHa option does not have an IDE setting.  Let it go to false,
  // and have EHa passed on the command line by leaving out the table
  // entry.

  {0,0,0,0,0}
};
cmIDEFlagTable const* cmGlobalVisualStudio7Generator::GetExtraFlagTableVS7()
{
  return cmVS7ExtraFlagTable;
}

std::string cmGlobalVisualStudio7Generator::Encoding()
{
  std::ostringstream encoding;
#ifdef CMAKE_ENCODING_UTF8
  encoding << "UTF-8";
#else
  encoding << "Windows-1252";
#endif
  return encoding.str();
}
