package com.fitbank.web;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;

import com.fitbank.common.BeanManager;
import com.fitbank.common.Clonador;
import com.fitbank.common.helper.FormatDates;
import com.fitbank.common.logger.FitbankLogger;
import com.fitbank.dto.management.Detail;
import com.fitbank.dto.management.Field;
import com.fitbank.dto.management.FormatProperties;
import com.fitbank.dto.management.Record;
import com.fitbank.dto.management.Table;
import javax.servlet.ServletRequest;

public class BindHelper {
	private DataManage dm;

	private ServletRequest request;

	private FacesUtil util;

	public BindHelper(FacesUtil pUtil) throws Exception {
		util = pUtil;
		this.dm = util.getDm();
		this.request = util.getRequest();
		this.bind();
	}

	@SuppressWarnings("unchecked")
	private void bind() throws Exception {
		Enumeration<String> keys = request.getParameterNames();
		while(keys.hasMoreElements()) {
			String key=keys.nextElement();
			try{
			if (key.indexOf("dm.") != 0) {
				continue;
			}
			FitbankLogger.getLogger().debug("key:"+key);
			List<String> address = this.getAddress(key);
			
			Object last = this.getLast(address);
			String lastAtt=address.get(address.size() - 1);
			if(lastAtt.compareTo(	"value_displayed_")==0){
				//lastAtt="value";
				continue;
			}
			String val=correctValue(request.getParameter(key));
			FitbankLogger.getLogger().debug(key+"="+val);
			if(last instanceof Field){
				String datatype=((Field)last).getDatatype();
				if(datatype!=null&&datatype.compareTo("dijit.form.DateTextBox")==0){
					try{
					SimpleDateFormat sdf=new SimpleDateFormat(FormatProperties.getInstance().getStringValue("date.format"));
					if(val.lastIndexOf("-")==5){
					 java.util.Date dVal= sdf.parse(val);
					 val=FormatDates.getInstance().getTransportDateFormat().format(dVal);
					}
					}catch(Exception e1){
						
					}
				}
			}
                        if(last instanceof Map){
                        Map m=(Map)last;
                        m.put(lastAtt, val);
                        }else{
			BeanManager.setBeanAttributeValue(last, lastAtt, val);
                        }
                        }catch(Exception e){
				FitbankLogger.getLogger().warn("Campo con error "+key+" "+e.getMessage());
				continue;
			}
		}
	}
  private String correctValue(String pVal){
  	try{
  		String val=pVal;
  		try{
  			if(pVal.trim().indexOf(",")>-1){
  				DecimalFormatSymbols dfs=new DecimalFormatSymbols(new Locale("en"));//this.getLanguage()));
  			 	 DecimalFormat df1=new DecimalFormat("###,###,###,###,##0.00",dfs);  
  		 	 BigDecimal v=new BigDecimal(""+df1.parse(pVal));
  			 val=v.toString();
  			}
  		}catch(Exception e1){
  			val=pVal;
  		}
  		return val;
  	}catch(Exception e){
  		return pVal;
  	}
  }
	private Object getLast(List<String> pAddress) throws Exception {
		Object last = this.dm;
                if(pAddress.size()==1){
                 return last;
                }
		for (int i = 0; i < pAddress.size()-1; i++) {
			try {
				last = this.getObject(last, pAddress.get(i));
			} catch (Exception e) {
				throw e;
			}
		}
		return last;
	}

	private List<String> getAddress(String pKey) {
		List<String> data = new ArrayList<String>();
		StringTokenizer st = new StringTokenizer(pKey, ".");
		boolean first=true;
                while (st.hasMoreElements()) {
                    String val=(String) st.nextElement();
                    if(first && val.compareTo("dm")==0){
                        first=false;
                        continue;
                    }else{
			data.add(val);
                    }
		}
		return data;
	}

	@SuppressWarnings("unchecked")
	private Object getObject(Object pParent, String pChild) throws Exception {
		Object value = null;
		boolean array = pChild.indexOf("[") > -1;
		int index = 0;
		if (array) {
			index = Integer.parseInt(pChild.substring(pChild.indexOf("[") + 1, pChild.indexOf("]") - 1));
			pChild = pChild.substring(0, pChild.indexOf("[") - 1);
		}
		if (pParent instanceof Map) {
			if (pParent instanceof Detail) {
				Detail det = (Detail) pParent;
				value = det.get(pChild);
				if (value == null) {
					char car = pChild.charAt(0);
					pChild = pChild.substring(1);
					if (car == 'f') {
						det.findFieldByNameCreate(pChild);
					}
					value = det.get(pChild);
				}
			} else if (pParent instanceof Table) {
				Table table = (Table) pParent;
				value = table.get(pChild);
				if (value == null && pChild.indexOf("_record") == 0) {
					int rec = Integer.parseInt(pChild.replaceAll("_record", "")) + 1;
					while (table.getRecordCount() < rec) {
						Record r0 = (Record) table.get("_record0");
						Record r = new Record();
						if (r0 != null) {
							r = Clonador.clonar(r0);
							List<Field> fs = r.getFields();
							for (Field field : fs) {
								field.setRealValue(null);
							}
						}
						table.addRecord(r);
					}
					value = table.get(pChild);
				}
			} else {
				if(pParent instanceof Record){
					Record rec=(Record)pParent;
					value=rec.findFieldByNameCreate(pChild);
				}else{
				Map m = (Map) pParent;
				value = m.get(pChild);
				}
			}
		} else {
			value = BeanManager.getBeanAttributeValue(pParent, pChild);
		}
		if (array) {
			if (value instanceof List) {
				value = ((List) value).get(index);
			} else {
				throw new Exception("No es un arreglo: " + pChild);
			}
		}
		return value;
	}
}
