/*============================================================================
  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 "cmUuid.h"
#include "cmake.h"
#include <cmsys/Encoding.hxx>

//----------------------------------------------------------------------------
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}
};

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

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

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.",
      cmState::STRING);
    }

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

  // 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",
       cmState::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*/, bool /*verbose*/,
  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(
    cmMakefile* mf)
{
  cmLocalVisualStudio7Generator *lg =
    new cmLocalVisualStudio7Generator(this, mf);
  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::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);
    }

  if (!this->CMakeInstance->GetIsInTryCompile() &&
      this->GetName() == "Visual Studio 7")
    {
    const char* cmakeWarnVS70 =
      this->CMakeInstance->GetState()->GetCacheEntryValue("CMAKE_WARN_VS70");
    if (!cmakeWarnVS70 || !cmSystemTools::IsOff(cmakeWarnVS70))
      {
      this->CMakeInstance->IssueMessage(
        cmake::WARNING,
        "The \"Visual Studio 7\" generator is deprecated "
        "and will be removed in a future version of CMake."
        "\n"
        "Add CMAKE_WARN_VS70=OFF to the cache to disable this warning."
        );
      }
    }
}

void cmGlobalVisualStudio7Generator
::OutputSLNFile(cmLocalGenerator* root,
                std::vector<cmLocalGenerator*>& generators)
{
  if(generators.empty())
    {
    return;
    }
  this->CurrentProject = root->GetMakefile()->GetProjectName();
  std::string fname = root->GetMakefile()->GetCurrentBinaryDirectory();
  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,
  std::vector<std::string> const& configs,
  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)->Target;
    if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
      {
      continue;
      }
    const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
    if(expath)
      {
      std::set<std::string> allConfigurations(configs.begin(), configs.end());
      const char* mapping = target->GetProperty("VS_PLATFORM_MAPPING");
      this->WriteProjectConfigurations(
        fout, target->GetName().c_str(), target->GetType(),
        configs, allConfigurations, mapping ? mapping : "");
      }
    else
      {
      const std::set<std::string>& configsPartOfDefaultBuild =
        this->IsPartOfDefaultBuild(configs, projectTargets, target);
      const char *vcprojName =
        target->GetProperty("GENERATOR_FILE_NAME");
      if (vcprojName)
        {
        this->WriteProjectConfigurations(fout, vcprojName, target->GetType(),
                                         configs, 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)->Target;
    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->GetCurrentBinaryDirectory();
        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;
            }
          }

        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)->Target;
    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->GetCurrentSourceDirectory();
      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)
{
  std::vector<std::string> configs;
  root->GetMakefile()->GetConfigurations(configs);

  // 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, "ALL_BUILD");

  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 = configs.begin();
      i != configs.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, configs, 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.empty())
      {
      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,
  std::vector<std::string> const& configs,
  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>::const_iterator i = configs.begin();
      i != configs.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 std::vector<std::string> propKeys =
      root->GetMakefile()->GetPropertyKeys();
  for(std::vector<std::string>::const_iterator it = propKeys.begin();
      it != propKeys.end(); ++it)
    {
    if(it->find("VS_GLOBAL_SECTION_") == 0)
      {
      std::string sectionType;
      std::string name = it->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(
              root->GetMakefile()->GetProperty(it->c_str()),
              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::vector<std::string> configs;
  target->GetMakefile()->GetConfigurations(configs);
  std::string pname = target->GetName();
  pname += "_UTILITY";
  std::string fname = target->GetMakefile()->GetCurrentBinaryDirectory();
  fname += "/";
  fname += pname;
  fname += ".vcproj";
  cmGeneratedFileStream fout(fname.c_str());
  fout.SetCopyIfDifferent(true);
  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 = configs.begin();
      i != configs.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(std::string const& name)
{
  std::string const& guidStoreName = name + "_GUID_CMAKE";
  if (const char* storedGUID =
      this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()))
    {
    return std::string(storedGUID);
    }
  // Compute a GUID that is deterministic but unique to the build tree.
  std::string input = this->CMakeInstance->GetState()->GetBinaryDirectory();
  input += "|";
  input += name;

  cmUuid uuidGenerator;

  std::vector<unsigned char> uuidNamespace;
  uuidGenerator.StringToBinary(
    "ee30c4be-5192-4fb0-b335-722a2dffe760", uuidNamespace);

  std::string guid = uuidGenerator.FromMd5(uuidNamespace, input);

  return cmSystemTools::UpperCase(guid);
}

//----------------------------------------------------------------------------
void cmGlobalVisualStudio7Generator
::GetDocumentation(cmDocumentationEntry& entry)
{
  entry.Name = cmGlobalVisualStudio7Generator::GetActualName();
  entry.Brief = "Deprecated. 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(
  std::vector<std::string> const& configs,
  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)
    {
    // check if INSTALL target is part of default build
    if(target->GetName() == "INSTALL")
      {
      // inspect CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD properties
      for(std::vector<std::string>::const_iterator i = configs.begin();
          i != configs.end(); ++i)
        {
        const char* propertyValue = target->GetMakefile()
          ->GetDefinition("CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD");
        cmGeneratorExpression ge;
        cmsys::auto_ptr<cmCompiledGeneratorExpression>
          cge = ge.Parse(propertyValue);
        if(cmSystemTools::IsOn(cge->Evaluate(target->GetMakefile(), *i)))
          {
          activeConfigs.insert(*i);
          }
        }
      }
    return activeConfigs;
    }
  if(type == cmTarget::UTILITY && !this->IsDependedOn(projectTargets, target))
    {
    return activeConfigs;
    }
  cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
  // inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
  for(std::vector<std::string>::const_iterator i = configs.begin();
      i != configs.end(); ++i)
    {
    const char* propertyValue =
      gt->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)
{
  cmGeneratorTarget* gtIn = this->GetGeneratorTarget(targetIn);
  for (OrderedTargetDependSet::const_iterator l = projectTargets.begin();
       l != projectTargets.end(); ++l)
    {
    TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(*l);
    if(tgtdeps.count(gtIn))
      {
      return true;
      }
    }
  return false;
}

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