/*********************************************************************/
/* 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"

#if IRIX
  #include <stdlib.h>
  #include <unistd.h> 
#endif

void check_insert_path();
void insert_path();
char reverse_dir();

extern char tintin_char;
/*********************/
/* the #MARK command */
/*********************/
void mark_command(ses)
     struct session *ses;
{
  if(ses) {
    ses->path_mark=0;
    ses->path_now=0;
    ses->path_lenght=0;
    tintin_puts("#OK. Path starts here.", ses);
  }
  else
    tintin_puts("NO SESSION ACTIVE => NO PATH!", ses);
}
/*********************/
/* the #MAP command  */
/*********************/
void map_command(arg, ses)
     char *arg;
     struct session *ses;
{
  if (ses) {
    get_arg_in_braces(arg,arg, 1);
    check_insert_path(arg,ses);
  }
  else {
    tintin_puts2("#Sorry, no session active=no path", ses);
  }
}    
/*************************/
/* the SAVEPATH command  */
/*************************/
void savepath_command(arg, ses)
     char *arg;
     struct session *ses;
{
  char result[BUFFER_SIZE], *ptr;
  if (ses) {
    get_arg_in_braces(arg,arg,1);
    if ((strlen(arg)<=0) || (ses->path_lenght<=0)){
	tintin_puts("Error - Inproper arguments, or no path to save...",ses);
	tintin_puts("Usage: #savepath <alias_to_be>",ses);
	}
    else {	
       sprintf(result, "Size:%d  Arg:%s\n\r",strlen(arg),arg);
       tintin_puts2(result, (struct session *)NULL);
       *result=tintin_char;
       *(result+1)='\0';
       strcat(result, "alias ");
       strcat(result, arg);
       strcat(result, " {");
       ptr=result+strlen(result);
       strncat(result,ses->path, ses->path_lenght);    
       *(ptr+ses->path_lenght)='}';
       *(ptr+ses->path_lenght+1)='\0';
       parse_input(result, ses);
    }
  }
  else
    tintin_puts2("#No session active, so no path to save.", ses);

}
/*********************/
/* the #PATH command */
/*********************/
void path_command(ses)
     struct session *ses;
{
  if(ses) {
    int pathpos, len, outlen;
    char mypath[MAX_PATH_LENGHT+16];
    strcpy(mypath, "#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(ses)
     struct session *ses;
{
  if(ses) {
    if(ses->path_lenght) {
      char command[2];
      strcpy(command, "x");
      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(ses)
     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(command, ses)
     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(dir, ses)
     char dir;
     struct session *ses;
{
    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(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';
  default: 
   return ' ';
  }
}