/* component.h */

#ifndef COMPONENT__H
#define COMPONENT__H

#include <iostream.h>
#include "node.h"
#include "user_types.h"
#include <LEDA/set.h>
#include <LEDA/dictionary.h>
#include "timed.h"
#include "buf_info.h"
#include <LEDA/graph.h>

/* dc_component
   - is a timed descendant of dc_node. see timed.h, node.h
   - all elements' parents must be components
   - components have a set of types inhererited by their element children, and
   which may or may not be inherited by sub-components
   */

class dc_component : public dc_node, public dc_timed {
private:
  /* marks beginning and ending of location in parse file */
  buf_info Buffer_Info;

  bool template_rehash_done;

  /* if template_path != "", template_ptr rehashed by search on template_path
     from search.

     otherwise template_ptr not rehashed */
  string template_path;
  dc_component *template_ptr;
  list_item template_hash_li;

  virtual void set_frozen( bool set, tag inheritance_src );
  virtual void set_dormant( bool set, bool inherited );

  bool rehash_template( void );

  /* goes down tree of component children to rehash deepest templates first.
     true on error. argument is maximum depth to search = number of 
     total templated components */
  bool resolve_template( int );
protected:
  node lgraph_node; /* node in link graph.  see links.h */

  dc_component( void ); /* constructor for descendant classes */

  /* set of user_types and inheritances */
  u_type_set uts;

  void child_init( dc_label * );

public:
  dc_component( cstring label, dc_component *parent = nil ); 
  ~dc_component();

  const dc_type sub_type( void ) const { return Component_t; }
  string type_string( void ) const { return "component"; }

  ostream &display( ostream &stream = cout );
  friend ostream &operator<<( ostream &stream, dc_component &C ) {
    return C.display( stream ); 
  }

  bool is_u_type( const user_type u_type ) const
    { return uts.is_type( u_type ); }
  bool is_u_type( const user_type u_type, bool &inh ) const {
    return uts.is_type( u_type, inh ); }
  string list_u_types( void ) const { return uts.list_types(); }
  bool set_u_type( const user_type u_type, const bool inh = false );
  bool set_u_type( cstring, const bool inheritance = false );
  /* bool unset_u_type( user_type u_type ) { return uts.unset_type( u_type ); }
     bool unset_u_type( string type_label ); */

  /* add the inherited user_defined types associated with C to this */
  void inherit_u_types( const dc_component *C ) { uts.inherit( C->uts ); }
  void inherit_u_types( const u_type_set &U ) { uts.inherit( U ); }

  /* does nothing for now */
  bool update( void );

  /* see buf_info.h */
  buf_info &buffer_info( void ) { return Buffer_Info; }

  /* inherited from dc_timed. used to change status */
  void set_frozen( bool set ) { set_frozen( set, tag_error ); }
  void set_dormant( bool set ) { set_dormant( set, false ); }

  /* returns node in link graph defined in link.h */
  const node get_node( void ) const { return lgraph_node; }

  /* rehashes children */
  int rehash( void );

  dc_label *duplicate( dc_node *parent ) const;
  
  /* component will inherit copies of elements and sub-components from template
     during rehash.

     nil value means no template

     loops in templating will cause infinte loop during rehash */
  void set_template( dc_component *Template );
  /* requires rehash_template() before it takes effect */
  void set_template( cstring tpath );

  dc_component *get_template( void ) const { return template_ptr; }
  
  friend class dc_clock;
  friend int rehash_templates( void );
  friend void clear_thlist( void );
};

#endif
