/*
 * format.c: default format strings
 *
 * Copyright(c) 1997-2000 - All Rights Reserved
 *
 * See the COPYRIGHT file.
 */

#ifndef lint
static char rcsid[] = "@(#)$Id: format.c,v 1.18 2000/07/31 22:33:55 kalt Exp $";
#endif

#include "os.h"

#include "struct.h"
#include "term.h"
#include "format.h"
#include "utils.h"

extern	struct server_	*server;

char	*default_format_str[F_MAX+1] =
{
  /* F_NUM */		"%N %p (from %s)",
  /* F_SNOTICE */	"--- %p (from %s)",
  /* F_SMSG */		"*%s:%d* %p",			/* DOES NOT EXIST */

  /* F_VNOTICE */	"-%o:%d- %p",
  
  /* F_UNOTICE */	"-%n:%d- %p",
  /* F_UMSG */		"*%n:%d* %p",
  /* F_NICK */		"*** %n is now known as %d",
  /* F_UMODE */		"*** user mode: %p",

  /* F_CNOTICE */	"-%n:%d- %p",
  /* F_CMSG */		"<%n:%d> %p",
  /* F_CMODE */		"*** %n %d MODE %p",
  /* F_SMODE */		"*** %s %d MODE %p",

  /* F_INVITE */	"*** %n (%u@%h) invited you to %p",
  /* F_JOIN */		"*** %n (%u@%h) has joined %d (%p)",
  /* F_PART */		"*** %n has left %d (%p) <%u@%h>",
  /* F_QUIT */		"*** %n (%p) <%u@%h>",
  /* F_KICK */		"*** %n %d KICKed %p",
  /* F_TOPIC */		"*** %n TOPIC %d: %p",

  /* F_DCC */		"=%n= %p",

  /* F_KILL */		"*** KILL by %s %{2}p",
  /* F_ERROR */		"%p",
  /* F_UNKNOWN */	"Unknown format: %o %m %d %p",

  /* F_MYPRIVM */	"-> *%d* %p",
  /* F_MYPRIVN */	"-> -%d- %p",
  /* F_MYPUBM */	"%d> %p",
  /* F_MYPUBN */	"%d- %p",
  /* F_MYQUERY */	"-> *%d* %p",
  /* F_MYDCC */		"-> =%d= %p",

  /* F_SPLIT */		"SPLIT: %s <-> %s",
  /* F_PREFIX */	"%H:%M|"
};

/*
 * user generated "chat" traffic
 * "RAW" options
 *	%d	recipient
 *	%m	command
 *	%p	parameters (e.g.: text)
 *
 * rendering
 *	%B	bold on/off
 *	%R	reverse video on/off
 *	%U	underline on/off
 *
 * "processed" options
 *	%S	server name you are connected to
 */
int
out_sprintf(buffer, attr, format, rcpt, cmd, param)
char	*buffer, *format, *rcpt, *cmd, *param;
u_char	*attr;
{
  char		*wp = buffer;
  u_char	video = 0, anyattr = 0;
  int		align;

  *wp = '\0';
  while (*format)
    {
      while (*format && *format != '%')
	{
	  *wp++ = *format++;
	  *attr++ = video;
	  if (video)
	      anyattr = 1;
	}

      if(*format++)
	{
          if (align = atoi(format))
            {
              if (align < 0)
                  format++;
              while (isdigit((int) *format))
                  format++;
            }
	  
	  *wp = '\0';
	  switch (*format++)
	    {
	  case '%':
	      *wp++ = '%'; attr++;
	      *wp = '\0';
	      align = 0;
	      break;
	  case 'B':
	      video ^= TERM_BOLD;
	      align = 0;
	      break;
	  case 'd':
	      strcat(buffer, rcpt);
	      break;
	  case 'm':
	      strcat(buffer, cmd);
	      break;
	  case 'p':
	      if (*format != '{')
		  strcat(buffer, param);
	      else
		{
		  strcat(buffer, sic_split(param, format));
		  if (index(format, '}'))
		      format = index(format, '}') + 1;
		}
	      break;
	  case 'R':
	      video ^= TERM_STANDOUT;
	      align = 0;
	      break;
	  case 'S':
	      if (server)
		  strcat(buffer, server->sname);
	      else
		  strcat(buffer, "<gee, what are we doing here?>");
	      break;
	  case 'U':
	      video ^= TERM_UNDERLINE;
	      align = 0;
	      break;
	  default:
	      *wp++ = (char) 191; *attr++ = TERM_STANDOUT; anyattr = 1;
	      *wp = '\0';
	      align = 0;
	      term_beep();
	      break;
	    }

	  if (align && *wp != '\0')
	    {
	      if (align > 0)
		  if (strlen(wp) < align)
		    {
		      char *where = wp;
		      
		      align -= strlen(wp);
		      where += strlen(wp);
		      while (align--)
			  *where++ = ' ';
		      *where = '\0';
		    }
		  else
		      wp[align] = '\0';
	      else
		  if (strlen(wp) < -align)
		    {
		      char *where = wp - align;
		      char *end = wp + strlen(wp);
		      
		      while (end >= wp)
			  *where-- = *end--;
		      while (where >= wp)
			  *where-- = ' ';
		    }
		  else
		      wp[-align] = '\0';
	    }

	  while (*wp != '\0')
	    {
	      wp++;
	      *attr++ = video;
	      if (video)
		  anyattr = 1;
	    }
	}
      else
	  break;
    }
  *wp = '\0';
  return anyattr;
}

/*
 * returns some words from the string str according to arg:
 *	{n}	-> n-th word
 *	{n,m}	-> words n-th to m-th (n < m)
 *	{$}	-> last word
 *	{$-1}	-> word before the last word
 *	{..:t#}	-> convert using tdiff, # is passed to tdiff as 2nd argument
 */
char *
sic_split(str, arg)
  char *str, *arg;
{
  static char result[1024];
  char temp[1024], *splitted[250];
  char *wp;
  int n = 0, m = 0, i = 0;

  *result = '\0';
  if (*arg++ != '{')
      return result;

  if ((n = atoi(arg)) == 0)
      if (*arg == '$')
	  n = -1 + atoi(arg+1);
      else
	  return result;
  if ((wp = index(arg, ',')) < index(arg, '}') && wp)
    {
      if ((m = atoi(++wp)) == 0)
	  if (*wp == '$')
	      m = -1 + atoi(wp+1);
	  else
	      return result;
    }
  strcpy(temp, str);
  if (splitted[i] = strtok(temp, " "))
    {
      i = 1;
      while (splitted[i] = strtok(NULL, " "))
	  i += 1;
    }
  if (n < 0)
      n += i + 1;
  if (m < 0)
      m += i + 1;

  if (n <= 0)
      n = 1;
  if (n > i)
      return result;

  if (m > i)
      m = i;

  if (m && m < n)
      return result;
  if (m == 0)
      m = n;

  /* UGLY thing */
  for (i = 1; i <= m; i++)
      if (*splitted[i-1] == ':')
	{
	  splitted[i-1] += 1;
	  break;
	}
  /* UGLY thing */

  strncpy(result, str + (splitted[n-1] - temp),
	  splitted[m-1] - splitted[n-1] + strlen(splitted[m-1]));
  result[splitted[m-1] - splitted[n-1] + strlen(splitted[m-1])] = '\0';

  if ((wp = index(arg, ':')) < index(arg, '}') && wp)
    {
      /* functions */
      switch (*(wp+1))
	{
      case 't': /* time */
	  strcpy(result, sic_tdiff(atol(result), (char) atoi(wp+2)));
	}
    }
  return result;
}


syntax highlighted by Code2HTML, v. 0.9.1