#ifndef SOCKETS_H
#define SOCKETS_H
#pragma interface

extern "C" {
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#ifdef LINUX
#include <sys/socketcall.h>
#else
  int ioctl (int FileDescriptor, unsigned long Command, ...);
#endif

  int close (int fd);
  int write (int fd, char* buf, int n);
  int read  (int fd, char* buf, int n);
  unsigned long inet_addr(char*);

}
#include <String.h>

const int default_size = 20;
const int sock_grow_by = 20;
const int max_waiting_connections = 5;   /* maximum = 10 */
const int default_host_port = 2056;      // because it is byte-order symmetric
const int max_read_chunk = 1024;

class Socket_Class {
 public:
  Socket_Class(int num_sockets = default_size);
  ~Socket_Class() {delete socketlist;
		   delete destinations;}
  int add_connection (int port = default_host_port); /* for server    */
  int add_connection (char* address, char* port);    /* for clients   */
  int add_connection (char* address, int port);      /* returns index */
  int send (int index, char* buffer, int size);      /* sends 'size' bytes */
                                                     /*  to socket 'index' */
  String* receive (int index);          /* returns NULL if nothing waiting */
  String* wait_receive (int index);
  void close_connection (int index);
 protected:
  int setup_host_socket (int portnum = default_host_port);
  void grow(int by = sock_grow_by);
  void next_available ();   /* corrects lowest_available */
  int size;
  int lowest_available;
  int* socketlist;
  unsigned long* destinations;
};

typedef struct One_Line {
  String* instring;
  int object_num;
}* input_line;

class Mud_Sockets : public Socket_Class {
 public:
  Mud_Sockets(int num_sockets = default_size);
  ~Mud_Sockets ();
  String* receive (int index);   /* check that input channel for data */
  String* wait_receive (int index);  /* blocking version */
  int send_line (int objectnum, String* s);
  input_line receive ();         /* grab a line from any channel */
  int add_connection (int port = default_host_port);      /* for server    */
  int add_connection (char* address, char* port, int obj=0); /* for clients  */
  int add_connection (char* address, int port, int obj=0);  /* returns index */
  int add_connection (String* full_address, int obj=0);
  void close_connection (int index);
  int move_connection (int oldobj , int newobj);
  int break_connection (int o_num);
  int get_object (int index)  {return objectlist[index];}
  String* get_destination (int o_num);
 protected:
  void grow(int by = sock_grow_by);
  int* objectlist;
  String** incoming_data;
};

#endif  /* SOCKETS_H */