#ifndef ENVIRONMENT_PARAMETERS_H
#define ENVIRONMENT_PARAMETERS_H

#include "../Cache/include/Cache_Parameters.h"
#include "../Data/include/Data_Parameters.h"
#include "../Queue/include/Parameters.h"
#include "../TTY/include/TTY_Parameters.h"
#include "../RamLock/include/RamLock_Parameters.h"
#include "../Sim2OS/include/Sim2OS_Parameters.h"

namespace environment {

  class Parameters
  {
  public : uint32_t    nb_iport;
  public : uint32_t    nb_dport;
  public : uint32_t    nb_entity;
  public : uint32_t  * icache_dedicated_nb_port;
  public : uint32_t  * dcache_dedicated_nb_port;

  public : uint32_t  * iaccess_nb_context    ;
  public : uint32_t  * iaccess_nb_packet     ;
  public : uint32_t  * iaccess_size_address  ;
  public : uint32_t  * iaccess_nb_instruction;
  public : uint32_t  * iaccess_size_instruction;

  public : uint32_t  * daccess_nb_context    ;
  public : uint32_t  * daccess_nb_packet     ;
  public : uint32_t  * daccess_size_address  ;
  public : uint32_t  * daccess_size_data     ;

    // Parameters cache
  public : cache::Parameters                     * param_cache;
    // Parameters tty
  public : uint32_t                                nb_component_tty;
  public : uint32_t                              * tty_address;
  public : tty::Parameters                      ** param_tty;
    // Parameters ramlock
  public : uint32_t                                nb_component_ramlock;
  public : uint32_t                              * ramlock_address;
  public : ramlock::Parameters                  ** param_ramlock;
    // Parameters sim2OS
  public : uint32_t                                sim2os_address;
  public : uint32_t                                sim2os_size;
  public : sim2os::Parameters                    * param_sim2os;
    // Parameters data
  public : data::Parameters                      * param_data;

    // Parameters buffer_respons
  public : queue::Parameters                    ** param_buffer_irsp;
  public : queue::Parameters                    ** param_buffer_drsp;

  public : Parameters (// General
		       uint32_t    nb_cache_dedicated,
		       
		       uint32_t  * iaccess_nb_context,
		       uint32_t  * iaccess_nb_instruction,
		       uint32_t  * iaccess_nb_packet,
		       uint32_t  * iaccess_size_address,
		       uint32_t  * iaccess_size_instruction,

		       uint32_t  * daccess_nb_context,
		       uint32_t  * daccess_nb_packet,
		       uint32_t  * daccess_size_address,
		       uint32_t  * daccess_size_data,

		       // buffer
		       uint32_t  * buffer_irsp_size,
		       uint32_t  * buffer_drsp_size,
		       
		       // Cache
		       uint32_t  * icache_dedicated_nb_level     ,
		       uint32_t  * icache_dedicated_nb_port      ,
		       uint32_t ** icache_dedicated_nb_line      ,
		       uint32_t ** icache_dedicated_size_line    ,
		       uint32_t ** icache_dedicated_size_word    ,
		       uint32_t ** icache_dedicated_associativity,
		       uint32_t ** icache_dedicated_hit_latence  ,
		       uint32_t ** icache_dedicated_miss_penality,
		       uint32_t  * dcache_dedicated_nb_level     ,
		       uint32_t  * dcache_dedicated_nb_port      ,
		       uint32_t ** dcache_dedicated_nb_line      ,
		       uint32_t ** dcache_dedicated_size_line    ,
		       uint32_t ** dcache_dedicated_size_word    ,
		       uint32_t ** dcache_dedicated_associativity,
		       uint32_t ** dcache_dedicated_hit_latence  ,
		       uint32_t ** dcache_dedicated_miss_penality,
		       uint32_t    cache_shared_nb_level         ,
// 		       uint32_t    cache_shared_nb_port          ,
		       uint32_t  * cache_shared_nb_line          ,
		       uint32_t  * cache_shared_size_line        ,
		       uint32_t  * cache_shared_size_word        ,
		       uint32_t  * cache_shared_associativity    ,
		       uint32_t  * cache_shared_hit_latence      ,
		       uint32_t  * cache_shared_miss_penality    ,

		       // TTY
		       uint32_t       nb_component_tty,
		       uint32_t     * tty_address,
		       uint32_t     * nb_tty,
		       std::string ** name_tty,
		       bool           with_xtty,

		       // RAMLOCK
		       uint32_t       nb_component_ramlock,
		       uint32_t     * ramlock_address,
		       uint32_t     * nb_lock,

		       // SIM2OS
		       uint32_t       sim2os_address,
		       uint32_t       sim2os_size,
		       SOCLIB_SEGMENT_TABLE * segment_table
		       )
    {
      this->nb_entity                = nb_cache_dedicated;

      this->icache_dedicated_nb_port = icache_dedicated_nb_port;
      this->dcache_dedicated_nb_port = dcache_dedicated_nb_port;

      this->iaccess_nb_context       = iaccess_nb_context      ;
      this->iaccess_nb_instruction   = iaccess_nb_instruction  ;
      this->iaccess_nb_packet        = iaccess_nb_packet       ;
      this->iaccess_size_address     = iaccess_size_address    ;
      this->iaccess_size_instruction = iaccess_size_instruction;
      this->daccess_nb_context       = daccess_nb_context      ;
      this->daccess_nb_packet        = daccess_nb_packet       ;
      this->daccess_size_address     = daccess_size_address    ;
      this->daccess_size_data        = daccess_size_data       ;

      param_cache = new cache::Parameters
	(nb_cache_dedicated            ,
	 icache_dedicated_nb_level     ,
	 icache_dedicated_nb_port      ,
	 icache_dedicated_nb_line      ,
	 icache_dedicated_size_line    ,
	 icache_dedicated_size_word    ,
	 icache_dedicated_associativity,
	 icache_dedicated_hit_latence  ,
	 icache_dedicated_miss_penality,
	 dcache_dedicated_nb_level     ,
	 dcache_dedicated_nb_port      ,
	 dcache_dedicated_nb_line      ,
	 dcache_dedicated_size_line    ,
	 dcache_dedicated_size_word    ,
	 dcache_dedicated_associativity,
	 dcache_dedicated_hit_latence  ,
	 dcache_dedicated_miss_penality,
	 cache_shared_nb_level         ,
// 	 cache_shared_nb_port          ,
	 cache_shared_nb_line          ,
	 cache_shared_size_line        ,
	 cache_shared_size_word        ,
	 cache_shared_associativity    ,
	 cache_shared_hit_latence      ,
	 cache_shared_miss_penality    
	 );

      nb_iport = 0;
      nb_dport = 0;
      for (uint32_t i=0; i<nb_cache_dedicated; i++)
	{
	  nb_iport += icache_dedicated_nb_port [i];
	  nb_dport += dcache_dedicated_nb_port [i];
	}

      this->nb_component_tty = nb_component_tty;
      this->tty_address      = tty_address;
      
      param_tty = new tty::Parameters * [nb_component_tty];
      for (uint32_t i=0; i<nb_component_tty; i++)
	{
	  uint32_t tty_size = nb_tty [i] * 16; // 4 32bit-register by tty

// 	  std::ostringstream str("");
// 	  str << "tty_" << i;
	  segment_table->addSegment("tty",tty_address[i],tty_size,0,0,true);

	  param_tty [i] = new tty::Parameters (nb_tty    [i],
					       name_tty  [i],
					       with_xtty    );
	}

      this->nb_component_ramlock = nb_component_ramlock;
      this->ramlock_address      = ramlock_address;
      
      param_ramlock = new ramlock::Parameters * [nb_component_ramlock];
      for (uint32_t i=0; i<nb_component_ramlock; i++)
	{
	  uint32_t ramlock_size = nb_lock[i]; // registre 8 bits because it's min size access
// 	  std::ostringstream str ("");
// 	  str << "ramlock" << i;
	  segment_table->addSegment("ramlock",ramlock_address[i],ramlock_size,0,0,true);

	  param_ramlock [i] = new ramlock::Parameters (nb_lock [i]);
	}

      this->sim2os_address       = sim2os_address      ;
      this->sim2os_size          = sim2os_size         ;

      segment_table->addSegment("sim2os",sim2os_address,sim2os_size,0,0,true);
      param_sim2os = new sim2os::Parameters (segment_table);

      param_data   = new data::Parameters (16,0,0, segment_table);

      param_buffer_irsp = new queue::Parameters * [nb_entity];
      for (uint32_t i=0; i<nb_entity; i++)
	param_buffer_irsp [i] = new queue::Parameters (buffer_irsp_size [i]);

      param_buffer_drsp = new queue::Parameters * [nb_entity];
      for (uint32_t i=0; i<nb_entity; i++)
	param_buffer_drsp [i] = new queue::Parameters (buffer_drsp_size [i]);
    }

  public : ~Parameters (void)
    {
      for (uint32_t i=0; i<nb_entity; i++)
	delete param_buffer_irsp [i];
      delete [] param_buffer_irsp;

      for (uint32_t i=0; i<nb_entity; i++)
	delete param_buffer_drsp [i];
      delete [] param_buffer_drsp;

      delete param_data  ;
      delete param_sim2os;
      for (uint32_t i=0; i<nb_component_ramlock; i++)
	delete param_ramlock [i];
      delete [] param_ramlock;
      for (uint32_t i=0; i<nb_component_tty; i++)
	delete param_tty [i];
      delete [] param_tty;
      delete param_cache;
    }
  };

};
#endif
