/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rjconsultores.ventaboletos.web.gui.controladores.esquemaoperacional;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.log4j.Logger;
import org.apache.log4j.lf5.util.DateFormatManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Paging;
import org.zkoss.zul.Radio;
import org.zkoss.zul.Spinner;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.ext.Constrainted;

import com.rjconsultores.ventaboletos.entidad.CasetaPeaje;
import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.GrupoRuta;
import com.rjconsultores.ventaboletos.entidad.OrgaoConcedente;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.ParadaSecuencia;
import com.rjconsultores.ventaboletos.entidad.Ruta;
import com.rjconsultores.ventaboletos.entidad.RutaCombinacion;
import com.rjconsultores.ventaboletos.entidad.RutaEmpresa;
import com.rjconsultores.ventaboletos.entidad.RutaSecuencia;
import com.rjconsultores.ventaboletos.entidad.Tramo;
import com.rjconsultores.ventaboletos.entidad.TramoServicio;
import com.rjconsultores.ventaboletos.entidad.Via;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.service.ClaseServicioService;
import com.rjconsultores.ventaboletos.service.EmpresaService;
import com.rjconsultores.ventaboletos.service.EsquemaCorridaService;
import com.rjconsultores.ventaboletos.service.GrupoRutaService;
import com.rjconsultores.ventaboletos.service.OrgaoConcedenteService;
import com.rjconsultores.ventaboletos.service.RutaCombinacionService;
import com.rjconsultores.ventaboletos.service.RutaEmpresaService;
import com.rjconsultores.ventaboletos.service.RutaSecuenciaService;
import com.rjconsultores.ventaboletos.service.RutaService;
import com.rjconsultores.ventaboletos.service.TramoService;
import com.rjconsultores.ventaboletos.service.UsuarioEmpresaService;
import com.rjconsultores.ventaboletos.service.ViaService;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.RegistroConDependenciaException;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;
import com.rjconsultores.ventaboletos.web.utilerias.MyListbox;
import com.rjconsultores.ventaboletos.web.utilerias.MyTextbox;
import com.rjconsultores.ventaboletos.web.utilerias.paginacion.HibernateSearchObject;
import com.rjconsultores.ventaboletos.web.utilerias.paginacion.PagedListWrapper;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderCatalogoDeRutasSecuencia;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderRutaEmpresa;

/**
 * 
 * @author Rafius
 */
@Controller("editarCatalogoDeRutaController")
@Scope("prototype")
public class EditarCatalogoDeRutaController extends MyGenericForwardComposer
		implements ListitemRenderer {

	private static final long serialVersionUID = 1L;
	@Autowired
	private RutaService rutaService;
	@Autowired
	private EsquemaCorridaService esquemaCorridaService;
	@Autowired
	private ClaseServicioService claseService;
	@Autowired
	private TramoService tramoService;
	@Autowired
	private RutaCombinacionService rutaCombinacionService;
	@Autowired
	private RutaSecuenciaService rutaSecuenciaService;
	@Autowired
	private ViaService viaService;
	@Autowired
	private UsuarioEmpresaService usuarioEmpresaService;
	@Autowired
	private EmpresaService empresaService;
	@Autowired
	private RutaEmpresaService rutaEmpresaService;
	@Autowired
	private OrgaoConcedenteService orgaoConcedenteService;
	@Autowired
	private GrupoRutaService grupoRutaService;
	@Autowired
	private transient PagedListWrapper<RutaCombinacion> plwRutaCombinacion;
	private Ruta ruta;
	private MyListbox rutaList;
	private MyListbox rutaSecuenciaList;
	private MyListbox rutaCombinacionList;
	private MyListbox rutaEmpresaList;
	private Paging pagingRutaCombinacion;
	private List<GrupoRuta> lsGrupoRuta;
	private List<RutaSecuencia> lsRutaSecuencia;
	private List<RutaCombinacion> lsRutaCombinacion;
	private List<ClaseServicio> lsClase;
	private List<Via> lsVia;
	private List<ParadaSecuencia> lsParadasSequencia;
	private List<Empresa> lsEmpresa;
	private List<RutaEmpresa> lsRutaEmpresa;
	private List<OrgaoConcedente> lsOrgaoConcedente;
	private Tramo tramoBandBox;
	private Textbox txtNome;
	private Textbox txtPrefixo;
	private Spinner numSecuencia;
	private Combobox cmbClase;
	private Combobox cmbVia;
	private Combobox cmbEmpresa;
	private Combobox cmbParada;
	private Radio rdNo;
	private Radio rdSi;
	private Radio radIda;
	private Radio radVolta;
	private Button btnApagar;
	private Integer ultimaSecuencia;
	private Boolean secuenciaFoiAlterada = Boolean.FALSE;
	private Boolean modificado = Boolean.FALSE;
	private static Logger log = Logger.getLogger(EditarCatalogoDeRutaController.class);
	private boolean carregouCombinacao;
	private MyTextbox txtNumRuta;
	private Intbox txtCantEixos;
	private Intbox txtCantAsientos;
	private Checkbox chkIndVentaRioCard;
	private MyTextbox txtNumRioCard;

	public Ruta getRuta() {
		return ruta;
	}

	public void setRuta(Ruta ruta) {
		this.ruta = ruta;
	}

	public List<ClaseServicio> getLsClase() {
		return lsClase;
	}

	public void setLsClase(List<ClaseServicio> lsClase) {
		this.lsClase = lsClase;
	}

	public List<RutaCombinacion> getLsRutaCombinacion() {
		return lsRutaCombinacion;
	}

	public void setLsRutaCombinacion(List<RutaCombinacion> lsRutaCombinacion) {
		this.lsRutaCombinacion = lsRutaCombinacion;
	}

	public List<RutaSecuencia> getLsRutaSecuencia() {
		return lsRutaSecuencia;
	}

	public void setLsRutaSecuencia(List<RutaSecuencia> lsRutaSecuencia) {
		this.lsRutaSecuencia = lsRutaSecuencia;
	}

	public List<Via> getLsVia() {
		return lsVia;
	}

	public void setLsVia(List<Via> lsVia) {
		this.lsVia = lsVia;
	}

	public List<Empresa> getLsEmpresa() {
		return lsEmpresa;
	}

	public void setLsEmpresa(List<Empresa> lsEmpresa) {
		this.lsEmpresa = lsEmpresa;
	}

	public List<ParadaSecuencia> getLsParadasSequencia() {
		return lsParadasSequencia;
	}

	public void setLsParadasSequencia(List<ParadaSecuencia> lsParadasSequencia) {
		this.lsParadasSequencia = lsParadasSequencia;
	}

	public List<RutaEmpresa> getLsRutaEmpresa() {
		return lsRutaEmpresa;
	}

	public void setLsRutaEmpresa(List<RutaEmpresa> lsRutaEmpresa) {
		this.lsRutaEmpresa = lsRutaEmpresa;
	}

	public Tramo getTramoBandBox() {
		return tramoBandBox;
	}

	public void setTramoBandBox(Tramo tramoBandBox) {
		this.tramoBandBox = tramoBandBox;
	}

	public Integer getUltimaSecuencia() {
		return ultimaSecuencia;
	}

	public void setUltimaSecuencia(Integer ultimaSecuencia) {
		this.ultimaSecuencia = ultimaSecuencia;
	}

	public List<OrgaoConcedente> getLsOrgaoConcedente() {
		return lsOrgaoConcedente;
	}

	public void setLsOrgaoConcedente(List<OrgaoConcedente> lsOrgaoConcedente) {
		this.lsOrgaoConcedente = lsOrgaoConcedente;
	}

	public List<GrupoRuta> getLsGrupoRuta() {
		return lsGrupoRuta;
	}

	public void setLsGrupoRuta(List<GrupoRuta> lsGrupoRuta) {
		this.lsGrupoRuta = lsGrupoRuta;
	}

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		lsClase = claseService.buscarTodosExceto(-1);
		lsVia = viaService.obtenerTodos();
		lsEmpresa = UsuarioLogado.getUsuarioLogado().getEmpresa();
		lsOrgaoConcedente = orgaoConcedenteService.obtenerTodos();
		lsGrupoRuta = grupoRutaService.obtenerTodos();

		ruta = (Ruta) Executions.getCurrent().getArg().get("ruta");
		rutaList = (MyListbox) Executions.getCurrent().getArg().get("rutaList");
		
		

		super.doAfterCompose(comp);

		// Secuencia
		rutaSecuenciaList.setItemRenderer(new RenderCatalogoDeRutasSecuencia());
		lsRutaSecuencia = new ArrayList<RutaSecuencia>();
		
			rutaSecuenciaList.addEventListener("onDoubleClick", new EventListener() {

	            @Override
	            public void onEvent(Event event) throws Exception {
	            	ParadaSecuencia psOrigen = (ParadaSecuencia)rutaSecuenciaList.getSelected();
	            	int indexSelecto = rutaSecuenciaList.getSelectedIndex();
	            	ParadaSecuencia psDestino = new ParadaSecuencia();
	            	try{
	            		 psDestino = (ParadaSecuencia)lsParadasSequencia.get(indexSelecto+1);
	            	}catch(IndexOutOfBoundsException e){
	            		
	            		Messagebox.show(Labels.getLabel("editarCatalogoDeRutaController.msg.finRuta"),
								Labels.getLabel("editarCatalogoDeRutaController.window.title"),
								Messagebox.OK, Messagebox.EXCLAMATION);
	            		return;
	            	}
	            	
	                if (psOrigen == null) {   //lsRutaSecuencia <-- esse objeto ja tem o id da ruta secuencia ....
	                    return;
	                }
	                Map args = new HashMap();
	                args.put("paradaSecuenciaOrigen", psOrigen);
	                args.put("paradaSecuenciaDestino", psDestino);
	                args.put("lsRutaSecuencia", lsRutaSecuencia);
	                
	                args.put("lsParadasSequencia", lsParadasSequencia);
	                args.put("rutaSecuenciaList", rutaSecuenciaList);
	                args.put("casetasList", psOrigen.getCasetas());
//	                args.put("tarifaOficialList", tarifaList);
	                openWindow("/gui/esquema_operacional/editarSecuencia.zul",
	                        Labels.getLabel("editarSecuenciaController.window.title"), args, MODAL);
//	                Peaje p = (Peaje) pedagioList.getSelected();
//	                verPeaje(p);
	            }
	        });

			txtNumRioCard.setDisabled(ruta.getIndVentaRioCard() == null || !ruta.getIndVentaRioCard());
			chkIndVentaRioCard.addEventListener("onClick", new EventListener() {
			
			@Override
			public void onEvent(Event event) throws Exception {
				disableEnableNumRioCard();
			}
		});
		

		// Combinacion
		rutaCombinacionList.setItemRenderer(this);
		lsRutaCombinacion = new ArrayList<RutaCombinacion>();

		// Ruta Empresa
		rutaEmpresaList.setItemRenderer(new RenderRutaEmpresa());
		lsRutaEmpresa = new ArrayList<RutaEmpresa>();

		lsParadasSequencia = new ArrayList<ParadaSecuencia>();

		if (ruta.getRutaId() != null) {
			ruta = rutaService.obtenerID(ruta.getRutaId());
			if (ruta.getIndNombreObligatorio()) {
				rdSi.setChecked(true);
			} else {
				rdNo.setChecked(true);
			}
			if (ruta.getIndSentidoIda() != null) {
				if (ruta.getIndSentidoIda()) {
					radIda.setChecked(true);
					radVolta.setChecked(false);
				} else {
					radIda.setChecked(false);
					radVolta.setChecked(true);
				}
			}

			lsRutaEmpresa = ruta.getLsRutaEmpresa();
			rutaEmpresaList.setData(lsRutaEmpresa);

			carregarParadaSecuencia();
			ruta.setRutaSecuenciaList(lsRutaSecuencia);

			numSecuencia.setValue(lsRutaSecuencia.size() + 2);
			txtNumRioCard.setValue(ruta.getNumRioCard());
		} else {
			List<RutaCombinacion> combinacion = new ArrayList<RutaCombinacion>();
			ruta.setRutaCombinacionList(combinacion);
			numSecuencia.setValue(1);
		}
		txtNome.focus();

		if (ruta.getRutaId() == null) {
			btnApagar.setVisible(Boolean.FALSE);
		}

		carregouCombinacao = false;
	}

	protected void disableEnableNumRioCard() {
		if(chkIndVentaRioCard.isChecked()) {
			txtNumRioCard.setDisabled(false);
			txtNumRioCard.setConstraint("no empty");
		} else {
			txtNumRioCard.setDisabled(true);
			txtNumRioCard.setValue("");
			txtNumRioCard.setConstraint((String) null);
		}
	}

	private void paginarCombinacao() {
		if (ruta.getRutaId() != null) {
			HibernateSearchObject<RutaCombinacion> claseServicioBusqueda =
					new HibernateSearchObject<RutaCombinacion>(RutaCombinacion.class,
							pagingRutaCombinacion.getPageSize());

			claseServicioBusqueda.addFilterEqual("activo", Boolean.TRUE);
			claseServicioBusqueda.addFilterEqual("ruta", ruta);

			plwRutaCombinacion.init(claseServicioBusqueda, rutaCombinacionList, pagingRutaCombinacion);
		}
	}

	private void addTramoPardaSecuencia(Parada parada, Via via, Short numsecuencia) {
		ParadaSecuencia paradaSecuencia = new ParadaSecuencia();
		paradaSecuencia.setParada(parada);
		paradaSecuencia.setSecuencia(numsecuencia);
		paradaSecuencia.setVia(via);
		lsParadasSequencia.add(paradaSecuencia);
	}
	private void addTramoPardaSecuencia(Parada parada, Via via, Short numsecuencia, List<CasetaPeaje> lCas, String tempo, String km) {
		ParadaSecuencia paradaSecuencia = new ParadaSecuencia();
		paradaSecuencia.setParada(parada);
		paradaSecuencia.setSecuencia(numsecuencia);
		paradaSecuencia.setVia(via);
		paradaSecuencia.setCasetas(lCas);
		paradaSecuencia.setKmReal(km);
		paradaSecuencia.setTempoReal(tempo);
		lsParadasSequencia.add(paradaSecuencia);
	}

	private void carregarParadaSecuencia() {
		lsParadasSequencia.clear();
		lsRutaSecuencia = rutaSecuenciaService.buscarSecuenciaOrdenado(ruta);
		short numSecuencia = 0;
		for (int i = 0; i < lsRutaSecuencia.size(); i++) {
			RutaSecuencia rs = lsRutaSecuencia.get(i);
			Tramo tramo = rs.getTramo();
			Via via = tramo.getVia();
			List<CasetaPeaje> lcas = rs.getLsCasetaPeaje();
			Short numsecuencia = ++numSecuencia;

			Parada paradaOrigem = tramo.getOrigem();
			BigDecimal km = tramo.getKmReal();
			
			addTramoPardaSecuencia(paradaOrigem, via, numsecuencia, lcas, getTempo(tramo.getTramoServicioList(), ruta), km != null ? km.toString() : "");
			if (i == lsRutaSecuencia.size() - 1) {
				Parada paradaDestino = tramo.getDestino();
				Integer ultSecuencia = numsecuencia.intValue() + 1;
				addTramoPardaSecuencia(paradaDestino, via,
						ultSecuencia.shortValue());
			}
		}

		rutaSecuenciaList.setData(lsParadasSequencia);
	}

	private String getTempo(List<TramoServicio> lsTramoServicio, Ruta rutaTempo) {

		for (TramoServicio tramoServicio : lsTramoServicio) {

			if (tramoServicio.getClaseServicio().equals(rutaTempo.getClaseServicio())) {
				Calendar c = Calendar.getInstance();
				c.setTime(tramoServicio.getTiemporecorrido());

				Long tempo = DateUtil.getElapsedMinutos(DateUtil.getFecInicio().getTime(), c.getTime());
				long minutos = (tempo % 60);
				int horas = (tempo.intValue() / 60);

				String sMinutos = String.valueOf(minutos);
				return horas + ":" + ((sMinutos.length() < 2) ? "0" + sMinutos : sMinutos);
			}
		}

		return "";
	}

	public void onClick$btModificar(Event ev) {
		numSecuencia.setDisabled(Boolean.FALSE);
		ultimaSecuencia = numSecuencia.getValue();
		modificado = Boolean.TRUE;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void onClick$btnAdicionarSecuencia(Event ev) throws InterruptedException {
		cmbVia.getValue();
		try {
			// Para uma ruta já existente, só é possí­vel adicionar paradas
			// entre a origem inicial e destino final.
			if (ruta.getRutaId() != null) {
				if ((numSecuencia.getValue() == 1) || (numSecuencia.getValue() > lsParadasSequencia.size())) {
					Messagebox.show(Labels.getLabel("editarCatalogoDeRutaController.msg.cambioSecuencia"),
							Labels.getLabel("editarCatalogoDeRutaController.window.title"),
							Messagebox.OK, Messagebox.EXCLAMATION);
					return;
				}
			}
			cmbParada.getSelectedItem();
			Parada parada = (Parada) cmbParada.getSelectedItem().getValue();

			Via via = (Via) cmbVia.getSelectedItem().getValue();
			boolean existe = false;

			for (ParadaSecuencia ps : lsParadasSequencia) {
				if (ps.getParada().equals(parada)) {
					existe = true;
				}
			}

			if (!existe) {
				if (!modificado) {
					addTramoPardaSecuencia(parada, via, numSecuencia.getValue().shortValue());
					rutaSecuenciaList.setData(lsParadasSequencia);
					numSecuencia.setValue(numSecuencia.getValue() + 1);
					secuenciaFoiAlterada = Boolean.TRUE;
					cmbParada.focus();
					cmbParada.setText("");
				} else {
					Boolean incrementar = Boolean.FALSE;
					for (int i = 0; i < lsParadasSequencia.size(); i++) {
						// Se numero de secuencia inserido marior que os que
						// existem, não faço nada.
						if (lsParadasSequencia.get(i).getSecuencia().intValue() < numSecuencia.getValue()) {
							continue;
							// Se existe uma sequancia igual a já digitada,
							// incremento +1 nesse secuencia
						} else if (lsParadasSequencia.get(i).getSecuencia().intValue() == numSecuencia.getValue()) {
							Integer novaSecuencia = lsParadasSequencia.get(i).getSecuencia().intValue() + 1;
							lsParadasSequencia.get(i).setSecuencia(new Short(novaSecuencia.toString()));
							incrementar = Boolean.TRUE;
							// So continuo incrementando se já houver uma
							// secuencia igual
						} else if (incrementar) {
							Integer novaSecuencia = lsParadasSequencia.get(i).getSecuencia().intValue() + 1;
							lsParadasSequencia.get(i).setSecuencia(new Short(novaSecuencia.toString()));
						} else {
							continue;
						}
					}

					addTramoPardaSecuencia(parada, via, numSecuencia.getValue().shortValue());
					// Em ordem crescente do numero da secuencia
					Collections.sort(lsParadasSequencia, new Comparator() {

						public int compare(Object o1, Object o2) {
							ParadaSecuencia p1 = (ParadaSecuencia) o1;
							ParadaSecuencia p2 = (ParadaSecuencia) o2;
							return p1.getSecuencia().intValue() < p2.getSecuencia().intValue() ? -1 : (p1.getSecuencia().intValue() > p2.getSecuencia().intValue() ? +1 : 0);
						}
					});

					rutaSecuenciaList.setData(lsParadasSequencia);
					secuenciaFoiAlterada = Boolean.TRUE;
					numSecuencia.setValue(ultimaSecuencia);
					numSecuencia.setDisabled(Boolean.TRUE);
					cmbParada.focus();
					cmbParada.setText("");
				}
			} else {
				Messagebox.show(Labels.getLabel("editarCatalogoDeRutaController.msg.validacion.yaExisteParada"),
						Labels.getLabel("editarCatalogoDeRutaController.window.title"),
						Messagebox.OK, Messagebox.INFORMATION);
			}
		} catch (Exception e) {
			log.error(e);
			Messagebox.show(Labels.getLabel("editarCatalogoDeRutaController.MSG.selectItem"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
		}
	}

	public void onClick$btnRemoverSecuencia(Event ev) {
		try {
			ParadaSecuencia paradaSecuencia = (ParadaSecuencia) rutaSecuenciaList.getSelected();
			if (paradaSecuencia != null) {

				if (ruta.getRutaId() != null) {
					List<Integer> lsEsquemas = esquemaCorridaService.existe(ruta, paradaSecuencia.getParada().getParadaId());
					if (!lsEsquemas.isEmpty()) {
						StringBuilder sb = new StringBuilder("");
						for (Integer esquemaCorridaId : lsEsquemas) {
							sb.append(esquemaCorridaId).append(", ");
						}
						sb.delete(sb.length() - 2, sb.length());

						String msg = new MessageFormat(Labels.getLabel("busquedaCatalogoDeRutaController.msg.validactionRemocionParada")).format(new Object[] { paradaSecuencia.getParada().getDescparada(), sb.toString() });

						Messagebox.show(msg, Labels.getLabel("editarCatalogoDeRutaController.window.title"),
								Messagebox.OK, Messagebox.ERROR);

						return;
					}
				}

				Short secuenciaMax = 0;
				for (ParadaSecuencia ps : lsParadasSequencia) {
					if (ps.getSecuencia().compareTo(secuenciaMax) > 0) {
						secuenciaMax = ps.getSecuencia();
					}
				}
				numSecuencia.setValue(secuenciaMax + 1);

				if (paradaSecuencia.getSecuencia() == 1 || paradaSecuencia.getSecuencia() == secuenciaMax) {
					Messagebox.show(Labels.getLabel("editarCatalogoDeRutaController.MSG.removerSecuencia"),
							Labels.getLabel("editarCatalogoDeRutaController.window.title"),
							Messagebox.OK, Messagebox.EXCLAMATION);
				} else {
					for (ParadaSecuencia ps : lsParadasSequencia) {
						if (ps.getParada().equals(paradaSecuencia.getParada())) {
							lsParadasSequencia.remove(ps);
							rutaSecuenciaList.setData(lsParadasSequencia);
							secuenciaFoiAlterada = Boolean.TRUE;
							log.debug("Sequencia Removida: "
									+ ps.getSecuencia() + " - "
									+ ps.getParada().getCveparada());
							break;
						}
					}
				}
			}
		} catch (Exception e) {
			log.error("Erro ao remover secuencia da ruta" + e.getMessage());
			Clients.alert(Labels.getLabel("MSG.Error"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"), Messagebox.ERROR);
		}
	}

	public void onClick$btnAdicionarEmpresaRuta(Event ev) {
		try {
			Comboitem cbiEmpresa = cmbEmpresa.getSelectedItem();

			if (cbiEmpresa != null) {
				Empresa empresa = (Empresa) cbiEmpresa.getValue();

				Boolean achou = Boolean.FALSE;

				for (RutaEmpresa re : lsRutaEmpresa) {
					if (re.getEmpresa().getEmpresaId().equals(empresa.getEmpresaId())) {
						achou = Boolean.TRUE;
					}
				}

				if (!achou) {
					RutaEmpresa rutaEmpresa = new RutaEmpresa();
					rutaEmpresa.setRuta(ruta);
					rutaEmpresa.setEmpresa(empresa);
					rutaEmpresa.setActivo(Boolean.TRUE);
					rutaEmpresa.setFecmodif(Calendar.getInstance().getTime());
					rutaEmpresa.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());

					lsRutaEmpresa.add(rutaEmpresa);
					ruta.setLsRutaEmpresa(lsRutaEmpresa);

					rutaEmpresaList.setData(lsRutaEmpresa);
				} else {
					Messagebox.show(Labels.getLabel("MSG.Registro.Existe"),
							Labels.getLabel("editarCatalogoDeRutaController.window.title"),
							Messagebox.OK, Messagebox.EXCLAMATION);
				}
			}
		} catch (Exception ex) {
			log.debug(ex);
			Clients.alert(Labels.getLabel("MSG.Error"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"), Messagebox.ERROR);
		}
	}

	public void onClick$btnRemoverEmpresaRuta(Event ev) {
		RutaEmpresa rutaEmpresa = (RutaEmpresa) rutaEmpresaList.getSelected();
		if (rutaEmpresa != null) {
			rutaEmpresa.setActivo(Boolean.FALSE);
			rutaEmpresa.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
			rutaEmpresa.setFecmodif(Calendar.getInstance().getTime());

			rutaEmpresaService.borrar(rutaEmpresa);

			lsRutaEmpresa.remove(rutaEmpresa);
			rutaEmpresaList.setData(lsRutaEmpresa);
		}
	}

	private boolean validar() throws InterruptedException {
		txtNome.getValue();
		cmbClase.getValue();

		if (lsParadasSequencia.size() < 2) {
			Messagebox.show(Labels.getLabel("editarCatalogoDeRutaController.msg.validacion.paradas"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);

			return false;
		}

		if (lsRutaEmpresa.isEmpty()) {
			Messagebox.show(Labels.getLabel("editarCatalogoDeRutaController.msg.validacion.empresa"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);

			return false;
		}

		return true;
	}

	// Quando alteramos os tramo em combinacao selecionando uma nova via
	// temos q atualizar os tramos da sequencia para que seja os mesmos
	// tramos em combinacao e sequencia:
	private void atualizarTramosSequencia() {
		List<RutaCombinacion> lsRutacComb = ruta.getRutaCombinacionList();
		List<RutaSecuencia> lsRutaSec = ruta.getRutaSecuenciaList();

		for (RutaCombinacion rc : lsRutacComb) {
			Tramo tramoRC = rc.getTramo();
			Parada origemRC = rc.getTramo().getOrigem();
			Parada destinoRC = rc.getTramo().getDestino();
			Via viaRC = rc.getTramo().getVia();
			for (RutaSecuencia rs : lsRutaSec) {
				Parada origemRS = rs.getTramo().getOrigem();
				Parada destinoRS = rs.getTramo().getDestino();
				Via viaRS = rs.getTramo().getVia();

				if ((origemRS.getParadaId().equals(origemRC.getParadaId()))
						&& (destinoRS.getParadaId().equals(destinoRC.getParadaId()))
						&& (!viaRS.getViaId().equals(viaRC.getViaId()))) {
					rs.setTramo(tramoRC);
				}
			}
		}
	}

	public void onClick$btnSalvar(Event ev) throws InterruptedException {
		txtPrefixo.getValue();
		txtNumRioCard.getValue();
		
		if(null != txtCantEixos && txtCantEixos.getValue()!= null && txtCantEixos.getValue() == 0){
			Messagebox.show(
					Labels.getLabel("editarCatalogoDeRutaController.lblCantEixosZeroInvalido.value"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
			return;
		}
		if(null != txtCantAsientos && txtCantAsientos.getValue() != null && txtCantAsientos.getValue() == 0){
			Messagebox.show(
					Labels.getLabel("editarCatalogoDeRutaController.lblCantAsientosZeroInvalido.value"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
			return;
		}

		List<Ruta> lsRuta = rutaService.buscarNumRuta(txtNumRuta.getValue());
		
		if (radIda.isChecked()) {
			ruta.setIndSentidoIda(Boolean.TRUE);
		} else if (radVolta.isChecked()) {
			ruta.setIndSentidoIda(Boolean.FALSE);
		}

		if (!lsRuta.isEmpty()) {
			boolean exists = CollectionUtils.exists(lsRuta, new Predicate() {

				@Override
				public boolean evaluate(Object object) {
					return ((Ruta) object).getNumRuta().equals(ruta.getNumRuta()) && ((Ruta) object).getIndSentidoIda().equals(ruta.getIndSentidoIda());
				}
			});

			if (ruta.getRutaId() == null && exists) {
				Messagebox.show(
						Labels.getLabel("editarCatalogoDeRutaController.registroNumRutaExiste"),
						Labels.getLabel("editarCatalogoDeRutaController.window.title"),
						Messagebox.OK, Messagebox.EXCLAMATION);

				return;
			}
		}

		if ((ruta.getRutaId() != null) && secuenciaFoiAlterada) {
			int resp = Messagebox.show(
					Labels.getLabel("editarCatalogoDeRutaController.msg.validacionCambionEnCombinaciones"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"),
					Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

			if (resp == Messagebox.NO) {
				return;
			}
		}

		if (!validar()) {
			return;
		}

		try {

			if (lsParadasSequencia.size() == 1) {
				Messagebox.show(Labels.getLabel("editarCatalogoDeRutaController.MSG.sequencia"),
						Labels.getLabel("editarCatalogoDeRutaController.window.title"),
						Messagebox.OK, Messagebox.EXCLAMATION);
			} else {
				ruta.setActivo(Boolean.TRUE);
				ruta.setFecmodif(Calendar.getInstance().getTime());
				ruta.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
				ruta.setClaseServicio((ClaseServicio) cmbClase.getSelectedItem().getValue());

				if (rdSi.isChecked()) {
					ruta.setIndNombreObligatorio(Boolean.TRUE);
				} else if (rdNo.isChecked()) {
					ruta.setIndNombreObligatorio(Boolean.FALSE);
				}

				ruta.setNumRioCard(txtNumRioCard.getValue());

				if (ruta.getRutaId() == null) {

					ruta = rutaService.suscribir(ruta, lsParadasSequencia);
					rutaList.addItem(ruta);

					Messagebox.show(Labels.getLabel(
							"editarCatalogoDeRutaController.MSG.suscribirOK").concat(" ID: "
							+ ruta.getRutaId().toString()),
							Labels.getLabel("editarCatalogoDeRutaController.window.title"),
							Messagebox.OK,
							Messagebox.INFORMATION);

					closeWindow();

				} else {

					// Gera Secuencia e Combinação Novamente se houve
					// modificação na Secuencia.
					if (secuenciaFoiAlterada) {
						ruta = rutaService.actualizacion(ruta, lsParadasSequencia);
					} else {
						ruta = rutaService.actualizacion(ruta, null);
					}

					rutaList.updateItem(ruta);

					Messagebox.show(Labels.getLabel(
							"editarCatalogoDeRutaController.MSG.suscribirOK").concat(" ID: "
							+ ruta.getRutaId().toString()),
							Labels.getLabel("editarCatalogoDeRutaController.window.title"),
							Messagebox.OK, Messagebox.INFORMATION);

					closeWindow();
				}
			}
		} catch (BusinessException ex) {
			Messagebox.show(ex.getLocalizedMessage(),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"),
					Messagebox.OK, Messagebox.ERROR);
		} catch (Exception ex) {
			log.error("Error al dar de alta ruta", ex);
			Messagebox.show(Labels.getLabel("MSG.Error"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"),
					Messagebox.OK, Messagebox.ERROR);
		}

	}

	public void onClick$btnApagar(Event ev) {
		try {
			int resp = Messagebox.show(Labels.getLabel("editarCatalogoDeRutaController.MSG.borrarPergunta"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"),
					Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

			if (resp == Messagebox.YES) {
				rutaService.borrar(ruta);
				Messagebox.show(Labels.getLabel("editarCatalogoDeRutaController.MSG.borrarOK"),
						Labels.getLabel("editarCatalogoDeRutaController.window.title"),
						Messagebox.OK, Messagebox.INFORMATION);

				rutaList.removeItem(ruta);

				closeWindow();
			}
		} catch (RegistroConDependenciaException ex) {
			Clients.alert(ex.getLocalizedMessage(),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"), Messagebox.INFORMATION);
		} catch (Exception ex) {
			log.error(ex);
			Clients.alert(Labels.getLabel("MSG.Error"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"), Messagebox.INFORMATION);
		}
	}

	public void render(Listitem lstm, Object o) throws Exception {
		try {
			RutaCombinacion rutaCombinacion = (RutaCombinacion) o;

			Listcell lc = new Listcell();

			lc = new Listcell();
			final Combobox comboVenda = new Combobox();
			comboVenda.setMold("rounded");
			comboVenda.setWidth("90%");
			List<String> op = new ArrayList<String>();
			op.add("Sim");
			op.add("Não");
			comboVenda.setModel(new ListModelList(op));
			comboVenda.setValue(rutaCombinacion.getIndventa() == Boolean.TRUE ? "Sim" : "Não");
			comboVenda.setTooltip(rutaCombinacion.getRutacombinacionId().toString());
			comboVenda.addEventListener("onChange", new EventListener() {

				@Override
				public void onEvent(Event event) throws Exception {
					String venda = (String) comboVenda.getSelectedItem().getValue();
					String idCombinacion = comboVenda.getTooltip();
					vendeSiNo(venda, idCombinacion);
				}
			});
			lc.appendChild(comboVenda);
			lc.setParent(lstm);

			
			Tramo tramo = rutaCombinacion.getTramo();
			String descTramoDetalhado = tramo.getOrigem().getDescparada() + "|" +tramo.getDestino().getDescparada();
			
			lc = new Listcell(rutaCombinacion.getTramo().getDesctramo() + "("+descTramoDetalhado+")");
			lc.setParent(lstm);

			lc = new Listcell();

			final Combobox comboVia = new Combobox();
			comboVia.setMold("rounded");
			comboVia.setWidth("90%");
			comboVia.setTooltip(rutaCombinacion.getRutacombinacionId().toString());

			List<Via> lsViaCombinacion = tramoService.obtenerViasOrigemDestino(
					rutaCombinacion.getTramo().getOrigem(), rutaCombinacion.getTramo().getDestino());

			if (lsViaCombinacion.size() == 1) {
				comboVia.setDisabled(Boolean.TRUE);
			}
			comboVia.setModel(new ListModelList(lsViaCombinacion));
			comboVia.setValue(rutaCombinacion.getTramo().getVia().getNombvia());
			comboVia.addEventListener("onChange", new EventListener() {

				@Override
				public void onEvent(Event event) throws Exception {
					Via v = (Via) comboVia.getSelectedItem().getValue();
					String idCombinacion = comboVenda.getTooltip();
					opcionVia(v, idCombinacion);
				}
			});
			lc.appendChild(comboVia);
			lc.setParent(lstm);

			lstm.setAttribute("data", rutaCombinacion);
		} catch (Exception e) {
			log.error("Erro ao mudar via da ruta combinacion: "
					+ e.getMessage());
			Clients.alert(Labels.getLabel("MSG.Error"),
					Labels.getLabel("editarCatalogoDeRutaController.window.title"), Messagebox.ERROR);
		}

	}
	
	public Intbox getTxtCantEixos() {
		return txtCantEixos;
	}

	public void setTxtCantEixos(Intbox txtCantEixos) {
		this.txtCantEixos = txtCantEixos;
	}

	public Intbox getTxtCantAsientos() {
		return txtCantAsientos;
	}

	public void setTxtCantAsientos(Intbox txtCantAsientos) {
		this.txtCantAsientos = txtCantAsientos;
	}

	public void vendeSiNo(String venda, String idCombinacion) {

		RutaCombinacion rc = (RutaCombinacion) rutaCombinacionList.getSelected();

		rc = rutaCombinacionService.obtenerID(Integer.parseInt(idCombinacion));
		// lsRutaCombinacion.remove(rc);
		rc.setIndventa(venda.equals("Sim") ? Boolean.TRUE : Boolean.FALSE);
		rc = rutaCombinacionService.actualizacion(rc);
		// lsRutaCombinacion.add(rc);
		rutaCombinacionList.clearSelection();
	}

	public void opcionVia(Via v, String idCombinacion) {

		RutaCombinacion rc = rutaCombinacionService.obtenerID(Integer.parseInt(idCombinacion));

		// lsRutaCombinacion.remove(rc);
		rc.setTramo(tramoService.obtenerTramotPorOrigemDestinoVia(rc.getTramo().getOrigem(), rc.getTramo().getDestino(), v));
		rutaCombinacionService.actualizacion(rc);
		// lsRutaCombinacion.add(rc);
		// rutaCombinacionList.updateItem(rc);

		atualizarTramosSequencia();
	}

	public void onClick$tabCombinacion(Event ev) throws SQLException {
		if (!carregouCombinacao) {
			Clients.showBusy("Cargando combinaciones");
			paginarCombinacao();
			Clients.clearBusy();
		}

		carregouCombinacao = true;
	}

	public Checkbox getChkIndVentaRioCard() {
		return chkIndVentaRioCard;
	}

	public void setChkIndVentaRioCard(Checkbox chkIndVentaRioCard) {
		this.chkIndVentaRioCard = chkIndVentaRioCard;
	}

	public MyTextbox getTxtNumRioCard() {
		return txtNumRioCard;
	}

	public void setTxtNumRioCard(MyTextbox txtNumRioCard) {
		this.txtNumRioCard = txtNumRioCard;
	}		
}