package surface;

import hu.swankey.ammo.common.script.AmmoScriptException;
import hu.swankey.ammo.common.script.AmmoScriptSyntaxException;
import hu.swankey.ammo.common.script.Synthetizer;
import hu.swankey.ammo.common.yggdrasil.definition.Definition;
import hu.swankey.ammo.common.yggdrasil.definition.MethodDefinition;
import hu.swankey.ammo.common.yggdrasil.definition.AttributeDefinition;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;

import client_engine.ClientController;

public class ScriptEditor extends Thread {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private static final String TITLE_PREFIX = "Editing ";
	private static final String BUTTON_OK = "Ok";
	private static final String VALIDATION_OK = "None.";
	private static final String LABEL_ERRORS = "Problems:";

	private static final int TEXTAREA_ROWS = 20;
	private static final int TEXTAREA_COLUMNS = 100;
	
	
	private Definition originalDef;
	private Definition currentDef;
	private final JFrame editorFrame = new JFrame();
	private final JTextArea textarea;
	private final JTextArea errorsArea = new JTextArea();
	private final JButton okButton = new JButton(BUTTON_OK);
	
	private boolean running = true;
	
	private ScriptEditor(Definition def){
		
		editorFrame.setTitle(TITLE_PREFIX + def.getPathString());
		
		originalDef = def;
		textarea = new JTextArea(def.getSource(), TEXTAREA_ROWS, TEXTAREA_COLUMNS);
		textarea.setFont( Font.decode(Font.MONOSPACED).deriveFont(Font.BOLD) );
		textarea.setBorder( BorderFactory.createLineBorder(null));
		textarea.addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {

			}

			@Override
			public void keyReleased(KeyEvent e) {
				parse();
			}			

			@Override
			public void keyPressed(KeyEvent e) {
			}
		});
		
		errorsArea.setEditable(false);
		errorsArea.setBackground( null );
		errorsArea.setFont( Font.decode(Font.MONOSPACED).deriveFont(Font.BOLD) );
		errorsArea.setText(VALIDATION_OK);
		
		
		okButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
//				saveModifications();			
				editorFrame.dispose();
				running = false;
			}
		});
		
		JLabel label_errors = new JLabel(LABEL_ERRORS);
		
		GroupLayout layout = new GroupLayout(editorFrame.getContentPane());
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);   
		editorFrame.setLayout(layout);
		
		layout.setVerticalGroup(layout.createSequentialGroup().addComponent(
				textarea)
				.addComponent(label_errors)
				.addComponent(errorsArea)
				.addGroup(layout.createParallelGroup().addComponent(okButton)) );

		layout.setHorizontalGroup(layout.createParallelGroup().addComponent(
				textarea)
				.addComponent(label_errors)
				.addComponent(errorsArea)
				.addGroup(layout.createSequentialGroup().addComponent(okButton)));		
		
		editorFrame.pack();
		editorFrame.setLocationRelativeTo(null);
		editorFrame.setVisible(true);
		
		start();
	}
	
	@Override
	public void run(){
		while (running) {
			
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	
	public static String showEditor(Definition def, ClientController controller) {
		
		ScriptEditor scriptEditor = new ScriptEditor(def);
		try {
			scriptEditor.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		return scriptEditor.textarea.getText();
	}
	
	private void parse(){
		
		try {
			
			if (originalDef instanceof MethodDefinition)
				Synthetizer.createMethodDefinition(textarea.getText());
			else if (originalDef instanceof AttributeDefinition)
				Synthetizer.createVariableDefinition(textarea.getText());
			else
				throw new RuntimeException("Unknown definition!");
			
			errorsArea.setText(VALIDATION_OK);
			okButton.setEnabled(true);
		} catch (AmmoScriptSyntaxException ex) {
			errorsArea.setText( ex.errorList() );
			okButton.setEnabled(false);
		} catch (AmmoScriptException ex) {
			errorsArea.setText( ex.getMessage() );
			okButton.setEnabled(false);
		}
	}
	
	
//	public void saveModifications() {
//		System.out.println("Warning! 'saveModifications()' not implemented!");
//	}

}
