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.ComplexYObject;
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 ComplexYObject {
	
	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, DefinitionClass type) {
		super(name, type);
	}
	
	public static DefinitionClass yclass() {
		return DefinitionClass.singleton();
	}
	
	
	public Wrappable getWrapped(){
		return wrapped;
	}
	
	public void setLogicalParent(Definition parent){
		this.parent = parent;
	}	
	
	public Definition getLogicalParent(){
		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 (getParent() != null)
			getParent().reportChangedElement(this);
	}

	
	public static class DefinitionClass extends ComplexYClass {
		
		private static final String[] PACKAGE_PATH = {Yggdrasil.PACKAGE_DEF };
		private static final String CLASS_NAME = "Definition";					
		private static DefinitionClass singleton;
		
		public static DefinitionClass singleton() {
			
			if (singleton == null){
	    		singleton = new DefinitionClass(CLASS_NAME, null);
	    		singleton.addElement( YAttributeDefinition.yclass().create(KEY_SOURCE, StringField.yclass(), new StringField(KEY_SOURCE, DEFAULT_SOURCE_VALUE)));
	    		singleton.addMethod(SetSource.function);
	    		placeClass(singleton);
			}
			
			return singleton;
		}
		
		protected DefinitionClass(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;
    		}
    	}
	}	
	
}
