pgplus/bin/
pgplus/help_files/
pgplus/port_redirector/
pgplus/src/configure/makefiles/
/* 
 * Playground+ - output.c 
 * Enhanced output processor by Mo McKinlay
 * ----------------------------------------------------------------------------
 *
 * Replaces the two versions of process_output supplied in PG+
 * Tweeks to basecode to show social tagging by Silver
 */

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>

#include "include/config.h"
#include "include/player.h"
#include "include/fix.h"
#include "include/proto.h"
#include "include/output.h"

/* tags[]
 *
 * This array lists the tag characters which should be used.
 * If 0 is specified, a tag won't be output.
 * Place the tags in the order that they should appear on output.
 * (For example, TT_ECHO preceeding TT_ROOM).
 */

tagentry_t tags[] = {
  { TT_LOGIN,   ']' }, /* Logins */
  { TT_LOGOUT,  '[' }, /* Logouts */
  { TT_RECON,   '%' }, /* Reconnections */
  { TT_ECHO,    '+' }, /* Echos */
  { TT_ITEM,    '^' }, /* Items */
  { TT_ROOM,    '-' }, /* Room messages */
  { TT_AUTO,    '#' }, /* Automessages */
  { TT_FRIEND,  '*' }, /* Old-style friend tells */
  { TT_OFRIEND, '=' }, /* Old-style friend tells to others */
  { TT_MULTI,   '&' }, /* Old-style multi-tells */
  { TT_NMULTI,  '*' }, /* New-style multi-tells */
  { TT_SOCIAL,  '~' }, /* Socials */
  { TT_PIPE,    '>' }, /* Pipes */
  { TT_TELL,    '>' }, /* Tells */
  { TT_SHOUT,   '!' }, /* Shouts */
  { TT_VOID,    0 },
};

/* output_checktags()
 *
 * Build a tagtype_t set based on the current global flags and player's
 * tag_flags settings.
 */

tagtype_t output_checktags(player *p) {
  tagtype_t t;
  
  if(p==current_player) return TT_VOID;
  t=TT_VOID;
  /* Tag logins/logouts/reconnects/echos */
  if((command_type&LOGIN_TAG) && (p->tag_flags & TAG_LOGINS)) {
    t|=TT_LOGIN;
  } else if((command_type&LOGOUT_TAG) && (p->tag_flags & TAG_LOGINS)) {
    t|=TT_LOGOUT;
  } else if((command_type&RECON_TAG) && (p->tag_flags & TAG_LOGINS)) {
    t|=TT_RECON;
  } else if((command_type&ECHO_COM) && (p->tag_flags & TAG_ECHO)) {
    t|=TT_ECHO;
  };
#ifdef ALLOW_MULTIS
  if (!(command_type & MULTI_COM)) {
#endif
    if(((command_type&PERSONAL) || (p->flags&TAGGED)) && 
       (p!=current_player)) {
      if((sys_flags&FRIEND_TAG) && (p->tag_flags&TAG_PERSONAL)) {
	t|=TT_FRIEND;
      } else if((sys_flags&OFRIEND_TAG) && (p->tag_flags&TAG_PERSONAL)) {
	t|=TT_OFRIEND;
      } else if((sys_flags&REPLY_TAG) && (p->tag_flags&TAG_PERSONAL)) {
	t|=TT_MULTI;
      } else if(command_type & PERSONAL) {
	t|=TT_TELL;
      } else {
	t|=TT_PIPE;
      };
    };
#ifdef ALLOW_MULTIS
  } else {
    t|=TT_NMULTI;
  };
#endif
  if(sys_flags&ITEM_TAG) {
    if(p->tag_flags & TAG_ITEMS) {
      t|=TT_ITEM;
    } else if(p->tag_flags & TAG_ROOM) {
      t|=TT_ROOM;
    };
  };
  if((command_type&SOCIAL) && (p->tag_flags & TAG_ROOM)) {
    t|=TT_SOCIAL;
  } else 
    if(((command_type&EVERYONE) || 
	     (sys_flags&EVERYONE_TAG)) &&
	    (p->tag_flags&TAG_SHOUT)) {
    t|=TT_SHOUT;
  } else if((command_type&AUTO) && (p->tag_flags & TAG_AUTOS)) {
    t|=TT_AUTO;
  } else if(((command_type&ROOM) || (sys_flags&ROOM_TAG)) && 
	    (p->tag_flags & TAG_ROOM) && 
	    (p!=current_player)) {
    t|=TT_ROOM;
  };
  if((command_type&ECHO_COM) && (p->tag_flags&SEEECHO)) {
    t|=TT_SEEECHO;
  };
  return t;
}

/* output_tags()
 *
 * Append appropriate tags to the stack.
 */

char *output_tags(player *p, tagtype_t t) {
  char *oldstack;
  int c;
  
  oldstack=stack;
  for(c=0; tags[c].type!=TT_VOID; c++) {
    if((t & tags[c].type) && (tags[c].tag)) {
      *stack++=tags[c].tag;
      p->column++;
    };
  };
  if(t & TT_SEEECHO) {
    *stack++='[';
    strcpy(stack, current_player->name);
    while(*stack) {
      stack++;
      p->column++;
    };
    *stack++=']';
    p->column+=2;
  };
  if(oldstack!=stack) {
    /* Put a space between the tag and the rest of the text */
    *stack++=' ';
    p->column++;
  };
  return stack;
}

file process_output(player *p, char *str) {
  file o;
  int x, l, xstart;
  char *wstart, *sstart, *t;
  int scat;
  o.where=stack;  
  output_tags(p, output_checktags(p));
  scat=sys_color_atm;
  x=p->column;
  /*
   * If HIGHLIGHT is set, turn it on here.
   */
  if((p->term) && (command_type&HIGHLIGHT)) {
    strcpy(stack, terms[(p->term - 1)].bold);  
    stack=strchr(stack, 0);
  };
  if((p->term) && (p->misc_flags & SYSTEM_COLOR)) {
    strcpy(stack, getcolor(p, p->colorset[sys_color_atm]));
    stack=strchr(stack, 0);
  };
  wstart=NULL;
  sstart=NULL;
  xstart=0;
  while(*str) {
    if(*str=='^' && (*(str+1)!='^')) {
      if(wstart==str) {
	wstart+=2;
	sstart+=2;
      };
      str++;
      if((p->term) && !(p->misc_flags & NOCOLOR)) {
	if(*str=='N' && 
	   !((command_type&HIGHLIGHT) && (sys_color_atm==SYSsc))) {
	  if(p->colorset[sys_color_atm]=='N') {
	    strcpy(stack, terms[(p->term - 1)].off);  
	  } else {
	    strcpy(stack, getcolor(p, p->colorset[sys_color_atm]));
	  };
	} else {
	  strcpy(stack, getcolor(p, *str));
	};
	stack=strchr(stack, 0); 
      };
      str++;
    } else if(*str=='\n') {
      if(!(*(str+1))) {
	/* Turn colour off before the CRLF */
	if((p->term) && 
	   (((sys_color_atm!=SYSsc) && (p->misc_flags&SYSTEM_COLOR)) ||
	   ((command_type & HIGHLIGHT) && !(p->misc_flags&NOCOLOR)))) {
	  strcpy(stack, getcolor(p, '^'));
	  stack=strchr(stack, 0);
	  sys_color_atm=SYSsc;
	};	
      };
      *stack++='\r';
      *stack++='\n';
      x=0;
      str++;
    } else {
      if(*str=='^') {
	str++;
      };
      if(!isalnum(*str)) {
	wstart=NULL;
	sstart=NULL;
	xstart=0;
      };
      if((x>=p->term_width) && (p->term_width!=0)) {
	/* This word will take us over the threshold */
	if(!wstart) {
	  /* No current word, just wrap now */
	  strcpy(stack, "\r\n   ");
	  stack=strchr(stack, 0);
	  x=4;
	  *stack=*str;
	  stack++;
	  str++;
	} else {
	  /* Find out the length of the word. If it's less
	   * than p->word_wrap, we cycle backwards, otherwise
	   * we just split the word and carry on
	   */
	  l=0;
	  for(t=wstart; t!=str; t++) l++;
	  if(l<p->word_wrap) {
	    /* Cycle backwards */
	    str=wstart;
	    stack=sstart;
	    strcpy(stack, "\r\n   ");
	    stack=strchr(stack, 0);
	    x=3;
	  } else {
	    /* Split the word up */
	    strcpy(stack, "\r\n   ");
	    stack=strchr(stack, 0);
	    if(isalnum(*str)) {
	      x=4;
	      wstart=str;
	      sstart=str;
	      xstart=x;
	      *stack=*str;
	      stack++;
	      str++;
	    } else {
	      x=3;
	      str++;
	      wstart=str;
	      sstart=str;
	      xstart=x;
	    };
	  };
	};
      } else {
	if(!isspace(*str) && !wstart) {
	  /* Start of a new word */
	  wstart=str;
	  sstart=stack;
	  xstart=x;
	};
	*stack=*str;
	x++;
	stack++;
	str++;
      };
    };
  };
  /* Turn colour off again */
  if((p->term) && (p->misc_flags&SYSTEM_COLOR)) {
    strcpy(stack, getcolor(p, '^'));
    stack=strchr(stack, 0);
  };
  if((p->term) && (command_type & HIGHLIGHT)) {
    strcpy(stack, terms[(p->term - 1)].off);  
    stack=strchr(stack, 0);
  };
  *stack=0;
  o.length = ((int) stack - (int) o.where) * sizeof(char);
  sys_color_atm=scat;
  p->column = x;
  return o;
}