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

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmExtraCodeBlocksGenerator.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.
  Copyright (c) 2004 Alexander Neundorf neundorf@kde.org, 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 "cmExtraCodeBlocksGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmake.h"
#include "cmSourceFile.h"
#include "cmGeneratedFileStream.h"
#include "cmTarget.h"
#include "cmSystemTools.h"

#include <cmsys/SystemTools.hxx>

/* Some useful URLs:
Homepage: 
http://www.codeblocks.org

File format docs:
http://wiki.codeblocks.org/index.php?title=File_formats_description
http://wiki.codeblocks.org/index.php?title=Workspace_file
http://wiki.codeblocks.org/index.php?title=Project_file

Discussion:
http://forums.codeblocks.org/index.php/topic,6789.0.html
*/

//----------------------------------------------------------------------------
void cmExtraCodeBlocksGenerator
::GetDocumentation(cmDocumentationEntry& entry, const char*) const
{
  entry.Name = this->GetName();
  entry.Brief = "Generates CodeBlocks project files.";
  entry.Full =
    "Project files for CodeBlocks will be created in the top directory "
    "and in every subdirectory which features a CMakeLists.txt file "
    "containing a PROJECT() call. "
    "Additionally a hierarchy of makefiles is generated into the "
    "build tree.  The appropriate make program can build the project through "
    "the default make target.  A \"make install\" target is also provided.";
}

cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator()
:cmExternalMakefileProjectGenerator()
{
#if defined(_WIN32)
  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
// disable until somebody actually tests it:
//  this->SupportedGlobalGenerators.push_back("NMake Makefiles");
//  this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
#endif
  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
}


void cmExtraCodeBlocksGenerator::SetGlobalGenerator(
                                                  cmGlobalGenerator* generator)
{
  cmExternalMakefileProjectGenerator::SetGlobalGenerator(generator);
  cmGlobalUnixMakefileGenerator3* mf = (cmGlobalUnixMakefileGenerator3*)
                                                                     generator;
  mf->SetToolSupportsColor(false);
  mf->SetForceVerboseMakefiles(true);
}

void cmExtraCodeBlocksGenerator::Generate()
{
  // for each sub project in the project create a codeblocks project
  for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
       it = this->GlobalGenerator->GetProjectMap().begin();
      it!= this->GlobalGenerator->GetProjectMap().end();
      ++it)
    {
    // create a project file
    this->CreateProjectFile(it->second);
    }
}


/* create the project file, if it already exists, merge it with the
existing one, otherwise create a new one */
void cmExtraCodeBlocksGenerator::CreateProjectFile(
                                     const std::vector<cmLocalGenerator*>& lgs)
{
  const cmMakefile* mf=lgs[0]->GetMakefile();
  std::string outputDir=mf->GetStartOutputDirectory();
  std::string projectDir=mf->GetHomeDirectory();
  std::string projectName=mf->GetProjectName();

  std::string filename=outputDir+"/";
  filename+=projectName+".cbp";
  std::string sessionFilename=outputDir+"/";
  sessionFilename+=projectName+".layout";

/*  if (cmSystemTools::FileExists(filename.c_str()))
    {
    this->MergeProjectFiles(outputDir, projectDir, filename,
                            cmakeFilePattern, sessionFilename);
    }
  else */
    {
    this->CreateNewProjectFile(lgs, filename);
    }

}


void cmExtraCodeBlocksGenerator
  ::CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
                         const std::string& filename)
{
  const cmMakefile* mf=lgs[0]->GetMakefile();
  cmGeneratedFileStream fout(filename.c_str());
  if(!fout)
    {
    return;
    }

  // figure out the compiler
  std::string compiler = this->GetCBCompilerId(mf);
  std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");

  fout<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n"
        "<CodeBlocks_project_file>\n"
        "   <FileVersion major=\"1\" minor=\"6\" />\n"
        "   <Project>\n"
        "      <Option title=\"" << mf->GetProjectName()<<"\" />\n"
        "      <Option makefile_is_custom=\"1\" />\n"
        "      <Option compiler=\"" << compiler << "\" />\n"
        "      <Build>\n";

  bool installTargetCreated = false;
  bool installStripTargetCreated = false;
  bool testTargetCreated = false;
  bool experimentalTargetCreated = false;
  bool nightlyTargetCreated = false;
  bool packageTargetCreated = false;
  bool packageSourceTargetCreated = false;
  bool rebuildCacheTargetCreated = false;

  this->AppendTarget(fout, "all", 0, make.c_str(), mf, compiler.c_str());

  // add all executable and library targets and some of the GLOBAL 
  // and UTILITY targets
  for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
       lg!=lgs.end(); lg++)
    {
    cmMakefile* makefile=(*lg)->GetMakefile();
    cmTargets& targets=makefile->GetTargets();
    for (cmTargets::iterator ti = targets.begin();
         ti != targets.end(); ti++)
      {
        switch(ti->second.GetType())
        {
          case cmTarget::UTILITY:
          case cmTarget::GLOBAL_TARGET:
            // only add these targets once
            if ((ti->first=="install") && (installTargetCreated==false)) 
              {
              installTargetCreated=true;
              }
            else if ((ti->first=="install/strip") 
                      && (installStripTargetCreated==false)) 
              {
              installStripTargetCreated=true;
              }
            else if ((ti->first=="test") && (testTargetCreated==false)) 
              {
              testTargetCreated=true;
              }
            else if ((ti->first=="Experimental") 
                      && (experimentalTargetCreated==false)) 
              {
              experimentalTargetCreated=true;
              }
            else if ((ti->first=="Nightly") && (nightlyTargetCreated==false)) 
              {
              nightlyTargetCreated=true;
              }
            else if ((ti->first=="package") && (packageTargetCreated==false)) 
              {
              packageTargetCreated=true;
              }
            else if ((ti->first=="package_source") 
                      && (packageSourceTargetCreated==false)) 
              {
              packageSourceTargetCreated=true;
              }
            else if ((ti->first=="rebuild_cache") 
                      && (rebuildCacheTargetCreated==false)) 
              {
              rebuildCacheTargetCreated=true;
              }
            else
              {
              break;
              }
            this->AppendTarget(fout, ti->first.c_str(), 0, 
                               make.c_str(), makefile, compiler.c_str());
            break;
          case cmTarget::EXECUTABLE:
          case cmTarget::STATIC_LIBRARY:
          case cmTarget::SHARED_LIBRARY:
          case cmTarget::MODULE_LIBRARY:
            {
            this->AppendTarget(fout, ti->first.c_str(), &ti->second, 
                               make.c_str(), makefile, compiler.c_str());
            std::string fastTarget = ti->first;
            fastTarget += "/fast";
            this->AppendTarget(fout, fastTarget.c_str(), &ti->second, 
                               make.c_str(), makefile, compiler.c_str());
            }
            break;
          // ignore these:
          case cmTarget::INSTALL_FILES:
          case cmTarget::INSTALL_PROGRAMS:
          case cmTarget::INSTALL_DIRECTORY:
          default:
            break;
        }
      }
    }

  fout<<"      </Build>\n";


  // Collect all used source files in the project
  std::map<std::string, std::string> sourceFiles;
  for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
       lg!=lgs.end(); lg++)
    {
    cmMakefile* makefile=(*lg)->GetMakefile();
    cmTargets& targets=makefile->GetTargets();
    for (cmTargets::iterator ti = targets.begin();
         ti != targets.end(); ti++)
      {
      switch(ti->second.GetType())
        {
        case cmTarget::EXECUTABLE:
        case cmTarget::STATIC_LIBRARY:
        case cmTarget::SHARED_LIBRARY:
        case cmTarget::MODULE_LIBRARY:
          {
          const std::vector<cmSourceFile*>&sources=ti->second.GetSourceFiles();
          for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
               si!=sources.end(); si++)
            {
            sourceFiles[(*si)->GetFullPath()] = ti->first;
            }
          }
        default:  // intended fallthrough
          break;
        }
      }
    }

  // insert all used source files in the CodeBlocks project
  for (std::map<std::string, std::string>::const_iterator 
       sit=sourceFiles.begin();
       sit!=sourceFiles.end();
       ++sit)
  {
  fout<<"      <Unit filename=\""<<sit->first <<"\">\n"
        "      </Unit>\n";
  }

  fout<<"   </Project>\n"
        "</CodeBlocks_project_file>\n";
}


// Generate the xml code for one target.
void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
                                              const char* targetName,
                                              cmTarget* target,
                                              const char* make,
                                              const cmMakefile* makefile,
                                              const char* compiler)
{
  std::string makefileName = makefile->GetStartOutputDirectory();
  makefileName += "/Makefile";
  makefileName = cmSystemTools::ConvertToOutputPath(makefileName.c_str());

  fout<<"      <Target title=\"" << targetName << "\">\n";
  if (target!=0)
    {
    int cbTargetType = this->GetCBTargetType(target);
    fout<<"         <Option output=\"" << target->GetLocation(0) 
                            << "\" prefix_auto=\"0\" extension_auto=\"0\" />\n"
          "         <Option working_dir=\"" 
                            << makefile->GetStartOutputDirectory() << "\" />\n"
          "         <Option object_output=\"./\" />\n"
          "         <Option type=\"" << cbTargetType << "\" />\n"
          "         <Option compiler=\"" << compiler << "\" />\n"
          "         <Compiler>\n";
      // the include directories for this target
      const std::vector<std::string>& incDirs = 
          target->GetMakefile()->GetIncludeDirectories();
      for(std::vector<std::string>::const_iterator dirIt=incDirs.begin();
          dirIt != incDirs.end();
          ++dirIt)
        {
        fout <<"            <Add directory=\"" << dirIt->c_str() << "\" />\n";
        }
      fout<<"         </Compiler>\n";
      }
    else // e.g. all and the GLOBAL and UTILITY targets
    {
    fout<<"         <Option working_dir=\"" 
                            << makefile->GetStartOutputDirectory() << "\" />\n"
        <<"         <Option type=\"" << 4 << "\" />\n";
    }

  fout<<"         <MakeCommands>\n"
        "            <Build command=\"" 
      << this->BuildMakeCommand(make, makefileName.c_str(), targetName)
      << "\" />\n"
        "            <CompileFile command=\"" 
      << this->BuildMakeCommand(make, makefileName.c_str(),"&quot;$file&quot;")
      << "\" />\n"
        "            <Clean command=\"" 
      << this->BuildMakeCommand(make, makefileName.c_str(), "clean") 
      << "\" />\n"
        "            <DistClean command=\"" 
      << this->BuildMakeCommand(make, makefileName.c_str(), "clean") 
      << "\" />\n"
        "         </MakeCommands>\n"
        "      </Target>\n";
  
}


// Translate the cmake compiler id into the CodeBlocks compiler id
std::string cmExtraCodeBlocksGenerator::GetCBCompilerId(const cmMakefile* mf)
{
  // figure out which language to use
  // for now care only for C and C++
  std::string compilerIdVar = "CMAKE_CXX_COMPILER_ID";
  if (this->GlobalGenerator->GetLanguageEnabled("CXX") == false)
    {
    compilerIdVar = "CMAKE_C_COMPILER_ID";
    }

  std::string hostSystemName = mf->GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME");
  std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
  std::string compilerId = mf->GetRequiredDefinition(compilerIdVar.c_str());
  std::string compiler = "gcc";
  if (compilerId == "MSVC")
    {
    compiler = "msvc";
    }
  else if (compilerId == "Borland")
    {
    compiler = "bcc";
    }
  else if (compilerId == "SDCC")
    {
    compiler = "sdcc";
    }
  else if (compilerId == "Intel")
    {
    compiler = "icc";
    }
  else if (compilerId == "Watcom")
    {
    compiler = "ow";
    }
  else if (compilerId == "GNU")
    {
    compiler = "gcc";
    }
  return compiler;
}


// Translate the cmake target type into the CodeBlocks target type id
int cmExtraCodeBlocksGenerator::GetCBTargetType(cmTarget* target)
{
  if ( target->GetType()==cmTarget::EXECUTABLE)
    {
    if ((target->GetPropertyAsBool("WIN32_EXECUTABLE"))
        || (target->GetPropertyAsBool("MACOSX_BUNDLE")))
      {
      return 0;
      }
    else
      {
      return 1;
      }
    }
  else if ( target->GetType()==cmTarget::STATIC_LIBRARY)
    {
    return 2;
    }
  else if ((target->GetType()==cmTarget::SHARED_LIBRARY) 
     || (target->GetType()==cmTarget::MODULE_LIBRARY))
    {
    return 3;
    }
  return 4;
}

// Create the command line for building the given target using the selected
// make
std::string cmExtraCodeBlocksGenerator::BuildMakeCommand(
             const std::string& make, const char* makefile, const char* target)
{
  std::string command = make;
  if (strcmp(this->GlobalGenerator->GetName(), "NMake Makefiles")==0)
    {
    command += " /NOLOGO /f &quot;";
    command += makefile;
    command += "&quot; ";
    command += target;
    }
  else
    {
    command += " -f &quot;";
    command += makefile;
    command += "&quot; ";
    command += target;
    }
  return command;
}
