package com.rjconsultores.ventaboletos.web.gui.componente.esquemaoperacional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.BooleanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zkplus.databind.DataBinder;
import org.zkoss.zkplus.spring.SpringUtil;
import org.zkoss.zul.Column;
import org.zkoss.zul.Columns;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.RendererCtrl;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.Spinner;

import com.rjconsultores.ventaboletos.dao.OrgaoTramoDAO;
import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.CoeficienteTarifa;
import com.rjconsultores.ventaboletos.entidad.OrgaoConcedente;
import com.rjconsultores.ventaboletos.entidad.OrgaoTramo;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.Tramo;
import com.rjconsultores.ventaboletos.entidad.TramoServicio;
import com.rjconsultores.ventaboletos.entidad.Via;
import com.rjconsultores.ventaboletos.service.TramoService;
import com.rjconsultores.ventaboletos.service.TramoServicioService;
import com.rjconsultores.ventaboletos.utilerias.ApplicationProperties;
import com.rjconsultores.ventaboletos.utilerias.CustomEnum;
import com.rjconsultores.ventaboletos.utilerias.HoraSistema;
import com.rjconsultores.ventaboletos.vo.esquemaoperacional.SecuenciaRutaTramoCoeficienteVO;

/**
 * Grid con la representacion de los tramos y secuencias de la ruta
 * 
 * @author gleimar
 * 
 */
public class GridRutaTramoCoeficiente extends Grid implements RowRenderer, RendererCtrl {

	private static final long serialVersionUID = 1L;
	private static final String CONSTRAINT_NO_EMPTY = "no empty";
	private static final String VALOR_COMBO_NAO = "Não";
	private static final String VALOR_COMBO_SIM = "Sim";
	private List<Via> lsVias;
	private List<CoeficienteTarifa> lsCoeficientes;
	private List<SecuenciaRutaTramoCoeficienteVO> lsSecuenciaRutaTramoCoeficienteVO;
	private ClaseServicio claseServicio;
	private OrgaoConcedente orgaoConcedente;
	private DataBinder dataBinder;
	private static Logger log = LogManager.getLogger(GridRutaTramoCoeficiente.class);

	public GridRutaTramoCoeficiente() {
		lsSecuenciaRutaTramoCoeficienteVO = new ArrayList<SecuenciaRutaTramoCoeficienteVO>();
		this.setRowRenderer(this);
		this.appendChild(generarColumns());
		dataBinder = new DataBinder();	
	}

	/**
	 * Informa la lista de vias disponibles
	 * 
	 * @param lsVias
	 */
	public void setLsVias(List<Via> lsVias) {
		this.lsVias = lsVias;
	}

	/**
	 * Cual es la clase de servicio confiugrada
	 * 
	 * @return
	 */
	public ClaseServicio getClaseServicio() {
		return claseServicio;
	}

	/**
	 * Indica cual es la clase de servicio usada para hacer la busqueda de los tramos
	 * 
	 * @param claseServicio
	 */
	public void setClaseServicio(ClaseServicio claseServicio) {
		this.claseServicio = claseServicio;
	}

	public OrgaoConcedente getOrgaoConcedente() {
		return orgaoConcedente;
	}

	public void setOrgaoConcedente(OrgaoConcedente orgaoConcedente) {
		this.orgaoConcedente = orgaoConcedente;
	}

	private ListModelList getListViaCombobox() {
		return new ListModelList(lsVias);
	}

	private ListModelList getListCoeficienteCombobox() {
		return new ListModelList(lsCoeficientes);
	}

	/**
	 * Limpia los registros que existen y agrega todos
	 * 
	 * @param lsSecuenciaRutaTramoCoeficienteVO
	 */
	public void agregarTodos(List<SecuenciaRutaTramoCoeficienteVO> lsSecuenciaRutaTramoCoeficienteVO) {
		this.lsSecuenciaRutaTramoCoeficienteVO.clear();
		this.lsSecuenciaRutaTramoCoeficienteVO.addAll(lsSecuenciaRutaTramoCoeficienteVO);

		actualizaModel();
	}

	private Columns generarColumns() {
		Columns columns = new Columns();

		columns.appendChild(criaColuna("#", "2%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnOrigen.label"), "20%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnDestino.label"), "20%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnVia.label"), "15%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnVenda.label"), "6%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnKmsReal.label"), "6%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnTiempoRecorrido.label"), "10%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnIDTramo.label"), "6%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnCoeficiente1.label"), "12%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnKmCoeficiente1.label"), "5%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnCoeficiente2.label"), "12%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnKmCoeficiente2.label"), "5%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnCoeficiente3.label"), "12%"));
		columns.appendChild(criaColuna(Labels.getLabel("gridRutaSecuencia.columnKmCoeficiente3.label"), "5%"));

		return columns;
	}

	private Column criaColuna(String label, String width) {
		Column coluna = new Column(label);
		coluna.setWidth(width);
		return coluna;
	}

	@Override
	public void render(Row row, Object obj) throws Exception {
		final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO = (SecuenciaRutaTramoCoeficienteVO) obj;
		dataBinder.bindBean(row.getUuid(), secuenciaRutaTramoCoeficienteVO);

		row.appendChild(criaCellSequencia(secuenciaRutaTramoCoeficienteVO));
		row.appendChild(criaCellOrigem(secuenciaRutaTramoCoeficienteVO));
		row.appendChild(criaCellDestino(secuenciaRutaTramoCoeficienteVO));
		
		final MyCustomTextboxDecimal dKmsReal = criaKmsReal(secuenciaRutaTramoCoeficienteVO, row.getUuid());
		final Spinner spHora = criaSpinerHora(secuenciaRutaTramoCoeficienteVO);
		final Spinner spMinuto = criaSpinerMinuto(secuenciaRutaTramoCoeficienteVO);
		final Label lblID = criaLabelId(secuenciaRutaTramoCoeficienteVO);
		
		final Combobox comboCoeficiente1 = criaCoeficienteTarifario1(secuenciaRutaTramoCoeficienteVO);
		final MyCustomTextboxDecimal kmCoeficiente1 = criaKmCoeficiente1(secuenciaRutaTramoCoeficienteVO, row.getUuid() + ".kmCoeficiente1");

		final Combobox comboCoeficiente2 = criaCoeficienteTarifario2(secuenciaRutaTramoCoeficienteVO);
		final MyCustomTextboxDecimal kmCoeficiente2 = criaKmCoeficiente2(secuenciaRutaTramoCoeficienteVO, row.getUuid() + ".kmCoeficiente2");
		
		final Combobox comboCoeficiente3 = criaCoeficienteTarifario3(secuenciaRutaTramoCoeficienteVO);
		final MyCustomTextboxDecimal kmCoeficiente3 = criaKmCoeficiente3(secuenciaRutaTramoCoeficienteVO, row.getUuid() + ".kmCoeficiente3");
		
		Combobox comboVia = criaCellComboVia(secuenciaRutaTramoCoeficienteVO);
		comboVia.addEventListener(Events.ON_CHANGE,
				new EventListenerComboVia(comboVia, spHora, spMinuto, lblID, kmCoeficiente2,
						comboCoeficiente1, secuenciaRutaTramoCoeficienteVO, kmCoeficiente1,
						comboCoeficiente2, dKmsReal, kmCoeficiente3, comboCoeficiente3));
		row.appendChild(comboVia);
		
		row.appendChild(criaCellComboVenda(secuenciaRutaTramoCoeficienteVO));
		
		row.appendChild(dKmsReal);
		
		row.appendChild(criaCellHora(row, secuenciaRutaTramoCoeficienteVO.getTiempoRecorrido(), spHora, spMinuto));

		row.appendChild(lblID);

		row.appendChild(comboCoeficiente1);
		
		row.appendChild(kmCoeficiente1);

		row.appendChild(comboCoeficiente2);
		
		row.appendChild(kmCoeficiente2);
		
		row.appendChild(comboCoeficiente3);
		
		row.appendChild(kmCoeficiente3);
	}

	private Hbox criaCellHora(Row row, final HoraSistema horaSistema, final Spinner spHora, final Spinner spMinuto) {
		Hbox hbox = new Hbox();
		hbox.appendChild(spHora);
		hbox.appendChild(new Label(":"));
		hbox.appendChild(spMinuto);

		if (horaSistema != null) {
			HoraSistema hora = horaSistema;
			spHora.setValue(hora.getHora());
			spMinuto.setValue(hora.getMinuto());
		}
		dataBinder.addBinding(spHora, "value", row.getUuid() + ".tiempoRecorrido.hora", null, null, "save", null, null, null, null);
		dataBinder.addBinding(spMinuto, "value", row.getUuid() + ".tiempoRecorrido.minuto", null, null, "save", null, null, null, null);
		return hbox;
	}

	private MyCustomTextboxDecimal criaKmCoeficiente3(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO, String rowId) {
		final MyCustomTextboxDecimal kmCoeficiente3 = new MyCustomTextboxDecimal();
		
		configuraKmCoeficiente(secuenciaRutaTramoCoeficienteVO, rowId, kmCoeficiente3, secuenciaRutaTramoCoeficienteVO.getKmCoeficiente3());
		
		return kmCoeficiente3;
	}
	
	private MyCustomTextboxDecimal criaKmCoeficiente2(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO, String rowId) {
		final MyCustomTextboxDecimal kmCoeficiente2 = new MyCustomTextboxDecimal();
		
		configuraKmCoeficiente(secuenciaRutaTramoCoeficienteVO, rowId, kmCoeficiente2, secuenciaRutaTramoCoeficienteVO.getKmCoeficiente2());
		
		return kmCoeficiente2;
	}

	private MyCustomTextboxDecimal criaKmCoeficiente1(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO, String rowId) {
		final MyCustomTextboxDecimal kmCoeficiente1 = new MyCustomTextboxDecimal();

		configuraKmCoeficiente(secuenciaRutaTramoCoeficienteVO, rowId, kmCoeficiente1, secuenciaRutaTramoCoeficienteVO.getKmCoeficiente1());
				
		return kmCoeficiente1;
	}

	private void configuraKmCoeficiente(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO, String rowId, final MyCustomTextboxDecimal kmCoeficiente,
			final BigDecimal valorKmCoeficiente) {
		kmCoeficiente.setValueBigDecimal(valorKmCoeficiente != null ? valorKmCoeficiente : BigDecimal.ZERO);
		kmCoeficiente.setWidth("80%");
		kmCoeficiente.setReadonly(!possuiOrgao(secuenciaRutaTramoCoeficienteVO));
		dataBinder.addBinding(kmCoeficiente, "value", rowId, null, null,
				"save", "com.rjconsultores.ventaboletos.web.utilerias.StringDecimalToDecimalConverter", null, null, null);
	}

	private Combobox criaCellComboVenda(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		final Combobox comboVenda = new Combobox();
		comboVenda.setId(comboVenda.getUuid());
		comboVenda.setReadonly(true);
		comboVenda.setWidth("100%");
		comboVenda.setConstraint(CONSTRAINT_NO_EMPTY);
		
		final ListModelList listComboVenda = configuraModelListComboVenda(secuenciaRutaTramoCoeficienteVO);
		
		comboVenda.setModel(listComboVenda);
		
		comboVenda.addEventListener(Events.ON_CHANGE, new EventListener() {
			@Override
			public void onEvent(Event evt) throws Exception {
				secuenciaRutaTramoCoeficienteVO.setPermiteVenda(
						VALOR_COMBO_SIM.equals(comboVenda.getSelectedItem().getValue()));
			}
		});
		
		return comboVenda;
	}

	private ListModelList configuraModelListComboVenda(SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		final ListModelList listComboVenda = new ListModelList();
		
		final Comboitem comboItemSim = new Comboitem(VALOR_COMBO_SIM);
		comboItemSim.setValue(VALOR_COMBO_SIM);
		
		final Comboitem comboItemNao = new Comboitem(VALOR_COMBO_NAO);
		comboItemNao.setValue(VALOR_COMBO_NAO);
		
		listComboVenda.add(comboItemSim.getValue());
		listComboVenda.add(comboItemNao.getValue());
		
		if (secuenciaRutaTramoCoeficienteVO.getPermiteVenda() == null) {
			secuenciaRutaTramoCoeficienteVO.setPermiteVenda(!ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.IS_GERAR_TRECHO_AUTOMATICO_DEFAULT_NAO.getDescricao()));
		}
		
		listComboVenda.addSelection(BooleanUtils.isTrue(secuenciaRutaTramoCoeficienteVO.getPermiteVenda())
				? comboItemSim.getValue()
				: comboItemNao.getValue());
			
		return listComboVenda;
	}

	private Combobox criaCoeficienteTarifario3(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		final Combobox cboCoeficiente = criaCoeficiente(secuenciaRutaTramoCoeficienteVO, 
				secuenciaRutaTramoCoeficienteVO.getCoeficienteTarifa3());
		cboCoeficiente.addEventListener(Events.ON_CHANGE, new EventListener() {
			@Override
			public void onEvent(Event arg0) throws Exception {
				if (cboCoeficiente.getSelectedItem() == null) {
					secuenciaRutaTramoCoeficienteVO.setCoeficienteTarifa3(null);
				} else {
					secuenciaRutaTramoCoeficienteVO.setCoeficienteTarifa3((CoeficienteTarifa) cboCoeficiente.getSelectedItem().getValue());
				}
			}

		});
		return cboCoeficiente;
	}
	
	private Combobox criaCoeficienteTarifario2(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		final Combobox cboCoeficiente = criaCoeficiente(secuenciaRutaTramoCoeficienteVO, 
				secuenciaRutaTramoCoeficienteVO.getCoeficienteTarifa2());
		cboCoeficiente.addEventListener(Events.ON_CHANGE, new EventListener() {
			@Override
			public void onEvent(Event arg0) throws Exception {
				if (cboCoeficiente.getSelectedItem() == null) {
					secuenciaRutaTramoCoeficienteVO.setCoeficienteTarifa2(null);
				} else {
					secuenciaRutaTramoCoeficienteVO.setCoeficienteTarifa2((CoeficienteTarifa) cboCoeficiente.getSelectedItem().getValue());
				}
			}
			
		});
		return cboCoeficiente;
	}

	private Combobox criaCoeficienteTarifario1(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		final Combobox cboCoeficiente = criaCoeficiente(secuenciaRutaTramoCoeficienteVO, secuenciaRutaTramoCoeficienteVO.getCoeficienteTarifa1());
		cboCoeficiente.addEventListener(Events.ON_CHANGE, new EventListener() {
			@Override
			public void onEvent(Event arg0) throws Exception {
				if (cboCoeficiente.getSelectedItem() == null) {
					secuenciaRutaTramoCoeficienteVO.setCoeficienteTarifa1(null);
				} else {
					secuenciaRutaTramoCoeficienteVO.setCoeficienteTarifa1((CoeficienteTarifa) cboCoeficiente.getSelectedItem().getValue());
				}
			}
		});
		return cboCoeficiente;
	}

	private Combobox criaCoeficiente(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO,
			CoeficienteTarifa coeficienteTarifa) {
		final Combobox cboCoeficiente = new Combobox();
		cboCoeficiente.setId(cboCoeficiente.getUuid());
		cboCoeficiente.setWidth("99%");

		ListModelList lmlCoeficiente = getListCoeficienteCombobox();
		if (coeficienteTarifa != null) {
			lmlCoeficiente.addSelection(coeficienteTarifa);
		}
		cboCoeficiente.setModel(lmlCoeficiente);
		cboCoeficiente.setConstraint(CONSTRAINT_NO_EMPTY);
		cboCoeficiente.setDisabled(!possuiOrgao(secuenciaRutaTramoCoeficienteVO));
		cboCoeficiente.setReadonly(true);
		return cboCoeficiente;
	}

	private boolean possuiOrgao(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		return secuenciaRutaTramoCoeficienteVO.getOrgaoTramoId() == null;
	}

	private boolean possuiTramo(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		return secuenciaRutaTramoCoeficienteVO.getTramoId() != null;
	}

	private Label criaLabelId(SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		final Label lblID = new Label("");
		lblID.setValue(possuiTramo(secuenciaRutaTramoCoeficienteVO) 
				? secuenciaRutaTramoCoeficienteVO.getTramoId().toString() : "");
		return lblID;
	}

	private Spinner criaSpinerMinuto(SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		final Spinner spMinuto = new Spinner();
		configuraSpinerHoraMinuto(secuenciaRutaTramoCoeficienteVO, spMinuto);
		spMinuto.setConstraint("max 59,no negative,no empty");
		return spMinuto;
	}

	private Spinner criaSpinerHora(SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		final Spinner spHora = new Spinner();
		configuraSpinerHoraMinuto(secuenciaRutaTramoCoeficienteVO, spHora);
		spHora.setConstraint("max 99, no negative, no empty");
		return spHora;
	}

	private void configuraSpinerHoraMinuto(SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO, 
			final Spinner spinner) {
		spinner.setWidth("40px");
		spinner.setReadonly(secuenciaRutaTramoCoeficienteVO.getTramoServicioId() != null);
		spinner.setButtonVisible(secuenciaRutaTramoCoeficienteVO.getTramoServicioId() == null);
	}

	private Combobox criaCellComboVia(SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		final Combobox cboVia = new Combobox();
		cboVia.setId(cboVia.getUuid());
		cboVia.setReadonly(true);
		ListModelList listModelList = getListViaCombobox();
		if (secuenciaRutaTramoCoeficienteVO.getVia() != null) {
			listModelList.addSelection(secuenciaRutaTramoCoeficienteVO.getVia());
		}
		cboVia.setModel(listModelList);
		cboVia.setConstraint(CONSTRAINT_NO_EMPTY);
		return cboVia;
	}

	private MyCustomTextboxDecimal criaKmsReal(SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO, String rowId) {
		MyCustomTextboxDecimal dKmsReal = new MyCustomTextboxDecimal((secuenciaRutaTramoCoeficienteVO.getKmReal() == null) ? BigDecimal.ZERO : secuenciaRutaTramoCoeficienteVO.getKmReal());
		dKmsReal.setWidth("90%");
		dKmsReal.setReadonly(possuiTramo(secuenciaRutaTramoCoeficienteVO));
		dataBinder.addBinding(dKmsReal, "value", rowId + ".kmReal", null, null, "save", 
				"com.rjconsultores.ventaboletos.web.utilerias.StringDecimalToDecimalConverter", null, null, null);
		return dKmsReal;
	}

	private Label criaCellDestino(SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		return criaLabel(secuenciaRutaTramoCoeficienteVO.getDestino().getCveparada()
				+ " - " + secuenciaRutaTramoCoeficienteVO.getDestino().getDescparada());
	}

	private Label criaCellOrigem(SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		return criaLabel(secuenciaRutaTramoCoeficienteVO.getOrigen().getCveparada()
				+ " - " + secuenciaRutaTramoCoeficienteVO.getOrigen().getDescparada());
	}

	private Intbox criaCellSequencia(final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		Intbox ibxSumSecuencia = new Intbox(secuenciaRutaTramoCoeficienteVO.getSecuencia());
		ibxSumSecuencia.setWidth("50%");
		ibxSumSecuencia.setReadonly(true);
		return ibxSumSecuencia;
	}

	private Label criaLabel(String  titulo) {
		Label lblDestino = new Label(titulo);
		lblDestino.setWidth("80%");
		return lblDestino;
	}

	/**
	 * Actualiza el modelo de grid
	 */
	private void actualizaModel() {
		this.setModel(new ListModelList(lsSecuenciaRutaTramoCoeficienteVO, false));
	}

	/**
	 * Indica si hay tramos
	 * 
	 * @return
	 */
	public boolean isEmpty() {
		return lsSecuenciaRutaTramoCoeficienteVO.isEmpty();
	}

	/**
	 * Llena el tramo con los datos de una busqueda
	 * 
	 * @param secuenciaRutaTramoCoeficienteVO
	 */
	private void llenarTramo(SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO) {
		TramoServicioService tramoServicioService = (TramoServicioService) SpringUtil.getBean("tramoServicioService");

		Parada destino = secuenciaRutaTramoCoeficienteVO.getDestino();
		Parada origen = secuenciaRutaTramoCoeficienteVO.getOrigen();
		Via via = secuenciaRutaTramoCoeficienteVO.getVia();

		TramoServicio tramoServicio = null;
		if ((destino != null) && (origen != null) && (via != null) && (claseServicio != null)) {
			tramoServicio = tramoServicioService.buscar(origen, destino, via, claseServicio);
		}

		Tramo tramo = null;
		if (tramoServicio != null) {
			tramo = tramoServicio.getTramo();
		} else {
			TramoService tramoService = (TramoService) SpringUtil.getBean("tramoService");
			if ((destino != null) && (origen != null) && (via != null)) {
				tramo = tramoService.buscar(origen, destino, via);
			}
		}

		if (tramoServicio != null) {
			HoraSistema hora = new HoraSistema(tramoServicio.getTiemporecorrido());
			secuenciaRutaTramoCoeficienteVO.setTiempoRecorrido(hora);
			secuenciaRutaTramoCoeficienteVO.setTramoServicioId(tramoServicio.getTramoservicioId());
		} else {
			secuenciaRutaTramoCoeficienteVO.setTiempoRecorrido(null);
			secuenciaRutaTramoCoeficienteVO.setTramoServicioId(null);
		}

		if (tramo != null) {
			secuenciaRutaTramoCoeficienteVO.setKmReal(tramo.getKmReal());
			secuenciaRutaTramoCoeficienteVO.setTramoId(tramo.getTramoId());
		} else {
			secuenciaRutaTramoCoeficienteVO.setKmReal(BigDecimal.ZERO);
			secuenciaRutaTramoCoeficienteVO.setTramoId(null);
		}

		OrgaoTramoDAO orgaoTramoDAO = (OrgaoTramoDAO) SpringUtil.getBean("orgaoTramoDAO");
		OrgaoTramo orgaoTramo = orgaoTramoDAO.buscar(origen.getParadaId(), destino.getParadaId(), via.getViaId(), orgaoConcedente.getOrgaoConcedenteId(), claseServicio.getClaseservicioId());

		if (orgaoTramo != null) {
			secuenciaRutaTramoCoeficienteVO.setOrgaoTramoId(orgaoTramo.getOrgaoTramoId());

			secuenciaRutaTramoCoeficienteVO.setCoeficienteTarifa1(orgaoTramo.getCoeficienteTarifa1());
			secuenciaRutaTramoCoeficienteVO.setKmCoeficiente1(orgaoTramo.getKmCoeficiente1());

			secuenciaRutaTramoCoeficienteVO.setCoeficienteTarifa2(orgaoTramo.getCoeficienteTarifa2());
			secuenciaRutaTramoCoeficienteVO.setKmCoeficiente2(orgaoTramo.getKmCoeficiente2());

		}
	}

	@Override
	public void doCatch(Throwable arg0) throws Throwable {
		throw arg0;
	}

	@Override
	public void doFinally() {
	}

	@Override
	public void doTry() {
	}

	public void debugList() {
		dataBinder.saveAll();
		for (SecuenciaRutaTramoCoeficienteVO s : lsSecuenciaRutaTramoCoeficienteVO) {
			log.debug(s);
		}
	}

	public List<SecuenciaRutaTramoCoeficienteVO> getLsSecuenciaRutaTramoCoeficienteVO() {
		dataBinder.saveAll();
		return lsSecuenciaRutaTramoCoeficienteVO;
	}

	public void setLsCoeficientes(List<CoeficienteTarifa> lsCoeficientes) {
		this.lsCoeficientes = lsCoeficientes;
	}
	
	private final class EventListenerComboVia implements EventListener {
		private final Combobox cboVia;
		private final Spinner spHora;
		private final Spinner spMinuto;
		private final Label lblID;
		private final MyCustomTextboxDecimal ibxKm2;
		private final Combobox cboCoeficiente1;
		private final SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO;
		private final MyCustomTextboxDecimal ibxKm1;
		private final Combobox cboCoeficiente2;
		private final MyCustomTextboxDecimal dKmsReal;
		private final MyCustomTextboxDecimal ibxKm3;
		private final Combobox cboCoeficiente3;

		private EventListenerComboVia(Combobox cboVia, Spinner spHora, Spinner spMinuto, Label lblID, 
				MyCustomTextboxDecimal ibxKm2, Combobox cboCoeficiente1, SecuenciaRutaTramoCoeficienteVO secuenciaRutaTramoCoeficienteVO, 
				MyCustomTextboxDecimal ibxKm1, Combobox cboCoeficiente2, MyCustomTextboxDecimal dKmsReal,
				MyCustomTextboxDecimal ibxKm3, Combobox cboCoeficiente3) {
			this.cboVia = cboVia;
			this.spHora = spHora;
			this.spMinuto = spMinuto;
			this.lblID = lblID;
			this.ibxKm2 = ibxKm2;
			this.cboCoeficiente1 = cboCoeficiente1;
			this.secuenciaRutaTramoCoeficienteVO = secuenciaRutaTramoCoeficienteVO;
			this.ibxKm1 = ibxKm1;
			this.cboCoeficiente2 = cboCoeficiente2;
			this.dKmsReal = dKmsReal;
			this.ibxKm3 = ibxKm3;
			this.cboCoeficiente3 = cboCoeficiente3;
		}

		@Override
		public void onEvent(Event evt) throws Exception {
			if (cboVia.getSelectedItem() != null) {

				BigDecimal kmRealAntigo = secuenciaRutaTramoCoeficienteVO.getKmReal();
				HoraSistema tiempoRecorridoAntigo = secuenciaRutaTramoCoeficienteVO.getTiempoRecorrido();

				secuenciaRutaTramoCoeficienteVO.setVia((Via) cboVia.getSelectedItem().getValue());
				llenarTramo(secuenciaRutaTramoCoeficienteVO);

				boolean tramoEditable = (secuenciaRutaTramoCoeficienteVO.getTramoId() == null);
				boolean tramoCoeficienteEditable = (secuenciaRutaTramoCoeficienteVO.getOrgaoTramoId() == null);
				boolean tramoServicioEditable = (secuenciaRutaTramoCoeficienteVO.getTramoServicioId() == null);

				if (!tramoEditable) {// cuando el tramo no es editable, es porque ya existe. Entonces lleno la pantalla con los nuevos valores
					dKmsReal.setValueBigDecimal(secuenciaRutaTramoCoeficienteVO.getKmReal());
				} else {
					secuenciaRutaTramoCoeficienteVO.setKmReal(kmRealAntigo);
				}

				lblID.setValue((secuenciaRutaTramoCoeficienteVO.getTramoId() != null) ? secuenciaRutaTramoCoeficienteVO.getTramoId().toString() : "");

				if (!tramoServicioEditable) {// cuando el tramoServicio no es editable, es porque ya existe. Entonces lleno la pantalla con los nuevos valores
					spHora.setValue(secuenciaRutaTramoCoeficienteVO.getTiempoRecorrido().getHora());
					spMinuto.setValue(secuenciaRutaTramoCoeficienteVO.getTiempoRecorrido().getMinuto());
				} else {
					secuenciaRutaTramoCoeficienteVO.setTiempoRecorrido(tiempoRecorridoAntigo);
				}

				if (!tramoCoeficienteEditable) {
					cboCoeficiente1.setText(secuenciaRutaTramoCoeficienteVO.getCoeficienteTarifa1().getDescCoeficiente());
					ibxKm1.setValueBigDecimal(secuenciaRutaTramoCoeficienteVO.getKmCoeficiente1());

					cboCoeficiente2.setSelectedIndex(-1);
					ibxKm2.setValueBigDecimal(BigDecimal.ZERO);
					
					cboCoeficiente3.setSelectedIndex(-1);
					ibxKm3.setValueBigDecimal(BigDecimal.ZERO);

					if (secuenciaRutaTramoCoeficienteVO.getCoeficienteTarifa2() != null) {
						cboCoeficiente2.setText(secuenciaRutaTramoCoeficienteVO.getCoeficienteTarifa2().getDescCoeficiente());
						ibxKm2.setValueBigDecimal(secuenciaRutaTramoCoeficienteVO.getKmCoeficiente2());
					}

					if (secuenciaRutaTramoCoeficienteVO.getCoeficienteTarifa3() != null) {
						cboCoeficiente3.setText(secuenciaRutaTramoCoeficienteVO.getCoeficienteTarifa3().getDescCoeficiente());
						ibxKm3.setValueBigDecimal(secuenciaRutaTramoCoeficienteVO.getKmCoeficiente3());
					}
				}

				dKmsReal.setReadonly(!tramoEditable);
				spHora.setReadonly(!tramoServicioEditable);
				spHora.setButtonVisible(tramoServicioEditable);
				spMinuto.setReadonly(!tramoServicioEditable);
				spMinuto.setButtonVisible(tramoServicioEditable);
				cboCoeficiente1.setDisabled(!tramoCoeficienteEditable);
				ibxKm1.setReadonly(!tramoCoeficienteEditable);
				cboCoeficiente2.setDisabled(!tramoCoeficienteEditable);
				ibxKm2.setReadonly(!tramoCoeficienteEditable);
				cboCoeficiente3.setDisabled(!tramoCoeficienteEditable);
				ibxKm3.setReadonly(!tramoCoeficienteEditable);

			}
		}
	}

}
