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

import hu.swankey.ammo.common.AmmoException;
import hu.swankey.ammo.common.yggdrasil.YPackage;
import hu.swankey.ammo.common.yggdrasil.basics.SoftLink;
import hu.swankey.ammo.common.yggdrasil.basics.YObject;

public class VariableDefinition extends ElementDefinition {
	
//	private static final String ID_DEFAULT_VALUE = "default";
	private YObject defaultValue;
	private String classLink;
	
//
//	private VariableDefinition(YClass yclass, String name, Element defaultValue) {
//		this(name, yclass.getClassPathString(), defaultValue);
//	}
	
//	public VariableDefinition(String name, String yclass, Element defaultValue) {
//		this(name, yclass());
//		this.classLink = yclass;
////		put( new SoftLink(ID_CLASS, yclass) );
//		
//		if (defaultValue != null) {
//			defaultValue.setName(ID_DEFAULT_VALUE);
//			this.defaultValue = defaultValue;
////			put( defaultValue );
//		}
//	}

	protected VariableDefinition(String name, VariableDefinitionClass yclass) {
		super(name, yclass);
	}
	
	public static VariableDefinitionClass yclass() {
		return VariableDefinitionClass.singleton();
	}

//	public void setClassName(String className) {
//		//set(ID_CLASS, className);
//		classLink = className;
//	}
	
	public void setWrappedClass(String classPath){
		classLink = classPath;
	}

	public SoftLink getWrappedClass() {
		return new SoftLink(classLink);
	}

	public void setDefaultValue(YObject value) {
		this.defaultValue = value;
	}

	public YObject getDefaultValue() {
		return defaultValue;
	}

	public void setElementAccessLevel(int newLevel){
		setAccessLevel(newLevel);
	}
	
	@Override
	public void synchronize() {
		// TODO Auto-generated method stub
		
	}	

	public YObject getWrappedElement() {
		
//		Element defaultValue = get(ID_DEFAULT_VALUE);

		if (defaultValue != null) {
			
			try {
				YObject value = (YObject) defaultValue.clone();
				value.setName(getName());
				return value;
			} catch (CloneNotSupportedException e) {
				throw new RuntimeException(e);
			}
			
		} else {
			
			YPackage rootPackage = YClass.getRootPackage();
			String[] path = getWrappedClass().getPathStrArray();
			YClass yclass = (YClass) rootPackage.get( path );
			
			if (yclass == null)
				throw new AmmoException("Class not found: '" + getWrappedClass().getValue() + "'");			
			
			YObject element = yclass.create(getName());
			element.setAccessLevel(getAccessLevel());
			return element;

		}
	}
	
//	public ComplexClassDefinition getContainerClass(){
//		Container container = getParent();
//		while(!(container instanceof ClassDefinition))
//			container = container.getParent();
//		return (ComplexClassDefinition) container;
//	}
	
	public static class VariableDefinitionClass extends ElementDefinitionClass {

		private static String CLASS_NAME = "VariableDef";
		private static VariableDefinitionClass singleton;

		private static VariableDefinitionClass singleton() {
			
			if (singleton == null) {
				singleton = new VariableDefinitionClass(CLASS_NAME);
				singleton.addSuperior(ElementDefinition.yclass());
			}
			return singleton;
		}

		protected VariableDefinitionClass(String name)  {
			super(name, null);
		}
		
		public VariableDefinition create(String name, String classPath, YObject value) {
    		VariableDefinition newVarDef = new VariableDefinition(name, this);
    		init(newVarDef);
    		newVarDef.setWrappedClass(classPath);
    		newVarDef.setDefaultValue(value);
    		return newVarDef;
    	}		
		
		public VariableDefinition create(String name, YClass yclass, YObject value) {
    		VariableDefinition newVarDef = new VariableDefinition(name, this);
    		init(newVarDef);
    		newVarDef.setWrappedClass(yclass.getPathString());
    		newVarDef.setDefaultValue(value);
    		return newVarDef;
    	}
		
    	@Override
    	public VariableDefinition create(String name) {
    		VariableDefinition newVarDef = new VariableDefinition(name, this);
    		init(newVarDef);
    		return newVarDef;
    	}

	}	

}
