/**
 * Jason Luu
 * July 22, 2009
 * Tokenizer
 */

#include <string.h>
#include <assert.h>
#include "util.h"
#include "token.h"
#include "ezxml.h"
#include "read_xml_util.h"

enum e_token_type GetTokenTypeFromChar(INP enum e_token_type cur_token_type, INP char cur);

/* Returns a token list of the text for a given string. */ 
t_token *GetTokensFromString(INP const char* inString, OUTP int * num_tokens)
{
	const char *cur;
	t_token * tokens;
	int i, in_string_index, prev_in_string_index;
	boolean has_null;
	enum e_token_type cur_token_type, new_token_type;

	*num_tokens = i = 0;
	cur_token_type = TOKEN_NULL;

	if(inString == NULL) { return NULL; };

	cur = inString;	

	/* Count number of tokens */
	while(*cur)
	{
  		new_token_type = GetTokenTypeFromChar(cur_token_type, *cur);
		if(new_token_type != cur_token_type) {
			cur_token_type = new_token_type;
			if(new_token_type != TOKEN_NULL) {
				i++;
			}
		}
	    ++cur;
	}
	*num_tokens = i;

	if(*num_tokens > 0) {
		tokens = my_calloc(*num_tokens + 1, sizeof(t_token));
	} else {
		return NULL;
	}

	/* populate tokens */
	i = 0;
	in_string_index = 0;
	has_null = TRUE;
	prev_in_string_index = 0;
	cur_token_type = TOKEN_NULL;

	cur = inString;	

	while(*cur)
	{
	    
		new_token_type = GetTokenTypeFromChar(cur_token_type, *cur);
		if(new_token_type != cur_token_type) {
			if(!has_null) {
				tokens[i-1].data[in_string_index - prev_in_string_index] = '\0'; /* NULL the end of the data string */
				has_null = TRUE;
			}
			if(new_token_type != TOKEN_NULL) {
				tokens[i].type = new_token_type;
				tokens[i].data = my_strdup(inString + in_string_index);
				prev_in_string_index = in_string_index;
				has_null = FALSE;				
				i++;
			}
			cur_token_type = new_token_type;
		}
		++cur;
		in_string_index++;
	}

	assert(i == *num_tokens);

	tokens[*num_tokens].type = TOKEN_NULL;
	tokens[*num_tokens].data = NULL;

    
	/* Return the list */ 
	return tokens;
}

void freeTokens(INP t_token *tokens, INP int num_tokens) {
	int i;
	for(i = 0; i < num_tokens; i++) {
		free(tokens[i].data);
	}
	free(tokens);
}


enum e_token_type GetTokenTypeFromChar(INP enum e_token_type cur_token_type, INP char cur) {
	if(IsWhitespace(cur)) {
		return TOKEN_NULL;
	} else {
		if(cur == '[') {
			return TOKEN_OPEN_SQUARE_BRACKET;
		} else if(cur == ']') {
			return TOKEN_CLOSE_SQUARE_BRACKET;
		} else if(cur == '{') {
			return TOKEN_OPEN_SQUIG_BRACKET;
		} else if(cur == '}') {
			return TOKEN_CLOSE_SQUIG_BRACKET;
		} else if(cur == ':') {
			return TOKEN_COLON;
		} else if(cur == '.') {
			return TOKEN_DOT;
		} else if(cur >= '0' && cur <= '9' && cur_token_type != TOKEN_STRING) {
			return TOKEN_INT;
		} else {
			return TOKEN_STRING;
		}
	}
}

boolean checkTokenType(INP t_token token, OUTP enum e_token_type token_type) {
	if(token.type != token_type) {
		return FALSE;
	}
	return TRUE;
}




void my_atof_2D(INOUTP float **matrix, INP int max_i, INP int max_j, INP char *instring) {
	int i, j;
	char *cur, *cur2, *copy, *final;
	int string_count;

	copy = my_strdup(instring);
	final = copy;
	while(*final != '\0') {
		final++;
	}


	cur = copy;
	i = j = 0;
	while(cur != final) {
		string_count = 0;
		while(IsWhitespace(*cur) && cur != final) {
			if(j == max_j) {
				i++;
				j = 0;
			}
			cur++;
		}
		if(cur == final) {
			break;
		}
		cur2 = cur;
		while(!IsWhitespace(*cur2) && cur2 != final) {
			cur2++;
		}
		*cur2 = '\0';
		assert(i < max_i && j < max_j);
		matrix[i][j] = atof(cur);
		j++;
		cur = cur2;
		*cur = ' ';
	}

	assert ((i == max_i && j == 0) || (i == max_i - 1 && j == max_j));
	
	free(copy);
}

