/* encapsulate.c --- Command chopping function.
 * (C) 2008 Stuart Allen, distribute and use 
 * according to GNU GPL, see file COPYING for details.
 */

#include "jacl.h"
#include "types.h"
#include "prototypes.h"
#include <string.h>

extern struct synonym_type *synonym_table;
extern struct filter_type *filter_table;

char            text_buffer[1024];

/* THIS IS A STRING CONSTANT TO POINT TO WHENEVER A COMMA IS
 * USED IN THE PLAYER'S INPUT */
char           *comma = "comma\0";
char           *then = "then\0";
char           *word[MAX_WORDS];
int				quoted[MAX_WORDS];
int				percented[MAX_WORDS];
int             wp;

void
encapsulate()
{
	int             index,
	                length;
	int             position = 0;
	int             new_word = TRUE;

	length = strlen(text_buffer);

	/* QUOTED IS USED TO STORE WHETHER EACH WORD WAS ENCLOSED IN QUOTES
	 * IN THE PLAYERS COMMAND - RESET EACH WORD TO NO */
    for (index = 0; index < MAX_WORDS; index++) {
		quoted[index] = 0;
		percented[index] = 0;
	}

	for (index = 0; index < length; index++) {

		switch (text_buffer[index]) {
		case ':':
		case '\t':
		case ' ':
		case ',':
			text_buffer[index] = 0;
			new_word = TRUE;
			break;
		case ';':
		case '#':
		case '\r':
		case '\n':
			/* TERMINATE THE WHOLE COMMAND ON HITTING A NEWLINE CHARACTER, A
			 * SEMICOLON OR A HASH */
			text_buffer[index] = 0;
			index = length;
			break;
		case '"':
			index++;
			/* NEED TO REMEMBER THAT THIS WORD WAS ENCLOSED IN QUOTES FOR 
			 * THE COMMAND 'write'*/	
			quoted[position] = 1;	

			word[position] = &text_buffer[index];

			if (position < MAX_WORDS)
				position++;

			/* IF A WORD IS ENCLOSED IN QUOTES, KEEP GOING UNTIL THE END
			 * OF THE LINE OR A CLOSING QUOTE IS FOUND, NOT BREAKING AT
			 * WHITESPACE AS USUAL */
			for (; index < length; index++) {
				if (text_buffer[index] == '"') {
					text_buffer[index] = 0;
					new_word = TRUE;
					break;
				} else if (text_buffer[index] == '\r' || text_buffer[index] == '\n') {
					text_buffer[index] = 0;
					index = length;
					break;
				}
			}
			break;
		default:
			if (new_word) {
                if (text_buffer[index] == '%' && text_buffer[index+1] != ' ' && text_buffer[index+1] != '\t') {
					percented[position]++;
                    break;
				}
				word[position] = &text_buffer[index];
				new_word = FALSE;
				if (position < MAX_WORDS)
					position++;
			}
			break;
		}

	}

	/* NULL OUT ALL THE WORD POINTERS BEYOND THE LAST WORD */
	for (index = position; index < MAX_WORDS; index++)
		word[index] = NULL;

	wp = 0;
}

// THIS VERSION OF ENCAPSULATE DOESN'T LOOK FOR CERTAIN SPECIAL CHARACTERS
void
command_encapsulate()
{
	int             index,
	                length;
	int             position = 0;
	int             new_word = TRUE;

	length = strlen(text_buffer);

	// QUOTED IS USED TO STORE WHETHER EACH WORD WAS ENCLOSED IN QUOTES
	// IN THE PLAYERS COMMAND - RESET EACH WORD TO NO
    for (index = 0; index < MAX_WORDS; index++) {
		quoted[index] = 0;
	}

	for (index = 0; index < length; index++) {

		// REDUSE EVERYTHING TO LOWER CASE EXCEPT TEXT ENCLOSED IN QUOTES
		text_buffer[index] = tolower((int) text_buffer[index]);

		switch (text_buffer[index]) {
		case ':':
		case '\t':
		case ' ':
			text_buffer[index] = 0;
			new_word = TRUE;
			break;
		case ',':
			text_buffer[index] = 0;
			// SET THIS WORD TO POINT TO A STRING CONSTANT OF 'comma' AS THE
			// COMMA ITSELF WILL BE NULLED OUT TO TERMINATE THE PRECEEDING
			// WORD IN THE COMMAND.
			word[position] = comma;
			if (position < MAX_WORDS)
				position++;
			new_word = TRUE;
			break;
		case '.':
			text_buffer[index] = 0;
			// SET THIS WORD TO POINT TO A STRING CONSTANT OF 'comma' AS THE
			// COMMA ITSELF WILL BE NULLED OUT TO TERMINATE THE PRECEEDING
			// WORD IN THE COMMAND
			word[position] = then;
			if (position < MAX_WORDS)
				position++;
			new_word = TRUE;
			break;
		case ';':
		case '\r':
		case '\n':
			// TERMINATE THE WHOLE COMMAND ON HITTING A NEWLINE CHARACTER, A
			// SEMICOLON OR A HASH
			text_buffer[index] = 0;
			index = length;
			break;
		case '"':
			index++;
			// NEED TO REMEMBER THAT THIS WORD WAS ENCLOSED IN QUOTES FOR 
			// THE COMMAND 'write'	
			quoted[position] = 1;	

			word[position] = &text_buffer[index];

			if (position < MAX_WORDS)
				position++;

			// IF A WORD IS ENCLOSED IN QUOTES, KEEP GOING UNTIL THE END
			// OF THE LINE OR A CLOSING QUOTE IS FOUND, NOT BREAKING AT
			// WHITESPACE AS USUAL
			for (; index < length; index++) {
				if (text_buffer[index] == '"') {
					text_buffer[index] = 0;
					new_word = TRUE;
					break;
				} else if (text_buffer[index] == '\r' || text_buffer[index] == '\n') {
					text_buffer[index] = 0;
					index = length;
					break;
				}
			}
			break;
		default:
			if (new_word) {
				word[position] = &text_buffer[index];
				new_word = FALSE;
				if (position < MAX_WORDS)
					position++;
			}
			break;
		}

	}

	// NULL OUT ALL THE WORD POINTERS BEYOND THE LAST WORD
	for (index = position; index < MAX_WORDS; index++) {
		word[index] = NULL;
	}

	wp = 0;
}

void
jacl_truncate()
{
	int             index,
	                counter,
	                match;
	int             position = 0;

	struct synonym_type *synonym;
	struct filter_type *filter = filter_table;

	// REMOVE ALL THE DEFINED 'filter's FROM THE PLAYER'S COMMAND
	if (filter != NULL) {
		while (word[position] != NULL) {
			match = FALSE;
			do {
				if (!strcmp(word[position], filter->word)) {
					for (index = position; word[index + 1] != NULL;
						 index++)
						word[index] = word[index + 1];
					word[index] = NULL;
					match = TRUE;
				}
				filter = filter->next_filter;
			}
			while (filter != NULL && !match);
			filter = filter_table;
			if (!match)
				position++;
		};
	}

	// SUBTITUTE ALL THE DEFINED 'synonym's IN THE PLAYER'S COMMAND
	if (synonym_table != NULL) {
		for (counter = 0; word[counter] != NULL; counter++) {
			synonym = synonym_table;
			do {
				if (!strcmp(word[counter], synonym->original)) {
					word[counter] = synonym->standard;
					break;
				}
				if (synonym->next_synonym != NULL)
					synonym = synonym->next_synonym;
				else
					break;
			}
			while (TRUE);
		}
	}
}
