//-----------------------------------------------------------
// Copyright Christian Arnault LAL-Orsay CNRS
// arnault@lal.in2p3.fr
// See the complete license in cmt_license.txt "http://www.cecill.info". 
//-----------------------------------------------------------

#ifndef __cmt_pattern_h__
#define __cmt_pattern_h__

#include "cmt_map.h"
#include "cmt_parser.h"
#include "cmt_system.h"

class Use;

class Template
{
public:
  typedef cmt_vector<Template> TemplateVector;
  cmt_string name;
  cmt_string value;
};

class Pattern
{
public:
  typedef cmt_vector<Pattern> PatternVector;
  typedef cmt_vector<Pattern*> PatternPtrVector;

  static void action (const CmtSystem::cmt_string_vector& words, Use* use);

  static Pattern* find (const cmt_string& name);
  static Pattern* find (const cmt_string& name, Use* use);
  static void add (const cmt_string& name,
                   const CmtSystem::cmt_string_vector& words,
                   int start_index,
                   bool global,
                   Use* use);

  static int pattern_number ();
  static Pattern& pattern (int index);
  static void clear_all ();
  static PatternVector& patterns ();

  static void apply_all_globals ();
  static void apply_all_globals (Use* use);
  static void show_all_names ();
  static void show_all ();
  static void show_all_applied_patterns ();
  static void show (const cmt_string& name);

public:
  Pattern ();
  ~Pattern ();

  void clear ();
  void apply () const;
  void apply (Use* constext_use) const;
  void apply (Use* constext_use,
              const Template::TemplateVector& templates) const;
  void expand (Use* constext_use,
               const Template::TemplateVector& templates,
               cmt_string& line) const;
  void show () const;

  cmt_string name;
  cmt_string line;
  bool global;
  Use* use;
};

class PatternList
{
public:

  typedef cmt_map<cmt_string, PatternList> PatternListMap;
  typedef cmt_vector<PatternList> PatternListVector;

  static PatternList* find (const cmt_string& name);
  static Pattern* find_pattern (const cmt_string& name);
  static Pattern* find (const cmt_string& name, Use* use);

  static PatternList* add (const cmt_string& name);

  static void clear_all ();
  static PatternListMap& pattern_list_map ();
  static PatternListVector& pattern_lists ();

  static void apply_all_globals ();
  static void apply_all_globals (Use* use);
  static void show_all_patterns ();
  static void show_all_pattern_names ();

public:
  PatternList ();
  PatternList (const cmt_string& name);
  ~PatternList ();

  Pattern::PatternPtrVector& get_patterns ();

  void add_pattern (Pattern* pattern);

  void clear ();

  cmt_string m_name;
  Pattern::PatternPtrVector m_patterns;
};

class ApplyPattern
{
public:
  typedef cmt_vector<ApplyPattern> ApplyPatternVector;

  static void action (const CmtSystem::cmt_string_vector& words,
                      Use* use);

  static ApplyPattern* add (const cmt_string& name, Use* use);

public:
  ApplyPattern ();
  ~ApplyPattern ();

  void show () const;
  void apply_globals () const;
  void apply () const;

  cmt_string name;
  Use* use;
  cmt_vector<Template> replacements;
};

class IgnorePattern
{
public:
  typedef cmt_vector<IgnorePattern> IgnorePatternVector;

  static void action (const CmtSystem::cmt_string_vector& words, Use* use);

  static IgnorePattern* find (const cmt_string& name, Use* use);
  static void add (const cmt_string& name, Use* use);

public:
  IgnorePattern ();
  ~IgnorePattern ();

  void show () const;

  cmt_string name;
  Use* use;
};

#endif
