#include "Behavioural/include/Usage.h"
#include "Common/include/Debug.h"
#include "Common/include/ErrorMorpheo.h"

namespace morpheo {
namespace behavioural {

#ifdef MODELSIM_COSIMULATION
  Tusage_t usage_cosimulation(Tusage_t usage)
  {
    Tusage_t _return = usage;
//  _return = usage_unset(_return,USE_SYSTEMC              );
    _return = usage_unset(_return,USE_SYSTEMC_INTERFACE    );
    _return = usage_unset(_return,USE_SYSTEMC_BODY         );
    _return = usage_unset(_return,USE_VHDL                 );
    _return = usage_unset(_return,USE_VHDL_TESTBENCH       );
    _return = usage_unset(_return,USE_VHDL_TESTBENCH_ASSERT);
//  _return = usage_unset(_return,USE_POSITION             );
    _return = usage_unset(_return,USE_STATISTICS           );
//  _return = usage_unset(_return,USE_INFORMATION          );
//  _return = usage_unset(_return,USE_HEADER               );
    _return = usage_set  (_return,USE_COSIMULATION         );
    
    return _return;
  }
#endif

  Tusage_t usage_set         (Tusage_t usage, Tusage_t flag)
  {
    return  ( usage | flag);
  }

  Tusage_t usage_unset       (Tusage_t usage, Tusage_t flag)
  {
    return ~(~usage | flag);
  }  

  bool     usage_is_set      (Tusage_t usage, Tusage_t flag)
  {
    return ((usage & flag) != 0);
  }
#undef  FUNCTION
#define FUNCTION "usage_environment"
  Tusage_t usage_environment (Tusage_t usage)
  {
#ifndef SYSTEMC
    if (usage_is_set(usage,USE_SYSTEMC_INTERFACE))
      throw ERRORMORPHEO(FUNCTION,_("Component use the flag \"USE_SYSTEMC_INTERFACE\", but the macro's compiler \"SYSTEMC\" is unset.\n"));
    if (usage_is_set(usage,USE_SYSTEMC_BODY))
      throw ERRORMORPHEO(FUNCTION,_("Component use the flag \"USE_SYSTEMC_BODY\", but the macro's compiler \"SYSTEMC\" is unset.\n"));
#endif
#ifndef VHDL
    if (usage_is_set(usage,USE_VHDL))
      throw ERRORMORPHEO(FUNCTION,_("Component use the flag \"USE_VHDL\", but the macro's compiler \"VHDL\" is unset.\n"));
#endif
#ifndef VHDL_TESTBENCH
    if (usage_is_set(usage,USE_VHDL_TESTBENCH))
      throw ERRORMORPHEO(FUNCTION,_("Component use the flag \"USE_VHDL_TESTBENCH\", but the macro's compiler \"VHDL_TESTBENCH\" is unset.\n"));
#endif
#ifndef VHDL_TESTBENCH_ASSERT
    if (usage_is_set(usage,USE_VHDL_TESTBENCH_ASSERT))
      throw ERRORMORPHEO(FUNCTION,_("Component use the flag \"USE_VHDL_TESTBENCH_ASSERT\", but the macro's compiler \"VHDL_TESTBENCH_ASSERT\" is unset.\n"));
#endif
#ifndef POSITION
    if (usage_is_set(usage,USE_POSITION))
      throw ERRORMORPHEO(FUNCTION,_("Component use the flag \"USE_POSITION\", but the macro's compiler \"POSITION\" is unset.\n"));
#endif
#ifndef STATISTICS
    if (usage_is_set(usage,USE_STATISTICS))
      throw ERRORMORPHEO(FUNCTION,_("Component use the flag \"USE_STATISTICS\", but the macro's compiler \"STATISTICS\" is unset.\n"));
#endif
// #ifndef INFORMATION
//     if (usage_is_set(usage,USE_INFORMATION))
//       throw ERRORMORPHEO(FUNCTION,_("Component use the flag \"USE_INFORMATION\", but the macro's compiler \"INFORMATION\" is unset.\n"));
// #endif

#ifndef DEBUG
#endif

    if (usage_is_set(usage,USE_STATISTICS) and not usage_is_set(usage,USE_SYSTEMC_BODY))
      throw ERRORMORPHEO(FUNCTION,_("Usage flags conflit : to use the statistics, you must set flag USE_SYSTEMC_BODY\n"));
    
//     if (usage_is_set(usage,USE_INFORMATION) and not usage_is_set(usage,USE_STATISTICS))
//       throw ERRORMORPHEO(FUNCTION,_("Usage flags conflit : to use the information, you must set flag USE_STATISTICS\n"));
    
    if (usage_is_set(usage,USE_VHDL_TESTBENCH) and not usage_is_set(usage,USE_SYSTEMC_BODY))
      throw ERRORMORPHEO(FUNCTION,_("Usage flags conflit : to use the vhdl's test bench, you must set flag USE_SYSTEMC_BODY\n"));
    
    if (usage_is_set(usage,USE_VHDL_TESTBENCH) and not usage_is_set(usage,USE_VHDL))
      throw ERRORMORPHEO(FUNCTION,_("Usage flags conflit : to use the vhdl's test bench, you must set flag USE_VHDL\n"));
    
    if (usage_is_set(usage,USE_VHDL_TESTBENCH_ASSERT) and not usage_is_set(usage,USE_VHDL_TESTBENCH))
      throw ERRORMORPHEO(FUNCTION,_("Usage flags conflit : to use an assert in vhdl's test bench, you must set flag USE_VHDL_TESTBENCH\n"));

    return usage;
  }

  Tusage_t usage_all (void)
  {
    Tusage_t usage = USE_NONE;

#ifdef SYSTEMC
    usage = usage_set(usage,USE_SYSTEMC_INTERFACE);
    usage = usage_set(usage,USE_SYSTEMC_BODY);
#endif
#ifdef VHDL
    usage = usage_set(usage,USE_VHDL);
#endif
#ifdef VHDL_TESTBENCH
    usage = usage_set(usage,USE_VHDL_TESTBENCH);
#endif
#ifdef VHDL_TESTBENCH_ASSERT
    usage = usage_set(usage,USE_VHDL_TESTBENCH_ASSERT);
#endif
#ifdef POSITION
    usage = usage_set(usage,USE_POSITION);
#endif
#ifdef STATISTICS
    usage = usage_set(usage,USE_STATISTICS);
#endif
// #ifdef INFORMATION
//     usage = usage_set(usage,USE_INFORMATION);
// #endif
    usage = usage_set(usage,USE_HEADER);
#ifdef DEBUG
#endif
    
    return usage;
  }


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