/*
 * $Id$
 *
 * [ Description ]
 * 
 */

#include "Behavioural/include/Signal.h"


namespace morpheo              {
namespace behavioural          {

#undef  FUNCTION
#define FUNCTION "Signal::connect"
  void Signal::connect (Signal * signal_dest)
  {
    log_printf(FUNC,Behavioural,FUNCTION,"Begin");

//     log_printf(TRACE,Behavioural,FUNCTION,"Connection between : %s with %s",get_name().c_str(),signal_dest->get_name().c_str());
//     log_printf(ALL,Behavioural,FUNCTION," * source");
//     log_printf(ALL,Behavioural,FUNCTION,"   * direction : %s",toString(_direction).c_str());
//     log_printf(ALL,Behavioural,FUNCTION,"   * sc_signal : %.8x",_sc_signal);
//     log_printf(ALL,Behavioural,FUNCTION,"   * type_info : %s",toString(_type_info).c_str());
//     log_printf(ALL,Behavioural,FUNCTION," * destination");
//     log_printf(ALL,Behavioural,FUNCTION,"   * direction : %s",toString(signal_dest->_direction).c_str());
//     log_printf(ALL,Behavioural,FUNCTION,"   * sc_signal : %.8x",signal_dest->_sc_signal);
//     log_printf(ALL,Behavioural,FUNCTION,"   * type_info : %s",toString(signal_dest->_type_info).c_str());

    if ((_direction == IN ) and (signal_dest->_direction == IN ))
      switch (_type_info)
	{
	case BOOL     : {(*(static_cast<sc_in  <bool    > *>(_sc_signal))) (*(static_cast<sc_in  <bool    > *>(signal_dest->_sc_signal))); break;}
	case UINT8_T  : {(*(static_cast<sc_in  <uint8_t > *>(_sc_signal))) (*(static_cast<sc_in  <uint8_t > *>(signal_dest->_sc_signal))); break;}
	case UINT16_T : {(*(static_cast<sc_in  <uint16_t> *>(_sc_signal))) (*(static_cast<sc_in  <uint16_t> *>(signal_dest->_sc_signal))); break;}
	case UINT32_T : {(*(static_cast<sc_in  <uint32_t> *>(_sc_signal))) (*(static_cast<sc_in  <uint32_t> *>(signal_dest->_sc_signal))); break;}
	case UINT64_T : {(*(static_cast<sc_in  <uint64_t> *>(_sc_signal))) (*(static_cast<sc_in  <uint64_t> *>(signal_dest->_sc_signal))); break;}
	default       : {throw (ErrorMorpheo ("<Signal::connect> Signal \""+_name+"\" : type unknow.")); break;}
	}
    else
      if ((_direction == IN ) and (signal_dest->_direction == OUT))
	switch (_type_info)
	  {
	  case BOOL     : {(*(static_cast<sc_in  <bool    > *>(_sc_signal))) (*(static_cast<sc_out <bool    > *>(signal_dest->_sc_signal))); break;}
	  case UINT8_T  : {(*(static_cast<sc_in  <uint8_t > *>(_sc_signal))) (*(static_cast<sc_out <uint8_t > *>(signal_dest->_sc_signal))); break;}
	  case UINT16_T : {(*(static_cast<sc_in  <uint16_t> *>(_sc_signal))) (*(static_cast<sc_out <uint16_t> *>(signal_dest->_sc_signal))); break;}
	  case UINT32_T : {(*(static_cast<sc_in  <uint32_t> *>(_sc_signal))) (*(static_cast<sc_out <uint32_t> *>(signal_dest->_sc_signal))); break;}
	  case UINT64_T : {(*(static_cast<sc_in  <uint64_t> *>(_sc_signal))) (*(static_cast<sc_out <uint64_t> *>(signal_dest->_sc_signal))); break;}
	  default       : {throw (ErrorMorpheo ("<Signal::connect> Signal \""+_name+"\" : type unknow.")); break;}
	  }
      else
	if ((_direction == IN ) and (signal_dest->_direction == INTERNAL))
	  switch (_type_info)
	    {
	    case BOOL     : {(*(static_cast<sc_in  <bool    > *>(_sc_signal))) (*(static_cast<sc_signal<bool    > *>(signal_dest->_sc_signal))); break;}
	    case UINT8_T  : {(*(static_cast<sc_in  <uint8_t > *>(_sc_signal))) (*(static_cast<sc_signal<uint8_t > *>(signal_dest->_sc_signal))); break;}
	    case UINT16_T : {(*(static_cast<sc_in  <uint16_t> *>(_sc_signal))) (*(static_cast<sc_signal<uint16_t> *>(signal_dest->_sc_signal))); break;}
	    case UINT32_T : {(*(static_cast<sc_in  <uint32_t> *>(_sc_signal))) (*(static_cast<sc_signal<uint32_t> *>(signal_dest->_sc_signal))); break;}
	    case UINT64_T : {(*(static_cast<sc_in  <uint64_t> *>(_sc_signal))) (*(static_cast<sc_signal<uint64_t> *>(signal_dest->_sc_signal))); break;}
	    default       : {throw (ErrorMorpheo ("<Signal::connect> Signal \""+_name+"\" : type unknow.")); break;}
	    }
	else
#ifdef SYSTEMCASS_SPECIFIC
	  if ((_direction == OUT) and (signal_dest->_direction == IN ))
	    switch (_type_info)
	      {
	      case BOOL     : {(*(static_cast<sc_out <bool    > *>(_sc_signal))) (*(static_cast<sc_in  <bool    > *>(signal_dest->_sc_signal))); break;}
	      case UINT8_T  : {(*(static_cast<sc_out <uint8_t > *>(_sc_signal))) (*(static_cast<sc_in  <uint8_t > *>(signal_dest->_sc_signal))); break;}
	      case UINT16_T : {(*(static_cast<sc_out <uint16_t> *>(_sc_signal))) (*(static_cast<sc_in  <uint16_t> *>(signal_dest->_sc_signal))); break;}
	      case UINT32_T : {(*(static_cast<sc_out <uint32_t> *>(_sc_signal))) (*(static_cast<sc_in  <uint32_t> *>(signal_dest->_sc_signal))); break;}
	      case UINT64_T : {(*(static_cast<sc_out <uint64_t> *>(_sc_signal))) (*(static_cast<sc_in  <uint64_t> *>(signal_dest->_sc_signal))); break;}
	      default       : {throw (ErrorMorpheo ("<Signal::connect> Signal \""+_name+"\" : type unknow.")); break;}
	      }
	  else
#endif
	    if ((_direction == OUT) and (signal_dest->_direction == OUT))
	      switch (_type_info)
		{
		case BOOL     : {(*(static_cast<sc_out <bool    > *>(_sc_signal))) (*(static_cast<sc_out <bool    > *>(signal_dest->_sc_signal))); break;}
		case UINT8_T  : {(*(static_cast<sc_out <uint8_t > *>(_sc_signal))) (*(static_cast<sc_out <uint8_t > *>(signal_dest->_sc_signal))); break;}
		case UINT16_T : {(*(static_cast<sc_out <uint16_t> *>(_sc_signal))) (*(static_cast<sc_out <uint16_t> *>(signal_dest->_sc_signal))); break;}
		case UINT32_T : {(*(static_cast<sc_out <uint32_t> *>(_sc_signal))) (*(static_cast<sc_out <uint32_t> *>(signal_dest->_sc_signal))); break;}
		case UINT64_T : {(*(static_cast<sc_out <uint64_t> *>(_sc_signal))) (*(static_cast<sc_out <uint64_t> *>(signal_dest->_sc_signal))); break;}
		default       : {throw (ErrorMorpheo ("<Signal::connect> Signal \""+_name+"\" : type unknow.")); break;}
		}
	    else
	      if ((_direction == OUT) and (signal_dest->_direction == INTERNAL))
		switch (_type_info)
		  {
		  case BOOL     : {(*(static_cast<sc_out <bool    > *>(_sc_signal))) (*(static_cast<sc_signal<bool    > *>(signal_dest->_sc_signal))); break;}
		  case UINT8_T  : {(*(static_cast<sc_out <uint8_t > *>(_sc_signal))) (*(static_cast<sc_signal<uint8_t > *>(signal_dest->_sc_signal))); break;}
		  case UINT16_T : {(*(static_cast<sc_out <uint16_t> *>(_sc_signal))) (*(static_cast<sc_signal<uint16_t> *>(signal_dest->_sc_signal))); break;}
		  case UINT32_T : {(*(static_cast<sc_out <uint32_t> *>(_sc_signal))) (*(static_cast<sc_signal<uint32_t> *>(signal_dest->_sc_signal))); break;}
		  case UINT64_T : {(*(static_cast<sc_out <uint64_t> *>(_sc_signal))) (*(static_cast<sc_signal<uint64_t> *>(signal_dest->_sc_signal))); break;}
		  default       : {throw (ErrorMorpheo ("<Signal::connect> Signal \""+_name+"\" : type unknow.")); break;}
		  }
// 	      else
// 		if ((_direction == INTERNAL) and (signal_dest->_direction == IN ))
// 		  switch (_type_info)
// 		    {
// 		    case BOOL     : {(*(static_cast<sc_signal<bool    > *>(_sc_signal))) (*(static_cast<sc_in  <bool    > *>(signal_dest->_sc_signal))); break;}
// 		    case UINT8_T  : {(*(static_cast<sc_signal<uint8_t > *>(_sc_signal))) (*(static_cast<sc_in  <uint8_t > *>(signal_dest->_sc_signal))); break;}
// 		    case UINT16_T : {(*(static_cast<sc_signal<uint16_t> *>(_sc_signal))) (*(static_cast<sc_in  <uint16_t> *>(signal_dest->_sc_signal))); break;}
// 		    case UINT32_T : {(*(static_cast<sc_signal<uint32_t> *>(_sc_signal))) (*(static_cast<sc_in  <uint32_t> *>(signal_dest->_sc_signal))); break;}
// 		    case UINT64_T : {(*(static_cast<sc_signal<uint64_t> *>(_sc_signal))) (*(static_cast<sc_in  <uint64_t> *>(signal_dest->_sc_signal))); break;}
// 		    default       : {throw (ErrorMorpheo ("<Signal::connect> Signal \""+_name+"\" : type unknow.")); break;}
// 		    }
// 		else
// 		  if ((_direction == INTERNAL ) and (signal_dest->_direction == OUT))
// 		    switch (_type_info)
// 		      {
// 		      case BOOL     : {(*(static_cast<sc_signal<bool    > *>(_sc_signal))) (*(static_cast<sc_out <bool    > *>(signal_dest->_sc_signal))); break;}
// 		      case UINT8_T  : {(*(static_cast<sc_signal<uint8_t > *>(_sc_signal))) (*(static_cast<sc_out <uint8_t > *>(signal_dest->_sc_signal))); break;}
// 		      case UINT16_T : {(*(static_cast<sc_signal<uint16_t> *>(_sc_signal))) (*(static_cast<sc_out <uint16_t> *>(signal_dest->_sc_signal))); break;}
// 		      case UINT32_T : {(*(static_cast<sc_signal<uint32_t> *>(_sc_signal))) (*(static_cast<sc_out <uint32_t> *>(signal_dest->_sc_signal))); break;}
// 		      case UINT64_T : {(*(static_cast<sc_signal<uint64_t> *>(_sc_signal))) (*(static_cast<sc_out <uint64_t> *>(signal_dest->_sc_signal))); break;}
// 		      default       : {throw (ErrorMorpheo ("<Signal::connect> Signal \""+_name+"\" : type unknow.")); break;}
// 		      }
// 		  else
// 		    if ((_direction == INTERNAL ) and (signal_dest->_direction == INTERNAL))
// 		      switch (_type_info)
// 			{
// 			case BOOL     : {(*(static_cast<sc_signal<bool    > *>(_sc_signal))) (*(static_cast<sc_signal<bool    > *>(signal_dest->_sc_signal))); break;}
// 			case UINT8_T  : {(*(static_cast<sc_signal<uint8_t > *>(_sc_signal))) (*(static_cast<sc_signal<uint8_t > *>(signal_dest->_sc_signal))); break;}
// 			case UINT16_T : {(*(static_cast<sc_signal<uint16_t> *>(_sc_signal))) (*(static_cast<sc_signal<uint16_t> *>(signal_dest->_sc_signal))); break;}
// 			case UINT32_T : {(*(static_cast<sc_signal<uint32_t> *>(_sc_signal))) (*(static_cast<sc_signal<uint32_t> *>(signal_dest->_sc_signal))); break;}
// 			case UINT64_T : {(*(static_cast<sc_signal<uint64_t> *>(_sc_signal))) (*(static_cast<sc_signal<uint64_t> *>(signal_dest->_sc_signal))); break;}
// 			default       : {throw (ErrorMorpheo ("<Signal::connect> Signal \""+_name+"\" : type unknow.")); break;}
// 			}
		    else
		      throw (ErrorMorpheo ("<Signal::connect> Signal \""+_name+"\" can't been connected with signal \""+signal_dest->get_name()+"\" : illegal direction ("+toString(_direction)+" with "+toString(signal_dest->_direction)+")."));

    log_printf(FUNC,Behavioural,FUNCTION,"End");
  };

}; // end namespace behavioural          
}; // end namespace morpheo              
