package language.code;

import language.CodeLanguage;
import background.CommandManager;
import background.VariableManager;
import background.commands.*;

public class CTypeCode extends CodeLanguage {

	public CTypeCode(CommandManager cm) { super(cm); }


	@Override
	public void createDictionary() {
		for (String type: VariableManager.getVariableTypes()) {
			dictionary.put(type, "premenna");
		}				
		addToDictionary("for", "for");
		addToDictionary("if", "if");
		addToDictionary("while", "while");		
		addToDictionary("scanf", "vstup");
		addToDictionary("printf", "vystup");
	}
	
	@Override
	public String getRegexForUpdate() {
		return ".*[a-zA-Z\\]] *=.*"; 			// je daco, co konci pismenom alebo koncom hranatej zatvorky, za tym moze a nemusi byt medzera, potom rovnitko, potom hocico
	}

	@Override
	public String getStringForUpdate() {
		return "="; 			// je daco, co konci pismenom alebo koncom hranatej zatvorky, za tym moze a nemusi byt medzera, potom rovnitko, potom hocico
	}
	
	@Override
	public String getEOLRegex() {
		return ";";
	}
	
	@Override
	public void recognizeData(String s, Command c) {
		c.vizualize = false;
		switch (c.getType()) {
			case "Variable": {	/* Format: int meno; */			
				VariableCommand c2 = (VariableCommand) c;				
				String parts[] = s.split("[ ]+"); 
				c2.type = parts[0].trim();
								
				if (parts[1].contains("[")) {						// bude to inicializacia pola
					String subparts[] = parts[1].trim().split("[\\[\\]]");
					c2.name = subparts[0].trim();
					c2.array = true;
					c2.setSize(subparts[1].trim());					
					if (subparts.length>2) {
						c2.array = false;
						c2.table = true;
						c2.setSize2(subparts[3].trim());
					}
				} else {									// bude inicializacia zakladnej premennej
					c2.name = parts[1].trim();				
				}
				break;
			}				
			case "Operation": {	/* Format: i=i+10; */			
				Operation c2 = (Operation) c;				
				String parts[] = s.split(this.getStringForUpdate(), 2); 

				if (parts[0].contains("[")) {						// bude to uprava pola
					String subparts[] = parts[0].trim().split("[\\[\\]]");
					c2.name = subparts[0].trim();				
					c2.array = true;					
					c2.setIndex(subparts[1].trim());
					if (subparts.length>2) {
						c2.array = false;
						c2.table = true;
						c2.setIndex2(subparts[3].trim());
					}

				} else {			 						// bude uprava zakladnej premennej
					c2.name = parts[0].trim();				
				}

				c2.decomposeValue(parts[1].trim(), c2.name);
				break;
			}
			case "If": {	/* Format: if (podmienka==true) */			
				IfSegment c2 = (IfSegment) c;				
				String parts[] = s.split(" ", 2); 				
				String x = parts[1].substring(1, parts[1].length()-1);		// odstranim vonkajsie zatvorky				
				c2.setCondition(x);
				break;
			}
			case "While": {	/* Format: while (podmienka==true) */			
				Cycle c2 = (Cycle) c;				
				String parts[] = s.split(" ", 2); 				
				String x = parts[1].substring(1, parts[1].length()-1);		// odstranim vonkajsie zatvorky
				c2.setCondition(x);
				break;
			}
			case "For": {	/* Format: for (i=1; i<=5; i=i+1) */			
				Cycle c2 = (Cycle) c;	
				String parts[] = s.split(" ", 2);			
				String subparts[] = parts[1].substring(1, parts[1].length()-1).split(",");

				Operation init = (Operation) commandManager.getCommand("Operation", c2.vizualize);
				recognizeData(subparts[0].trim(), init);
				c2.init = init;
				init.codeLine = c2.codeLine;
				
				c2.setCondition(subparts[1].trim());

				Operation inc = (Operation) commandManager.getCommand("Operation", c2.vizualize);
				recognizeData(subparts[2].trim(), inc);
				c2.increment = inc;
				inc.codeLine = c2.codeLine;
				break;
			}
			case "Read": {   /* Format: scanf(%d, number) */
				Read c2 = (Read) c;
				String parts[] = s.split("[,)]");

				if (parts[1].contains("[")) {						// bude to pole
					String subparts[] = parts[1].trim().split("[\\[\\]]");
					c2.name = subparts[0].trim();				
					c2.array = true;					
					c2.setIndex(subparts[1].trim());
					if (subparts.length>2) {
						c2.array = false;
						c2.table = true;
						c2.setIndex2(subparts[3].trim());
					}
				} else {			 						// bude zakladna premenna
					c2.name = parts[1].trim();				
				}								
				break;
				
			}
			case "Write": {   /* Format: printf("string")   OR   printf(variable) */
				Write c2 = (Write) c;
				String parts[] = s.split("[()]");
				parts[1] = parts[1].trim();

				if (parts[1].contains("[")) {						// bude to pole
					String subparts[] = parts[1].trim().split("[\\[\\]]");
					c2.name = subparts[0].trim();
					c2.array = true;					
					c2.setIndex(subparts[1].trim());
					if (subparts.length>2) {
						c2.array = false;
						c2.table = true;
						c2.setIndex2(subparts[3].trim());
					}
				} else if (parts[1].startsWith("\"") && parts[1].endsWith("\"")) {			 						
					c2.value = parts[1].replace("\"", "");;
				} else {											// bude zakladna premenna
					c2.name = parts[1].trim();				
				}								
				break;
				
			}
		}
	}	

	
	
	@Override
	public String changeFormat(String s) {
		return formatProcess(s, "{", "}");
	}	
}
