std::vector<SyntaxHighlightToken> PolycodeSyntaxHighlighter::parseLua(String text, SyntaxHighlightToken overrideToken) {
	std::vector<SyntaxHighlightToken> tokens;
	
	text = text+"\n";
	
	const int MODE_GENERAL = 0;
	const int MODE_COMMENT = 1;
	const int MODE_STRING = 2;
	const int MODE_METHOD = 3;
	const int MODE_KEYWORD = 4;
	const int MODE_NUMBER = 5;
	const int MODE_MEMBER = 6;
						
	int mode = MODE_GENERAL;	
	bool isComment = false;
	
	if(text.find_first_of("]]") != -1) {
		if(overrideToken.overrideType == SyntaxHighlightToken::TOKEN_TYPE_OVERRIDE_LINE || overrideToken.overrideType == SyntaxHighlightToken::TOKEN_TYPE_OVERRIDE_START ) {
		mode = MODE_COMMENT;
		}
	}
				
	String line = "";
	
	char lastSeparator = ' ';

	for(int i=0; i < text.length(); i++) {
		char ch = text[i];				
		if(contains_char(ch, &separators)) {			

			unsigned int type = mode;
			unsigned int ch_type = mode;
	
			if(ch == '\"' && mode != MODE_COMMENT)
				ch_type = MODE_STRING;
	
			if(mode != MODE_STRING && ch == '('  && mode != MODE_COMMENT) {
				type = MODE_METHOD;
			}

			if(mode != MODE_STRING  && mode != MODE_COMMENT) {
				if(contains(line, &keywords)) {
					type = MODE_KEYWORD;
				}
			}
	
			if(mode != MODE_STRING && !isComment && mode != MODE_COMMENT) {
			
				if(line.isNumber()) {
					type = MODE_NUMBER;
				} else {
					if(lastSeparator == '.' && ch != '.' && ch != ':') {
						type = MODE_MEMBER;
					}							
				}
			}		
	
			if(isComment) {
				type = MODE_COMMENT;
				ch_type = MODE_COMMENT;
			}
				
			if(mode == MODE_COMMENT) {
				type = MODE_COMMENT;
				ch_type = MODE_COMMENT;
			}
			
	
			if(line != "")
				tokens.push_back(SyntaxHighlightToken(line, type));
			tokens.push_back(SyntaxHighlightToken(ch, ch_type));

			if(ch == '-' && lastSeparator == '-' && text[i-1] == lastSeparator && mode != MODE_STRING) {
				isComment = true;
				tokens[tokens.size()-1].type = MODE_COMMENT;
				tokens[tokens.size()-2].type = MODE_COMMENT;				
			}

			if(ch == '[' && lastSeparator == '[' && isComment && mode != MODE_STRING) {
				unsigned int old_mode = mode;
				mode = MODE_COMMENT;
				tokens[tokens.size()-1].overrideType = SyntaxHighlightToken::TOKEN_TYPE_OVERRIDE_START;
				
				// ugly hack for ---[[, which is not a block comment
				if(tokens.size() > 4) {
					if(tokens[tokens.size()-5].text == "-") {
						mode = old_mode;
						tokens[tokens.size()-1].overrideType = SyntaxHighlightToken::TOKEN_TYPE_NO_OVERRIDE;						
					}
				}
			}
			
			if(ch == ']' && lastSeparator == ']') {
				if(mode == MODE_COMMENT) 
					mode = MODE_GENERAL;
				if(mode != MODE_STRING)
					tokens[tokens.size()-1].overrideType = SyntaxHighlightToken::TOKEN_TYPE_OVERRIDE_END;
			}
			
			if(ch == '\n' ) {
				isComment = false;
				mode = MODE_GENERAL;
			}
				

			if(ch == '\"'  && mode != MODE_COMMENT) {
				if(mode == MODE_STRING) {
					mode = MODE_GENERAL;	
				} else {
					mode = MODE_STRING;
				}
			}	
						
			line = "";
			lastSeparator = ch;			
		} else {
			line.append(ch);
		}
	}
	
	for(int i=0; i < tokens.size(); i++) {
		switch(tokens[i].type) {
			case MODE_STRING:
				tokens[i].color = globalSyntaxTheme->colors[4];			
			break;
			case MODE_COMMENT:
				tokens[i].color = globalSyntaxTheme->colors[1];
			break;			
			case MODE_METHOD:
				tokens[i].color = globalSyntaxTheme->colors[3];			
			break;			
			case MODE_KEYWORD:
				tokens[i].color = globalSyntaxTheme->colors[2];
			break;		
			case MODE_NUMBER:
				tokens[i].color = globalSyntaxTheme->colors[6];
			break;		
			case MODE_MEMBER:
				tokens[i].color = globalSyntaxTheme->colors[5];
			break;															
			default:
				tokens[i].color = globalSyntaxTheme->colors[0];
			break;
		}
	}
	
	return tokens;
}
std::vector<SyntaxHighlightToken> PolycodeSyntaxHighlighter::parseLua(String text) {
	std::vector<SyntaxHighlightToken> tokens;
	
	text = text+"\n";
	
	const int MODE_GENERAL = 0;
	const int MODE_COMMENT = 1;
	const int MODE_STRING = 2;
	const int MODE_METHOD = 3;
	const int MODE_KEYWORD = 4;
	const int MODE_NUMBER = 5;
	const int MODE_MEMBER = 6;
						
	int mode = MODE_GENERAL;
	
	bool isComment = false;
	
	String line = "";
	
	char lastSeparator = ' ';

	
	for(int i=0; i < text.length(); i++) {
		char ch = text[i];				
		if(contains(String(ch), separators)) {			

			unsigned int type = mode;
			unsigned int ch_type = mode;

	
			if(ch == '\"' && mode != MODE_COMMENT)
				ch_type = MODE_STRING;
	
			if(mode != MODE_STRING && ch == '('  && mode != MODE_COMMENT) {
				type = MODE_METHOD;
			}

			if(mode != MODE_STRING  && mode != MODE_COMMENT) {
				if(contains(line, keywords)) {
					type = MODE_KEYWORD;
				}
			}
	
			if(mode != MODE_STRING && !isComment && mode != MODE_COMMENT) {
			
				if(line.isNumber()) {
					type = MODE_NUMBER;
				} else {
					if(lastSeparator == '.' && ch != '.' && ch != ':') {
						type = MODE_MEMBER;
					}							
				}
			}		
	
			if(isComment) {
				type = MODE_COMMENT;
				ch_type = MODE_COMMENT;
			}
				
			if(mode == MODE_COMMENT) {
				type = MODE_COMMENT;
				ch_type = MODE_COMMENT;
			}
			
	
			if(line != "")
				tokens.push_back(SyntaxHighlightToken(line, type));
			tokens.push_back(SyntaxHighlightToken(String(ch), ch_type));

			if(ch == '-' && lastSeparator == '-' && mode != MODE_STRING) {
				isComment = true;
				tokens[tokens.size()-1].type = MODE_COMMENT;
				tokens[tokens.size()-2].type = MODE_COMMENT;				
			}

			if(ch == '[' && lastSeparator == '[' && isComment && mode != MODE_STRING) {
				unsigned int old_mode = mode;
				mode = MODE_COMMENT;
				
				// ugly hack for ---[[, which is not a block comment
				if(tokens.size() > 4) {
					if(tokens[tokens.size()-5].text == "-") {
						mode = old_mode;
					}
				}
			}
			
			if(ch == ']' && lastSeparator == ']' && mode == MODE_COMMENT) {
				mode = MODE_GENERAL;
			}
			
			if(ch == '\n' )
				isComment = false;
				

			if(ch == '\"'  && mode != MODE_COMMENT) {
				if(mode == MODE_STRING) {
					mode = MODE_GENERAL;	
				} else {
					mode = MODE_STRING;
				}
			}	
						
			line = "";
			lastSeparator = ch;			
		} else {
			line += String(ch);
		}
	}
	
	for(int i=0; i < tokens.size(); i++) {
		switch(tokens[i].type) {
			case MODE_STRING:
				tokens[i].color = colorScheme[4];			
			break;
			case MODE_COMMENT:
				tokens[i].color = colorScheme[1];			
			break;			
			case MODE_METHOD:
				tokens[i].color = colorScheme[3];			
			break;			
			case MODE_KEYWORD:
				tokens[i].color = colorScheme[2];
			break;		
			case MODE_NUMBER:
				tokens[i].color = colorScheme[6];
			break;		
			case MODE_MEMBER:
				tokens[i].color = colorScheme[5];
			break;															
			default:
				tokens[i].color = colorScheme[0];
			break;
		}
//		printf("%s(%d)", tokens[i].text.c_str(), tokens[i].type);		
	}
	
	return tokens;
}