/*============================================================================
  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 "cmWhileCommand.h"
#include "cmIfCommand.h"

bool cmWhileFunctionBlocker::
IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
                  cmExecutionStatus &inStatus)
{
  // at end of for each execute recorded commands
  if (!cmSystemTools::Strucmp(lff.Name.c_str(),"while"))
    {
    // record the number of while commands past this one
    this->Depth++;
    }
  else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile"))
    {
    // if this is the endwhile for this while loop then execute
    if (!this->Depth) 
      {
      // Remove the function blocker for this scope or bail.
      cmsys::auto_ptr<cmFunctionBlocker>
        fb(mf.RemoveFunctionBlocker(this, lff));
      if(!fb.get()) { return false; }

      std::string errorString;
    
      std::vector<std::string> expandedArguments;
      mf.ExpandArguments(this->Args, expandedArguments);
      cmake::MessageType messageType;
      bool isTrue = 
        cmIfCommand::IsTrue(expandedArguments,errorString,
                            &mf, messageType);

      while (isTrue)
        {      
        if (errorString.size())
          {
          std::string err = "had incorrect arguments: ";
          unsigned int i;
          for(i =0; i < this->Args.size(); ++i)
            {
            err += (this->Args[i].Quoted?"\"":"");
            err += this->Args[i].Value;
            err += (this->Args[i].Quoted?"\"":"");
            err += " ";
            }
          err += "(";
          err += errorString;
          err += ").";
          mf.IssueMessage(messageType, err);
          if (messageType == cmake::FATAL_ERROR)
            {
            cmSystemTools::SetFatalErrorOccured();
            return true;
            }
          }

        // Invoke all the functions that were collected in the block.
        for(unsigned int c = 0; c < this->Functions.size(); ++c)
          {
          cmExecutionStatus status;
          mf.ExecuteCommand(this->Functions[c],status);
          if (status.GetReturnInvoked())
            {
            inStatus.SetReturnInvoked(true);
            return true;
            }
          if (status.GetBreakInvoked())
            {
            return true;
            }
          if(cmSystemTools::GetFatalErrorOccured() )
            {
            return true;
            }
          }
        expandedArguments.clear();
        mf.ExpandArguments(this->Args, expandedArguments);
        isTrue = 
          cmIfCommand::IsTrue(expandedArguments,errorString,
                              &mf, messageType);
        }
      return true;
      }
    else
      {
      // decrement for each nested while that ends
      this->Depth--;
      }
    }

  // record the command
  this->Functions.push_back(lff);
  
  // always return true
  return true;
}

bool cmWhileFunctionBlocker::
ShouldRemove(const cmListFileFunction& lff, cmMakefile& )
{
  if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile"))
    {
    // if the endwhile has arguments, then make sure
    // they match the arguments of the matching while
    if (lff.Arguments.size() == 0 ||
        lff.Arguments == this->Args)
      {
      return true;
      }
    }
  return false;
}

bool cmWhileCommand
::InvokeInitialPass(const std::vector<cmListFileArgument>& args, 
                    cmExecutionStatus &)
{
  if(args.size() < 1)
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }
  
  // create a function blocker
  cmWhileFunctionBlocker *f = new cmWhileFunctionBlocker();
  f->Args = args;
  this->Makefile->AddFunctionBlocker(f);
  
  return true;
}

