#ifndef TCPIP_DEVICE_H
#define TCPIP_DEVICE_H

/*!
  \file
  \brief TCP/IP 通信制御

  \author Satofumi KAMIMURA

  $Id: tcpipDevice.h 286 2008-10-20 09:40:22Z satofumi $
*/

#include "sdlBase.h"
#include "connectionDevice.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
#include <SDL_net.h>
#endif


/*!
  \brief TCP/IP 通信制御
*/
class TcpipDevice : protected SDL_Base, public ConnectionDevice {
  friend class TcpipServer;

#if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
  TCPsocket tcp_socket;
  SDLNet_SocketSet own_set;
  static bool initialized;
  static int sockets_num;
  static int sockets_max;
  static SDLNet_SocketSet socket_set;
#endif
  static void resizeSocketSet(void);
  void initialize(bool eachCheckSocket);

  int raw_connect(const char* host, long port);
  void raw_disconnect(void);
  int raw_setBaudrate(long baudrate);
  int raw_send(const char* data, int len);
  void raw_flush(void);
  void raw_check(int size, long timeout);
#if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
  void addSocket(TCPsocket socket);
  void delSocket(TCPsocket socket);
  static int checkAllSockets(long timeout = 0);
#endif

public:
  /*!
    \brief バッファサイズ指定のコンストラクタ

    \param buffer_size [i] バッファサイズ
    \param eachCheckSockets [i] 受信チェックをソケット毎に行う場合 true
  */
  TcpipDevice(int buffer_size, bool eachCheckSockets = true);

  /*!
    \brief 受信チェック方法指定のコンストラクタ

    \param eachCheckSockets [i] 受信チェックをソケット毎に行う場合 true
  */
  TcpipDevice(bool eachCheckSockets = true);
#if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
  /*!
    \brief SDL_net 資源を受け取るコンストラクタ

    \param net_socket [i] SDL_net の接続オブジェクト
    \param eachCheckSockets [i] 受信チェックをソケット毎に行う場合 true
    \param buffer_size [i] バッファサイズ
  */
  TcpipDevice(TCPsocket net_socket, bool eachCheckSockets = true,
	      int buffer_size = BufferSize-1);
#endif
  virtual ~TcpipDevice(void);

  const char* what(void);
  bool isConnected(void);

  /*!
    \brief 受信チェック

    \param timeout [i] タイムアウト [msec]
    \retval 戻り値 > 0 受信データあり
    \retval 0 受信データなし
    \retval 戻り値 < 0 エラー
  */
  int checkSocket(long timeout = 0);
};

#endif /* !TCPIP_DEVICE_H */
