/**
 * Jason Luu
 * July 22, 2009
 * Tokenizer
 */

#include <cstring>
using namespace std;


#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_util.h"
#include "vtr_memory.h"

#include "token.h"
#include "read_xml_util.h"

enum e_token_type GetTokenTypeFromChar(const enum e_token_type cur_token_type,
		const char cur);

bool IsWhitespace(char c);

/* Returns true if character is whatspace between tokens */
bool IsWhitespace(char c) {
	switch (c) {
	case ' ':
	case '\t':
	case '\r':
	case '\n':
		return true;
	default:
		return false;
	}
}

/* Returns a token list of the text for a given string. */
t_token *GetTokensFromString(const char* inString, int * num_tokens) {
	const char *cur;
	t_token * tokens;
	int i, in_string_index, prev_in_string_index;
	bool has_null;
	enum e_token_type cur_token_type, new_token_type;

	*num_tokens = i = 0;
	cur_token_type = TOKEN_NULL;

	if (inString == nullptr) {
		return nullptr;
	};

	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 = (t_token*)vtr::calloc(*num_tokens + 1, sizeof(t_token));
	} else {
		return nullptr;
	}

	/* 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 = vtr::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++;
	}

	VTR_ASSERT(i == *num_tokens);

	tokens[*num_tokens].type = TOKEN_NULL;
	tokens[*num_tokens].data = nullptr;

	/* Return the list */
	return tokens;
}

void freeTokens(t_token *tokens, const int num_tokens) {
	int i;
	for (i = 0; i < num_tokens; i++) {
		free(tokens[i].data);
	}
	free(tokens);
}

enum e_token_type GetTokenTypeFromChar(const enum e_token_type cur_token_type,
		const 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;
		}
	}
}

bool checkTokenType(const t_token token, enum e_token_type token_type) {
	if (token.type != token_type) {
		return false;
	}
	return true;
}

void my_atof_2D(float **matrix, const int max_i, const int max_j,
		const char *instring) {
	int i, j;
	char *cur, *cur2, *copy, *final;

	copy = vtr::strdup(instring);
	final = copy;
	while (*final != '\0') {
		final++;
	}

	cur = copy;
	i = j = 0;
	while (cur != final) {
		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';
		VTR_ASSERT(i < max_i && j < max_j);
		matrix[i][j] = vtr::atof(cur);
		j++;
		cur = cur2;
		*cur = ' ';
	}

	VTR_ASSERT((i == max_i && j == 0) || (i == max_i - 1 && j == max_j));

	free(copy);
}

/* Date:July 2nd, 2013													*
 * Author: Daniel Chen													*
 * Purpose: Checks if the number of entries (separated by whitespace)	*
 *	        matches the the expected number (max_i * max_j),			*
 *			can be used before calling my_atof_2D						*/
bool check_my_atof_2D(const int max_i, const int max_j,
		const char *instring, int * num_entries){

	/* Check if max_i * max_j matches number of entries in instring */
	const char *cur = instring;
	bool in_str = false;
	int entry_count = 0;

	/* First count number of entries in instring */
	while (*cur != '\0'){
		if(!IsWhitespace(*cur) && !in_str){
			in_str = true;
			entry_count ++;
		}
		else if(IsWhitespace(*cur)){
			in_str = false;
		}
		cur++;
	}
	*num_entries = entry_count;
	
	if(max_i * max_j != entry_count) return false;
	return true;
}

