/* This containes item logic for client/server.  IT doesn't contain
 * the actual commands that send the data, but does contain
 * the logic for what items should be sent.
 */


#include <global.h>
#include <object.h>	/* LOOK_OBJ */
#include <newclient.h>
#include <newserver.h>
#include <sproto.h>

#ifdef ERIC_SERVER

/* This is more or less stolen from the query_weight function. */
#define WEIGHT(op) (op->nrof?op->weight:op->weight+op->carrying)


/* 
 *  This is a similar to query_name, but returns flags
 *  to be sended to client. 
 */
unsigned int query_flags (object *op)
{
    unsigned int flags = 0;

    if(QUERY_FLAG(op,FLAG_APPLIED)) {
	switch(op->type) {
	  case BOW:
	  case WAND:
	  case ROD:
	  case HORN:
	    flags = a_readied;
	    break;
	  case WEAPON:
	    flags = a_wielded;
	    break;
	  case SKILL:
	  case ARMOUR:
	  case HELMET:
	  case SHIELD:
	  case RING:
	  case BOOTS:
	  case GLOVES:
	  case AMULET:
	  case GIRDLE:
	  case BRACERS:
	  case CLOAK:
	    flags = a_worn;
	    break;
	  case CONTAINER:
	    flags = a_active;
	    break;
	  default:
	    flags = a_applied;
	    break;
	}
    }
    if (op->type == CONTAINER && ((op->env && op->env->container == op) || 
	(!op->env && QUERY_FLAG(op,FLAG_APPLIED))))
	flags |= F_OPEN;
    
    if (QUERY_FLAG(op,FLAG_KNOWN_CURSED)) {
	if(QUERY_FLAG(op,FLAG_DAMNED))
	    flags |= F_DAMNED;
	else if(QUERY_FLAG(op,FLAG_CURSED))
	    flags |= F_CURSED;
    }
    if (QUERY_FLAG(op,FLAG_KNOWN_MAGICAL) && !QUERY_FLAG(op,FLAG_IDENTIFIED))
	flags |= F_MAGIC;
    if (QUERY_FLAG(op,FLAG_UNPAID))
	flags |= F_UNPAID;

    return flags;
}

void esrv_draw_look(object *pl)
{
    object *tmp, *last;
    int flags, got_one=0;
    int client_num;
    SockList sl;
    char *buf;

  if(QUERY_FLAG(pl, FLAG_REMOVED) || pl->map == NULL ||
    pl->map->in_memory != MAP_IN_MEMORY || out_of_map(pl->map,pl->x,pl->y))
	return;


    if ((client_num=getcnum(pl->contr->eric_server))<0) return;
    for (tmp=get_map_ob(pl->map,pl->x,pl->y); tmp && tmp->above;tmp=tmp->above)
	; 

    sl.buf=malloc(MAXSOCKBUF);

    Write_String_To_Socket(client_num, "delinv 0", strlen("delinv 0"));
    strcpy((char*)sl.buf,"item ");
    sl.len=strlen((char*)sl.buf);

    SockList_AddInt(&sl, 0);

    for (last=NULL; tmp!=last; tmp=tmp->below) {
	if (QUERY_FLAG(tmp, FLAG_IS_FLOOR) && !last) {
	    last = tmp->below;  /* assumes double floor mode */
	    if (last && QUERY_FLAG(last, FLAG_IS_FLOOR))
		last = last->below;
	}
	if (LOOK_OBJ(tmp)) {
	    flags = query_flags (tmp);
	    if (QUERY_FLAG(tmp, FLAG_NO_PICK))
		flags |=  F_NOPICK;
	    if (!cs_sockets[client_num].faces_sent[tmp->face->number])
		esrv_send_face(client_num, tmp->face->number);

	    SockList_AddInt(&sl, tmp->count);
	    SockList_AddInt(&sl, flags);
	    SockList_AddInt(&sl, QUERY_FLAG(tmp, FLAG_NO_PICK) ? -1 : WEIGHT(tmp));
	    SockList_AddInt(&sl, tmp->face->number);
	    buf=query_short_name(tmp);
	    SockList_AddChar(&sl, strlen(buf));
	    strcpy((char*)sl.buf+sl.len, buf);
	    sl.len += strlen(buf);
	    got_one=1;
	}
    }
    if (got_one)
	Send_With_Handling(client_num, &sl);

    free(sl.buf);
}

void esrv_send_inventory(object *pl, object *op)
{
    object *tmp;
    int flags, got_one=0;
    int client_num;
    SockList sl;
    char *buf;
    
    if ((client_num=getcnum(pl->contr->eric_server))<0) return;
    sl.buf=malloc(MAXSOCKBUF);

    sprintf((char*)sl.buf,"delinv %d", op->count);
    sl.len=strlen((char*)sl.buf);
    Send_With_Handling(client_num, &sl);

    strcpy((char*)sl.buf,"item ");
    sl.len=strlen((char*)sl.buf);

    SockList_AddInt(&sl, op->count);
    
    for (tmp=op->inv; tmp; tmp=tmp->below) {
	if (LOOK_OBJ(tmp)) {
	    flags = query_flags (tmp);
	    if (QUERY_FLAG(tmp, FLAG_NO_PICK))
		flags |=  F_NOPICK;
	    if (!cs_sockets[client_num].faces_sent[tmp->face->number])
		esrv_send_face(client_num, tmp->face->number);

	    SockList_AddInt(&sl, tmp->count);
	    SockList_AddInt(&sl, flags);
	    SockList_AddInt(&sl, QUERY_FLAG(tmp, FLAG_NO_PICK) ? -1 : WEIGHT(tmp));
	    SockList_AddInt(&sl, tmp->face->number);
	    buf=query_short_name(tmp);
	    SockList_AddChar(&sl, strlen(buf));
	    strcpy((char*)sl.buf+sl.len, buf);
	    sl.len += strlen(buf);
	    got_one = 1;
	}
    }
    if (got_one)
	Send_With_Handling(client_num, &sl);
    free(sl.buf);
}

void esrv_send_item(object *pl, object*op)
{
    int client_num;
    SockList sl;
    char *buf;
    
    /* If we have a request to send the player item, skip a few checks. */
    if (op!=pl) {
	if (! LOOK_OBJ(op)) 
	    return;
	if (!op->env) /* tmp. solution to keep items right order in look window */
	    esrv_draw_look(pl);
    }

    if ((client_num=getcnum(pl->contr->eric_server))<0) return;
    sl.buf=malloc(MAXSOCKBUF);

    strcpy((char*)sl.buf,"item ");
    sl.len=strlen((char*)sl.buf);

    SockList_AddInt(&sl, op->env? op->env->count:0);
    if (!cs_sockets[client_num].faces_sent[op->face->number])
	esrv_send_face(client_num, op->face->number);

    SockList_AddInt(&sl, op->count);
    SockList_AddInt(&sl, query_flags(op));
    SockList_AddInt(&sl, WEIGHT(op));
    SockList_AddInt(&sl, op->face->number);
    buf=query_short_name(op);
    SockList_AddChar(&sl,strlen(buf));
    strcpy((char*)sl.buf+sl.len, buf);
    sl.len += strlen(buf);
    Send_With_Handling(client_num, &sl);
    free(sl.buf);
}
#else
void esrv_send_item(object *pl, object*op) {}
void esrv_send_inventory(object *pl, object *op) {}
void esrv_draw_look(object *pl) {}
#endif

