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

#include "cmSourceFile.h"

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

  // break the arguments into source file names and properties
  int numFiles = 0;
  std::vector<std::string>::const_iterator j;
  j = args.begin();
  // old style allows for specifier before PROPERTIES keyword
  while (j != args.end() &&
         *j != "ABSTRACT" &&
         *j != "WRAP_EXCLUDE" &&
         *j != "GENERATED" &&
         *j != "COMPILE_FLAGS" &&
         *j != "OBJECT_DEPENDS" &&
         *j != "PROPERTIES")
    {
    numFiles++;
    ++j;
    }

  // now call the worker function
  std::string errors;
  bool ret =
    cmSetSourceFilesPropertiesCommand
    ::RunCommand(this->Makefile,
                 args.begin(),
                 args.begin() + numFiles,
                 args.begin() + numFiles,
                 args.end(), errors);
  if (!ret)
    {
    this->SetError(errors.c_str());
    }
  return ret;
}

bool cmSetSourceFilesPropertiesCommand
::RunCommand(cmMakefile *mf,
             std::vector<std::string>::const_iterator filebeg,
             std::vector<std::string>::const_iterator fileend,
             std::vector<std::string>::const_iterator propbeg,
             std::vector<std::string>::const_iterator propend,
             std::string &errors)
{
  std::vector<std::string> propertyPairs;
  bool generated = false;
  std::vector<std::string>::const_iterator j;
  // build the property pairs
  for(j= propbeg; j != propend;++j)
    {
    // old style allows for specifier before PROPERTIES keyword
    if(*j == "ABSTRACT")
      {
      propertyPairs.push_back("ABSTRACT");
      propertyPairs.push_back("1");
      }
    else if(*j == "WRAP_EXCLUDE")
      {
      propertyPairs.push_back("WRAP_EXCLUDE");
      propertyPairs.push_back("1");
      }
    else if(*j == "GENERATED")
      {
      generated = true;
      propertyPairs.push_back("GENERATED");
      propertyPairs.push_back("1");
      }
    else if(*j == "COMPILE_FLAGS")
      {
      propertyPairs.push_back("COMPILE_FLAGS");
      ++j;
      if(j == propend)
        {
        errors = "called with incorrect number of arguments "
          "COMPILE_FLAGS with no flags";
        return false;
        }
      propertyPairs.push_back(*j);
      }
    else if(*j == "OBJECT_DEPENDS")
      {
      propertyPairs.push_back("OBJECT_DEPENDS");
      ++j;
      if(j == propend)
        {
        errors = "called with incorrect number of arguments "
          "OBJECT_DEPENDS with no dependencies";
        return false;
        }
      propertyPairs.push_back(*j);
      }
    else if(*j == "PROPERTIES")
      {
      // now loop through the rest of the arguments, new style
      ++j;
      while (j != propend)
        {
        propertyPairs.push_back(*j);
        if(*j == "GENERATED")
          {
          ++j;
          if(j != propend && cmSystemTools::IsOn(j->c_str()))
            {
            generated = true;
            }
          }
        else
          {
          ++j;
          }
        if(j == propend)
          {
          errors = "called with incorrect number of arguments.";
          return false;
          }
        propertyPairs.push_back(*j);
        ++j;
        }
      // break out of the loop because j is already == end
      break;
      }
    else
      {
      errors = "called with illegal arguments, maybe missing a "
        "PROPERTIES specifier?";
      return false;
      }
    }

  // now loop over all the files
  for(j= filebeg; j != fileend;++j)
    {
    // get the source file
    cmSourceFile* sf =
      mf->GetOrCreateSource(j->c_str(), generated);
    if(sf)
      {
      // now loop through all the props and set them
      unsigned int k;
      for (k = 0; k < propertyPairs.size(); k = k + 2)
        {
        sf->SetProperty(propertyPairs[k].c_str(),propertyPairs[k+1].c_str());
        }
      }
    }
  return true;
}

