package language;

import java.util.ArrayList;
import java.util.Iterator;


import background.commands.Command;

public class Translator {


		public CodeLanguage codeLang;
		public VizLanguage vizLang;
				
		public Translator(CodeLanguage code, VizLanguage viz) {
			codeLang = code;
			vizLang = viz;
		}
		
		public Command translateCommand(String s) {
			// skusim to prelozit aj ako slovo standardneho programu aj ako vizualizacny prikaz, priorita je na vizualizacnom prikaze pri nejednoznacnosti
			Command c1 = codeLang.translate(s);			
			Command c2 = vizLang.translate(s);
					
			if (c2!=null) { vizLang.recognizeData(s, c2); c2.setCodeLine(s); return c2; }
			else { 
				if (c1!=null) { codeLang.recognizeData(s, c1); c1.setCodeLine(s);} 
				else { codeLang.commandManager.errorManager.errorHappened("NotTranslated");} 
				return c1;												// ak je aj c1 null tak to vrati celkovo null 
			} 					
		}
		
		
		
		public ArrayList<Command> translate(String input) {
			input = codeLang.changeFormat(input);
			return this.recognize(input);
		}
		
		
		public ArrayList<Command> recognize(String input) {
			ArrayList<String> lines = new ArrayList<String>();
			ArrayList<Command> commands = new ArrayList<Command>();
			String xLine, innerLines;
			Command c;
			Boolean lineIsSet;
		
			String xLines[] = input.split("[\\r\\n"+ vizLang.getEOLRegex() + codeLang.getEOLRegex() +"]+"); 		
			for (int i=0; i<xLines.length; i++) { lines.add(xLines[i]);}		
			
			Iterator<String> lineIterator = lines.iterator();		
			xLine = lineIterator.next().trim();
			lineIsSet = true;
					
			while ((xLine!=null) && lineIsSet) {
				lineIsSet = false;
				c = this.translateCommand(xLine.trim());
				
				if (c!=null) {
					
					if (c.getType().equals("Repeat") || c.getType().equals("While") || c.getType().equals("For") || c.getType().equals("If")) {				
						innerLines = "";
						while (lineIterator.hasNext() && !lineIsSet) {
							xLine = lineIterator.next().trim();
							
							if (xLine.startsWith("*")) innerLines = innerLines + xLine.substring(1)+";";		// potrebujem useknut aj tu hviezdicku z vnutornych riadkov
							else lineIsSet = true;						
						}					
						if (innerLines!="") c.innerCommands = this.recognize(innerLines); // spracujem vnutorne casti						
					}

					if (c!=null) commands.add(c);					// pokial som ho uspesne prelozila, pridam si ho do zoznamu prikazov
					
					if (!lineIsSet && lineIterator.hasNext()) {xLine = lineIterator.next().trim(); lineIsSet = true;}				
				}						
			}		
			return commands;
		}

		

		/* ***************** HIGHLIGHTING **************** */
		
		
		public String addHTMLClass(String s, String xClass) {
			if (xClass.isEmpty()) return s;
			else return "<span class='" + xClass + "'>" + s + "</span>";
		}

		
		public String checkForKeyword(String s) {						 
			if (vizLang.checkForKeyword(s)) return "viz";
			if (codeLang.checkForKeyword(s)) return "code";
			return "";
		}
				
		public static String processForHTML(String s) {		
			return s.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");				
		}
		
		public String highlightHTML(String s) {				
			String style = "body {color: black; font-family: 'Lucida Console', Monaco, sans; font-size: 10px;} .tech {color: blue;}  .viz { color: red; }  .code { color: green; } .param {color:orange;}";	
			String result = "<html><head><style>"+ style +"</style></head><body>";
			
			s = codeLang.changeFormat(s);
			
			s = processForHTML(s);			
			s = s.replaceAll("\\*", addHTMLClass("*", "tech"));
			s = s.replaceAll("#", addHTMLClass("#", "tech"));
			s = s.replaceAll("\\(", addHTMLClass("(", "tech"));
			s = s.replaceAll("\\)", addHTMLClass(")", "tech"));
			
			for (String keyword: codeLang.getKeywords()) {
				s = s.replaceAll(keyword, addHTMLClass(keyword, "code"));				
			}

			for (String keyword: vizLang.getKeywords()) {
				s = s.replaceAll(keyword, addHTMLClass(keyword, "viz"));
			}
			
			for (String keyword: vizLang.getParamWords()) {
				s = s.replaceAll(keyword, addHTMLClass(keyword, "param"));
			}						
			
			s = s.replaceAll("[\\r\\n]+", "<br>");
			result += s;
			
			result += "</body></html>";		
			
			return result;
		}
		

		
		
		
}
