
#include "cmt_database.h"
#include "cmt_vector.h"

template <class T> 
class dumper
{
public :
  void dump_vector (const cmt_vector<T>& vector, 
                    const cmt_string& title)
      {
        int i;
        
        {
            //const cmt_vector<T>::frame_ptr frame = vector.get_frame ();
          T** frame = vector.get_frame ();
          
          cout << title << " frame=" << frame << " size=" << vector.size () << endl;
          
          int element = 0;
          
          for (i = 0; i < vector.get_frame_number (); i++)
            {
                //cmt_vector<T>::element_ptr ptr = frame[i];
              T* ptr = frame[i];
              for (int j = 0; j < vector.get_frame_size (); j++)
                {
                  element++;
                  if (element >= vector.size ()) break;
                  
                  cout << "   frame[" << i << "][" << j << "]=" << &ptr[j] << endl;
                }
              
              if (element >= vector.size ()) break;
            }
        }
      }
};

Database& Database::instance ()
{
  static Database db;

  return (db);
}

void Database::dump (const cmt_string& title,
                     keys key_set)
{
  static Database& db = instance ();
  static dumper<Branch> branch_dumper;
  static dumper<Constituent> constituent_dumper;
  static dumper<Fragment> fragment_dumper;
  static dumper<Group> group_dumper;
  static dumper<Language> language_dumper;
  static dumper<Pattern> pattern_dumper;
  static dumper<Selector> selector_dumper;
  static dumper<Tag> tag_dumper;
  static dumper<Use> use_dumper;
  static dumper<Symbol> symbol_dumper;

  cout << "Database>-------------" << title << endl;

  if ((key_set & key_branch) != 0) branch_dumper.dump_vector (db.m_branches, "Branches");
  if ((key_set & key_constituent) != 0) constituent_dumper.dump_vector (db.m_constituents, "Constituents");
  if ((key_set & key_fragment) != 0) fragment_dumper.dump_vector (db.m_fragments, "Fragments");
  if ((key_set & key_group) != 0) group_dumper.dump_vector (db.m_groups, "Groups");
  if ((key_set & key_language) != 0) language_dumper.dump_vector (db.m_languages, "Languages");
  if ((key_set & key_pattern) != 0) pattern_dumper.dump_vector (db.m_patterns, "Patterns");
  if ((key_set & key_selector) != 0) selector_dumper.dump_vector (db.m_selectors, "Selectors");
  if ((key_set & key_tag) != 0) tag_dumper.dump_vector (db.m_all_tags, "AllTags");
  if ((key_set & key_use) != 0) use_dumper.dump_vector (db.m_all_uses, "Uses");
  if ((key_set & key_symbol) != 0) symbol_dumper.dump_vector (db.m_symbols, "Symbols");

  cout << "Database>-------------" << endl;
}

void Database::clear ()
{
  Branch::clear_all ();
  Constituent::clear_all ();
  Fragment::clear_all ();
  Group::clear_all ();
  Language::clear_all ();
  Pattern::clear_all ();
  Selector::clear_all ();
  Tag::clear_all ();
  Use::clear_all ();
  Symbol::clear_all ();
}

Branch::BranchVector& Database::branches ()
{
  static Database& db = instance ();

  return (db.m_branches);
}

Constituent::ConstituentVector& Database::constituents ()
{
  static Database& db = instance ();

  return (db.m_constituents);
}

Fragment::FragmentVector& Database::fragments ()
{
  static Database& db = instance ();

  return (db.m_fragments);
}

Group::GroupVector& Database::groups ()
{
  static Database& db = instance ();

  return (db.m_groups);
}

Language::LanguageVector& Database::languages ()
{
  static Database& db = instance ();

  return (db.m_languages);
}

Pattern::PatternVector& Database::patterns ()
{
  static Database& db = instance ();

  return (db.m_patterns);
}

Selector::SelectorVector& Database::selectors ()
{
  static Database& db = instance ();

  return (db.m_selectors);
}

Tag::TagVector& Database::all_tags ()
{
  static Database& db = instance ();

  return (db.m_all_tags);
}

Tag::TagPtrVector& Database::tags ()
{
  static Database& db = instance ();

  return (db.m_tags);
}

Use::UseVector& Database::all_uses ()
{
  static Database& db = instance ();

  return (db.m_all_uses);
}

Use::UsePtrVector& Database::uses ()
{
  static Database& db = instance ();

  return (db.m_uses);
}

Symbol::SymbolVector& Database::symbols ()
{
  static Database& db = instance ();

  return (db.m_symbols);
}

Database::Database ()
{
}

