/* root.h */

#ifndef ROOT__H
#define ROOT__H

#include "component.h"
#include "clock.h"
#include "data.h"
#include "modification.h"
#include "default.h"

/* - one dc_root exists which contains a list mapping tags to all non-temporary 
   dc_labels.
   - a root object is a non-temporary dc_label or descendant class whose parent 
   is nil. root objects are contained in the roots label list.

   - the root also contains 
   -- a list of all constraints( elements with a boolean
   function that are considered flagged when their function returns false
   -- a global clock labeled "main_clock"
   */
class dc_element;

const char *const iter_counter_lbl = "main_clock";

struct dc_root {
private:
  void dealloc( void ); /* called by clear and by destructor */
  void alloc( void ); /* called by clear and constructor */
public:
  dc_clock *iter_counter;
  dc_node *default_list;
  dc_element *invalids; /* count of invalid constraints */

  list<tag> constraint_list;
  list<dc_label *> templated_list;
  /* should only be manipulated by dc_component */
  list<dc_component *> template_hash_list;
  list<dc_modification *> mod_list;

  /* maps dc_label addresses to tags.
     ALL non-temporary dc_labels appear in global_list */
  dictionary <tag, dc_label *> tag_list;
  
  /* contains labels of only ROOT components */
  dictionary <string, dc_label *> label_list;

  dc_root();
  ~dc_root();

  void expand( list<dc_label *> & ); /* appends all children ids to list */

  void clear( void ); /* deletes everything, and resets */

  void delete_templated( void );

  int do_mods( void ) const; /* returns # of errors */

  /* called by clocks at end of advance time */
  void end_advance( void );

  friend class dc_modification;
};

extern dc_root root;

extern node nil_node; /* nil node in link_graph */

dc_default *get_default( cstring, dc_node *search_origin );

struct dc_element;

/* allocates a constraint with the given label */
dc_element *add_constraint( const string &label, dc_component *parent );

/* assigns label to implicit constraint */
dc_element *add_constraint( dc_component *parent );

bool remove_constraint( const tag ); /* true on error */

int flag_constraints( void ); /* returns number of false constraints and
				 prints a warning message for each false 
				 constraint */

void list_constraints( ostream & = cout );
void list_failed_constraints( ostream & = cout );

inline void expand( list<dc_label *> &l ) { root.expand( l ); }

inline double advance_time( double dt ) { 
  return root.iter_counter->advance( dt ); }

#include "dep_remove.h"
/* rehash -- call
   for each element in hierarchy
            all element references are relinked
	    all func_calls are relinked
	    all sets are researched
	    clock is reset
	    dependencies are removed
	    return type is checked
	    value is reset to initial if any
	    all component links sources and targets are relinked
	    */
	    
int rehash( void ); /* returns number of dependencies */
int rehash( dep_list &removed ); /* returns number of dependencies, and
				    list returned in removed */

inline int rehash_root( void ) { return rehash(); }

/* remove all templated objects and replace */
int rehash_templates( void );

/* for debugging */
/* outputs all labels to stdout */
void list_labels( ostream &strem = cout, const bool see_all = false );
/* outputs all tags to stdout */ 
void list_tags( ostream &strem = cout, const bool see_all = false ); 

#endif

