#ifndef CNETSTREAM_H
#define CNETSTREAM_H

//////////////////////////////////////
//                                  //
//  Class representing the network  //
//  stream.                         //
//                                  //
//////////////////////////////////////

class CNetStream
{
 protected:
  int sock;

  std::string MachineName;
  std::string dottedIP;
  std::string dottedIPother;
  int port;
  bool fail;

  void Write(char * buffer, int size);
  void Read(char * buffer, int size);


 public:
  // Data manipulation function
  std::string GetMachineName() const { return MachineName; }
  std::string GetDottedIP() const { return dottedIP; }
  void SetDottedIP(const std::string& newIP) { dottedIP = newIP; }
  std::string GetDottedIPother() const { return dottedIPother; }
  void SetDottedIPother(const std::string& newIP) { dottedIPother = newIP; }
  int GetPort() const { return port; }
  void SetPort(int newport) { port = newport; }
  int GetSocket() const { return sock; }
  void SetSocket(int newsock) { sock = newsock; }
  bool Fail(void) const { return fail; }
  void SetFail(bool newfail) { fail = newfail; }


  // Constructor
  CNetStream(int newport, std::string newIP)
    : dottedIP(""), dottedIPother(newIP)
    { 
      fail = false;
      port = newport;
      std::vector<std::string> temp;
      temp = GetHostInfo();
      MachineName = temp[0];
      dottedIP = temp[1];
    }

  // Destructor
  virtual ~CNetStream() { CloseSocket(sock); }

  CNetStream& operator << (const CNetMessage& message);
  CNetStream& operator >> (CNetMessage& message);

  virtual bool Connect() = 0;
};

inline CNetStream* operator << (CNetStream* p_o, const CNetMessage& message)
{
  p_o->operator << (message);
  return p_o;
}

inline CNetStream* operator >> (CNetStream* p_o, CNetMessage& message)
{
  p_o->operator >> (message);
  return p_o;
}




class CClientStream : public CNetStream
{
 public:
  CClientStream(int newport = -1, std::string newIP = std::string(""))
    : CNetStream(newport, newIP) {}

  virtual bool Connect();
};



class CServerStream : public CNetStream
{
  int listensock;
 public:
  CServerStream(int newport = -1)
    : CNetStream(newport, "") {}

  virtual bool Connect();
};


extern CNetStream* n_in_out;

#endif
