#ifndef morpheo_behavioural_Interface_h
#define morpheo_behavioural_Interface_h

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

#ifdef SYSTEMC
#include "systemc.h"
#endif

#include <stdint.h>
#include <iostream>
#include <list>
#include "Behavioural/include/Signal.h"
#include "Behavioural/include/Direction.h"
#include "Behavioural/include/Localisation.h"
#ifdef VHDL
#include "Behavioural/include/Vhdl.h"
#endif
#ifdef VHDL_TESTBENCH
#include "Behavioural/include/Vhdl_Testbench.h"
#endif
#include "Include/ToString.h"
#include "Include/ErrorMorpheo.h"
#include "Include/Debug.h"

using namespace std;

namespace morpheo              {
namespace behavioural          {

  class Interface
  {
    friend class Interfaces;

    // -----[ fields ]----------------------------------------------------
  private   : const string          _name         ;
  private   : const direction_t     _direction    ;
  private   : const localisation_t  _localisation ;
  private   :       string          _comment      ;

  private   : list<Signal *>      * _list_signal  ;


#ifdef POSITION
  private   :       bool            _is_map       ;
  private   :       void          * _entity_map   ; // Entity -> erreur cyclique
  private   :       void          * _interface_map; // pour être homogène avec _entity_map
#endif

    // -----[ methods ]---------------------------------------------------
  public    :                       Interface            (string         name        ,
							  direction_t    direction   ,
							  localisation_t localisation);

  public    :                       Interface            (const Interface    & interface);
  public    :                       ~Interface           ();

  public    : void                  set_comment          (string comment);
  private   : string                get_comment          (void          );

  private   : string                get_signal           (void);
  public    : Signal *              set_signal           (string          name     ,
							  direction_t     direction,
							  uint32_t        size     ,
							  presence_port_t presence_port = PORT_VHDL_YES_TESTBENCH_YES);

#ifdef SYSTEMC
  public    : sc_in_clk *           set_signal_clk       (string          name     ,
							  uint32_t        size     ,
							  presence_port_t presence_port=PORT_VHDL_YES_TESTBENCH_YES)
    {
      log_printf(FUNC,Behavioural,"set_signal_clk","Begin");

      Signal * sig = set_signal (name, IN , size, presence_port);
      sc_in_clk * signal = new sc_in_clk (sig->_name.c_str());

      log_printf(FUNC,Behavioural,"set_signal_clk","End");

      return signal;
    };

  public    : template <typename T>
              sc_in <T> *           set_signal_in       (string          name     ,
							 uint32_t        size     ,
							 presence_port_t presence_port=PORT_VHDL_YES_TESTBENCH_YES)
    {
      log_printf(FUNC,Behavioural,"set_signal_in","Begin");

      Signal * sig = set_signal (name, IN , size, presence_port);
      sc_in <T> * port = new sc_in <T> (sig->_name.c_str());
#ifdef VHDL_TESTBENCH
      sig->alloc<T> (static_cast<void *>(port));
#endif

      log_printf(FUNC,Behavioural,"set_signal_in","End");

      return port;
    };

  public    : template <typename T>
              sc_out <T> *          set_signal_out      (string          name     ,
							 uint32_t        size     ,
							 presence_port_t presence_port=PORT_VHDL_YES_TESTBENCH_YES)
    {
      log_printf(FUNC,Behavioural,"set_signal_out","Begin");

      Signal * sig = set_signal (name, OUT , size, presence_port);
      sc_out <T> * port = new sc_out <T> (sig->_name.c_str());
#ifdef VHDL_TESTBENCH
      sig->alloc<T> (static_cast<void *>(port));
#endif

      log_printf(FUNC,Behavioural,"set_signal_out","End");

      return port;
    };
#endif

#ifdef VHDL
  public    : void                  set_port             (Vhdl * & vhdl);
#endif
#ifdef VHDL_TESTBENCH
  public    : void                  set_port             (Vhdl_Testbench * & vhdl_testbench);
#endif

#ifdef POSITION
  public    : void                  port_map             (void * entity,
							  void * interface);
#endif

#ifdef VHDL_TESTBENCH
  public    : void                  testbench            (Vhdl_Testbench * & vhdl_testbench);
#endif

  public    : XML                   toXML                (void);
#ifdef POSITION
  public    : XML                   toXML_mapping        (void);
#endif
  public    : friend ostream&       operator<<           (ostream& output_stream,
  					  		  morpheo::behavioural::Interface & x);

  };

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

#endif
