#ifndef morpheo_behavioural_Parameters_h
#define morpheo_behavioural_Parameters_h

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

#include <stdint.h>
#include <iostream>
#include <math.h>
#include "Behavioural/include/Environnement.h"
#include "Behavioural/include/Constants.h"
#include "Behavioural/include/Test.h"
#include "Common/include/ErrorMorpheo.h"
#include "Common/include/ToString.h"
#include "Common/include/Log2.h"
#include "Common/include/Debug.h"

namespace morpheo     {
namespace behavioural {

  class Parameters_test
  {
  private   : std::string _component;
  protected : std::string _error;
  protected : std::string _warning;
  protected : std::string _information;

  public    : Parameters_test (std::string component) 
    {
      _component = component;
      _error     = "";
      _warning   = "";
    };
  public    : ~Parameters_test (void) {};

  public    : bool        have_error  (void)            { return (_error.length() != 0);};
  public    : void        error       (std::string str) { _error       += "[   ERROR   ] <" + _component + "> " + str + "\n";}
  public    : void        warning     (std::string str) { _warning     += "[  WARNING  ] <" + _component + "> " + str + "\n";}
  public    : void        information (std::string str) { _information += "[INFORMATION] <" + _component + "> " + str + "\n";}
  public    : std::string print       (void)            { return _error + _warning + _information;};
  };

  // Virtual Class - Interface of each component
  class Parameters
  {
    // -----[ fields ]----------------------------------------------------
  public   : static const uint32_t   _size_instruction            = 32;
  public   : static const uint32_t   _nb_operation                = MAX_OPERATION;
  public   : static const uint32_t   _nb_type                     = MAX_TYPE;
  public   : static const uint32_t   _size_operation              = SIZE_OPERATION;
  public   : static const uint32_t   _size_type                   = SIZE_TYPE;     
  public   : static const uint32_t   _size_exception              = SIZE_EXCEPTION;
  public   : static const uint32_t   _size_exception_use          = SIZE_EXCEPTION_USE;
  public   : static const uint32_t   _size_exception_memory       = SIZE_EXCEPTION_MEMORY;
  public   : static const uint32_t   _size_exception_custom       = SIZE_EXCEPTION_CUSTOM;
  public   : static const uint32_t   _size_exception_alu          = SIZE_EXCEPTION_ALU   ;
  public   : static const uint32_t   _size_exception_decod        = SIZE_EXCEPTION_DECOD ;
  public   : static const uint32_t   _size_exception_ifetch       = SIZE_EXCEPTION_IFETCH;
  public   : static const uint32_t   _size_icache_type            = SIZE_ICACHE_TYPE;
  public   : static const uint32_t   _size_icache_error           = SIZE_ICACHE_ERROR;
  public   : static const uint32_t   _size_dcache_type            = SIZE_DCACHE_TYPE;
  public   : static const uint32_t   _size_dcache_error           = SIZE_DCACHE_ERROR;
  public   : static const uint32_t   _nb_general_register_logic   = 32;
  public   : static const uint32_t   _nb_special_register_logic   = NB_SPR_LOGIC;
  public   : static const uint32_t   _size_general_register_logic = 5;
  public   : static const uint32_t   _size_special_register_logic = LOG2_NB_SPR_LOGIC;
  public   : static const uint32_t   _size_event_state            = SIZE_EVENT_STATE;
  public   : static const uint32_t   _size_event_type             = SIZE_EVENT_TYPE;
  public   : static const uint32_t   _size_branch_state           = SIZE_BRANCH_STATE;
  public   : static const uint32_t   _size_branch_condition       = SIZE_BRANCH_CONDITION;

    // -----[ methods ]---------------------------------------------------
  public   :                          Parameters           (void);
  public   : virtual                 ~Parameters           ();
	
    // methods to print and test parameters
  public   : virtual std::string     print                 (uint32_t depth) = 0;
  public   : virtual Parameters_test msg_error             (void) = 0;

    // methods to generate configuration file
    
    // methods to test
  public   :         void            test                  (void);
  };
}; // end namespace behavioural          
}; // end namespace morpheo              

#endif
