#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "olc.h"

#define HEDIT( fun )		bool fun( CHAR_DATA *ch, char *argument )
#define EDIT_HELP(Ch, Help)	( Help = (HELP_DATA *)Ch->desc->pEdit )

/*
 * Help Editor Prototypes
 */
DECLARE_OLC_FUN (hedit_create);
DECLARE_OLC_FUN (hedit_delete);
DECLARE_OLC_FUN (hedit_desc);
DECLARE_OLC_FUN (hedit_rank);
DECLARE_OLC_FUN (hedit_keywords);
DECLARE_OLC_FUN (hedit_show);
const struct olc_cmd_type hedit_table[] = {
/*  {   command         function        }, */

  {"commands", show_commands},
  {"create", hedit_create},
  {"delete", hedit_delete},
  {"desc", hedit_desc},
  {"rank", hedit_rank},
  {"keywords", hedit_keywords},
  {"show", hedit_show}, {"?", show_help}, {"", 0,}
};
void hedit (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  char command[MAX_INPUT_LENGTH];
  int cmd;
  smash_tilde (argument);
  strcpy (arg, argument);
  argument = one_argument (argument, command);
  if (!IS_IMP (ch))
    send_to_char ("HEdit: Insufficient security to modify area.\n\r", ch);
  if (command[0] == '\0')
    {
      hedit_show (ch, argument);
      return;
    }
  if (!str_cmp (command, "done"))
    {
      edit_done (ch);
      return;
    }

  /* Search Table and Dispatch Command. */
  for (cmd = 0; hedit_table[cmd].name[0] != '\0'; cmd++)
    {
      if (!str_cmp (command, hedit_table[cmd].name))
	{
	  (*hedit_table[cmd].olc_fun) (ch, argument);
	  return;
	}
    }

  /* Default to Standard Interpreter. */
  interpret (ch, arg);
  return;
}


/* Entry point for editing help_data. */
void do_hedit (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  HELP_DATA *iHelp;
  if (IS_NPC (ch))
    return;
  argument = one_argument (argument, arg);
  if (arg[0] == '\0')
    {
      send_to_char ("Syntax:  edit help <keywords>\n\r", ch);
      return;
    }
  else
    {
      for (iHelp = help_first; iHelp; iHelp = iHelp->next)
	{

	  /*
	   * This help better not exist already!
	   */
	  if (is_name (arg, iHelp->keyword))
	    {
	      ch->desc->pEdit = (void *) iHelp;
	      ch->desc->editor = ED_HELP;
	      break;
	    }
	}
      if (!iHelp)
	{
	  iHelp = new_help ();
	  iHelp->keyword = str_dup (arg);
	  if (!help_first)
	    help_first = iHelp;
	  if (help_last)
	    help_last->next = iHelp;
	  help_last = iHelp;
	  iHelp->next = NULL;
	  ch->desc->pEdit = (void *) iHelp;
	  ch->desc->editor = ED_HELP;
	}
    }
  return;
}

HEDIT (hedit_show)
{
  HELP_DATA *pHelp;
  char buf[MAX_STRING_LENGTH];
  if (!EDIT_HELP (ch, pHelp))
    {
      send_to_char ("Null help file.\n\r", ch);
      return FALSE;
    }
  sprintf (buf, "Seen at rank:  [%d]\n\r"
	   "Keywords:      [%s]\n\r"
	   "Text:\n\r%s\n\r", pHelp->rank, pHelp->keyword, pHelp->text);
  send_to_char (buf, ch);
  return FALSE;
}

HEDIT (hedit_create)
{
  HELP_DATA *iHelp;
  HELP_DATA *NewHelp;
  char buf[MAX_STRING_LENGTH];
  if (!EDIT_HELP (ch, iHelp))
    {
      send_to_char ("Null help file.\n\r", ch);
      return FALSE;
    }
  if (argument[0] == '\0')
    {
      send_to_char ("Syntax: create <keywords>\n\r", ch);
      return FALSE;
    }

  /*
   * This help better not exist already!
   */
  for (iHelp = help_first; iHelp; iHelp = iHelp->next)
    {
      if (is_name (argument, iHelp->keyword))
	{
	  send_to_char ("That help file already exists.\n\r", ch);
	  return FALSE;
	}
    }
  NewHelp = new_help ();
  NewHelp->keyword = str_dup (argument);
  if (!help_first)		/* If it is we have a leak */
    help_first = NewHelp;
  if (help_last)
    help_last->next = NewHelp;
  help_last = NewHelp;
  NewHelp->next = NULL;
  ch->desc->pEdit = (void *) NewHelp;
  ch->desc->editor = ED_HELP;
  sprintf (buf, "Created help with the keyword(s): %s\n\r", NewHelp->keyword);
  send_to_char (buf, ch);
  return TRUE;
}

HEDIT (hedit_delete)
{
  HELP_DATA *pHelp;
  HELP_DATA *PrevHelp = NULL;
  if (!EDIT_HELP (ch, pHelp))
    {
      send_to_char ("Null help file.\n\r", ch);
      return FALSE;
    }
  if (argument[0] == '\0')
    {
      send_to_char ("Syntax: delete <keyword>\n\r", ch);
      return FALSE;
    }

  /*
   * This help better exist
   */
  for (pHelp = help_first; pHelp; PrevHelp = pHelp, pHelp = pHelp->next)
    {
      if (is_name (argument, pHelp->keyword))
	break;
    }
  if (!pHelp)
    {
      send_to_char ("That help file does not exist.\n\r", ch);
      return FALSE;
    }
  if (pHelp == (HELP_DATA *) ch->desc->pEdit)
    {
      edit_done (ch);
    }
  if (!PrevHelp)
    {				/* At first help file   */
      help_first = pHelp->next;
      free_help (pHelp);
    }
  else if (!pHelp->next)
    {				/* At the last help file */
      help_last = PrevHelp;
      PrevHelp->next = NULL;
      free_help (pHelp);
    }
  else
    /* Somewhere else...    */
    {
      PrevHelp->next = pHelp->next;
      free_help (pHelp);
    }
  send_to_char ("Help file deleted.\n\r", ch);
  return TRUE;
}

HEDIT (hedit_desc)
{
  HELP_DATA *pHelp;
  if (!EDIT_HELP (ch, pHelp))
    {
      send_to_char ("Null help file.\n\r", ch);
      return FALSE;
    }
  if (argument[0] != '\0')
    {
      send_to_char ("Syntax:  desc\n\r", ch);
      return FALSE;
    }
  edit_string (ch, &pHelp->text);
  return TRUE;
}

HEDIT (hedit_rank)
{
  HELP_DATA *pHelp;
  int value;
  if (!EDIT_HELP (ch, pHelp))
    {
      send_to_char ("Null help file.\n\r", ch);
      return FALSE;
    }
  value = atoi (argument);
  if (argument[0] == '\0' || value < -1)
    {
      send_to_char ("Syntax:  rank [rank >= -1]\n\r", ch);
      return FALSE;
    }
  pHelp->rank = value;
  send_to_char ("Help rank set.\n\r", ch);
  return TRUE;
}

HEDIT (hedit_keywords)
{
  HELP_DATA *pHelp;
  int i;
  int length;
  if (!EDIT_HELP (ch, pHelp))
    {
      send_to_char ("Null help file.\n\r", ch);
      return FALSE;
    }
  if (argument[0] == '\0')
    {
      send_to_char ("Syntax:  keywords <keywords>\n\r", ch);
      return FALSE;
    }
  length = strlen (argument);
  for (i = 0; i < length; i++)
    argument[i] = toupper (argument[i]);
  pHelp->keyword = str_dup (argument);
  send_to_char ("Help keywords set.\n\r", ch);
  return TRUE;
}