// simple_input_handling.c - useful simple input handling using
// callbacks and a dispatcher

#include "simple_input_handling.h"
#include "simple_input_handling_private.h"

#include <stdio.h>
#include <stdlib.h>

static char *prompt_ = NULL;
static void (*handler_[256])(char *input_line);

//------------------------------------------------------------
// The main run-loop of the program that accepts keyboard input

void run()
{
  unsigned char *input_line = malloc(sizeof(char) * 
                                     (MAX_LINE_LENGTH + 1));
  int chars_read = 0;

  for(;;)
  {
    if (!prompt_)
      printf(">");
    else
      printf("%s",prompt_);
    if ((chars_read = readLine(input_line,MAX_LINE_LENGTH) == 
         ILLEGAL_ARGUMENTS))
    {
      printf("Error: readLine returned ILLEGAL_ARGUMENTS\n");
      exit(-1);
    }
    dispatch(input_line);
  }
}

//------------------------------------------------------------
// reads one line from the keyboard
int readLine(char *str,unsigned max_length)
{
  char character_read = '\0';
  unsigned num_chars = 0;

  if ((max_length <= 1) || (!str))
    return(ILLEGAL_ARGUMENTS);

  while((character_read = getchar()) != '\n')
  {
    *str++ = character_read;
    if (++num_chars >= max_length)
      break;
  }
  *str = '\0';
  return(num_chars);
}

//------------------------------------------------------------
void addToDispatcher(unsigned char input,
                     void (*handler)(char *input_line))
{
  handler_[input] = handler;
}

//------------------------------------------------------------
void removeFromDispatcher(unsigned char input)
{
  handler_[input] = NULL;
}

//------------------------------------------------------------
void setPrompt(char *prompt)
{
  if (prompt_)
    free(prompt_);
  prompt_ = prompt;
}

//------------------------------------------------------------
// dispatches the keyboard input

void dispatch(char *input_line)
{
  if (handler_[*input_line] != NULL)
    handler_[*input_line](input_line);
  else
    commandNotRecognized(input_line);
}

//------------------------------------------------------------
void commandNotRecognized(char *command_line)
{
  printf("Error: command not recognized... %s\n",command_line);
}
