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

#include "Behavioural/Custom/include/Custom_example.h"
#include "Behavioural/Custom/include/Encryption.h"
#include "Behavioural/Custom/include/Random.h"

namespace morpheo {
namespace behavioural {
namespace custom {

  static encryption::Encryption group_encryption (GROUP_CUSTOM_3,
						  OPERATION_CUSTOM_L_4,
						  OPERATION_CUSTOM_L_8);

  static random::Random         group_random     (GROUP_CUSTOM_7);


#undef  FUNCTION
#define FUNCTION "custom::example_get_valid_group"
  bool example_get_valid_group (uint32_t group)
  {
    switch (group)
      {
      case 26 : // CUSTOM_3
      case 30 : // CUSTOM_7
	{
	  return true;
	  break;
	}
      case 24 : // CUSTOM_1
      case 25 : // CUSTOM_2
      case 27 : // CUSTOM_4
      case 28 : // CUSTOM_5
      case 29 : // CUSTOM_6
      case 31 : // CUSTOM_8
	{
	  break;
	}
      default :
	{
	  throw ERRORMORPHEO(FUNCTION, "Invalid custom group number");
	}
      }

    return false;
  }

#undef  FUNCTION
#define FUNCTION "custom::example_get_nb_register"
  uint32_t example_get_nb_register (uint32_t group)
  {
    switch (group)
      {
      case 26 : // CUSTOM_3
	{
	  return group_encryption.get_nb_register();
	}
      case 30 : // CUSTOM_7
	{
	  return group_random    .get_nb_register();
	}
      case 24 : // CUSTOM_1
      case 25 : // CUSTOM_2
      case 27 : // CUSTOM_4
      case 28 : // CUSTOM_5
      case 29 : // CUSTOM_6
      case 31 : // CUSTOM_8
	{
	  break;
	}
      default :
	{
	  throw ERRORMORPHEO(FUNCTION, "Invalid custom group number");
	}
      }
    
    return 0;
  }

#undef  FUNCTION
#define FUNCTION "custom::example_get_access_mode"
  access_mode_t example_get_access_mode (uint32_t group, uint32_t reg)
  {
    if (reg < example_get_nb_register (group))
      switch (group)
	{
	case 26 : // CUSTOM_3
	  {
	    return group_encryption.get_access_mode(reg);
	  }
	case 30 : // CUSTOM_7
	  {
	    return group_random    .get_access_mode(reg);
	  }
	case 24 : // CUSTOM_1
	case 25 : // CUSTOM_2
	case 27 : // CUSTOM_4
	case 28 : // CUSTOM_5
	case 29 : // CUSTOM_6
	case 31 : // CUSTOM_8
	  {
	    break;
	  }
	default :
	  {
	    throw ERRORMORPHEO(FUNCTION, "Invalid custom group number");
	  }
	}
    return access_mode_t (SPR_ACCESS_MODE_NONE, SPR_ACCESS_MODE_NONE);
  }

#undef  FUNCTION
#define FUNCTION "custom::example_get_custom_decod"
  custom_decod_t *  example_get_custom_decod (Toperation_t operation)
  {
    switch (operation)
      {
      case OPERATION_CUSTOM_L_4    :
      case OPERATION_CUSTOM_L_8    :
	{
	  return group_encryption.get_custom_decod(operation);
	}
      case OPERATION_CUSTOM_L_1    :
      case OPERATION_CUSTOM_L_2    :
      case OPERATION_CUSTOM_L_3    :
      case OPERATION_CUSTOM_L_5    :
      case OPERATION_CUSTOM_L_6    :
      case OPERATION_CUSTOM_L_7    :
      case OPERATION_CUSTOM_LF_1_D :
      case OPERATION_CUSTOM_LF_1_S :
      case OPERATION_CUSTOM_LV_1   :
      case OPERATION_CUSTOM_LV_2   :
      case OPERATION_CUSTOM_LV_3   :
      case OPERATION_CUSTOM_LV_4   :
	{
	  break;
	}
      default :
	{
	  throw ERRORMORPHEO(FUNCTION, "Invalid custom operation");
	}
      }

    return NULL; // unimplemented function

  }

#undef  FUNCTION
#define FUNCTION "custom::example_get_custom_execute_genMoore"
  custom_execute_genMoore_t * example_get_custom_execute_genMoore (Toperation_t operation)
  {
    switch (operation)
      {
      case OPERATION_CUSTOM_L_4    :
      case OPERATION_CUSTOM_L_8    :
	{
	  return group_encryption.get_custom_execute_genMoore(operation);
	}
      case OPERATION_CUSTOM_L_1    :
      case OPERATION_CUSTOM_L_2    :
      case OPERATION_CUSTOM_L_3    :
      case OPERATION_CUSTOM_L_5    :
      case OPERATION_CUSTOM_L_6    :
      case OPERATION_CUSTOM_L_7    :
      case OPERATION_CUSTOM_LF_1_D :
      case OPERATION_CUSTOM_LF_1_S :
      case OPERATION_CUSTOM_LV_1   :
      case OPERATION_CUSTOM_LV_2   :
      case OPERATION_CUSTOM_LV_3   :
      case OPERATION_CUSTOM_LV_4   :
	{
	  break;
	}
      default :
	{
	  throw ERRORMORPHEO(FUNCTION, "Invalid custom operation");
	}
      }

    return &(morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::functionnal_unit::operation_unimplemented); // unimplemented function
  }

#undef  FUNCTION
#define FUNCTION "custom::example_get_custom_execute_transition"
  custom_execute_transition_t * example_get_custom_execute_transition (uint32_t group)
  {
    switch (group)
      {
      case 26 : // CUSTOM_3
	{
	  return group_encryption.get_custom_execute_transition();
	}
      case 30 : // CUSTOM_7
	{
	  return group_random    .get_custom_execute_transition();
	}
      case 24 : // CUSTOM_1
      case 25 : // CUSTOM_2
      case 27 : // CUSTOM_4
      case 28 : // CUSTOM_5
      case 29 : // CUSTOM_6
      case 31 : // CUSTOM_8
	{
	  break;
	}
      default :
	{
	  throw ERRORMORPHEO(FUNCTION, "Invalid custom group number");
	}
      }
    
    return NULL; // unimplemented function
  }

#undef  FUNCTION
#define FUNCTION "custom::example_get_custom_execute_reset"
  custom_execute_transition_t * example_get_custom_execute_reset (uint32_t group)
  {
    switch (group)
      {
      case 26 : // CUSTOM_3
	{
	  return group_encryption.get_custom_execute_reset();
	}
      case 30 : // CUSTOM_7
	{
	  return group_random    .get_custom_execute_reset();
	}
      case 24 : // CUSTOM_1
      case 25 : // CUSTOM_2
      case 27 : // CUSTOM_4
      case 28 : // CUSTOM_5
      case 29 : // CUSTOM_6
      case 31 : // CUSTOM_8
	{
	  break;
	}
      default :
	{
	  throw ERRORMORPHEO(FUNCTION, "Invalid custom group number");
	}
      }
    
    return NULL; // unimplemented function
  }

#undef  FUNCTION
#define FUNCTION "custom::example_get_custom_information"
  custom_information_t example_get_custom_information (uint32_t context)
  {
    // for all context

    custom_information_t info;
    
    info._get_valid_group               = &morpheo::behavioural::custom::example_get_valid_group              ;
    info._get_nb_register               = &morpheo::behavioural::custom::example_get_nb_register              ;
    info._get_access_mode               = &morpheo::behavioural::custom::example_get_access_mode              ;
    info._get_custom_decod              = &morpheo::behavioural::custom::example_get_custom_decod             ;
    info._get_custom_execute_genMoore   = &morpheo::behavioural::custom::example_get_custom_execute_genMoore  ;
    info._get_custom_execute_transition = &morpheo::behavioural::custom::example_get_custom_execute_transition;
    info._get_custom_execute_reset      = &morpheo::behavioural::custom::example_get_custom_execute_reset     ;
    return info;
  }
  
}; // end namespace custom
}; // end namespace behavioural
}; // end namespace morpheo              
