package com.smartgwt.sample.client;

import java.util.HashMap;
import java.util.Map;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.JavaScriptObject;
import com.smartgwt.client.core.DataClass;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.SimpleType;
import com.smartgwt.client.data.SimpleTypeFormatter;
import com.smartgwt.client.types.FieldType;
import com.smartgwt.client.util.JSOHelper;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.DataBoundComponent;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.FormItemValueFormatter;
import com.smartgwt.client.widgets.form.FormItemValueParser;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridRecord;

public class CurrencyTypeTest implements EntryPoint {
	
	

	class MCurrencyFormatter implements SimpleTypeFormatter {
		
		
		public String format(Object value, DataClass field, DataBoundComponent component, Record record) {
			
			if(value == null)
				return "";
			
			if(value instanceof JavaScriptObject){
				JavaScriptObject object = (JavaScriptObject) value;
				
				Double amount = JSOHelper.getAttributeAsDouble(object, SilkMCurrency.FIELD_REFAMOUNT);
				if (amount == null) amount = 0D;
				Double curAmount = JSOHelper.getAttributeAsDouble(object, SilkMCurrency.FIELD_CURAMOUNT);
				if (curAmount == null) curAmount = 0D;
				Integer currencyID = JSOHelper.getAttributeAsInt(object, SilkMCurrency.FIELD_CURRENCY_ID);
				if (currencyID == null) currencyID = 0;
				
				
			 return "r:" + amount + ", c:" + curAmount + ", cid:" + currencyID;
			}
		 return (String) value;
		}

	}
	
	 class SilkMCurrency extends SimpleType { 
		public final static String SIMPLETYPE_NAME = "silkMCurrency";
		public final static String FIELD_REFAMOUNT = "refAmount"; 
		public final static String FIELD_CURRENCY_ID = "currencyId";
		public final static String FIELD_CURAMOUNT = "curAmount";
		public SilkMCurrency() { 
			super(SIMPLETYPE_NAME, FieldType.TEXT); 
			
			this.setNormalDisplayFormatter(new MCurrencyFormatter()); 
			this.setShortDisplayFormatter(new MCurrencyFormatter()); 
		}
		
		@Override 
		public void setShortDisplayFormatter(SimpleTypeFormatter formatter) {
			super.setShortDisplayFormatter(formatter); 
		}
		
		@Override public void setNormalDisplayFormatter(SimpleTypeFormatter formatter) {
			super.setNormalDisplayFormatter(formatter); 
		} 
	}

	
	 class SilkMCurrencyEditor extends TextItem {

		private Double refAmount;
		private Double curAmount;
		private Integer currencyID ;
		
		public SilkMCurrencyEditor() {
			super();

			//link the formatter to the editor
			super.setEditorValueFormatter(new MCurrencyEditorValueFormatter());
			super.setEditorValueParser(new MCurrencyEditorValueParser());
	    }
	}
				
		
	 class MCurrencyEditorValueFormatter implements FormItemValueFormatter {
		
		public String formatValue(Object value, Record record, DynamicForm form, FormItem item) {
			
			if(value == null)
				return "";

			if(value instanceof JavaScriptObject){
				JavaScriptObject object = (JavaScriptObject) value;
				
				Double refAmount = JSOHelper.getAttributeAsDouble(object, SilkMCurrency.FIELD_REFAMOUNT);
				if (refAmount == null) refAmount = 0D;
				Double curAmount = JSOHelper.getAttributeAsDouble(object, SilkMCurrency.FIELD_CURAMOUNT);
				if (curAmount == null) curAmount = 0D;
				Integer currencyID = JSOHelper.getAttributeAsInt(object, SilkMCurrency.FIELD_CURRENCY_ID);
				if (currencyID == null) currencyID = 0;
				
				return refAmount + "," + curAmount + "," + currencyID;
			}
			
		 return (String) value;
		}
	}
	
	 class MCurrencyEditorValueParser implements FormItemValueParser {

		public Object parseValue(String value, DynamicForm form, FormItem item) {
			JavaScriptObject jsObject = (JavaScriptObject) item.getValue();
			
			String[] rawStrings = value.split(",");
			if (rawStrings != null && rawStrings.length == 3) {
				jsObject = JavaScriptObject.createObject();
				JSOHelper.setAttribute(jsObject, SilkMCurrency.FIELD_REFAMOUNT, Double.parseDouble(rawStrings[0]));
				JSOHelper.setAttribute(jsObject, SilkMCurrency.FIELD_CURAMOUNT, Double.parseDouble(rawStrings[1]));
				JSOHelper.setAttribute(jsObject, SilkMCurrency.FIELD_CURRENCY_ID, Integer.parseInt(rawStrings[2]));
				SC.logEcho(jsObject);
			}
			return jsObject;
		}
		
	};
	
	private DataSource testDS;
	public void onModuleLoad () {
		
		testDS = new DataSource();
		DataSourceField pkField = new DataSourceField("pk", FieldType.SEQUENCE);
		pkField.setPrimaryKey(true);
		pkField.setCanEdit(false);
		DataSourceField amountField = new DataSourceField();
		amountField.setName("amount");
		
		SimpleType curType = new SilkMCurrency();
		
		amountField.setType(curType);
		amountField.setEditorType(new SilkMCurrencyEditor());
		amountField.setTitle("Amount");
		
		testDS.setClientOnly(true);
		Map testMap = new HashMap();
		testMap.put("curType", "EUR");
		testMap.put(SilkMCurrency.FIELD_REFAMOUNT, 20000);
		
		final JavaScriptObject testObject = JSOHelper.convertMapToJavascriptObject(testMap);
		
		testDS.setTestData(new Record[] {
				new ListGridRecord() {{ setAttribute("pk", 0); setAttribute("amount", testObject); }}
		});
		testDS.setFields(pkField, amountField);
		
		ListGrid testGrid = new ListGrid();
		testGrid.setID("testGrid"); // easier to work with in the developer console
		testGrid.setWidth(300);
		testGrid.setDataSource(testDS);
		testGrid.setAutoFetchData(true);
		testGrid.setCanEdit(true);
		
		testGrid.setNeverValidate(true);
		
		// This would test formatting the edited value before save occurs...
//		testGrid.setAutoSaveEdits(false);
		
		testGrid.draw();

	}

}
