#ifdef VHDL

#ifndef morpheo_behavioural_Vhdl_h
#define morpheo_behavioural_Vhdl_h

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

#include <stdint.h>
#include <iostream>
#include <list>
#include "Behavioural/include/Environnement.h"
#include "Behavioural/include/Direction.h"
#include "Common/include/ToString.h"
#include "Common/include/Debug.h"
#include "Common/include/ErrorMorpheo.h"

namespace morpheo              {
  namespace behavioural          {

    std::string std_logic        (uint32_t size);
    std::string std_logic_conv   (uint32_t size, std::string   value);
    std::string std_logic_conv   (uint32_t size, uint32_t value);
    std::string std_logic_range  (uint32_t size, uint32_t max , uint32_t min  );
    std::string std_logic_range  (uint32_t max , uint32_t min  );
    std::string std_logic_range  (uint32_t size);
    std::string std_logic_others (uint32_t size, uint32_t cst  );

    class Vhdl
    {
      // -----[ fields ]----------------------------------------------------
    private   : const std::string     _name                         ;

    private   : std::list<std::string>     _list_library_work            ;
    private   : std::list<std::string>     _list_signal                  ;
    private   : std::list<std::string>     _list_type                    ;
    private   : std::list<std::string>     _list_alias                   ;
    private   : std::list<std::string>     _list_port                    ;
    private   : std::list<std::string>     _list_body                    ;

      // -----[ methods ]---------------------------------------------------
    public    :                  Vhdl                        (std::string name);
    public    :                  ~Vhdl                       ();

    public    : void             generate_file               (void);
    public    : void             generate_file               (bool generate_package,
							      bool generate_model  );

    private   : void             generate_file_package       (void);
    private   : void             generate_file_model         (void);

    private   : std::string           get_package                 (uint32_t    depth                 ,
								   std::string      filename              ,
								   std::string      package_name          ,
								   std::string      entity_name           );
    private   : std::string           get_model                   (uint32_t    depth                 ,
								   std::string      filename              ,
								   std::string      entity_name           ,
								   std::string      architecture_name     );
    private   : std::string           get_header                  (uint32_t    depth                 ,
								   std::string      filename              );
    private   : std::string           get_entity                  (uint32_t    depth                 ,
								   std::string      name                  );
    private   : std::string           get_architecture            (uint32_t    depth                 , 
								   std::string      name                  ,
								   std::string      entity_name           );
    private   : std::string           get_component               (uint32_t    depth                 ,
								   std::string      name                  );

    private   : std::string           get_port                    (uint32_t    depth                 );
    public    : void             set_port                    (std::string      name                  ,
							      direction_t direction             ,
							      std::string      type                  );
    public    : void             set_port                    (std::string      name                  ,
							      direction_t direction             ,
							      uint32_t    size                  );
    private   : std::string           get_signal                  (uint32_t    depth                 );
    public    : void             set_signal                  (std::string      name                  ,
							      std::string      type                  );
    public    : void             set_signal                  (std::string      name                  ,
							      uint32_t    signal                );
    public    : void             set_signal                  (std::string      name                  ,
							      std::string      type                  ,
							      std::string      init                  );
    public    : void             set_signal                  (std::string      name                  ,
							      uint32_t    size                  ,
							      std::string      init                  );
    public    : void             set_signal                  (std::string      name                  ,
							      uint32_t    size                  ,
							      uint32_t    init                  );
    public    : void             set_constant                (std::string      name                  ,
							      std::string      type                  ,
							      std::string      init                  );
    public    : void             set_constant                (std::string      name                  ,
							      uint32_t    size                  ,
							      std::string      init                  );
    public    : void             set_constant                (std::string      name                  ,
							      uint32_t    size                  ,
							      uint32_t    init                  );

    private   : std::string           get_type                    (uint32_t    depth                 );
    public    : void             set_type                    (std::string      name                  ,
							      std::string      type                  );
    private   : std::string           get_alias                   (uint32_t    depth                 );
    public    : void             set_alias                   (std::string      name1                 ,
							      std::string      type1                 ,
							      std::string      name2                 ,
							      std::string      range2                );
    public    : void             set_alias                   (std::string      name1                 ,
							      uint32_t    size1                 ,
							      std::string      name2                 ,
							      std::string      range2                );

    public    : std::string           get_list                    (std::list<std::string> liste                ,
								   uint32_t     depth                ,
								   std::string       separator            ,
								   bool         last_separator       );
    public    : void             set_list                    (std::list<std::string> & liste              ,
							      std::string         text               );

    private   : std::string           get_body                    (uint32_t       depth              );
    public    : void             set_body                    (std::string         text               );

    public    : void        set_body_component          (std::string         name_instance      ,
							 std::string         name_component     ,
							 std::list<std::string>   list_port_map      );
    public    : void        set_body_component_port_map (std::list<std::string> & list_port_map      ,
							 std::string         name_port          ,
							 uint32_t       size_port          ,
							 std::string         name_signal        ,
							 uint32_t       size_signal        );

    private   : std::string get_library_ieee            (uint32_t    depth                 );
    private   : std::string get_library_work            (uint32_t    depth                 );
    public    : void        set_library_work            (std::string      package_name          );

    private   : std::string direction_toString          (direction_t direction);
    };

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

#endif
#endif
