/*
 * $Id: Component_signal_internal.cpp 113 2009-04-14 18:39:12Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/include/Component.h"

namespace morpheo              {
namespace behavioural          {

#undef  FUNCTION
#define FUNCTION "Component::signal_internal"
  Signal * Component::signal_internal (Entity * entity_productor,
				       Signal * signal_productor,
                                       Entity * entity_consumer,
				       Signal * signal_consumer)
  {
    log_printf(FUNC,Behavioural,FUNCTION,"Begin");

    bool productor_is_cosimulation = usage_is_set(entity_productor->get_usage(),USE_COSIMULATION);
    bool consumer_is_cosimulation  = usage_is_set(entity_consumer ->get_usage(),USE_COSIMULATION);
    bool is_cosimulation           = consumer_is_cosimulation or productor_is_cosimulation;
    if (productor_is_cosimulation and consumer_is_cosimulation)
      throw ERRORMORPHEO (FUNCTION,toString(_("Entity \"%s\" and Entity \"%s\" use both cosimulation. It's not supported.\n"),entity_productor->get_name().c_str(),entity_consumer->get_name().c_str()));
    
    // create name of internal's signal
    Entity * entity = (consumer_is_cosimulation)?entity_consumer:entity_productor;
    Signal * signal = (consumer_is_cosimulation)?signal_consumer:signal_productor;

    std::string str_entity = entity->get_name();
    std::string str_signal = signal->get_name();
    
//     UpperCase (str_entity);
//     UpperCase (str_signal);
    
    std::string name_internal = (is_cosimulation)?str_signal:("internal_"+str_entity+"_"+str_signal);
    
    // test if internal's signal exist ... else, create
    Signal * signal_internal = _entity->find_signal (name_internal);
    
    if (signal_internal == NULL)
      {
	// signal don't exist ... create
	log_printf(TRACE,Behavioural,FUNCTION, " * Create an internal signal : \"%s\".",name_internal.c_str());
	
	Interface * interface = _entity->find_interface("");
	
	if (interface == NULL)
	  throw ERRORMORPHEO (FUNCTION,toString(_("Component \"%s\", doesn't have an interface \"\".\n"),_entity->get_name().c_str()));

// 	std::string signame   = entity->get_name()+"_"+signal->get_name();
        std::string signame   = name_internal;
        type_info_t type_info = signal->get_type_info();

	// Signal's creation
	switch (type_info)
	  {
	  case BOOL     : interface->set_signal_internal<bool    >(signame, signal->get_size()); break;
	  case UINT8_T  : interface->set_signal_internal<uint8_t >(signame, signal->get_size()); break;
	  case UINT16_T : interface->set_signal_internal<uint16_t>(signame, signal->get_size()); break;
	  case UINT32_T : interface->set_signal_internal<uint32_t>(signame, signal->get_size()); break;
	  case UINT64_T : interface->set_signal_internal<uint64_t>(signame, signal->get_size()); break;
	  default       :throw (ErrorMorpheo ("Signal \""+name_internal+"\" : type unknow."));
	  }
	
	signal_internal = _entity->find_signal (name_internal);
	
	if (signal_internal == NULL)
	  throw (ErrorMorpheo ("Signal \""+name_internal+"\" : error in creation of internal's signal."));
      }

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

    return signal_internal;
  };

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

