#include "lexer.h"
#include <iostream>
#include <cctype>
#include <string>
#include <map>


using namespace std;


int lineNumber = 0;
					  //01234567	
const string symbols = "+-*();/\"";
const TokenType tt_symbols[7] = {T_PLUS,T_MINUS,T_STAR,T_LPAREN,T_RPAREN,T_SC,T_SLASH};

const string key_words[5] = {"int","string","set","print","println"};

const TokenType Kw[5]={T_INT,T_STRING,T_SET,T_PRINT,T_PRINTLN};


map<TokenType,string> Data_Tokens
{
	{T_INT,"T_INT"},
	{T_STRING,"T_STRING"},
	{T_SET,"T_SET"},
	{T_PRINT,"T_PRINT"},
	{T_PRINTLN,"T_PRINTLN"},
	{T_ID,"T_ID"},
	{T_ICONST,"T_ICONST"},
	{T_SCONST,"T_SCONST"},
	{T_PLUS,"T_PLUS"},
	{T_MINUS,"T_MINUS"},
	{T_STAR,"T_STAR"},
	{T_SLASH,"T_SLASH"},
	{T_LPAREN,"T_LPAREN"},
	{T_RPAREN,"T_RPAREN"},
	{T_SC,"T_SC"},
	{T_ERROR,"T_ERROR"},
	{T_DONE,"T_DONE"},
};



ostream& operator<<(ostream& c_out, const Token& tok)
{
	c_out<<Data_Tokens[tok.GetTokenType()]; 
	return c_out;
}


Token getToken(istream& br)
{
 	
 	char current_char; 	
 	string lexeme ="";
 	TokenType TT;
 	
 	br.peek();
 	
 	if(br.peek() != EOF)
 	{	
	 	while((current_char = br.get()) != EOF || current_char == br.bad())
	 	{	
	 		//IDENTIFIER
	 		if(isalpha(current_char))
	 		{
	 			//bool kword =false;
	 			lexeme = current_char;
	 			
	 			while(isalnum(br.peek()))
	 			{
	 				current_char =  br.get();
	 				lexeme += current_char;
	 				
	 				for(unsigned int k =0; k < 5; k++)
	 				{
			 			if(lexeme.size() == key_words[k].size())
	 					{	//KEYWORD 
	 						if(key_words[k].compare(lexeme) == 0)
	 						{
	 							if(!isalpha(br.peek()))
	 								return Kw[k];
	 						}
	 					}
	 				}
	 			}
	 			TT = T_ID;
	 				 			
	 			break;
	 		}

	 		//DIGIT
	 		else if(isdigit(current_char))
	 		{
	 			lexeme = current_char;
	 			while(isdigit(br.peek()))
	 			{
	 				current_char = br.get();
	 				lexeme += current_char;
	 			}
	 			
	 			TT = T_ICONST;
	 			
	 			break;
	 		}
	 		
	 		//SYMBOLS
	 		else
	 		{
	 			//WHITESPACES
	 			if(current_char=='\n' || isblank(current_char))
	 				continue;
	 			
	 			//COMMENTS
	 			if(current_char == symbols[6] && br.peek() == symbols[6])
	 				return T_DONE;

	 			//STRING CONST
	 			else if (current_char == symbols[7])
	 			{
	 				bool open_close_quote = false;	
	 				lexeme = current_char;
	 				
	 				while(!open_close_quote && br.peek() != '\n')
	 				{
	 					current_char = br.get();
	 					lexeme += current_char;
	 					
	 					if(current_char == symbols[7])
	 						open_close_quote = true;
	 				}
	 				
	 				if(br.peek() == '\n' && open_close_quote == false)
	 					lexeme += br.get();
	 				
	 				TT =  open_close_quote ? T_SCONST : T_ERROR;

	 				break;
	 			}
	 			
	 			//BALANCE OF SYMBOLS
	 			else
	 			{
	 				for(unsigned int i =0; i<(symbols.size() - 1); i++)
	 				{
	 					if(current_char == symbols[i])
	 					{
	 						TT = tt_symbols[i];
	 						break;
	 					}
	 					
	 					else
	 					{
	 						lexeme = current_char;
		 					TT= T_ERROR;
		 				}
	 				}
	 				break;
	 			}
	 		}//else
	 	}//while
	 	//cout<<"DID NOT ENTER WHILE"<<endl;
	}//if
	
	else
		TT = T_DONE;
 	
 	Token _token(TT,lexeme);
	
	return _token;
}


