/*============================================================================
  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 "cmFLTKWrapUICommand.h"

#include "cmSourceFile.h"

// cmFLTKWrapUICommand
bool cmFLTKWrapUICommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() < 2 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }

  // what is the current source dir
  std::string cdir = this->Makefile->GetCurrentDirectory();
  const char* fluid_exe =
    this->Makefile->GetRequiredDefinition("FLTK_FLUID_EXECUTABLE");

  // get parameter for the command
  this->Target = args[0];  // Target that will use the generated files

  std::vector<std::string> newArgs;
  this->Makefile->ExpandSourceListArguments(args,newArgs, 1);
  
  // get the list of GUI files from which .cxx and .h will be generated 
  std::string outputDirectory = this->Makefile->GetCurrentOutputDirectory();

  // Some of the generated files are *.h so the directory "GUI" 
  // where they are created have to be added to the include path
  this->Makefile->AddIncludeDirectory( outputDirectory.c_str() );

  for(std::vector<std::string>::iterator i = (newArgs.begin() + 1); 
      i != newArgs.end(); i++)
    {
    cmSourceFile *curr = this->Makefile->GetSource(i->c_str());
    // if we should use the source GUI 
    // to generate .cxx and .h files
    if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE"))
      {
      std::string outName = outputDirectory;
      outName += "/";
      outName += cmSystemTools::GetFilenameWithoutExtension(*i);
      std::string hname = outName;
      hname += ".h";
      std::string origname = cdir + "/" + *i;
      // add starting depends
      std::vector<std::string> depends;
      depends.push_back(origname);
      depends.push_back(fluid_exe);
      std::string cxxres = outName;
      cxxres += ".cxx";

      cmCustomCommandLine commandLine;
      commandLine.push_back(fluid_exe);
      commandLine.push_back("-c"); // instructs Fluid to run in command line
      commandLine.push_back("-h"); // optionally rename .h files
      commandLine.push_back(hname);
      commandLine.push_back("-o"); // optionally rename .cxx files
      commandLine.push_back(cxxres);
      commandLine.push_back(origname);// name of the GUI fluid file
      cmCustomCommandLines commandLines;
      commandLines.push_back(commandLine);

      // Add command for generating the .h and .cxx files
      const char* no_main_dependency = 0;
      const char* no_comment = 0;
      const char* no_working_dir = 0;
      this->Makefile->AddCustomCommandToOutput(cxxres.c_str(),
                                           depends, no_main_dependency,
                                           commandLines, no_comment,
                                           no_working_dir);
      this->Makefile->AddCustomCommandToOutput(hname.c_str(),
                                           depends, no_main_dependency,
                                           commandLines, no_comment,
                                           no_working_dir);

      cmSourceFile *sf = this->Makefile->GetSource(cxxres.c_str());
      sf->AddDepend(hname.c_str());
      sf->AddDepend(origname.c_str());
      this->GeneratedSourcesClasses.push_back(sf);
      }
    }

  // create the variable with the list of sources in it
  size_t lastHeadersClass = this->GeneratedSourcesClasses.size();
  std::string sourceListValue;
  for(size_t classNum = 0; classNum < lastHeadersClass; classNum++)
    {
    if (classNum)
      {
      sourceListValue += ";";
      }
    sourceListValue += this->GeneratedSourcesClasses[classNum]->GetFullPath();
    }
  std::string varName = this->Target;
  varName += "_FLTK_UI_SRCS";
  this->Makefile->AddDefinition(varName.c_str(), sourceListValue.c_str());
  
  return true;
}

void cmFLTKWrapUICommand::FinalPass() 
{
  // people should add the srcs to the target themselves, but the old command
  // didn't support that, so check and see if they added the files in and if
  // they didn;t then print a warning and add then anyhow
  cmTarget* target = this->Makefile->FindTarget(this->Target.c_str());
  if(!target)
    {
    std::string msg = 
      "FLTK_WRAP_UI was called with a target that was never created: ";
    msg += this->Target;
    msg +=".  The problem was found while processing the source directory: ";
    msg += this->Makefile->GetStartDirectory();
    msg += ".  This FLTK_WRAP_UI call will be ignored.";
    cmSystemTools::Message(msg.c_str(),"Warning");
    return;
    }
  std::vector<cmSourceFile*> const& srcs = 
    target->GetSourceFiles();
  bool found = false;
  for (unsigned int i = 0; i < srcs.size(); ++i)
    {
    if (srcs[i]->GetFullPath() == 
        this->GeneratedSourcesClasses[0]->GetFullPath())
      {
      found = true;
      break;
      }
    }
  if (!found)
    {
    std::string msg = 
      "In CMake 2.2 the FLTK_WRAP_UI command sets a variable to the list of "
      "source files that should be added to your executable or library. It "
      "appears that you have not added these source files to your target. "
      "You should change your CMakeLists.txt file to "
      "directly add the generated files to the target. "
      "For example FTLK_WRAP_UI(foo src1 src2 src3) "
      "will create a variable named foo_FLTK_UI_SRCS that contains the list "
      "of sources to add to your target when you call ADD_LIBRARY or "
      "ADD_EXECUTABLE. For now CMake will add the sources to your target "
      "for you as was done in CMake 2.0 and earlier. In the future this may "
      "become an error."; 
    msg +="The problem was found while processing the source directory: ";
    msg += this->Makefile->GetStartDirectory();
    cmSystemTools::Message(msg.c_str(),"Warning");
    // first we add the rules for all the .fl to .h and .cxx files
    size_t lastHeadersClass = this->GeneratedSourcesClasses.size();
    
    // Generate code for all the .fl files
    for(size_t classNum = 0; classNum < lastHeadersClass; classNum++)
      {
      this->Makefile->GetTargets()[this->Target]
        .AddSourceFile(this->GeneratedSourcesClasses[classNum]);
      }
    }
}



