/*********************************************************************/
/* file: path.c - stuff for the path feature                         */
/*                             TINTIN III                            */
/*          (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t             */
/*                     coded by peter unold 1992                     */
/*********************************************************************/
/* the path is implemented as a fix-sized queue. It gets a bit messy */
/* here and there, but it should work....                            */
/*********************************************************************/
#include <string.h>
#include "tintin.h"

/*********************/
/* the #MARK command */
/*********************/
void mark_command(struct session *ses)
{
  if(ses) {
    ses->path_mark=0;
    ses->path_now=0;
    ses->path_lenght=0;
    tintin_puts("OK. MARK SET.", ses);
  }
  else
    tintin_puts("NO SESSION ACTIVE => NO PATH!", ses);
}

/*********************/
/* the #PATH command */
/*********************/
void path_command(struct session *ses)
{
  if(ses) {
    int pathpos, len, outlen;
    char mypath[MAX_PATH_LENGHT+16]="#PATH YOU WENT:";

    for(pathpos=ses->path_mark, len=ses->path_lenght, outlen=strlen(mypath); len; 
        len--, pathpos=(pathpos+1)%MAX_PATH_LENGHT)
      mypath[outlen++]=ses->path[pathpos];
      mypath[outlen]='\0';
      tintin_puts(mypath, ses);
  }
  else
    tintin_puts("#NO SESSION ACTIVE => NO PATH!", ses);
}


/***********************/
/* the #RETURN command */
/***********************/
void return_command(struct session *ses)
{
  if(ses) {
    if(ses->path_lenght) {
      char command[2]={'x', '\n'};

      command[0]=reverse_dir(ses->path[(ses->path_mark+(ses->path_lenght-1))%MAX_PATH_LENGHT]);
      ses->path_lenght--;

      if(ses->logfile)
        fwrite(command, 1, 2, ses->logfile);
      if(write(ses->socket, command, 2)==-1)
        syserr("write in send_to_mud");
    }
  }
  else
      tintin_puts("#NO SESSION ACTIVE => NO PATH!", ses);
}


/***********************/
/* the #UNPATH command */
/***********************/
void unpath_command(struct session *ses)
{
  if(ses) {
    if(ses->path_lenght) {
      ses->path_lenght--;
      tintin_puts("OK. FORGOT THAT MOVE.", ses);
    }
  }
  else 
    tintin_puts("#NO SESSION ACTIVE => NO PATH!", ses);
}

/*********************************************************/
/* check to see if command=direction then insert in path */
/*********************************************************/
void check_insert_path(char *command, struct session *ses)
{
  if(is_abrev(command, "north"))
    insert_path('n', ses);
  else if(is_abrev(command, "east"))
    insert_path('e', ses);
  else if(is_abrev(command, "south"))
    insert_path('s', ses);
  else if(is_abrev(command, "west"))
    insert_path('w', ses);
  else if(is_abrev(command, "up"))
    insert_path('u', ses);
  else if(is_abrev(command, "down"))
    insert_path('d', ses);
}

/***************************************************************************/
/* insert a direction in the path - first check if player went back though */
/* I know this gives problems with one-way-exits but......                 */
/***************************************************************************/
void insert_path(char dir, struct session *ses)
{
  if(ses->path_lenght && dir==reverse_dir(ses->path[(ses->path_mark+
    (ses->path_lenght-1))%MAX_PATH_LENGHT])) 
    ses->path_lenght--;             /*player went back*/
  else {
    if(ses->path_lenght==MAX_PATH_LENGHT)
      ses->path_mark=(ses->path_mark+1)%MAX_PATH_LENGHT;
    ses->path[(ses->path_mark+ses->path_lenght)%MAX_PATH_LENGHT]=dir;

    if(ses->path_lenght<MAX_PATH_LENGHT)
      ses->path_lenght++;
  }
}

/***************************************************/
/* return char containing reverse direction as dir */
/***************************************************/
char reverse_dir(char dir)
{
  switch(dir) {
  case 'n':
    return 's';
  case 'e':
    return 'w';
  case 's':
    return 'n';
  case 'w':
    return 'e';
  case 'u':
    return 'd';
  case 'd':
    return 'u';
  }
}