/*============================================================================
  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
