/*
    Grapple - A fully featured network layer with a simple interface
    Copyright (C) 2006 Michael Simms

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Michael Simms
    michael@linuxgamepublishing.com
*/

#ifndef GRAPPLE_STRUCTS_H
#define GRAPPLE_STRUCTS_H

#include <pthread.h>
#include <sys/types.h>

#include "grapple_callback.h"
#include "grapple_client.h"
#include "grapple_server.h"
#include "grapple_protocols.h"
#include "grapple_enums.h"
#include "socket.h"

typedef union
{
  int i;
  char c[4];
} intchar;

typedef union
{
  double d;
  char c[8];
} doublechar;

typedef struct _grapple_queue
{
  grapple_messagetype_internal messagetype;
  void *data;
  size_t length;
  unsigned int id;
  int reliablemode;
  int from; //Matches grapple_connection->serverid
  struct _grapple_queue *next;
  struct _grapple_queue *prev;
} grapple_queue;

typedef struct _grapple_callback_list
{
  grapple_callback callback;
  void *context;
  grapple_messagetype type;
  struct _grapple_callback_list *next;
  struct _grapple_callback_list *prev;
} grapple_callback_list;

typedef struct _grapple_confirm
{
  int messageid;
  int *receivers;
  int receivercount;
  int maxreceiver;
  time_t timeout;
  struct _grapple_confirm *next;
  struct _grapple_confirm *prev;
} grapple_confirm;


typedef struct _grapple_connection
{
  socketbuf *sock;
  socketbuf *failoversock;
  int sequential;
  char *name;
  int serverid;
  int reconnectserverid;
  int me;
  int delete;
  int handshook;
  int handshakeflags;
  int reconnecting;
  struct timeval pingstart;
  int pingnumber;
  double pingtime;
  struct timeval pingend;
  grapple_protocol protocol;
  int reliablemode;
  grapple_confirm *confirm;
  pthread_mutex_t confirm_mutex;
  pthread_mutex_t message_out_mutex;
  pthread_mutex_t message_in_mutex;
  grapple_queue *message_in_queue;
  grapple_queue *message_out_queue;
  struct _grapple_connection *next;
  struct _grapple_connection *prev;
} grapple_connection;

typedef struct
{
  pthread_t thread;
  struct _grapple_callbackevent *event_queue;
  pthread_mutex_t event_queue_mutex;
  int finished;
} grapple_callback_dispatcher;

typedef struct _grapple_failover_host
{
  int id;
  char *address;
  struct _grapple_failover_host *next;
  struct _grapple_failover_host *prev;
} grapple_failover_host;

typedef struct _grapple_group_container
{
  int id;
  struct _grapple_group_container *next;
  struct _grapple_group_container *prev;
} grapple_group_container;

typedef struct _internal_grapple_group
{
  int id;
  char *name;
  grapple_group_container *contents;
  struct _internal_grapple_group *next;
  struct _internal_grapple_group *prev;
} internal_grapple_group;

typedef struct _internal_server_data
{
  grapple_server servernum;
  int port;
  grapple_protocol protocol;
  socketbuf *sock;
  int sequential;
  int reliablemode;
  int closed;
  int usercount;
  int maxusers;
  char *ip;
  char *productname;
  char *productversion;
  char *session;
  char *password;
  pthread_t thread;
  int threaddestroy;
  int failover;
  int timeout;
  int user_serverid;
  socketbuf *wakesock;
  time_t reconnect_expire;
  grapple_error last_error;
  time_t last_confirm_check;
  grapple_confirmid sendwait;
  double autoping;
  grapple_confirm *confirm;
  pthread_mutex_t internal_mutex;
  pthread_mutex_t confirm_mutex;
  grapple_failover_host *failoverhosts;
  internal_grapple_group *groups;
  pthread_mutex_t callback_mutex;
  grapple_callback_list *callbackanchor;
  pthread_mutex_t message_in_mutex;
  grapple_queue *message_in_queue;
  pthread_mutex_t connection_mutex;
  pthread_mutex_t group_mutex;
  pthread_mutex_t failover_mutex;
  socket_processlist *socklist;
  grapple_connection *userlist;
  grapple_callback_dispatcher *dispatcher;
  struct _internal_server_data *next;
  struct _internal_server_data *prev;
} internal_server_data;

typedef struct _internal_client_data
{
  grapple_client clientnum;
  char *address;
  int port;
  grapple_protocol protocol;
  char *name_provisional;
  char *name;
  int serverid;
  char *session;
  char *password;
  socketbuf *sock;
  socketbuf *failoversock;
  int sequential;
  int reliablemode;
  int next_group;
  char *productname;
  char *productversion;
  pthread_t thread;
  int connecting;
  int disconnected;
  int threaddestroy;
  int failover;
  int timeout;
  socketbuf *wakesock;
  grapple_error last_error;
  struct timeval pingstart;
  int pingnumber;
  double pingtime;
  socket_processlist *socklist;
  grapple_confirmid sendwait;
  struct timeval pingend;
  grapple_failover_host *failoverhosts;
  internal_grapple_group *groups;
  pthread_mutex_t internal_mutex;
  pthread_mutex_t callback_mutex;
  grapple_callback_list *callbackanchor;
  pthread_mutex_t message_in_mutex;
  grapple_queue *message_in_queue;
  pthread_mutex_t message_out_mutex;
  grapple_queue *message_out_queue;
  pthread_mutex_t connection_mutex;
  pthread_mutex_t group_mutex;
  pthread_mutex_t failover_mutex;
  grapple_connection *userlist;
  grapple_callback_dispatcher *dispatcher;
  struct _internal_client_data *next;
  struct _internal_client_data *prev;
} internal_client_data;

#endif
