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

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmCommandArgumentsHelper.h,v $
  Language:  C++
  Date:      $Date: 2012/03/29 17:21:09 $
  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.

=========================================================================*/
#ifndef cmCommandArgumentsHelper_h
#define cmCommandArgumentsHelper_h

#include "cmStandardIncludes.h"

class cmCommandArgumentsHelper;
class cmCommandArgumentGroup;

/* cmCommandArgumentsHelper, cmCommandArgumentGroup and cmCommandArgument (i.e.
its derived classes cmCAXXX can be used to simplify the processing of 
arguments to cmake commands. Maybe they can also be used to generate
documentation.

For every argument supported by a command one cmCommandArgument is created
and added to cmCommandArgumentsHelper. cmCommand has a cmCommandArgumentsHelper
as member variable so this should be used.

The order of the arguments is defined using the Follows(arg) method. It says 
that this argument follows immediateley the given argument. It can be used
with multiple arguments if the argument can follow after different arguments.

Arguments can be arranged in groups using cmCommandArgumentGroup. Every 
member of a group can follow any other member of the group. These groups
can also be used to define the order.

Once all arguments and groups are set up, cmCommandArgumentsHelper::Parse()
is called and afterwards the values of the arguments can be evaluated.

For an example see cmExportCommand.cxx.
*/
class cmCommandArgument
{
  public:
    cmCommandArgument(cmCommandArgumentsHelper* args, 
                      const char* key, 
                      cmCommandArgumentGroup* group=0);
    virtual ~cmCommandArgument() {}

    /// this argument may follow after arg. 0 means it comes first.
    void Follows(const cmCommandArgument* arg);

    /// this argument may follow after any of the arguments in the given group
    void FollowsGroup(const cmCommandArgumentGroup* group);

    /// Returns true if the argument was found in the argument list
    bool WasFound() const                             {return this->WasActive;}

    // The following methods are only called from 
    // cmCommandArgumentsHelper::Parse(), but making this a friend would 
    // give it access to everything

    /// Make the current argument the currently active argument
    void Activate();
    /// Consume the current string
    bool Consume(const std::string& arg);

    /// Return true if this argument may follow after the given argument.
    bool MayFollow(const cmCommandArgument* current) const;

    /** Returns true if the given key matches the key for this argument.
    If this argument has an empty key everything matches. */
    bool KeyMatches(const std::string& key) const;

    /// Make this argument follow all members of the own group
    void ApplyOwnGroup();

    /// Reset argument, so it's back to its initial state
    void Reset();
  private:
    const char* Key;
    std::set<const cmCommandArgument*> ArgumentsBefore;
    cmCommandArgumentGroup* Group;
    bool WasActive;
    bool ArgumentsBeforeEmpty;
    unsigned int CurrentIndex;

    virtual bool DoConsume(const std::string& arg, unsigned int index) = 0;
    virtual void DoReset() = 0;
};

/** cmCAStringVector is to be used for arguments which can consist of more 
than one string, e.g. the FILES argument in INSTALL(FILES f1 f2 f3 ...). */
class cmCAStringVector : public cmCommandArgument
{
  public:
    cmCAStringVector(cmCommandArgumentsHelper* args, 
                     const char* key, 
                     cmCommandArgumentGroup* group=0);

    /// Return the vector of strings
    const std::vector<std::string>& GetVector() const    {return this->Vector;}

    /** Is there a keyword which should be skipped in 
    the arguments (e.g. ARGS for ADD_CUSTOM_COMMAND) ? */
    void SetIgnore(const char* ignore)                   {this->Ignore=ignore;}
  private:
    std::vector<std::string> Vector;
    unsigned int DataStart;
    const char* Ignore;
    cmCAStringVector();
    virtual bool DoConsume(const std::string& arg, unsigned int index);
    virtual void DoReset();
};

/** cmCAString is to be used for arguments which consist of one value,
e.g. the executable name in ADD_EXECUTABLE(). */
class cmCAString : public cmCommandArgument
{
  public:
    cmCAString(cmCommandArgumentsHelper* args, 
               const char* key, 
               cmCommandArgumentGroup* group=0);

    /// Return the string
    const std::string& GetString() const                 {return this->String;}
    const char* GetCString() const               {return this->String.c_str();}
    void SetDefaultString(const char* text)
                                    {this->DefaultString = (text ? text : "");}
  private:
    std::string String;
    std::string DefaultString;
    unsigned int DataStart;
    virtual bool DoConsume(const std::string& arg, unsigned int index);
    virtual void DoReset();
    cmCAString();
};

/** cmCAEnabler is to be used for options which are off by default and can be
enabled using a special argument, e.g. EXCLUDE_FROM_ALL in ADD_EXECUTABLE(). */
class cmCAEnabler : public cmCommandArgument
{
  public:
    cmCAEnabler(cmCommandArgumentsHelper* args, 
                const char* key, 
                cmCommandArgumentGroup* group=0);

    /// Has it been enabled ?
    bool IsEnabled() const                              {return this->Enabled;}
  private:
    bool Enabled;
    virtual bool DoConsume(const std::string& arg, unsigned int index);
    virtual void DoReset();
    cmCAEnabler();
};

/** cmCADisable is to be used for options which are on by default and can be
disabled using a special argument.*/
class cmCADisabler : public cmCommandArgument
{
  public:
    cmCADisabler(cmCommandArgumentsHelper* args, 
                 const char* key, 
                 cmCommandArgumentGroup* group=0);

    /// Is it still enabled ?
    bool IsEnabled() const                              {return this->Enabled;}
  private:
    bool Enabled;
    virtual bool DoConsume(const std::string& arg, unsigned int index);
    virtual void DoReset();
    cmCADisabler();
};


/** Group of arguments, needed for ordering. E.g. WIN32, EXCLUDE_FROM_ALL and 
MACSOX_BUNDLE from ADD_EXECUTABLE() are a group.
*/
class cmCommandArgumentGroup
{
  friend class cmCommandArgument;
  public:
    cmCommandArgumentGroup() {}

    /// All members of this group may follow the given argument
    void Follows(const cmCommandArgument* arg);

    /// All members of this group may follow all members of the given group
    void FollowsGroup(const cmCommandArgumentGroup* group);
  private:
    std::vector<cmCommandArgument*> ContainedArguments;
};

class cmCommandArgumentsHelper
{
  public:
    /// Parse the argument list
    void Parse(const std::vector<std::string>* args, 
               std::vector<std::string>* unconsumedArgs);
    /// Add an argument.
    void AddArgument(cmCommandArgument* arg);
  private:
    std::vector<cmCommandArgument*> Arguments;
};


#endif
