package hu.swankey.ammo.common.yggdrasil;

import hu.swankey.ammo.common.script.AmmoScriptException;
import hu.swankey.ammo.common.script.yunits.YMethod;
import hu.swankey.ammo.common.yggdrasil.basics.ComplexObject;
import hu.swankey.ammo.common.yggdrasil.basics.YObject;
import hu.swankey.logging.LoggerInitialiser;

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;

public class ScriptManager implements TreeModelListener {

    private final String NAME_OF_AUTOSCRIPT = "autoscript";
    private Yggdrasil yggdrasil;
    //private HashMap<StringField, Function> autoscripts = new HashMap<StringField, Function>();
    //private ArrayList<Script> autoscripts = new ArrayList<Script>();
    
    private ArrayList<ComplexObject> autoComplexes = new ArrayList<ComplexObject>();



    public ScriptManager(Yggdrasil yggdrasil) {

        LoggerInitialiser.initLog(this.getClass().getName());

        if (yggdrasil == null)
            throw new RuntimeException("Yggdrasil cannot be null");

        this.yggdrasil = yggdrasil;

        Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Waiting for init..");
    }



    public void init() {
        yggdrasil.getTreeModel(yggdrasil.getRoot()).addTreeModelListener(this);
        Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Init completed.");
    }



    public void executeAutoScripts() {
        for (ComplexObject autoComplex : autoComplexes) {
        	
            try {
            	YMethod autoMethod = autoComplex.getMethod(NAME_OF_AUTOSCRIPT, null);
//            	System.out.println("Run: " + autoMethod.getWrapperElement().getPathString());
            	
            	//Map<String, YObject> env = new HashMap<String, YObject>();
            	//env.put(Yggdrasil.VAR_PARENT, autoComplex);
            	
            	autoMethod.run(null, /*env,*/ autoComplex);
//                if (!script.isParsed())
//                    script.parse();
//                script.run(null);
            } catch (AmmoScriptException ex) {
                Logger.getLogger(ScriptManager.class.getName()).log(Level.SEVERE, "Exception thrown while running autoscript at '" + autoComplex.getPathString() + "': \n" + ex.getMessage(), ex);
                ex.printStackTrace();
            }
        }
    }


    @Override
    public void treeNodesChanged(TreeModelEvent e) {
        //Object o = e.getSource();

//        if (o instanceof Script) {
//            Script scriptfield = (Script) o;
//            boolean contains = autoscripts.contains(scriptfield);
//            boolean autoscript = scriptfield.getName().equals(NAME_OF_AUTOSCRIPT);
//
//            if (contains && !autoscript)
//                autoscripts.remove(scriptfield);
//
//            if (!contains && autoscript)
//                autoscripts.add(scriptfield);
//        }
        
        //System.out.println("ScriptManager figyelmen kívül hagyja a csomópont-változásokat!");
        
//        for (Object o : e.getChildren()){
//        	System.out.println("Csomópont-változás: " + ((Element)o).getName() );
//        }

    }



    @Override
    public void treeNodesInserted(TreeModelEvent e) {
        for (Object o : e.getChildren()){
        	if (o instanceof ComplexObject && ((ComplexObject)o).getMethod(NAME_OF_AUTOSCRIPT, null) != null) {
        		autoComplexes.add((ComplexObject)o);
        		Logger.getLogger(this.getClass().getName()).log(Level.INFO, "AutoComplex registered: " + ((ComplexObject) o).getPathString());
        	}
        }
    }



    @Override
    public void treeNodesRemoved(TreeModelEvent e) {
        for (Object o : e.getChildren())
            remove((YObject) o);
    }



    private void remove(YObject element) {

    	throw new UnsupportedOperationException();
//        if (element instanceof Script && ((StringField) element).getName().equals(NAME_OF_AUTOSCRIPT)) {
//            StringField autoscript = (Script) element;
//            autoscripts.remove(autoscript);
//            Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Autoscript unregistered: " + autoscript.getPathString());
//        }
//
//        if (element instanceof Container) {
//            for (Element subelement : ((Container) element).getElements()) {
//                remove(subelement);
//            }
//        }
    }



    @Override
    public void treeStructureChanged(TreeModelEvent e) {
        System.out.println("ScriptManager not support treeStructureChanged event, yet..");
    }
}
