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

#ifndef __cmt_h__
#define __cmt_h__

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

class ArgParser;
class Symbol;
class Tag;

class CmtContext
{
public:

  CmtContext ();
  ~CmtContext ();

  void clear ();
  int initialize ();

  ActionType m_action;
  bool m_build_nmake;
  cmt_string m_cmt_config;
  cmt_string m_cmt_root;
  cmt_string m_cmt_home;
  cmt_string m_cmt_user_context;
  cmt_string m_cmt_site;
  cmt_string m_cmt_version;
  bool m_use_cmt;
  bool m_use_projects;
  
  cmt_string m_current_dir;
  FilePath   m_current_file_path;
  cmt_string m_current_package;
  cmt_string m_current_config;
  cmt_string m_current_path;
  cmt_string m_current_prefix;
  cmt_string m_current_cmtpath;
  cmt_string m_current_offset;
  
  AccessMode m_current_access;
  CmtDirStyle m_current_style;
  CmtStructuringStyle m_current_structuring_style;
  
  cmt_string m_current_tag;
  cmt_string m_current_target;
  cmt_string m_current_version;
  
  //  cmt_string m_extra_tags;
  CmtSystem::cmt_string_vector m_extra_tags;
  CmtSystem::cmt_string_vector m_tags;
  CmtSystem::cmt_string_vector m_tags_add;
  CmtSystem::cmt_string_vector m_tags_remove;

  cmt_string m_configure_error;
  
  bool m_debug;
  
  cmt_string m_default_path;
  bool m_quiet;
  bool m_disable_warnings;
  bool m_warnings;
  bool m_recursive;
  CmtScopeFilteringMode m_scope_filtering_mode;
  bool m_simulation;
  bool m_standard_macros_done;
  bool m_all_sets_done;

  bool m_autoconfigure_cmtpath;

  bool m_env_access;
  PrintMode m_print_mode;
  bool m_strip_path;

private:

  CmtContext& operator = (const CmtContext& other);
  CmtContext (const CmtContext& other);
};

class Cmt
{
public:
  static void build_config (const cmt_string& prefix, cmt_string& config);
  static void build_makefile (const cmt_string& target);
  static void build_msdev_file (const cmt_string& target);
  // Visual Studio.Net Support                            
  static void build_vsnet_file (const cmt_string& target);

  static inline bool build_nmake ();
  static void build_OS9_makefile (const cmt_string& target);
  static void build_prefix (const cmt_string& package, cmt_string& prefix);
  static void clear ();

  //  static void configure ();
  static void configure (const ArgParser& ap);
  static void configure_cmt_path (Use* use);
  static void configure_config_tag ();
  static void configure_current_cmtpath ();
  static void configure_current_dir ();
  static cmt_string configure_current_package ();
  //  static void configure_current_package ();
  //  static void configure_current_structuring_style ();
  static void configure_current_structuring_style (const ArgParser& ap);
  static void configure_default_path ();
  static void configure_home (Use* use);
  static void configure_user_context (Use* use);
  static void configure_hosttype_tag ();
  static void configure_site_tag (Use* use);
  static void configure_tags (Use* use);
  static void configure_uname_tag ();
  static void configure_devenv_tag ();
  static void configure_version_tag ();
  //  static void configure_cmt_message ();
  static void configure_cmt_message (const ArgParser& ap);

  static void do_awk (const ArgParser& ap);
  static void do_broadcast (const ArgParser& ap);
  static void do_build_constituent_makefile (const ArgParser& ap);
  static void do_build_constituent_config (const ArgParser& ap);
  static void do_build_constituents_makefile (const ArgParser& ap);
  static void do_build_constituents_config (const ArgParser& ap);
  static void do_build_broadcast_config (const ArgParser& ap);
  static void do_build_dependencies (const ArgParser& ap,
                                     int argc,
                                     char* argv[]);
  static void do_build_library_links (const ArgParser& ap);
  static void do_build_make_setup (const ArgParser& ap);
  static void do_build_msdev (const ArgParser& ap);
  static void do_build_CMT_pacman (const ArgParser& ap);
  // Visual Studio.Net Support                                               
  static void do_build_vsnet (const ArgParser& ap);

  static void do_build_os9_makefile (const ArgParser& ap);
  static void do_build_prototype (const ArgParser& ap);
  static void do_build_readme (const ArgParser& ap);
  static void do_build_tag_makefile (const ArgParser& ap);
  static void do_build_temporary_name (const ArgParser& ap);
  static void do_build_triggers (const ArgParser& ap);
  static void do_build_windefs (const ArgParser& ap);
  static void do_check_configuration (const ArgParser& ap);
  static void do_check_files (const ArgParser& ap);
  static void do_check_version (const ArgParser& ap);
  static void do_checkout (const ArgParser& ap);
  static void do_cleanup (const ArgParser& ap);
  static void do_config (const ArgParser& ap);
  static void do_create (const ArgParser& ap);
  static void do_create_project (const ArgParser& ap);
  static void do_cvsbranches (const ArgParser& ap);
  static void do_cvssubpackages (const ArgParser& ap);
  static void do_cvssubprojects (const ArgParser& ap);
  static void do_cvstags (const ArgParser& ap);
  static void do_do (const ArgParser& ap);
  static void do_expand_model (const ArgParser& ap);
  static void do_filter       (const ArgParser& ap);
  static void do_help         (const ArgParser& ap);
  static void do_lock         (const ArgParser& ap);
  static void do_relocate     (const ArgParser& ap);
  static void do_remove       (const ArgParser& ap);
  static void do_remove_library_links (const ArgParser& ap);
  static void do_run (const ArgParser& ap);
  static void do_run_sequence (const ArgParser& ap);

  static void do_set_version (const ArgParser& ap);
  static void do_set_versions (const ArgParser& ap);

  static void do_setup (const ArgParser& ap);
  static void do_show_action (const ArgParser& ap);
  static void do_show_action_names (const ArgParser& ap);
  static void do_show_action_value (const ArgParser& ap);
  static void do_show_actions (const ArgParser& ap);
  static void do_show_alias (const ArgParser& ap);
  static void do_show_alias_names (const ArgParser& ap);
  static void do_show_alias_value (const ArgParser& ap);
  static void do_show_aliases (const ArgParser& ap);
  static void do_show_all_tags (const ArgParser& ap);
  static void do_show_applied_patterns (const ArgParser& ap);
  static void do_show_author (const ArgParser& ap);
  static void do_show_branches (const ArgParser& ap);
  static void do_show_clients (const ArgParser& ap);
  static void do_show_cmtpath_patterns (const ArgParser& ap);
  static void do_show_constituent (const ArgParser& ap);
  static void do_show_constituent_names (const ArgParser& ap);
  static void do_show_constituents (const ArgParser& ap);
  static void do_show_container (const ArgParser& ap);
  static void do_show_cycles (const ArgParser& ap);
  static void do_show_fragment (const ArgParser& ap);
  static void do_show_fragments (const ArgParser& ap);
  static void do_show_groups (const ArgParser& ap);
  static void do_show_include_dirs (const ArgParser& ap);
  static void do_show_language (const ArgParser& ap);
  static void do_show_languages (const ArgParser& ap);
  static void do_show_macro (const ArgParser& ap);
  static void do_show_macro_names (const ArgParser& ap);
  static void do_show_macro_value (const ArgParser& ap);
  static void do_show_macros (const ArgParser& ap);
  static void do_show_manager (const ArgParser& ap);
  static void do_show_packages (const ArgParser& ap);
  static void do_show_path (const ArgParser& ap, ostream& out = cout);
  static void do_show_pattern (const ArgParser& ap);
  static void do_show_pattern_names (const ArgParser& ap);
  static void do_show_patterns (const ArgParser& ap);
  static void do_show_projects (const ArgParser& ap);
  static void do_show_project_author (const ArgParser& ap);  
  static void do_show_pwd (const ArgParser& ap);
  static void do_show_setup (const ArgParser& ap, ostream& out = cout);
  static void do_show_set (const ArgParser& ap);
  static void do_show_set_names (const ArgParser& ap);
  static void do_show_set_value (const ArgParser& ap);
  static void do_show_sets (const ArgParser& ap);
  static void do_show_strategies (const ArgParser& ap);
  static void do_show_tags (const ArgParser& ap, ostream& out = cout);
  static void do_show_use_paths (const ArgParser& ap);
  static void do_show_uses (const ArgParser& ap, ostream& out = cout);
  static void do_show_version (const ArgParser& ap);
  static void do_show_versions (const ArgParser& ap);
  static void do_show_system (const ArgParser& ap);
  static void do_unlock (const ArgParser& ap);
  static void do_version (const ArgParser& ap);


  static const cmt_string& filter_dir (const cmt_string& dir);

  static inline ActionType get_action ();

  static inline const cmt_string& get_cmt_home ();
  static inline const cmt_string& get_cmt_user_context ();
  static inline const cmt_string& get_cmt_version ();
  static inline const cmt_string& get_current_dir ();
  static const cmt_string get_current_dir_real ();
  static inline const cmt_string& get_current_package ();
  static const cmt_string& get_current_path ();
  static const cmt_string& get_current_cmtpath ();
  static const cmt_string& get_current_offset ();
  static inline AccessMode get_current_access ();
  static inline CmtStructuringStyle get_current_structuring_style ();
  static inline CmtDirStyle get_current_style ();
  static const cmt_string& get_current_version ();
  static inline const cmt_string& get_current_target ();
  static inline const CmtSystem::cmt_string_vector& get_tags_remove ();
  static inline bool get_debug ();
  static inline bool get_disable_warnings ();  
  static inline bool get_quiet ();
  static inline bool get_warnings ();
  static inline bool get_recursive ();
  static CmtScopeFilteringMode get_scope_filtering_mode ();
  static inline bool get_all_sets_done ();

  static void get_cmt_flags (CmtSystem::cmt_string_vector& flags);
  static cmt_string get_cmt_flags ();
  static cmt_string get_cmt_flags (const cmt_string& file_name);
  static bool set_cmt_flags (const cmt_string& flags);
  static bool add_cmt_flag (const cmt_string& flag);

  /// If a project file exists above the current directory we don't need CMTPATH
  static void guess_current_project ();

  static void install_cleanup_scripts ();
  static void install_setup_scripts ();
  static void install_scripts (ScriptType type, const cmt_string& flags);
  static void install_native_version_file ();
  //  static bool load (const cmt_string& path,
  static bool load (const ArgParser& ap,
		    const cmt_string& path,
                    const cmt_string& package,
                    const cmt_string& version,
                    const cmt_string& tag_name = "");
  static bool need_prototypes ();
  static void parse_arguments (ArgParser& ap);
  static int parser (const cmt_string& command_line);
  static int parser (int argc, char* argv[]);
  static void print (PrintMode mode, ostream& out = cout);
  //static void print (PrintMode mode);
  static void print_clean (PrintMode mode);
  static void print_context (Use& use, PrintMode mode, const cmt_string& tag, ostream& out = cout);
  //static void print_context (Use& use, PrintMode mode, const cmt_string& tag);
  static void print_macros (PrintMode mode, const cmt_string& pattern = "",
			    ostream& out = cout);
  //  static void print_macros (PrintMode mode, const cmt_string& pattern = "");
  static void print_symbol_names (PrintMode mode, const cmt_string& pattern = "");
  static void print_tabs (int tabs);
  static void print_xml_prolog (const cmt_string& root = "cmt", ostream& out = cout);
  //  static int reach_current_package ();
  static int use_current_package ();
  static int use_extra_file (const cmt_string& file);
  static int apply_globals ();
  static void restore_all_tags (Use* use);
  static inline void set_current_access (AccessMode mode);
  static inline void set_recursive (bool mode);
  static inline void set_scope_filtering_mode (CmtScopeFilteringMode mode);
  static void set_standard_macros ();
  static inline void set_all_sets_done ();
  static inline void reset_all_sets_done ();
  static void use_cmt ();
  static void use_home_requirements ();
  static void use_user_context_requirements ();
  static void use_special_requirements (const cmt_string& path, 
					const cmt_string& name, 
					const cmt_string& file_name);
  static cmt_string vector_to_string (const CmtSystem::cmt_string_vector& v);
  static void vector_to_string (const CmtSystem::cmt_string_vector& v,
                                const cmt_string& separator,
                                cmt_string& result);

  static inline const bool& get_env_access ();
  static inline void set_env_access (const bool& access);
  static inline const PrintMode& get_print_mode ();
  static inline void set_print_mode (const PrintMode& mode);
  static inline const bool& get_strip_path ();

private:
  static CmtContext& m_cmt_context;
  //  static CmtContext * m_cmt_context;
};

//----------------------------------------------------------
inline bool Cmt::build_nmake ()
{
  return (m_cmt_context.m_build_nmake);
}

inline ActionType Cmt::get_action ()
{
  return (m_cmt_context.m_action);
}

inline const cmt_string& Cmt::get_cmt_home ()
{
  return (m_cmt_context.m_cmt_home);
}

inline const cmt_string& Cmt::get_cmt_user_context ()
{
  return (m_cmt_context.m_cmt_user_context);
}

inline const cmt_string& Cmt::get_cmt_version ()
{
  return (m_cmt_context.m_cmt_version);
}

inline const cmt_string& Cmt::get_current_dir ()
{
  return (m_cmt_context.m_current_dir);
}

inline const cmt_string& Cmt::get_current_package ()
{
  return (m_cmt_context.m_current_package);
}

inline AccessMode Cmt::get_current_access ()
{
  return (m_cmt_context.m_current_access);
}

inline CmtStructuringStyle Cmt::get_current_structuring_style ()
{
  return (m_cmt_context.m_current_structuring_style);
}

inline CmtDirStyle Cmt::get_current_style ()
{
  return (m_cmt_context.m_current_style);
}

inline const cmt_string& Cmt::get_current_target ()
{
  return (m_cmt_context.m_current_target);
}

inline const CmtSystem::cmt_string_vector& Cmt::get_tags_remove ()
{
  return m_cmt_context.m_tags_remove;
}

inline bool Cmt::get_debug ()
{
  return (m_cmt_context.m_debug);
}

inline bool Cmt::get_quiet ()
{
  return (m_cmt_context.m_quiet);
}

inline bool Cmt::get_disable_warnings ()
{
  return (m_cmt_context.m_disable_warnings);
}

inline bool Cmt::get_warnings ()
{
  return (m_cmt_context.m_warnings);
}

inline bool Cmt::get_recursive ()
{
  return (m_cmt_context.m_recursive);
}

inline bool Cmt::get_all_sets_done ()
{
  return (m_cmt_context.m_all_sets_done);
}

inline void Cmt::set_current_access (AccessMode mode)
{
  m_cmt_context.m_current_access = mode;
}

//----------------------------------------------------------
inline void Cmt::set_recursive (bool mode)
{
  m_cmt_context.m_recursive = mode;
}

//----------------------------------------------------------
inline void Cmt::set_scope_filtering_mode (CmtScopeFilteringMode mode)
{
  m_cmt_context.m_scope_filtering_mode = mode;
}

inline void Cmt::set_all_sets_done ()
{
  m_cmt_context.m_all_sets_done = true;
}

inline void Cmt::reset_all_sets_done ()
{
  m_cmt_context.m_all_sets_done = false;
}

inline const bool& Cmt::get_env_access ()
{
  return m_cmt_context.m_env_access;
}

inline void Cmt::set_env_access (const bool& access)
{
  m_cmt_context.m_env_access = access;
}

inline const PrintMode& Cmt::get_print_mode ()
{
  return m_cmt_context.m_print_mode;
}

inline void Cmt::set_print_mode (const PrintMode& mode)
{
  m_cmt_context.m_print_mode = mode;
}

inline const bool& Cmt::get_strip_path ()
{
  return m_cmt_context.m_strip_path;
}
//----------------------------------------------------------

#endif
