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

import hu.swankey.ammo.common.script.yunits.YClass;
import hu.swankey.ammo.common.script.yunits.YMethod;
import hu.swankey.ammo.common.script.yunits.YSimpleClass;

import java.util.Map;

public class IntegerField extends SimpleObject {

	/** Default value */
	public static final Integer DEFAULT_VALUE = 0;

	public IntegerField(String name) {
		this(name, yclass(), null);
	}
	
	public IntegerField(Integer value) {
		this(value.toString(), yclass(), value);
	}

	public IntegerField(String name, Integer value) {
		this(name, yclass(), value);
	}

	protected IntegerField(String name, IntegerClass type, Object value) {
		super(name, type, value);
	}
	
	public static IntegerClass yclass(){
		return IntegerClass.singleton();
	}

//	protected IntegerField(IntegerType type, String name, Integer value,
//			int accessLevel) {
//		super(name, type, value, accessLevel);
//	}

	@Override
	public void setValue(Object value) {
		if (value instanceof Integer)
			super.setValue(value);
		else
			throw new RuntimeException(
					"'value' should be an Integer, but it is a(n) "
							+ (value == null? "null" : value.getClass()));
	}

	@Override
	public Integer getValue() {
		return (Integer) super.getValue();
	}

//	@Override
//	public String toString() {
//		return getValue();
//	}

	@Override
	public IntegerClass getYClass() {
		return (IntegerClass) super.getYClass();
	}
	
	public Object clone(){
		IntegerField newInt = new IntegerField(getName());
		newInt.setValue( getValue() );
		return newInt;
	}

	public static class IntegerClass extends YSimpleClass {
		
		private static final String CLASS_NAME = "Integer";
		private static IntegerClass SINGLETON;
		
		public static IntegerClass singleton(){
			if (SINGLETON == null){
				SINGLETON = new IntegerClass(CLASS_NAME);
				SINGLETON.addSuperior( SimpleObject.yclass() );
				SINGLETON.addMethod(Addition.function);
				SINGLETON.addMethod(Substraction.function);
				placeClass(SINGLETON);
			}
			return SINGLETON;
		}

		protected IntegerClass(String name) {
			super(name);
		}

	    public IntegerField create(String name) {
	         return new IntegerField(name, this, null);
	    }

        @Override
        public Integer getDefaultValue() {
            return DEFAULT_VALUE;
        }	

		@Override
		public String getName() {
			return CLASS_NAME;
		}
		
		
		private static class Addition extends YMethod {

			private static final String FUNCTION_NAME = "+";
			private static final String KEY_VALUE = "value";
			private static final YClass YCLASS_VALUE = IntegerField.yclass();

			public static final Addition function = new Addition();

			protected Addition() {
				super(FUNCTION_NAME);
				addParameter(KEY_VALUE, YCLASS_VALUE, null);
				setReturnType(IntegerField.yclass());
			}

			@Override
			public YObject run(Map<String, YObject> params/*,Map<String, YObject> env*/, YObject thisElement) {
				
				int newValue = ((IntegerField)params.get(KEY_VALUE)).getValue() + ((IntegerField)thisElement).getValue();

				return new IntegerField(newValue);
			}
		}
		
		private static class Substraction extends YMethod {

			private static final String FUNCTION_NAME = "-";
			private static final String KEY_VALUE = "value";
			private static final YClass YCLASS_VALUE = IntegerField.yclass();

			public static final Substraction function = new Substraction();

			protected Substraction() {
				super(FUNCTION_NAME);
				addParameter(KEY_VALUE, YCLASS_VALUE, null);
				setReturnType(IntegerField.yclass());
			}

			@Override
			public YObject run(Map<String, YObject> params/*,Map<String, YObject> env*/, YObject thisElement) {
				
				int newValue = ((IntegerField)thisElement).getValue() - ((IntegerField)params.get(KEY_VALUE)).getValue();

				return new IntegerField(newValue);
			}
		}	
	}
}