#include <Inventor/cve/SbNetListener.h>
#include <Inventor/cve/SoNetworkP.h>
#include <Inventor/cve/SoComputer.h>
#include <Inventor/cve/TNet.h>



//! Constructor.
SbNetListener::SbNetListener() : lcon(0)
{
  SoNetworkP::addListener(this);
}


//! Constructor.
SbNetListener::SbNetListener(SbInetPort port) : lcon(0), addr(SbInetAddr(0, port))
{
  SoNetworkP::addListener(this);
}


//! Constructor.
SbNetListener::SbNetListener(const SbInetAddr &ia) : lcon(0), addr(ia)
{
  SoNetworkP::addListener(this);
}


//! Constructor.
SbNetListener::SbNetListener(SbInetIP ip, SbInetPort port) : lcon(0), addr(SbInetAddr(ip, port))
{
  SoNetworkP::addListener(this);
}


//! Destructor.
SbNetListener::~SbNetListener()
{
  close();
  SoNetworkP::removeListener(this);
}


//! The function starts listening. If it is already listening, nothing happens and TRUE is returned.
SbBool SbNetListener::listen()
{
  if (isListening())
    return TRUE;

  int s = tnListenOnIP(addr.getIP(), addr.getPort());
  if (s == -1) return FALSE;
  lcon = s;
  return TRUE;
}


//! Sets a new listening address. If object is already listening, the listening is stopped.
void SbNetListener::setAddr(const SbInetAddr &addr)
{
  close();
  this->addr = addr;
}


//! The function stops the listening and frees the resources.
void SbNetListener::close()
{
  if (lcon == 0)
    return;

  tnClose(lcon);
  lcon = 0;
}


//! Return TRUE if the object is listening.
SbBool SbNetListener::isListening() const
{
  return (lcon != 0) ? TRUE : FALSE;
}


//! The function accepts connection and returns the computer.
SoComputer* SbNetListener::accept() const
{
  SbNetConnection s = this->acceptPlaneConnection();
  if (s != -1)
    return new SoComputer(s);
  else
    return NULL;
}


//! The function accepts connection and returns the socket.
SbNetConnection SbNetListener::acceptPlaneConnection() const
{
  if (lcon == 0)
    return -1;

  return tnAccept(lcon);
}


//! Returns listening address (ip and port pair).
const SbInetAddr& SbNetListener::getAddr() const
{
  return addr;
}
