package hu.swankey.ammo.common.yggdrasil.definition;


import hu.swankey.ammo.common.script.yunits.Wrappable;
import hu.swankey.ammo.common.script.yunits.YClass;
import hu.swankey.ammo.common.script.yunits.YMethod;
import hu.swankey.ammo.common.yggdrasil.Yggdrasil;
import hu.swankey.ammo.common.yggdrasil.basics.ComplexObject;
import hu.swankey.ammo.common.yggdrasil.basics.StringField;
import hu.swankey.ammo.common.yggdrasil.basics.YObject;

import java.util.Map;


public abstract class Definition extends ComplexObject {
	
	public static final String KEY_SOURCE = "source";
	public static final String DEFAULT_SOURCE_VALUE = "<no source>";
	
	protected Wrappable wrapped;
	private Definition parent;
	
	protected Definition(String name, ElementDefinitionClass type) {
		super(name, type);
	}
	
	public static ElementDefinitionClass yclass() {
		return ElementDefinitionClass.singleton();
	}
	
	
	public Wrappable getWrapped(){
		return wrapped;
	}
	
//	public void setParent(Definition parent){
//		this.parent = parent;
//	}	
//	
//	public Definition getParent(){
//		return parent;
//	}
	
	public void setSource(String code){
		set(KEY_SOURCE, code);
	}
	
	
	public String getSource(){
		return getStringField(KEY_SOURCE).getValue();
	}	
	
	public abstract void synchronize();
	
	protected void reportChange(){
		if (getContainer() != null)
			getContainer().reportChangedElement(this);
	}

	
	public static class ElementDefinitionClass extends ComplexClass {
		
		private static final String[] PACKAGE_PATH = {Yggdrasil.PACKAGE_DEF };
		private static final String CLASS_NAME = "Def";					
		private static ElementDefinitionClass singleton;
		
		public static ElementDefinitionClass singleton() {
			
			if (singleton == null){
	    		singleton = new ElementDefinitionClass(CLASS_NAME, null);
	    		singleton.addElement( VariableDefinition.yclass().create(KEY_SOURCE, StringField.yclass(), new StringField(KEY_SOURCE, DEFAULT_SOURCE_VALUE)));
	    		singleton.addMethod(SetSource.function);
	    		placeClass(singleton);
			}
			
			return singleton;
		}
		
		protected ElementDefinitionClass(String name, String[] path ) {
			super(name, (path != null? path : PACKAGE_PATH) );
		}
		
    	@Override
    	public Definition create(String name) {
    		throw new UnsupportedOperationException();
    	}
    	
		
    	private static class SetSource extends YMethod {

    		private static final String FUNCTION_NAME = "setSource";
    		private static final String KEY_SOURCE = "source";
    		private static final YClass YCLASS_SOURCE = StringField.yclass();

    		public static final SetSource function = new SetSource();

    		protected SetSource() {
    			super(FUNCTION_NAME);
    			addParameter(KEY_SOURCE, YCLASS_SOURCE, null);
    			setReturnType( YObject.yclass() );
    		}

    		@Override
    		public YObject run(Map<String, YObject> params/*, Map<String, YObject> env*/, YObject thisElement) {
    			
//    			YContainer thisE = (YContainer) thisElement;
//    			YObject obj = params.get(KEY_SOURCE);
//    			
//    			thisE.put(obj);
    			
    			System.out.println("setSource() not implemented!");
//    			
    			return null;
    		}
    	}
	}	
	
}
