package com.fitbank.homebanking;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;

import com.fitbank.dto.management.Criterion;
import com.fitbank.dto.management.Detail;
import com.fitbank.dto.management.Record;
import com.fitbank.dto.management.Table;

public class LOV {
	private HttpServletRequest request;

	private String lovName;

	private int page = 1;

	private Map<String, String> parameters = new HashMap<String, String>();

	private Detail detail = null;

	private List<String> columns = new ArrayList<String>();

	private List<String> columnLabels = new ArrayList<String>();

	private List<Integer> columnWidth = new ArrayList<Integer>();

	public static final String LOV_NAME = "_lov_";

	public static final String LOV_PAGE = "_page_";

	public static final String LOV_TITLE_CTL = "LOV_TITLE";

	public static final String LOV_COLUMNS_CTL = "LOV_COLUMNS";

	public static final String LOV_COLUMN_LABELS_CTL = "LOV_COLUMN_LABELS";

	public static final String LOV_COLUMN_WIDTH_CTL = "LOV_COLUMN_WIDTHS";

	public static final String LOV_CODE_CTL = "LOV_CODE";

	public static final String LOV_DATA_CTL = "LOV_DATA";

	public static final String VALUE_SEPARATOR = ";";
	private String url="";

	@SuppressWarnings("unchecked")
	public LOV(HttpServletRequest pRequest) throws Exception {
		request = pRequest;
		lovName = request.getParameter(LOV_NAME);
		String aux = request.getParameter(LOV_PAGE);
		if (aux != null) {
			page = Integer.parseInt(aux);
		}

		Enumeration<String> param = request.getParameterNames();
		while (param.hasMoreElements()) {
			String paramName = param.nextElement();
			if (paramName.indexOf("cLov_") < 0&&paramName.indexOf("pLov_") < 0) {
				continue;
			}
			String val = request.getParameter(paramName).trim();
			if(paramName.indexOf("cLov_") >= 0) {
				this.url+="&"+paramName+"="+val;
			}
			if (val.compareTo("_") == 0) {
				val = "";
			}
			
			paramName = paramName.replaceAll("cLov_", "");
			paramName = paramName.replaceAll("pLov_", "");
			parameters.put(paramName, val);
		}
		DataManage dm = (DataManage) request.getSession().getAttribute(DataManage.KEY);
		detail = new Detail();
		detail.setType(MessageTypes.CON.name());
		Object obj = null;
		try {
			obj = this.request.getSession().getAttribute(this.lovName);
		} catch (Exception e1) {
			return;
		}

		if (!(obj instanceof Transaction)) {
			return;
		}
		dm.prepareDetail(detail, (Transaction) obj);
		String alias = (String) detail.findFieldByNameCreate(LOV_DATA_CTL).getValue();
		Table lov = detail.findTableByAlias(alias);
		if (lov == null) {
			throw new Exception("No se ha encontrado la Tabla " + alias);
		}
		lov.setPageNumber(this.page);
		List<Criterion> lCriteria = lov.getCriteria();
		for (Criterion criterion : lCriteria) {
			if (this.parameters.containsKey(criterion.getName())) {
				criterion.setValue(this.parameters.get(criterion.getName()));
			}
		}
		for (Criterion criterion : lCriteria) {
			if (criterion.getCondition().compareTo("like") == 0 && (criterion.getValue() == null || criterion.getValue().toString().trim().compareTo("") == 0)) {
				criterion.setValue("%");
			}
		}
		BussinessDelegate bd = new BussinessDelegate();
		Transaction tt = (Transaction) request.getSession().getAttribute(DataManage.TRN_DATA);
		if (tt != null)
			detail.setRealtransaction(tt.getSubsystem() + ":" + tt.getTransaction());
		this.detail = bd.process(detail);
		this.prepareColumns();
	}

	@SuppressWarnings("unchecked")
	public String getLOVData() throws Exception {
		try {
			String data = "";
			data += this.getHeader((String) detail.findFieldByName(LOV_TITLE_CTL).getValue());
			String alias = (String) detail.findFieldByName(LOV_DATA_CTL).getValue();
			data += this.getData(detail.findTableByAlias(alias).getRecords());
			String has=detail.findTableByAlias(alias).getHasMorePages();
                        boolean mpg = false;
                        if(has!=null && has.compareTo("1")==0){
                            mpg = true;
                        }
			data += this.getFooter(mpg);
			return data;
		} catch (Exception e) {
			return e.getMessage();
		}
	}

	private String getHeader(String pTitle) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		pw.println("<form name='lov'>");

		pw.println("  <table width='100%'  class='simple'>");
		pw.println("  <tr><td colspan='" + this.columns.size() + "'>");
		pw.println(pTitle);
		pw.println("</td></tr>");
		pw.println(" <tr>");
		for (int i = 0; i < this.columnLabels.size(); i++) {
			String label = this.columnLabels.get(i);
			if (this.columnWidth.size() == this.columnLabels.size()) {
				if(this.columnWidth.get(i).intValue()==-1){
				pw.println("  <th  style=\"background-color:#FFFFFF;color:#FFFFFF;font-size:1px;\" ></th>");
				}else{
				pw.println("  <th width='" + this.columnWidth.get(i) + "'  >" + label + "</th>");
				}
				} else {
				pw.println("  <th  >" + label + "</th>");
			}
		}
		pw.println("</tr><tr>");
		int i=0;
		for (String col : columns) {
			String value = this.request.getParameter("pLov_" + col);
			if (value == null || value.compareTo("_") == 0) {
				value = "";
			}
			if(this.columnWidth.get(i).intValue()==-1){
				pw.println("<th></th>");	
			}else{
                            String disabledSearch = "";
                   if(detail.findFieldByNameCreate("DISABLE_SEARCH_BUTTON")
                        .getValue()!=null){         
                if(detail.findFieldByNameCreate("DISABLE_SEARCH_BUTTON")
                        .getValue().toString().compareTo("1")==0){
                    disabledSearch = "disabled='disabled'";
                }
                   }
			pw.println("<th   class='sortable'><input type='text' "+ disabledSearch +" name='pLov_" + col + "' id='pLov_" + col + "' style='width:100%' value='" + value + "'/></th>");
			}
		i++;
		}
		pw.println("</tr>");
		pw.close();
		return sw.toString();
	}

	private String getFooter(boolean hasMore) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		pw.println("<tr><td colspan='" + columns.size() + "'>");
		pw.println("<table width='100%'>");
		pw.println("<tr>");
		String prev = this.lovName+url + ((this.page == 1) ? "" : ("&_page_=" + (page - 1)));
		String next = this.lovName+url + "&_page_=" + (page + 1);
                String disabledPrev = "";
                if(this.page == 1){
                    disabledPrev = "disabled='true'";
                }
		pw.println(" <td width='30%'><input type='button' "+ disabledPrev +"  name='previous' id='previous' value='Anterior' onclick='executeQueryLov(\"" + prev + "\");return false' /></td>");
		String disabledSearch = "";
                if(detail.findFieldByNameCreate("DISABLE_SEARCH_BUTTON")
                        .getValue()!=null){        
                if(detail.findFieldByNameCreate("DISABLE_SEARCH_BUTTON")
                        .getValue().toString().compareTo("1")==0){
                    disabledSearch = "disabled='true'";
                }
                }
                pw.println(" <td width='30%'><input type='button' "+ disabledSearch +" name='query' id='query' value='Consultar' onclick='executeQueryLov(\"" + this.lovName+this.url + "\");return false' /></td>");
		
                String disabledNext = "";
                if(!hasMore){
                    disabledNext = "disabled='true'";
                }
                pw.println(" <td width='30%'><input type='button' name='next' "+ disabledNext +"  id='next' value='Siguiente' onclick='executeQueryLov(\"" + next + "\");return false'/></td>");
		pw.println(" </tr></table></td></tr></table></form>");
		pw.close();
		return sw.toString();
	}

	private String getData(Iterable<Record> pData)throws Exception {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
                if(!pData.iterator().hasNext()){
                pw.println("   <tr><td>Sin Datos para esta Búsqueda / No data for this search</td></tr>");
                }
		for (Record record : pData) {
			pw.println("   <tr onclick='selectLovRecord(this);' onmouseover=\"this.className='sel'\" onmouseout=\"this.className=''\">");
			int i=0;
			for (String col : columns) {
				Object value=record.findFieldByNameCreate(col).getValue();
				if(value!=null){
					
					if(this.columnWidth.get(i).intValue()==-1){
					pw.println("<td style=\"background-color:#FFFFFF;color:#FFFFFF;font-size:1px;\">" + value + "</td>");
					}else{
				if(record.findFieldByNameCreate(col).getValue() instanceof BigDecimal ){
					value=record.findFieldByNameCreate(col).getAmountValue();
					pw.println("<td style=\"text-align:right;\">" + value + "</td>");
				}else{
					pw.println("<td >" + value + "</td>");
				}
					}
				}
				if(value==null){
					value="";
					pw.println("<td >" + value + "</td>");
				}
				i++;
			}
			pw.println("   </tr>");
			
		}

		pw.close();
		return sw.toString();
	}

	private void prepareColumns() throws Exception {
		String data = (String) this.detail.findFieldByName(LOV_COLUMNS_CTL).getValue();
		if (data == null || data.compareTo("") == 0) {
			throw new Exception("Lista de valores no Tiene Columnas Definidas");
		}
		this.columns = new ArrayList<String>();
		StringTokenizer st = new StringTokenizer(data, ";");
		while (st.hasMoreElements()) {
			this.columns.add((String) st.nextElement());
		}
		data = (String) this.detail.findFieldByName(LOV_COLUMN_LABELS_CTL).getValue();
		if (data == null || data.compareTo("") == 0) {
			throw new Exception("Lista de valores no Tiene Columnas Definidas");
		}
		this.columnLabels = new ArrayList<String>();
		st = new StringTokenizer(data, ";");
		while (st.hasMoreElements()) {
			this.columnLabels.add((String) st.nextElement());
		}
		if (this.columnLabels.size() != this.columns.size()) {
			throw new Exception("El número de elementos en la Lista de columnas y etiquetas no son iguales");
		}

		data = (String) this.detail.findFieldByName(LOV_COLUMN_WIDTH_CTL).getValue();
		if (!(data == null || data.compareTo("") == 0)) {
			this.columnWidth = new ArrayList<Integer>();
			st = new StringTokenizer(data, ";");
			while (st.hasMoreElements()) {
				this.columnWidth.add(Integer.parseInt((String) st.nextElement()));
			}
			if (this.columnWidth.size() != this.columns.size()) {
				this.columnWidth = new ArrayList<Integer>();
			}
		}

	}
}