/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmLocalVisualStudioGenerator.cxx,v $
  Language:  C++
  Date:      $Date: 2012/03/29 17:21:07 $
  Version:   $Revision: 1.1.1.1 $

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "cmLocalVisualStudioGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmSystemTools.h"
#include "windows.h"

//----------------------------------------------------------------------------
cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator()
{
  this->WindowsShell = true;
  this->WindowsVSIDE = true;
}

//----------------------------------------------------------------------------
cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator()
{
}

//----------------------------------------------------------------------------
bool cmLocalVisualStudioGenerator::SourceFileCompiles(const cmSourceFile* sf)
{
  // Identify the language of the source file.
  if(const char* lang = this->GetSourceFileLanguage(*sf))
    {
    // Check whether this source will actually be compiled.
    return (!sf->GetCustomCommand() &&
            !sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
            !sf->GetPropertyAsBool("EXTERNAL_OBJECT"));
    }
  else
    {
    // Unknown source file language.  Assume it will not be compiled.
    return false;
    }
}

//----------------------------------------------------------------------------
void cmLocalVisualStudioGenerator::CountObjectNames(
    const std::vector<cmSourceGroup>& groups,
    std::map<cmStdString, int>& counts)
{
  for(unsigned int i = 0; i < groups.size(); ++i)
    {
    cmSourceGroup sg = groups[i];
    std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles();
    for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin();
        s != srcs.end(); ++s)
      {
      const cmSourceFile* sf = *s;
      if(this->SourceFileCompiles(sf))
        {
        std::string objectName = cmSystemTools::LowerCase(
            cmSystemTools::GetFilenameWithoutLastExtension(
              sf->GetFullPath()));
        objectName += ".obj";
        counts[objectName] += 1;
        }
      }
    this->CountObjectNames(sg.GetGroupChildren(), counts);
    }
}

//----------------------------------------------------------------------------
void cmLocalVisualStudioGenerator::InsertNeedObjectNames(
   const std::vector<cmSourceGroup>& groups,
    std::map<cmStdString, int>& count)
{
  for(unsigned int i = 0; i < groups.size(); ++i)
    {
    cmSourceGroup sg = groups[i];
    std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles();
    for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin();
        s != srcs.end(); ++s)
      {
      const cmSourceFile* sf = *s;
      if(this->SourceFileCompiles(sf))
        {
        std::string objectName = cmSystemTools::LowerCase(
           cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
        objectName += ".obj";
        if(count[objectName] > 1)
          {
          this->NeedObjectName.insert(sf);
          }
        }
      }
    this->InsertNeedObjectNames(sg.GetGroupChildren(), count);
    }
}


//----------------------------------------------------------------------------
void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements
(std::vector<cmSourceGroup> const& sourceGroups)
{
  // Clear the current set of requirements.
  this->NeedObjectName.clear();

  // Count the number of object files with each name.  Note that
  // windows file names are not case sensitive.
  std::map<cmStdString, int> objectNameCounts;
  this->CountObjectNames(sourceGroups, objectNameCounts);

  // For all source files producing duplicate names we need unique
  // object name computation.
  this->InsertNeedObjectNames(sourceGroups, objectNameCounts);
}

//----------------------------------------------------------------------------
std::string
cmLocalVisualStudioGenerator
::ConstructScript(const cmCustomCommandLines& commandLines,
                  const char* workingDirectory,
                  const char* configName,
                  bool escapeOldStyle,
                  bool escapeAllowMakeVars,
                  const char* newline_text)
{
  // Avoid leading or trailing newlines.
  const char* newline = "";

  // Store the script in a string.
  std::string script;
  if(workingDirectory)
    {
    // Change the working directory.
    script += newline;
    newline = newline_text;
    script += "cd ";
    script += this->Convert(workingDirectory, START_OUTPUT, SHELL);

    // Change the working drive.
    if(workingDirectory[0] && workingDirectory[1] == ':')
      {
      script += newline;
      newline = newline_text;
      script += workingDirectory[0];
      script += workingDirectory[1];
      }
    }
  // for visual studio IDE add extra stuff to the PATH
  // if CMAKE_MSVCIDE_RUN_PATH is set.
  if(this->Makefile->GetDefinition("MSVC_IDE"))
    {
    const char* extraPath =
      this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH");
    if(extraPath)
      {
      script += newline;
      newline = newline_text;
      script += "set PATH=";
      script += extraPath;
      script += ";%PATH%";
      }
    }
  // Write each command on a single line.
  for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
      cl != commandLines.end(); ++cl)
    {
    // Start a new line.
    script += newline;
    newline = newline_text;

    // Start with the command name.
    const cmCustomCommandLine& commandLine = *cl;
    std::string commandName = this->GetRealLocation(commandLine[0].c_str(), 
                                                    configName);
    if(!workingDirectory)
      {
      script += this->Convert(commandName.c_str(),START_OUTPUT,SHELL);
      }
    else
      {
      script += this->Convert(commandName.c_str(),NONE,SHELL);
      }

    // Add the arguments.
    for(unsigned int j=1;j < commandLine.size(); ++j)
      {
      script += " ";
      if(escapeOldStyle)
        {
        script += this->EscapeForShellOldStyle(commandLine[j].c_str());
        }
      else
        {
        script += this->EscapeForShell(commandLine[j].c_str(),
                                       escapeAllowMakeVars);
        }
      }
    }
  return script;
}

