/*============================================================================
  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 "cmGlobalVisualStudio6Generator.h"
#include "cmLocalVisualStudio6Generator.h"
#include "cmMakefile.h"
#include "cmake.h"
#include "cmGeneratedFileStream.h"
#include <cmsys/FStream.hxx>

// Utility function to make a valid VS6 *.dsp filename out
// of a CMake target name:
//
std::string GetVS6TargetName(const std::string& targetName)
{
  std::string name(targetName);

  // Eliminate hyphens. VS6 cannot handle hyphens in *.dsp filenames...
  // Replace them with underscores.
  //
  cmSystemTools::ReplaceString(name, "-", "_");

  return name;
}

cmGlobalVisualStudio6Generator::cmGlobalVisualStudio6Generator(cmake* cm)
  : cmGlobalVisualStudioGenerator(cm)
{
  this->MSDevCommandInitialized = false;
  this->Version = VS6;
}

void cmGlobalVisualStudio6Generator
::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");
  this->GenerateConfigurations(mf);
  this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
}

void cmGlobalVisualStudio6Generator::GenerateConfigurations(cmMakefile* mf)
{
  std::string fname= mf->GetRequiredDefinition("CMAKE_ROOT");
  const char* def= mf->GetDefinition( "MSPROJECT_TEMPLATE_DIRECTORY");
  if(def)
    {
    fname = def;
    }
  else
    {
    fname += "/Templates";
    }
  fname += "/CMakeVisualStudio6Configurations.cmake";
  if(!mf->ReadDependentFile(fname.c_str()))
    {
    cmSystemTools::Error("Cannot open ", fname.c_str(),
                         ".  Please copy this file from the main "
                         "CMake/Templates directory and edit it for "
                         "your build configurations.");
    }
  else if(!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
    {
    cmSystemTools::Error("CMAKE_CONFIGURATION_TYPES not set by ",
                         fname.c_str(),
                         ".  Please copy this file from the main "
                         "CMake/Templates directory and edit it for "
                         "your build configurations.");
    }
}

//----------------------------------------------------------------------------
void cmGlobalVisualStudio6Generator::FindMakeProgram(cmMakefile* mf)
{
  this->cmGlobalVisualStudioGenerator::FindMakeProgram(mf);
  mf->AddDefinition("CMAKE_VS_MSDEV_COMMAND",
                    this->GetMSDevCommand().c_str());
}

//----------------------------------------------------------------------------
std::string const& cmGlobalVisualStudio6Generator::GetMSDevCommand()
{
  if(!this->MSDevCommandInitialized)
    {
    this->MSDevCommandInitialized = true;
    this->MSDevCommand = this->FindMSDevCommand();
    }
  return this->MSDevCommand;
}

//----------------------------------------------------------------------------
std::string cmGlobalVisualStudio6Generator::FindMSDevCommand()
{
  std::string vscmd;
  std::string vskey = this->GetRegistryBase() + "\\Setup;VsCommonDir";
  if(cmSystemTools::ReadRegistryValue(vskey.c_str(), vscmd,
                                      cmSystemTools::KeyWOW64_32))
    {
    cmSystemTools::ConvertToUnixSlashes(vscmd);
    vscmd += "/MSDev98/Bin/";
    }
  vscmd += "msdev.exe";
  return vscmd;
}

//----------------------------------------------------------------------------
void
cmGlobalVisualStudio6Generator::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
  )
{
  // now build the test
  makeCommand.push_back(
    this->SelectMakeProgram(makeProgram, this->GetMSDevCommand())
    );

  makeCommand.push_back(std::string(projectName)+".dsw");
  makeCommand.push_back("/MAKE");
  std::string targetArg;
  bool clean = false;
  std::string realTarget = targetName;
  if ( realTarget == "clean" )
    {
    clean = true;
    realTarget = "ALL_BUILD";
    }
  if (!realTarget.empty())
    {
    targetArg += realTarget;
    }
  else
    {
    targetArg += "ALL_BUILD";
    }
  targetArg += " - ";
  if(!config.empty())
    {
    targetArg += config;
    }
  else
    {
    targetArg += "Debug";
    }
  makeCommand.push_back(targetArg);
  if(clean)
    {
    makeCommand.push_back("/CLEAN");
    }
  else
    {
    makeCommand.push_back("/BUILD");
    }
  makeCommand.insert(makeCommand.end(),
                     makeOptions.begin(), makeOptions.end());
}

///! Create a local generator appropriate to this Global Generator
cmLocalGenerator *
cmGlobalVisualStudio6Generator::CreateLocalGenerator(cmMakefile* mf)
{
  return new cmLocalVisualStudio6Generator(this, mf);
}


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

  // Now write out the DSW
  this->OutputDSWFile();

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

// Write a DSW file to the stream
void cmGlobalVisualStudio6Generator
::WriteDSWFile(std::ostream& fout,cmLocalGenerator* root,
               std::vector<cmLocalGenerator*>& generators)
{
  // Write out the header for a DSW file
  this->WriteDSWHeader(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");

  for(OrderedTargetDependSet::const_iterator
        tt = orderedProjectTargets.begin();
      tt != orderedProjectTargets.end(); ++tt)
    {
    cmGeneratorTarget const* target = *tt;
    if(target->GetType() == cmState::INTERFACE_LIBRARY)
      {
      continue;
      }
    // Write the project into the DSW file
    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->GetUtilities());
      }
    else
      {
      std::string dspname = GetVS6TargetName(target->GetName());
      std::string dir =
          target->GetLocalGenerator()->GetCurrentBinaryDirectory();
      dir = root->Convert(dir.c_str(), cmLocalGenerator::START_OUTPUT);
      this->WriteProject(fout, dspname.c_str(), dir.c_str(), target);
      }
    }

  // Write the footer for the DSW file
  this->WriteDSWFooter(fout);
}

void cmGlobalVisualStudio6Generator
::OutputDSWFile(cmLocalGenerator* root,
                std::vector<cmLocalGenerator*>& generators)
{
  if(generators.empty())
    {
    return;
    }
  std::string fname = root->GetMakefile()->GetCurrentBinaryDirectory();
  fname += "/";
  fname += root->GetProjectName();
  fname += ".dsw";
  cmsys::ofstream fout(fname.c_str());
  if(!fout)
    {
    cmSystemTools::Error("Error can not open DSW file for write: ",
                         fname.c_str());
    cmSystemTools::ReportLastSystemError("");
    return;
    }
  this->WriteDSWFile(fout, root, generators);
}

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

// Write a dsp file into the DSW file,
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout,
                                            const std::string& dspname,
                                            const char* dir,
                                            const cmGeneratorTarget *target)
{
  fout << "#########################################################"
    "######################\n\n";
  fout << "Project: \"" << dspname << "\"="
       << dir << "\\" << dspname << ".dsp - Package Owner=<4>\n\n";
  fout << "Package=<5>\n{{{\n}}}\n\n";
  fout << "Package=<4>\n";
  fout << "{{{\n";
  VSDependSet const& depends = this->VSTargetDepends[target];
  for(VSDependSet::const_iterator di = depends.begin();
      di != depends.end(); ++di)
    {
    const char* name = di->c_str();
    fout << "Begin Project Dependency\n";
    fout << "Project_Dep_Name " << GetVS6TargetName(name) << "\n";
    fout << "End Project Dependency\n";
    }
  fout << "}}}\n\n";

  UtilityDependsMap::iterator ui = this->UtilityDepends.find(target);
  if(ui != this->UtilityDepends.end())
    {
    const char* uname = ui->second.c_str();
    fout << "Project: \"" << uname << "\"="
         << dir << "\\" << uname << ".dsp - Package Owner=<4>\n\n";
    fout <<
      "Package=<5>\n{{{\n}}}\n\n"
      "Package=<4>\n"
      "{{{\n"
      "Begin Project Dependency\n"
      "Project_Dep_Name " << dspname << "\n"
      "End Project Dependency\n"
      "}}}\n\n";
      ;
    }
}


// Write a dsp file into the DSW file,
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmGlobalVisualStudio6Generator::WriteExternalProject(std::ostream& fout,
                               const std::string& name,
                               const char* location,
                               const std::set<std::string>& dependencies)
{
 fout << "#########################################################"
    "######################\n\n";
  fout << "Project: \"" << name << "\"="
       << location << " - Package Owner=<4>\n\n";
  fout << "Package=<5>\n{{{\n}}}\n\n";
  fout << "Package=<4>\n";
  fout << "{{{\n";


  std::set<std::string>::const_iterator i, end;
  // write dependencies.
  i = dependencies.begin();
  end = dependencies.end();
  for(;i!= end; ++i)
  {
    fout << "Begin Project Dependency\n";
    fout << "Project_Dep_Name " << GetVS6TargetName(*i) << "\n";
    fout << "End Project Dependency\n";
  }
  fout << "}}}\n\n";
}



// Standard end of dsw file
void cmGlobalVisualStudio6Generator::WriteDSWFooter(std::ostream& fout)
{
  fout << "######################################################"
    "#########################\n\n";
  fout << "Global:\n\n";
  fout << "Package=<5>\n{{{\n}}}\n\n";
  fout << "Package=<3>\n{{{\n}}}\n\n";
  fout << "#####################################################"
    "##########################\n\n";
}


// ouput standard header for dsw file
void cmGlobalVisualStudio6Generator::WriteDSWHeader(std::ostream& fout)
{
  fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n";
  fout << "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n";
}

//----------------------------------------------------------------------------
std::string
cmGlobalVisualStudio6Generator::WriteUtilityDepend(
        const cmGeneratorTarget *target)
{
  std::string pname = target->GetName();
  pname += "_UTILITY";
  pname = GetVS6TargetName(pname.c_str());
  std::string fname =
          target->GetLocalGenerator()->GetCurrentBinaryDirectory();
  fname += "/";
  fname += pname;
  fname += ".dsp";
  cmGeneratedFileStream fout(fname.c_str());
  fout.SetCopyIfDifferent(true);
  fout <<
    "# Microsoft Developer Studio Project File - Name=\""
       << pname << "\" - Package Owner=<4>\n"
    "# Microsoft Developer Studio Generated Build File, Format Version 6.00\n"
    "# ** DO NOT EDIT **\n"
    "\n"
    "# TARGTYPE \"Win32 (x86) Generic Project\" 0x010a\n"
    "\n"
    "CFG=" << pname << " - Win32 Debug\n"
    "!MESSAGE \"" << pname << " - Win32 Debug\""
    " (based on \"Win32 (x86) Generic Project\")\n"
    "!MESSAGE \"" << pname << " - Win32 Release\" "
    "(based on \"Win32 (x86) Generic Project\")\n"
    "!MESSAGE \"" << pname << " - Win32 MinSizeRel\" "
    "(based on \"Win32 (x86) Generic Project\")\n"
    "!MESSAGE \"" << pname << " - Win32 RelWithDebInfo\" "
    "(based on \"Win32 (x86) Generic Project\")\n"
    "\n"
    "# Begin Project\n"
    "# Begin Target\n"
    "# Name \"" << pname << " - Win32 Debug\"\n"
    "# Name \"" << pname << " - Win32 Release\"\n"
    "# Name \"" << pname << " - Win32 MinSizeRel\"\n"
    "# Name \"" << pname << " - Win32 RelWithDebInfo\"\n"
    "# End Target\n"
    "# End Project\n"
    ;
  return pname;
}

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

//----------------------------------------------------------------------------
void
cmGlobalVisualStudio6Generator
::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;
    }
}
