/*============================================================================
  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.
============================================================================*/
#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();}
  private:
    std::string String;
    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
