/* pipe.cc */

#include "pipe.h"
#include "signal_change.h"

dc_pipe::dc_pipe( void ) {
  direction = false;
  pipe_type = undef_cpt;
}

dc_pipe::dc_pipe( cpipe_type cpt, const string &label, 
		  dc_component *parent ) {
  direction = false;
  set_both( label, parent );
  pipe_type = undef_cpt;

  set_pipe_type( cpt );
}

void dc_pipe::reset( void ) {
  dc_element::reset();
  direction = !is_simple() || is_inited();
  /*cerr << "dc_pipe::reset -- " << label() << ", direction = " << direction
    << "\n";*/
}

bool dc_pipe::update( void ) {
  double lt;
  if( clock && ( lt = clock->t() ) > time ) {
    if( force_update() ) {
      signal_update_error( this );
      return true;
    }

    if( !pipe_table[pipe_type].valid( ( dc_component * )get_parent() ) ) {
      signal_update_error( this );
      return true;
    }
    
    if( direction ) {
      dc_data *n = get_previous();
      if( !n || pipe_table[pipe_type].set( *this, *n ) ) {
	signal_update_error( this );	
	return true;
      }
      dc_trace( TRACE_MANY ) {
	cerr << "dc_pipe::update -- set " << full_type() << " to " << *n 
	     << "\n";
      }
      direction = !is_simple();
    } else {
      dc_data *n = pipe_table[pipe_type].get( *this );
      if( n == nil ) {
	signal_update_error( this );
	return true;
      }
      dc_element::set( *n );
    }
    time = lt;
    signal_update( this );
  }

  return false;
}

bool dc_pipe::set_pipe_type( cpipe_type t ) {
  if( pipe_table[t].valid( ( dc_component * )get_parent() ) ) {
    pipe_type = t;
    direction = true;
    return false;
  }
  return true;
}

bool dc_pipe::set( dc_data &d ) {
  if( dc_element::set( d ) ) return true;
  direction = true;
  return false;
}

