/* bool.cc */

#include "bool.h"

dc_boolean::dc_boolean( const bool b = false ) {
  val = b;
  valid = true;
}

dc_boolean::dc_boolean( const bool b, const string &label, dc_node *parent = nil
			) {
  val = b;
  set_both( label, parent );
}

dc_boolean &dc_boolean::operator=( const bool b ) {
  val = b;
  return *this;
}

dc_boolean &dc_boolean::operator=( dc_data &D ) {
  if( D.type() != Boolean_t ) {
    cerr << "dc_boolean::operator= -- cannot assign " << D.type_string()
	 << " to " << type_string() << "\n";
  } else {
    val = ( ( dc_boolean * )&D )->val;
  }
  if( D.is_temporary() ) delete( &D );
  return *this;
}

dc_boolean &dc_boolean::operator&&( dc_boolean &B ) {
  dc_boolean *result = new dc_boolean( val && B.val );
  if( is_temporary() ) delete( this );
  if( B.is_temporary() ) delete( &B );
  return *result;
}

dc_boolean &dc_boolean::operator||( dc_boolean &B ) {
  dc_boolean *result = new dc_boolean( val || B.val );
  if( is_temporary() ) delete( this );
  if( B.is_temporary() ) delete( &B );
  return *result;
}

dc_boolean &dc_boolean::operator!( void ) {
  dc_boolean *result = new dc_boolean( !val );
  if( is_temporary() ) delete( this );
  return *result;
}

dc_boolean &dc_boolean::operator^( dc_boolean &B ) {
  dc_boolean *result = new dc_boolean( val != B.val );
  if( is_temporary() ) delete( this );
  if( B.is_temporary() ) delete( &B );
  return *result;
}

dc_boolean &dc_boolean::operator==( dc_boolean &B ) {
  dc_boolean *result = new dc_boolean( val == B.val );
  if( is_temporary() ) delete( this );
  if( B.is_temporary() ) delete( &B );
  return *result;
}

dc_boolean &dc_boolean::operator!=( dc_boolean &B ) {
  dc_boolean *result = new dc_boolean( val != B.val );
  if( is_temporary() ) delete( this );
  if( B.is_temporary() ) delete( &B );
  return *result;
}

dc_data &If( dc_boolean &B, dc_data &Then, dc_data &Else ) {
  if( B.val ) {
    if( B.is_temporary() ) delete( &B );
    if( Else.is_temporary() ) delete( &Else );
    return Then;
  } else {
    if( B.is_temporary() ) delete( &B );
    if( Then.is_temporary() ) delete( &Then );
    return Else;
  }
}

ostream &dc_boolean::display_c( ostream &stream = cout ) const {
  if( val )
    stream << "true";
  else
    stream << "false";
  return stream;
}

dc_label *dc_boolean::duplicate( dc_node *parent ) const {
  dc_boolean *dupe = new dc_boolean( val );
  if( !is_temporary() ) {
    if( dupe->set_both( local_label(), parent ) ) {
      delete( dupe );
      return nil;
    }
  }
  dupe->set_visible( is_visible() );
  return ( dc_label * )dupe;
}

istream &operator>>( istream &stream, dc_boolean &B ) {
  string s;
  stream >> s;
  if( s == "1" || s == "true" ) {
    B.val = true;
  } else if( s == "0" || s == "false" ) {
    B.val = false;
  } else {
    cerr << "dc_boolean::operator>> -- warning : bad input \"" << s << "\"\n";
  }
  return stream;
}
