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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Doublebox;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Tab;
import org.zkoss.zul.Textbox;

import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.Conexion;
import com.rjconsultores.ventaboletos.entidad.ConexionCtrl;
import com.rjconsultores.ventaboletos.entidad.ConexionDescuento;
import com.rjconsultores.ventaboletos.entidad.ConexionRutaConf;
import com.rjconsultores.ventaboletos.entidad.ConexionRutaExcepcionPtoVta;
import com.rjconsultores.ventaboletos.entidad.ConexionRutaExcepcionTipoPtoVta;
import com.rjconsultores.ventaboletos.entidad.ConexionRutaLocalidadeRemovida;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.entidad.Ruta;
import com.rjconsultores.ventaboletos.entidad.RutaCombinacion;
import com.rjconsultores.ventaboletos.entidad.RutaEmpresa;
import com.rjconsultores.ventaboletos.entidad.TipoPuntoVenta;
import com.rjconsultores.ventaboletos.service.ClaseServicioService;
import com.rjconsultores.ventaboletos.service.ConexionCtrlService;
import com.rjconsultores.ventaboletos.service.ConexionDescuentoService;
import com.rjconsultores.ventaboletos.service.ConexionRutaCombinacionService;
import com.rjconsultores.ventaboletos.service.ConexionRutaConfService;
import com.rjconsultores.ventaboletos.service.ConexionRutaExcepcionPtoVtaService;
import com.rjconsultores.ventaboletos.service.ConexionRutaExcepcionTipoPtoVtaService;
import com.rjconsultores.ventaboletos.service.ConexionRutaLocalidadeRemovidaService;
import com.rjconsultores.ventaboletos.service.ConexionRutaTramoCtrlService;
import com.rjconsultores.ventaboletos.service.ConexionService;
import com.rjconsultores.ventaboletos.service.RutaEmpresaService;
import com.rjconsultores.ventaboletos.service.RutaService;
import com.rjconsultores.ventaboletos.service.TipoPuntoVentaService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.vo.parada.ConexionCtrlVO;
import com.rjconsultores.ventaboletos.vo.parada.ConexionRutaConfVO;
import com.rjconsultores.ventaboletos.vo.parada.ConexionRutaCtrlVO;
import com.rjconsultores.ventaboletos.vo.parada.ParadaVOConexionRuta;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;
import com.rjconsultores.ventaboletos.web.utilerias.MyListbox;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderConexionRuta;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderConexionRutaRemoveSelecionada;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderEixoConexionRutaRemoveSelecionada;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderGeracaoConexionPorRuta;

@Controller("gerarConexionPorRutaController")
@Scope("prototype")
public class GerarConexionPorRutaController extends MyGenericForwardComposer {

	private static final long serialVersionUID = 1L;
	private static Logger log = LogManager.getLogger(GerarConexionPorRutaController.class);

	@Autowired
	private ConexionRutaConfService conexionRutaConfService;
	@Autowired
	private ConexionRutaTramoCtrlService conexionRutaTramoCtrlService;
	@Autowired
	private RutaService rutaService;
	@Autowired
	private TipoPuntoVentaService tipoPuntoVentaService;
	@Autowired
	private ConexionRutaExcepcionPtoVtaService conexionRutaRestricaoPtoVtaService;
	@Autowired
	private ConexionRutaExcepcionTipoPtoVtaService conexionRutaExcepcionTipoPtoVtaService;
	@Autowired
	ConexionRutaCombinacionService conexionRutaCombinacionService;
	
	@Autowired
	private ConexionService conexionService;
	@Autowired
	private ClaseServicioService claseServicioService;
	@Autowired
	private ConexionDescuentoService conexionDescuentoService;
	@Autowired
	private ConexionCtrlService conexionCtrlService;
	
	@Autowired
	ConexionRutaLocalidadeRemovidaService conexionRutaLocalidadeRemovidaService;
	@Autowired
	RutaEmpresaService rutaEmpresaService;
	private MyListbox localidadesOrigemlList;
	private MyListbox localidadesDestinoList;
	private MyListbox  localidadesDestinoLinhaCList;
	private MyListbox localidadesLinhaASelecionadaList;
	private MyListbox localidadesLinhaBSelecionadaList;
	private MyListbox localidadesLinhaCSelecionadaList;
	private Tab resultadoCombinacao;
	private Button btnSalvar;
	private Button btnApagar;
	private Intbox txtTiempoMin;
	private Intbox txtTiempoMax;
	private Textbox txtDescricao;
	private MyListbox rutasAList;
	private MyListbox rutasBList;
	private MyListbox rutasCList;
	private MyListbox localidadesCombinadasList;
	private MyListbox localidadesComunsABList;
	private MyListbox localidadesComunsBCList;
	private MyListbox listEspCanal;
	private MyListbox listPuntoVenta;

	private List<Parada> lsLocalidadesComunsLinhasBC;
	private Combobox cmbTipoPtovta;
	private Combobox cmbPtovta;
	private Combobox cmbRutaA;
	private Combobox cmbRutaB;
	private Combobox cmbRutaC;
	private List<TipoPuntoVenta> lsTipoPtovta;

	private List<ConexionCtrl> conexoesCtrl;
	List<ParadaVOConexionRuta> localidadesGeradas;
	private ConexionRutaConf conexionRutaConf;
	private MyListbox conexionRutaConfList;
	private Boolean isConexaoPorAgrupamento;
	
	private Doublebox txtDesconto;
	private Combobox cmbOrigemConexao;
	private Combobox cmbDestinoConexao;
	
	private Button btnFiltrar;
	List<ParadaVOConexionRuta> localidadesGeradasFiltro;
	private List<Parada> lsOrigemConexao;
	private List<Parada> lsDestinoConexao;
	private Checkbox chkUtilizaPricing;
	
	private boolean isConexionGerada;
	
	@Override
	public void doAfterCompose(Component comp) throws Exception {

		super.doAfterCompose(comp);

		this.isConexionGerada = false;
		txtTiempoMax.setConstraint("no empty");
		txtTiempoMin.setConstraint("no empty");
		txtDescricao.setConstraint("no empty");

		lsTipoPtovta = tipoPuntoVentaService.obtenerTodos();

		conexionRutaConf = (ConexionRutaConf) Executions.getCurrent().getArg().get("conexionRutaConf");
		conexionRutaConfList = (MyListbox) Executions.getCurrent().getArg().get("conexionRutaConfList");
		conexoesCtrl = new ArrayList<>();
		
		if (conexionRutaConf != null) {
			

			btnSalvar.setDisabled(false);
			btnApagar.setDisabled(false);
			
			txtDescricao.setValue(conexionRutaConf.getDescricao());
			txtTiempoMin.setValue(conexionRutaConf.getTiempoMin());
			txtTiempoMax.setValue(conexionRutaConf.getTiempoMax());
			txtDesconto.setValue(conexionRutaConf.getDescuento() == null ? null : conexionRutaConf.getDescuento().doubleValue());
			
			configuraExcecaoPorPontoVenda();

			configuraExcecaoPorTipoVenda();
			
			configuraRutasPorEixo();

			isConexaoPorAgrupamento = validaConfAgrupamentoLocalidadeEmpresaLinhas();
			//Eixo A
			configuraLocalidadesEixoA();
			
			//Eixo B
			configuraLocalidadesEixoB();
			
			//Eixo C
			configuraLocalidadesEixoC();

			gerarCombinacao(true);
		}else{
			btnSalvar.setDisabled(true);
			btnApagar.setDisabled(true);
		}

		configuraRendererListaLocalidadesSelecionadasEixoA();
		
		configuraRendererListaLocalidadesSelecionadasEixoB();
		
		configuraRendererListaLocalidadesSelecionadasEixoC();
		
		resultadoCombinacao.setSelected(false);
		
	}

	/**
	 * Valida se a epresa da linha esta configurada para funcionar com agrupamento de localidade na conexao
	 * @param rutaA
	 * @return
	 */
	private Boolean validaConfAgrupamentoLocalidadeEmpresaLinhas() {
		List<Ruta> rutas = new ArrayList<Ruta>(); 
		rutas.addAll(rutasAList.getListData());
		rutas.addAll(rutasBList.getListData());
		Boolean isConexaoPorAgrupamento = Boolean.FALSE;
		if(rutas !=null) {
			for (Ruta ruta : rutas) {				
				List<RutaEmpresa> rutaEmpresaList = rutaEmpresaService.obtenerPorRuta(ruta);
				for (RutaEmpresa rutaEmpresa : rutaEmpresaList) {
					if(rutaEmpresa.getEmpresa() !=null && Boolean.TRUE.equals(rutaEmpresa.getEmpresa().getIndAgrupLocConexao())) {
						isConexaoPorAgrupamento = true;
						break;
					}
				}				
			}
		}
		return isConexaoPorAgrupamento;
	}

	private void configuraRendererListaLocalidadesSelecionadasEixoC() {
		localidadesLinhaCSelecionadaList.setItemRenderer(new RenderConexionRutaRemoveSelecionada(new EventListener() {

			@Override
			public void onEvent(Event arg0) throws Exception {

				Parada conexionRutaVO = (Parada) arg0.getTarget().getAttribute("data");
				for (Object objectParada : localidadesLinhaCSelecionadaList.getListData()) {
					if (((Parada) objectParada).equals(conexionRutaVO)) {
						localidadesLinhaCSelecionadaList.removeItem(conexionRutaVO);
						if(!localidadesDestinoLinhaCList.getListData().contains(conexionRutaVO)) {
							localidadesDestinoLinhaCList.addItemNovo(conexionRutaVO);
						}
						break;
					}
				}
			}
		}));
	}

	private void configuraRendererListaLocalidadesSelecionadasEixoB() {
		localidadesLinhaBSelecionadaList.setItemRenderer(new RenderConexionRutaRemoveSelecionada(new EventListener() {

			@Override
			public void onEvent(Event arg0) throws Exception {

				Parada conexionRutaVO = (Parada) arg0.getTarget().getAttribute("data");
				for (Object objectParada : localidadesLinhaBSelecionadaList.getListData()) {
					if (((Parada) objectParada).equals(conexionRutaVO)) {
						localidadesLinhaBSelecionadaList.removeItem(conexionRutaVO);
						if(!localidadesDestinoList.getListData().contains(conexionRutaVO)) {
							localidadesDestinoList.addItemNovo(conexionRutaVO);
						}
						break;
					}
				}
				gerarLocalidadesComunsBC();
			}
		}));
	}

	private void configuraRendererListaLocalidadesSelecionadasEixoA() {
		localidadesLinhaASelecionadaList.setItemRenderer(new RenderConexionRutaRemoveSelecionada(new EventListener() {

			@Override
			public void onEvent(Event arg0) throws Exception {

				Parada conexionRutaVO = (Parada) arg0.getTarget().getAttribute("data");
				for (Object objectParada : localidadesLinhaASelecionadaList.getListData()) {
					if (((Parada) objectParada).equals(conexionRutaVO)) {
						localidadesLinhaASelecionadaList.removeItem(conexionRutaVO);
						if(!localidadesOrigemlList.getListData().contains(conexionRutaVO)) {
							localidadesOrigemlList.addItemNovo(conexionRutaVO);
						}
						break;
					}
				}
			}
		}));
	}

	/**
	 * Configura localidades eixo C
	 * @throws InterruptedException
	 */
	private void configuraLocalidadesEixoC() throws InterruptedException {
		Set<Parada> lsParadasTodasPossiveisEixoC = new HashSet<Parada>();
		Set<Parada> lsParadasCadastradasEixoC = new HashSet<Parada>();
		lsParadasCadastradasEixoC.addAll(conexionRutaTramoCtrlService.buscarLocalidadesEixoC(conexionRutaConf.getConexionRutaConfId()));			
		lsParadasTodasPossiveisEixoC.addAll(conexionRutaTramoCtrlService.buscarTodasLocalidadesDestinoC(conexionRutaConf.getConexionRutaConfId()));
		lsParadasTodasPossiveisEixoC.removeAll(lsParadasCadastradasEixoC);
		localidadesLinhaCSelecionadaList.setData(new ArrayList<Parada>(lsParadasCadastradasEixoC));
		localidadesDestinoLinhaCList.setData(new ArrayList<Parada>(lsParadasTodasPossiveisEixoC));
		executarPesquisaLocalidadesDestinoLinhasC();
	}

	/**
	 * Configura localidades eixo B
	 * @throws InterruptedException
	 */
	private void configuraLocalidadesEixoB() throws InterruptedException {
		Set<Parada> lsParadasTodasPossiveisEixoB = new HashSet<Parada>();
		Set<Parada> lsParadasCadastradasEixoB = new HashSet<Parada>();
		lsParadasCadastradasEixoB.addAll(conexionRutaTramoCtrlService.buscarLocalidadeEixoB(conexionRutaConf.getConexionRutaConfId()));
		lsParadasTodasPossiveisEixoB.addAll(conexionRutaTramoCtrlService.buscarTodasLocalidadesDestino(conexionRutaConf.getConexionRutaConfId()));
		lsParadasTodasPossiveisEixoB.removeAll(lsParadasCadastradasEixoB);
		localidadesLinhaBSelecionadaList.setData(new ArrayList<Parada>(lsParadasCadastradasEixoB));
		localidadesDestinoList.setData(new ArrayList<Parada>(lsParadasTodasPossiveisEixoB));
		executarPesquisaLocalidadesDestino();
	}

	/**
	 * Configura localidades eixo A
	 * @throws InterruptedException
	 */
	private void configuraLocalidadesEixoA() throws InterruptedException {
		Set<Parada> lsParadasTodasPossiveisEixoA = new HashSet<Parada>();
		Set<Parada> lsParadasCadastradasEixoA = new HashSet<Parada>();
		lsParadasCadastradasEixoA.addAll(conexionRutaTramoCtrlService.buscarLocalidadesEixoA(conexionRutaConf.getConexionRutaConfId()));
		lsParadasTodasPossiveisEixoA.addAll(conexionRutaTramoCtrlService.buscarTodasLocalidadesOrigem(conexionRutaConf.getConexionRutaConfId()));
		lsParadasTodasPossiveisEixoA.removeAll(lsParadasCadastradasEixoA);
		localidadesLinhaASelecionadaList.setData(new ArrayList<Parada>(lsParadasCadastradasEixoA));
		localidadesOrigemlList.setData(new ArrayList<Parada>(lsParadasTodasPossiveisEixoA));
		executarPesquisaLocalidadesOrigen();
	}

	/**
	 * Configura as rutas (linhas) para cada eixo
	 */
	private void configuraRutasPorEixo() {
		//Busca uma lista de linhas (rutas), esta lista contem 3 sub-listas (1 para cada eixo de conexao A, B e C)
		List<List<Ruta>> rutas = conexionRutaConfService.buscarRutasPorConexionConf(conexionRutaConf.getConexionRutaConfId());
		List<Ruta> lsRutaA = rutas.get(0);
		List<Ruta> lsRutaB = rutas.get(1);
		List<Ruta> lsRutaC = rutas.get(2);
		rutasAList.setData(lsRutaA);
		rutasBList.setData(lsRutaB);
		rutasCList.setData(lsRutaC);
	}

	/**
	 * Configura a lista de excecoes por tipo de venda (canal de venda)
	 */
	private void configuraExcecaoPorTipoVenda() {
		//Busca a lista de excecoes por tipo de venda (canal de venda)
		List<ConexionRutaExcepcionTipoPtoVta> conexionRutaExcepcionTipoPtoVtaList =  conexionRutaExcepcionTipoPtoVtaService.buscarPorConexionConf(conexionRutaConf);
		for (ConexionRutaExcepcionTipoPtoVta conexionRutaExcepcionTipoPtoVta:conexionRutaExcepcionTipoPtoVtaList ) {
			listEspCanal.addItemNovo(conexionRutaExcepcionTipoPtoVta.getTipoPtovta());
		}
	}

	/**
	 * Configura a lista de excecoes por ponto de venda
	 */
	private void configuraExcecaoPorPontoVenda() {
		//Busca a lista de excecoes por ponto de venda
		List<ConexionRutaExcepcionPtoVta> conexionRutaExcepcionPtoVtaList = conexionRutaRestricaoPtoVtaService.buscarPorConexionConf(conexionRutaConf);
		for (ConexionRutaExcepcionPtoVta conexionRutaExcepcionPtoVta : conexionRutaExcepcionPtoVtaList) {
			listPuntoVenta.addItemNovo(conexionRutaExcepcionPtoVta.getPuntoVenta());
		}
	}

	@SuppressWarnings("unchecked")
	public void onClick$btnSalvar(Event ev) throws Exception {
		
		if(!validarItensSalvar()) {
			return;
		}

		if(conexionRutaConf != null && conexionRutaConf.getConexionRutaConfId() != null) {
			conexionRutaConfService.excluirConfiguracao(conexionRutaConf, false, isConexionGerada);
		}
		
		List<ConexionRutaCtrlVO> lsConexionRutaCtrl = conexionRutaCombinacionService.extrairConexionRutaCtrl(localidadesGeradas);
		
		boolean itemNovo = false;
		if(conexionRutaConf == null) {
			 conexionRutaConf = new ConexionRutaConf();
			 itemNovo = true;
		}
		
		conexionRutaConf.setDescricao(txtDescricao.getText());	
		conexionRutaConf.setTiempoMin(txtTiempoMin.getValue());
		conexionRutaConf.setTiempoMax(txtTiempoMax.getValue());
		
		Double desconto = txtDesconto.getValue() == null ? 0d : txtDesconto.getValue();
		Boolean descontoAlterado = false;
		BigDecimal descontoAnterior = conexionRutaConf.getDescuento();
		
		//Valida se o desconto ja existia ou se e novo
		if(descontoAnterior != null && (desconto != null && descontoAnterior.doubleValue() != desconto)) {
			conexionRutaConf.setDescuento(new BigDecimal(desconto));
			descontoAlterado = true;
		}
		
		if(descontoAnterior == null && desconto != null) {
			conexionRutaConf.setDescuento(new BigDecimal(desconto));
		} 
		
		List<TipoPuntoVenta> canalVentas = listEspCanal.getListData();
		List<PuntoVenta> puntoVentas = listPuntoVenta.getListData();
		
		conexionRutaConf = conexionRutaConfService.salvarConfiguracao(conexionRutaConf, canalVentas, puntoVentas,
																	  conexoesCtrl, lsConexionRutaCtrl, localidadesGeradas,
																	  isConexionGerada);
		
		removeLocalidadesExcluidas();
		adicionaLocalidadesExcluidas();		
		
		
		//Atualizar o indPricing alterado pela tabela
		atualizarIndPricing();
		
		List<ConexionDescuento> conexionDescontos = new ArrayList<>();
		
		if(isConexionGerada) {		
			if(desconto != null && desconto != 0 ) {
				criarNovosDescontosPorConexao(conexionDescontos);
			}
		} else if(descontoAlterado){ //Se nao foi gerado novas conexoes, mas foi alterado o desconto
			
			if( desconto == null || desconto == 0) {
				desativarDescontosAnteriores(conexionDescontos);// remover todos os descontos criados
			} else {
				alterarValorDescontos(conexionDescontos);
			}
		}
		
		if(!conexionDescontos.isEmpty()) { // Salvar Descontos
			conexionDescuentoService.suscribirTodos(conexionDescontos);
		}
		
		if(itemNovo) {
			conexionRutaConfList.addItemNovo(conexionRutaConf);
		}else {
			conexionRutaConfList.updateItem(conexionRutaConf);
		}
		
		mostraMensagem(Labels.getLabel("editarConexionPorRutaController.MSG.suscribirOK"));
		
		isConexionGerada = false;

		closeWindow();
	}

	private void atualizarIndPricing() {
		List<Long> conexoesVerificadas = new ArrayList<>();
		
		localidades: for(ConexionCtrl conCtrl : conexoesCtrl) {
			
			//Para evitar que registros antigos deem problema no banco de dados ao salvar
			if(conexoesVerificadas.contains(conCtrl.getConexionctrlId())) {
				continue localidades;
			} else {
				conexoesVerificadas.add(conCtrl.getConexionctrlId());
			}
					
			for(ParadaVOConexionRuta loc : localidadesGeradas ) {

				if(isMesmaConexao(loc, conCtrl)) {
					//So atualizar quando os valores forem alterados
					if(!conCtrl.getIndPricing().equals(loc.getConexionCtrl().getIndPricing())) {
						conCtrl.setIndPricing(loc.getConexionCtrl().getIndPricing());
						conCtrl.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
						conCtrl.setFecmodif(Calendar.getInstance().getTime());
						conCtrl.setActivo(true);
						
						conexionCtrlService.actualizacion(conCtrl);
					}
					
					continue localidades;
				}
			}
		}
	}
	
	private boolean isMesmaConexao(ParadaVOConexionRuta loc, ConexionCtrl conCtrl) {
		return conCtrl.getConexionctrlId() != null && loc.getConexionCtrl().getConexionctrlId() != null && conCtrl.getConexionctrlId().equals(loc.getConexionCtrl().getConexionctrlId());
	}

	private void desativarDescontosAnteriores(List<ConexionDescuento> conexionDescontos) {
		List<Conexion> conexoes  = buscarTodasConexoes();
		
		for(Conexion con : conexoes) {
			List<ConexionDescuento> conDescList = conexionDescuentoService.buscarPorConexion(con);
			
				for(ConexionDescuento conDesc : conDescList) {
					conDesc.setActivo(Boolean.FALSE);
				}
				conexionDescontos.addAll(conDescList);
		}
	}

	private void criarNovosDescontosPorConexao(List<ConexionDescuento> conexionDescontos) {
		List<Conexion> conexoes  = buscarTodasConexoes();
		
		ClaseServicio classeTodos = claseServicioService.obtenerID(-1);
		
		for(Conexion con : conexoes) {
			ConexionDescuento conDesc = criarConexionDesconto(con, classeTodos);
			conexionDescontos.add(conDesc);
		}
	}

	private void alterarValorDescontos(List<ConexionDescuento> conexionDescontos) {
		List<Conexion> conexoes  = buscarTodasConexoes();
		
		for(Conexion con : conexoes) {
			List<ConexionDescuento> conDescList = conexionDescuentoService.buscarPorConexion(con);
			
			// Caso tenha sido destivado sem gerar novas combinacoes
			if(conDescList == null || conDescList.isEmpty()) { 
				conDescList = conexionDescuentoService.buscarPorConexionInativos(con);
			}
			
			if(conDescList == null || conDescList.isEmpty()) {
				//Cria novos descontos, caso seja um registro antigo que foi alterado somente o desconto
				ClaseServicio classeTodos = claseServicioService.obtenerID(-1);
				ConexionDescuento conDesc = criarConexionDesconto(con, classeTodos);
				conexionDescontos.add(conDesc);
				
			} else {
				//Altera os descontos encontrados
				for(ConexionDescuento conDesc : conDescList) {
					//Desativa o desconto caso tenha sido marcado pricing
					conDesc.setActivo(!con.getIndPricing());
					conDesc.setFecModif(Calendar.getInstance().getTime());
					conDesc.setDescuento(conexionRutaConf.getDescuento());
				}
			}
			
			conexionDescontos.addAll(conDescList);
		}
	}

	private List<Conexion> buscarTodasConexoes() {
		try {
			List<Conexion> conexoes  = new ArrayList<>();
			
			for(ConexionCtrl coneCtrl : conexoesCtrl) {
				List<Conexion> conec  = conexionService.buscarPorConexionCtrl(coneCtrl.getConexionctrlId());
				
				for(Conexion c : conec) {
					c.setIndPricing(coneCtrl.getIndPricing());
				}
				
				conexoes.addAll(conec);
			}
			
			return conexoes;
		} catch (Exception e) {
			log.error("Erro ao buscar todas as conexoes: ", e);
		}
		return null;
	}

	private ConexionDescuento criarConexionDesconto(Conexion con, ClaseServicio classeTodos) {
		ConexionDescuento conDesc = new ConexionDescuento();
		
		conDesc.setConexion(con);
		conDesc.setFecModif(Calendar.getInstance().getTime());
		conDesc.setGrupo(con.getNumgrupo());
		conDesc.setDescuento(conexionRutaConf.getDescuento());
		conDesc.setDescuentoTasaEmbarque(BigDecimal.ZERO);
		conDesc.setSecuencia(con.getNumsecuencia());
		//Desativa o desconto caso tenha sido marcado pricing
		conDesc.setActivo(!con.getIndPricing());
		conDesc.setClaseServicio(classeTodos);
		
		return conDesc;
	}

	private void removeLocalidadesExcluidas() {
		conexionRutaLocalidadeRemovidaService.removerTodosPorConexionrutaconfId(conexionRutaConf.getConexionRutaConfId());
	}

	private void adicionaLocalidadesExcluidas() {
		List<Parada> removerLocalidadesComumABList = obterlsLocalidadesComunsABDesabilitadasNoMomento();
		if(!removerLocalidadesComumABList.isEmpty()) {
			for (Parada parada : removerLocalidadesComumABList) {
				conexionRutaLocalidadeRemovidaService.suscribir(conexionRutaConf.getConexionRutaConfId(), parada.getParadaId());				
			}
		}
	}
	
	public void onClick$btnApagar(Event ev) throws Exception {
		
		int resp = Messagebox.show(
				Labels.getLabel("editarConexionPorRutaController.MSG.PerguntaApagar"),
				Labels.getLabel("editarConexionExcepcionController.window.title"),
				Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

		if (resp == Messagebox.YES) {
			conexionRutaConfService.excluirConfiguracao(conexionRutaConf, true, true);
			conexionRutaConfList.removeItem(conexionRutaConf);
			mostraMensagem(Labels.getLabel("editarConexionPorRutaController.MSG.ApagarOK"));
			closeWindow();
		}
		
	}

	public void onClick$btnPesquisaPermissao(Event ev) throws InterruptedException {
		executarPesquisaLocalidadesOrigen();
	}

	public void onClick$btnPesquisaLocalidadesDestino(Event ev) throws InterruptedException {
		executarPesquisaLocalidadesDestino();
	}
	
	public void renderizarLinhasAB() {
		localidadesComunsABList.setItemRenderer(new RenderEixoConexionRutaRemoveSelecionada(new EventListener() {
	
			@Override
			public void onEvent(Event arg0) throws Exception {
	 
				Parada conexionRutaVO = (Parada) arg0.getTarget().getAttribute("data");
				List<Parada> localidadesComunsABListIter =  new ArrayList(obterlsLocalidadesComunsAB());
				for (Parada paradaIter : localidadesComunsABListIter) {
					//Caso parada seja a mesma ou seja uma parada do mesmo agrupamento remove. 
					if (paradaIter.equals(conexionRutaVO) || (paradaIter.getAgrupamentoParada()!=null && paradaIter.getAgrupamentoParada().equals(conexionRutaVO.getAgrupamentoParada()))) {
						if(!Boolean.TRUE.equals(paradaIter.getIsParadaConexaoRutaExcluida())) {
							localidadesComunsABList.removeItem(conexionRutaVO);
							conexionRutaVO.setIsParadaConexaoRutaExcluida(Boolean.TRUE);
							localidadesComunsABList.addItemNovo(conexionRutaVO);
						}else {
							localidadesComunsABList.removeItem(conexionRutaVO);
							conexionRutaVO.setIsParadaConexaoRutaExcluida(Boolean.FALSE);
							localidadesComunsABList.addItemNovo(conexionRutaVO);
						}
					}
				}
			}
		}));
	}

	public void renderizarLinhasBC() {
		localidadesComunsBCList.setItemRenderer(new RenderEixoConexionRutaRemoveSelecionada(new EventListener() {
	
			@Override
			public void onEvent(Event arg0) throws Exception {
	
				Parada conexionRutaVO = (Parada) arg0.getTarget().getAttribute("data");
				for (Object objectParada : localidadesComunsBCList.getListData()) {
					if (((Parada) objectParada).equals(conexionRutaVO)) {
						localidadesComunsBCList.removeItem(conexionRutaVO);
						lsLocalidadesComunsLinhasBC.remove(conexionRutaVO);
						break;
					}
				}
			}
		}));
	}

	private void executarPesquisaLocalidadesOrigen() throws InterruptedException {

		localidadesCombinadasList.clear();
		localidadesComunsABList.setModel(new ListModelList(new ArrayList<Parada>()));
		try {

			localidadesOrigemlList.setItemRenderer(new RenderConexionRuta(new EventListener() {

				@Override
				public void onEvent(Event arg0) throws Exception {
					Parada parada = (Parada) arg0.getTarget().getAttribute("data");
					if (arg0.getTarget().getAttribute("tipo").equals(RenderConexionRuta.BOTAO_ADICIONAR_PERMISSAO)) {
						if (localidadesLinhaASelecionadaList.getListData().isEmpty()) {
							localidadesLinhaASelecionadaList.addItemNovo(parada);
						} else {
							for (Object objectParada : localidadesLinhaASelecionadaList.getListData()) {
								List<Parada> lsLocalidadesComunsABHabilitadaNoMomento = obterlsLocalidadesComunsABHabilitadasNoMomento();
								if (localidadesLinhaASelecionadaList.getListData().contains(parada) ||  (lsLocalidadesComunsABHabilitadaNoMomento != null && lsLocalidadesComunsABHabilitadaNoMomento.contains(parada))) {
									return;
								}
								if (!((Parada) objectParada).equals(parada)) {
									localidadesLinhaASelecionadaList.addItemNovo(parada);
									break;
								}
							}
						}
						localidadesOrigemlList.removeItem(parada);
					}
				}
			}));
			gerarLocalidadesComunsAB();
		} catch (Exception e) {
			log.error("", e);
		}

	}

	private void executarPesquisaLocalidadesDestino() throws InterruptedException {
		
		localidadesCombinadasList.clear();
		localidadesComunsBCList.setModel(new ListModelList(new ArrayList<Parada>()));

		try {
			localidadesDestinoList.setItemRenderer(new RenderConexionRuta(new EventListener() {

				@Override
				public void onEvent(Event arg0) throws Exception {
					Parada parada = (Parada) arg0.getTarget().getAttribute("data");
					if (arg0.getTarget().getAttribute("tipo").equals(RenderConexionRuta.BOTAO_ADICIONAR_PERMISSAO)) {
						if (localidadesLinhaBSelecionadaList.getListData().isEmpty()) {
							localidadesLinhaBSelecionadaList.addItemNovo(parada);
						} else {
							for (Object objectParada : localidadesLinhaBSelecionadaList.getListData()) {
								List<Parada> lsLocalidadesComunsABHabilitadaNoMomento = obterlsLocalidadesComunsABHabilitadasNoMomento();

								
								if (localidadesLinhaBSelecionadaList.getListData().contains(parada) ||   (lsLocalidadesComunsABHabilitadaNoMomento != null && lsLocalidadesComunsABHabilitadaNoMomento.contains(parada))) {
									return;
								}
								if (!((Parada) objectParada).equals(parada)) {
									localidadesLinhaBSelecionadaList.addItemNovo(parada);
									break;
								}
							}
						}
						gerarLocalidadesComunsBC();
					}
				}
			}));
			gerarLocalidadesComuns();
		} catch (Exception e) {
			log.error("Erro ao executarPesquisaLocalidadesDestino", e);
		}

	}
	
	private void executarPesquisaLocalidadesDestinoLinhasC() throws InterruptedException {
		
		localidadesCombinadasList.clear();
		
		try {
			localidadesDestinoLinhaCList.setItemRenderer(new RenderConexionRuta(new EventListener() {

				@Override
				public void onEvent(Event arg0) throws Exception {
					Parada parada = (Parada) arg0.getTarget().getAttribute("data");
					if (arg0.getTarget().getAttribute("tipo").equals(RenderConexionRuta.BOTAO_ADICIONAR_PERMISSAO)) {
						if (localidadesLinhaCSelecionadaList.getListData().isEmpty()) {
							localidadesLinhaCSelecionadaList.addItemNovo(parada);
						} else {
							for (Object objectParada : localidadesLinhaCSelecionadaList.getListData()) {
								if (localidadesLinhaCSelecionadaList.getListData().contains(parada) ||   (getLsLocalidadesComunsLinhasBC() != null && getLsLocalidadesComunsLinhasBC().contains(parada))) {
									return;
								}
								if (!((Parada) objectParada).equals(parada)) {
									localidadesLinhaCSelecionadaList.addItemNovo(parada);
									break;
								}
							}
						}
						localidadesDestinoLinhaCList.removeItem(parada);
					}
				}
			}));
			gerarLocalidadesComunsBC();
		} catch (Exception e) {
			log.error("", e);
		}

	}

	private void gerarLocalidadesComuns() {

		gerarLocalidadesComunsAB();
		gerarLocalidadesComunsBC();

	}
	
	@SuppressWarnings("unchecked")
	private void gerarLocalidadesComunsAB() {
		Set<Parada> lsParadasOrigem = new HashSet<Parada>(localidadesOrigemlList.getListData());
		Set<Parada> lsParadasDestino = new HashSet<Parada>(localidadesDestinoList.getListData());
		ArrayList<Parada> paradasDuplicadas = new ArrayList<Parada>(lsParadasOrigem);
 		isConexaoPorAgrupamento = !Boolean.TRUE.equals(isConexaoPorAgrupamento) ? validaConfAgrupamentoLocalidadeEmpresaLinhas() : isConexaoPorAgrupamento;
		if(Boolean.TRUE.equals(isConexaoPorAgrupamento) && !lsParadasDestino.isEmpty()) {
			Set<Parada> lsParadasAgrupamento = getLsAgrupamentoParada(lsParadasOrigem, lsParadasDestino);
			if(lsParadasAgrupamento!=null && !lsParadasAgrupamento.isEmpty()) {
				for (Parada parada : lsParadasAgrupamento) {
					if(!paradasDuplicadas.contains(parada)) {
						paradasDuplicadas.add(parada);						
					}
					
					if(!lsParadasDestino.isEmpty() && !lsParadasDestino.contains(parada)) {
						lsParadasDestino.add(parada);						
					}
				}
			}
			
		}
		
		paradasDuplicadas.retainAll(lsParadasDestino);
		validaLocalidadesExcluidas(lsParadasOrigem, paradasDuplicadas);
		//Lista auxiliar usada para ser setada na Listview de localidades comuns A e B
		List<Parada> lsLocalidadesComunsABAux = new ArrayList<Parada>();
		List<Parada> lsLocalidadesAgrupamento = new ArrayList<Parada>();

		localidadesLinhaASelecionadaList.getListData().removeAll(paradasDuplicadas);
		localidadesLinhaBSelecionadaList.getListData().removeAll(paradasDuplicadas);
		adicionaParadasDuplicadas(paradasDuplicadas, lsLocalidadesComunsABAux, lsLocalidadesAgrupamento);
		//Trata o caso de parada entre eixo ser a mesma parada da linha já adiconada anteriormente.
		if(!paradasDuplicadas.isEmpty() && lsLocalidadesComunsABAux.isEmpty() ) {
			return;
		}
		localidadesComunsABList.setData(lsLocalidadesComunsABAux);	
		renderizarLinhasAB(); 
	}

	private Set<Parada> getLsAgrupamentoParada(Set<Parada> lsParadasOrigem, Set<Parada> lsParadasDestino) {
		Set<Parada> lsParadasAgrupamento = new HashSet<Parada>();
		for (Parada parada : lsParadasOrigem ) {
			if (parada!=null && parada.getAgrupamentoParada() !=null) {
				Set<Parada> lsParadasAgrupamentoAux = new HashSet<Parada>();
				lsParadasAgrupamentoAux.addAll(conexionRutaCombinacionService.getParadasByAgrupamentoId(parada));
				Boolean isAgrupamentoOrigem = Boolean.FALSE;
				Boolean isAgrupamentoDestino = Boolean.FALSE;
				for (Parada paradaAgrupamento : lsParadasAgrupamentoAux) {
					if(lsParadasOrigem.contains(paradaAgrupamento)) {
						isAgrupamentoOrigem = Boolean.TRUE;
					}
					if(lsParadasDestino.contains(paradaAgrupamento)) {
						isAgrupamentoDestino = Boolean.TRUE;
					}
				}
				if(isAgrupamentoOrigem && isAgrupamentoDestino ) {
					lsParadasAgrupamento = lsParadasAgrupamentoAux;
				}
			}
			
		}
		return lsParadasAgrupamento;
	}

	/**
	 * Valida Localidades excluidas, caso encontre insere na tela botao adicionar, caso nao encontre inserena tela o botao remover.
	 * @param lsParadas
	 * @param paradasDuplicadas
	 */
	private void validaLocalidadesExcluidas(Set<Parada> lsParadas, ArrayList<Parada> paradasDuplicadas) {
		
		if(paradasDuplicadas!=null && !paradasDuplicadas.isEmpty() && conexionRutaConf != null  ) {
			List<ConexionRutaLocalidadeRemovida> ConexionRutaLocalidadeRemovidaList = conexionRutaLocalidadeRemovidaService.obtenerPorConexionrutaconfIdEParadaIdList(conexionRutaConf.getConexionRutaConfId(),paradasDuplicadas);
			if(ConexionRutaLocalidadeRemovidaList !=null) {
				ArrayList<Parada> paradasDuplicadasAux = new ArrayList<Parada>(lsParadas);
				for (ConexionRutaLocalidadeRemovida conexionRutaLocalidadeRemovida : ConexionRutaLocalidadeRemovidaList) {
					for (Parada parada : paradasDuplicadasAux) {
						if(conexionRutaLocalidadeRemovida.getParadaId()!=null && conexionRutaLocalidadeRemovida.getParadaId().intValue() ==parada.getParadaId().intValue()) {
							paradasDuplicadas.remove(parada);
							parada.setIsParadaConexaoRutaExcluida(Boolean.TRUE);
							paradasDuplicadas.add(parada);
						}
					}
				}			
			}
		}
	}

	private void adicionaParadasDuplicadas(ArrayList<Parada> paradasDuplicadas, List<Parada> lsLocalidadesComunsABAux, List<Parada> lsLocalidadesAgrupamento) {
		for (Parada parada : paradasDuplicadas) {
			List<Parada> lsLocalidadesComunsAB = obterlsLocalidadesComunsABHabilitadasNoMomento();
			if(!lsLocalidadesComunsAB.contains(parada)){
				if(parada.getAgrupamentoParada()!=null && Boolean.TRUE.equals(isConexaoPorAgrupamento)) {
					try {
						validaParadaAgrupamento(lsLocalidadesAgrupamento, lsLocalidadesComunsABAux, parada);
					} catch (CloneNotSupportedException e) {
						log.error("Erro ao clonar objeto Parada: " + parada.toString(), e);
						continue;
					}
				}else {
					lsLocalidadesComunsABAux.add(parada);
				}
			}
		}
	}
	
	private void validaParadaAgrupamento(List<Parada> lsLocalidadesAgrupamento ,  List<Parada> lsLocalidadesComunsABAux, Parada parada) throws CloneNotSupportedException {
		Parada paradaAux = new Parada();
		
		paradaAux = (Parada) parada.clone();
		
		paradaAux.setDescparada(parada.getAgrupamentoParada().getDescAgrupamentoParada());
		paradaAux.setCveparada(parada.getAgrupamentoParada().getCveAgrupamentoParada());
		//Caso agrupamento ja adicionado na lista nao aparece na listview para nao duplicar 
		//mas e adicionado de localidades comuns de classe normalmente, apenas na listeview (tela que nao ira aparecer).
		Boolean isAdicionaParadaListView = Boolean.TRUE;
		for (Parada paradaAgrupamento : lsLocalidadesAgrupamento) {
			if( paradaAux.getAgrupamentoParada().equals(paradaAgrupamento.getAgrupamentoParada())) {
				isAdicionaParadaListView = Boolean.FALSE;
			}
		}
		if(isAdicionaParadaListView) {
			lsLocalidadesAgrupamento.add(parada);
			lsLocalidadesComunsABAux.add(paradaAux);
		}

	}
	
	@SuppressWarnings("unchecked")
	private void gerarLocalidadesComunsBC() {
		Set<Parada> lsParadas = new HashSet<Parada>(0);
		lsParadas = new HashSet<Parada>(localidadesLinhaBSelecionadaList.getListData());
		ArrayList<Parada> paradasDuplicadas = new ArrayList<Parada>(lsParadas);
		paradasDuplicadas.retainAll(localidadesDestinoLinhaCList.getListData());
		localidadesLinhaCSelecionadaList.getListData().removeAll(paradasDuplicadas);
		if(lsLocalidadesComunsLinhasBC!=null) {
			for (Parada parada : paradasDuplicadas) {
				if(!lsLocalidadesComunsLinhasBC.contains(parada)){
					lsLocalidadesComunsLinhasBC.add(parada);
				}
			}
		}else {
			lsLocalidadesComunsLinhasBC = new ArrayList<Parada>(paradasDuplicadas);			
		}
		localidadesComunsBCList.setData(new ListModelList(lsLocalidadesComunsLinhasBC));
		renderizarLinhasBC();
		
	}
	
	public void onSelect$cmbRutaA(Event ev) throws Exception {
	}

	public void onSelect$cmbRutaB(Event ev) throws Exception {
	}

	public void onClick$btnCombinarTrechos(Event ev) throws InterruptedException {
		List<Parada> lsLocalidadesComunsAB = obterlsLocalidadesComunsABHabilitadasNoMomento();
		if (lsLocalidadesComunsAB == null || lsLocalidadesComunsAB.isEmpty()) {
			Messagebox.show(Labels.getLabel("editarConexionPorRutaController.MSG.selecionarConexion"),
					Labels.getLabel("editarConexionPorRutaController.window.title"),
					Messagebox.OK, Messagebox.INFORMATION);
			return;
		}

		gerarCombinacao(false);		
	}
	
	private boolean validarItensSalvar() throws InterruptedException {
		

		if (localidadesCombinadasList.getListData().isEmpty()) {
			Messagebox.show(Labels.getLabel("editarConexionPorRutaController.MSG.selecionarConexion"),
					Labels.getLabel("editarConexionPorRutaController.window.title"),
					Messagebox.OK, Messagebox.INFORMATION);
			return false;
		}
		
		txtTiempoMax.getValue();
		txtTiempoMin.getValue();
		txtDesconto.getValue();
		
		return true;
	}

	public void onClick$btnNovoCanalVenta(Event ev) throws InterruptedException {
		
		if(cmbTipoPtovta.getSelectedItem() == null){
			return;
		}
		TipoPuntoVenta ptovta = (TipoPuntoVenta) cmbTipoPtovta.getSelectedItem().getValue();
		
		if (listEspCanal.getListData().contains(ptovta)) {
			Messagebox.show(
					Labels.getLabel("editarPricingEspecificoOcupacionController.MSG.noPricingEspecificoCanalJaCadastrado"),
					Labels.getLabel("busquedaPricingEspecificoController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
		} else if(ptovta != null) {
			listEspCanal.addItemNovo(ptovta);
		}
		
		cmbTipoPtovta.setValue("");
	}
	
	public void onClick$btnApagarCanalVenta(Event ev) throws InterruptedException {

		int resp = Messagebox.show(
				Labels.getLabel("editarConexionExcepcionController.MSG.borrarConexionPergunta"),
				Labels.getLabel("editarConexionExcepcionController.window.title"),
				Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

		if (resp == Messagebox.YES) {
			if (listEspCanal.getSelected() != null) {
				listEspCanal.removeItem((TipoPuntoVenta) listEspCanal.getSelectedItem().getValue());
			} else {
				Messagebox.show(Labels.getLabel("editarConexionExcepcionController.MSG.selecionarConexion"),
						Labels.getLabel("editarConexionExcepcionController.window.title"),
						Messagebox.OK, Messagebox.INFORMATION);
			}
		}
	}
	
	public void onClick$btnNovoPuntoVenta(Event ev) throws InterruptedException {

		if(cmbPtovta.getSelectedItem() == null){
			return;
		}
		PuntoVenta puntoVenta = (PuntoVenta) cmbPtovta.getSelectedItem().getValue();		
		
		if (listPuntoVenta.getListData().contains(puntoVenta)) {
			Messagebox.show(
					Labels.getLabel("editarConexionPorRutaController.MSG.noPuntoVentaJaCadastrado"),
					Labels.getLabel("editarConexionPorRutaController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
		} else if(puntoVenta != null) {
			listPuntoVenta.addItemNovo(puntoVenta);
		}
		
		cmbTipoPtovta.setValue("");
	}
	
	public void onClick$btnApagarPuntoVenta(Event ev) throws InterruptedException {

		int resp = Messagebox.show(
				Labels.getLabel("editarConexionExcepcionController.MSG.borrarPuntoVentaPergunta"),
				Labels.getLabel("editarConexionPorRutaController.window.title"),
				Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

		if (resp == Messagebox.YES) {
			if (listPuntoVenta.getSelected() != null) {
				listPuntoVenta.removeItem((PuntoVenta) listPuntoVenta.getSelectedItem().getValue());
			} else {
				Messagebox.show(Labels.getLabel("editarConexionExcepcionController.MSG.selecionarConexion"),
						Labels.getLabel("editarConexionExcepcionController.window.title"),
						Messagebox.OK, Messagebox.INFORMATION);
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public void onClick$btnNovoRutaA(Event ev) throws InterruptedException {
		
		if (!validarLinhaJaSelecionada()) {
			Messagebox.show(Labels.getLabel("editarConexionPorRutaController.MSG.rutaJaSelecionada"),
					Labels.getLabel("editarConexionPorRutaController.window.title"),
					Messagebox.OK, Messagebox.INFORMATION);
			return;
		}
		
		if(cmbRutaA.getSelectedItem() == null){
			return;
		}
		Ruta rutaA = (Ruta) cmbRutaA.getSelectedItem().getValue();
		
		if (rutasAList.getListData().contains(rutaA)) {
			Messagebox.show(
					Labels.getLabel("editarPricingEspecificoOcupacionController.MSG.noPricingEspecificoCanalJaCadastrado"),
					Labels.getLabel("busquedaPricingEspecificoController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
		} else {
			if(rutaA.getRutaId() == -1){
				rutasAList.clear();
			}else {
				List<Ruta> canaisVenta = rutasAList.getListData();
				for (Ruta rutaAux : canaisVenta) {
					if(rutaA.getRutaId() == -1){
						rutasAList.clear();
						rutasAList.addItemNovo(rutaAux);
						rutaA = null;
						break;
					}
				}
			}
			Set<Parada> lsParadas = new HashSet<Parada>(0);
			lsParadas.addAll(localidadesLinhaASelecionadaList.getListData());
			if(rutaA != null) {
				rutaA = rutaService.obtenerID(rutaA.getRutaId());
				if (rutaA.getRutaCombinacionList() != null) {
					for (RutaCombinacion rc : rutaA.getRutaCombinacionList()) {
						if (rc.getTramo() != null) {
							lsParadas.add(rc.getTramo().getOrigem());
							lsParadas.add(rc.getTramo().getDestino());
						}
					}
				}
				
				localidadesOrigemlList.setData(new ListModelList(new ArrayList<Parada>(lsParadas)));
				localidadesLinhaASelecionadaList.setData(new ListModelList(new ArrayList<Parada>(lsParadas)));
				
				rutasAList.addItemNovo(rutaA);
			}			
		}
		executarPesquisaLocalidadesOrigen();
		cmbRutaA.setValue("");
	}
	
	public void onClick$btnApagarRutaA(Event ev) throws InterruptedException {

		int resp = Messagebox.show(
				Labels.getLabel("editarConexionExcepcionController.MSG.borrarConexionPergunta"),
				Labels.getLabel("editarConexionExcepcionController.window.title"),
				Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

		if (resp == Messagebox.YES) {
			if (rutasAList.getSelected() != null) {
				rutasAList.removeItem((Ruta) rutasAList.getSelectedItem().getValue());
			} else {
				Messagebox.show(Labels.getLabel("editarConexionExcepcionController.MSG.borrarRutaPergunta"),
						Labels.getLabel("editarConexionExcepcionController.window.title"),
						Messagebox.OK, Messagebox.INFORMATION);
			}
		}
	}

	@SuppressWarnings("unchecked")
	public void onClick$btnNovoRutaB(Event ev) throws InterruptedException {

		if (!validarLinhaJaSelecionada()) {
			Messagebox.show(Labels.getLabel("editarConexionPorRutaController.MSG.rutaJaSelecionada"),
					Labels.getLabel("editarConexionPorRutaController.window.title"),
					Messagebox.OK, Messagebox.INFORMATION);
			return;
		}
		
		if(cmbRutaB.getSelectedItem() == null){
			return;
		}
		Ruta rutaB = (Ruta) cmbRutaB.getSelectedItem().getValue();
		
		if (rutasBList.getListData().contains(rutaB)) {
			Messagebox.show(
					Labels.getLabel("editarPricingEspecificoOcupacionController.MSG.noPricingEspecificoCanalJaCadastrado"),
					Labels.getLabel("busquedaPricingEspecificoController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
		} else {
			if(rutaB.getRutaId() == -1){
				rutasBList.clear();
			}else {
				List<Ruta> canaisVenta = rutasBList.getListData();
				for (Ruta rutaAux : canaisVenta) {
					if(rutaB.getRutaId() == -1){
						rutasBList.clear();
						rutasBList.addItemNovo(rutaAux);
						rutaB = null;
						break;
					}
				}
			}
			Set<Parada> lsParadas = new HashSet<Parada>(0);
			lsParadas.addAll(localidadesLinhaBSelecionadaList.getListData());
			if(rutaB != null) {
				rutaB = rutaService.obtenerID(rutaB.getRutaId());
				if (rutaB.getRutaCombinacionList() != null) {
					for (RutaCombinacion rc : rutaB.getRutaCombinacionList()) {
						if (rc.getTramo() != null) {
							lsParadas.add(rc.getTramo().getOrigem());
							lsParadas.add(rc.getTramo().getDestino());
						}
					}
				}
				localidadesDestinoList.setData(new ListModelList(new ArrayList<Parada>(lsParadas)));			
				localidadesLinhaBSelecionadaList.setData(new ListModelList(new ArrayList<Parada>(lsParadas)));
				
				rutasBList.addItemNovo(rutaB);
			}			
		}
		executarPesquisaLocalidadesDestino();
		cmbRutaB.setValue("");
		
	}
	
	public void onClick$btnApagarRutaB(Event ev) throws InterruptedException {

		int resp = Messagebox.show(
				Labels.getLabel("editarConexionExcepcionController.MSG.borrarConexionPergunta"),
				Labels.getLabel("editarConexionExcepcionController.window.title"),
				Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

		if (resp == Messagebox.YES) {
			if (rutasBList.getSelected() != null) {
				rutasBList.removeItem((Ruta) rutasBList.getSelectedItem().getValue());
			} else {
				Messagebox.show(Labels.getLabel("editarConexionExcepcionController.MSG.borrarRutaPergunta"),
						Labels.getLabel("editarConexionExcepcionController.window.title"),
						Messagebox.OK, Messagebox.INFORMATION);
			}
		}
	}
	@SuppressWarnings("unchecked")
	public void onClick$btnNovoRutaC(Event ev) throws InterruptedException {
	

		if (!validarLinhaJaSelecionada()) {
			Messagebox.show(Labels.getLabel("editarConexionPorRutaController.MSG.rutaJaSelecionada"),
					Labels.getLabel("editarConexionPorRutaController.window.title"),
					Messagebox.OK, Messagebox.INFORMATION);
			return;
		}
		
		if(cmbRutaC.getSelectedItem() == null){
			return;
		}
		Ruta rutaC = (Ruta) cmbRutaC.getSelectedItem().getValue();
		
		if (rutasCList.getListData().contains(rutaC)) {
			Messagebox.show(
					Labels.getLabel("editarPricingEspecificoOcupacionController.MSG.noPricingEspecificoCanalJaCadastrado"),
					Labels.getLabel("busquedaPricingEspecificoController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
		} else {
			if(rutaC.getRutaId() == -1){
				rutasCList.clear();
			}else {
				List<Ruta> canaisVenta = rutasCList.getListData();
				for (Ruta rutaAux : canaisVenta) {
					if(rutaC.getRutaId() == -1){
						rutasCList.clear();
						rutasCList.addItemNovo(rutaAux);
						rutaC = null;
						break;
					}
				}
			}
			Set<Parada> lsParadas = new HashSet<Parada>(0);
			lsParadas.addAll(localidadesLinhaCSelecionadaList.getListData());
			if(rutaC != null) {
				rutaC = rutaService.obtenerID(rutaC.getRutaId());
				if (rutaC.getRutaCombinacionList() != null) {
					for (RutaCombinacion rc : rutaC.getRutaCombinacionList()) {
						if (rc.getTramo() != null) {
							lsParadas.add(rc.getTramo().getOrigem());
							lsParadas.add(rc.getTramo().getDestino());
						}
					}
				}
				localidadesDestinoLinhaCList.setData(new ListModelList(new ArrayList<Parada>(lsParadas)));				
				localidadesLinhaCSelecionadaList.setData(new ListModelList(new ArrayList<Parada>(lsParadas)));
				
				rutasCList.addItemNovo(rutaC);
			}			
		}
		executarPesquisaLocalidadesDestinoLinhasC();
		cmbRutaC.setValue("");
	}
	public void onClick$btnApagarRutaC(Event ev) throws InterruptedException {

		int resp = Messagebox.show(
				Labels.getLabel("editarConexionExcepcionController.MSG.borrarConexionPergunta"),
				Labels.getLabel("editarConexionExcepcionController.window.title"),
				Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

		if (resp == Messagebox.YES) {
			if (rutasCList.getSelected() != null) {
				rutasCList.removeItem((Ruta) rutasCList.getSelectedItem().getValue());
			} else {
				Messagebox.show(Labels.getLabel("editarConexionExcepcionController.MSG.borrarRutaPergunta"),
						Labels.getLabel("editarConexionExcepcionController.window.title"),
						Messagebox.OK, Messagebox.INFORMATION);
			}
		}
	}

	/**
	 * @return the lsPtovata
	 */
	public List<TipoPuntoVenta> getLsTipoPtovta() {
		return lsTipoPtovta;
	}

	/**
	 * @param lsPtovata
	 *            the lsPtovata to set
	 */
	public void setLsPtovata(List<TipoPuntoVenta> lsTipoPtovta) {
		this.lsTipoPtovta = lsTipoPtovta;
	}
	
	private void mostraMensagem(String msg) throws InterruptedException {
		Messagebox.show(msg, Labels.getLabel("editarConexionController.window.title"), Messagebox.OK, Messagebox.INFORMATION);
	}

	
	public List<Parada> getLsLocalidadesComunsLinhasBC() {
		return lsLocalidadesComunsLinhasBC;
	}

	public void setLsLocalidadesComunsLinhasBC(List<Parada> lsLocalidadesComunsLinhasBC) {
		this.lsLocalidadesComunsLinhasBC = lsLocalidadesComunsLinhasBC;
	}


	@SuppressWarnings("unchecked")
	private void gerarCombinacao(boolean carregarGravadas) {

		log.debug(String.format("Inicio Geracao Combinacao {%s}", new Date()));
		
		localidadesGeradas = new ArrayList<ParadaVOConexionRuta>();
		conexoesCtrl = new ArrayList<ConexionCtrl>();
		
		localidadesGeradasFiltro = new ArrayList<ParadaVOConexionRuta>();
		List<Parada> listParada1 = localidadesLinhaASelecionadaList.getListData();
		List<Ruta> rutasEixoA = rutasAList.getListData();
		List<Ruta> rutasEixoB = rutasBList.getListData();
		List<Ruta> rutasEixoC = rutasCList.getListData();
		List<Parada> listParada4 = localidadesLinhaBSelecionadaList.getListData();
		List<Parada> listParadasC = localidadesLinhaCSelecionadaList.getListData();
		List<ConexionCtrlVO> conexoesCtrlVO = new ArrayList<ConexionCtrlVO>(0);

		if(carregarGravadas && conexionRutaConf != null) {
			ConexionRutaConfVO conexionRutaConfVO = conexionRutaConfService.carregarConexoesCadastradas(conexionRutaConf.getConexionRutaConfId());
			localidadesGeradas = new ArrayList<ParadaVOConexionRuta>(conexionRutaConfVO.getLocalidadesCombinadas());
			conexoesCtrl = new ArrayList<ConexionCtrl>(conexionRutaConfVO.getListConexionCtrl());
		} else {
			this.isConexionGerada = true;
			List<Parada> lsLocalidadesComunsAB = obterlsLocalidadesComunsABHabilitadasNoMomento();
			if(rutasEixoC.isEmpty()) {				
				conexionRutaCombinacionService.gerarCombinacionEntre2Eixos(listParada1,rutasEixoA, rutasEixoB, lsLocalidadesComunsAB, listParada4, rutasEixoA, rutasEixoB, localidadesGeradas, conexoesCtrlVO, isConexaoPorAgrupamento);
			} else {
				conexionRutaCombinacionService.gerarCombinacionEntre3Eixos(listParada1,rutasEixoA, rutasEixoB, lsLocalidadesComunsAB, listParada4,listParadasC, rutasEixoA, rutasEixoB,rutasEixoC,localidadesGeradas, conexoesCtrlVO );
			}
			
			for (ConexionCtrlVO conexionCtrlVO : conexoesCtrlVO) {
				ConexionCtrl conexionAux = new ConexionCtrl(conexionCtrlVO.getOrigenId(), conexionCtrlVO.getDestinoId(), conexionCtrlVO.getGrupo());
				conexionAux.setIndPricing(conexionCtrlVO.getIndPricing());
				conexionAux.setConexionctrlId(conexionCtrlVO.getConexionctrlId());
				conexoesCtrl.add(conexionAux);
			}
			
		}

		localidadesGeradasFiltro.addAll(localidadesGeradas);
		
		atualizarFiltrosCombinacao(localidadesGeradas);
		
		localidadesCombinadasList.setData(localidadesGeradasFiltro);
		
		localidadesCombinadasList.setItemRenderer(new RenderGeracaoConexionPorRuta());
		
		resultadoCombinacao.setSelected(true);
		
		btnSalvar.setDisabled(Boolean.FALSE);
		
		log.debug(String.format("Fim Geracao Combinacao {%s}", new Date()));

	}
	
	private void atualizarFiltrosCombinacao(List<ParadaVOConexionRuta> localidadesGeradas2) {
		lsOrigemConexao = new ArrayList<>();
		lsDestinoConexao = new ArrayList<>();
		
		for(ParadaVOConexionRuta con : localidadesGeradas2) {
			if(!lsOrigemConexao.contains(con.getParadaOrigemTrecho())) {
				lsOrigemConexao.add(con.getParadaOrigemTrecho());
			}
			
			if(!lsDestinoConexao.contains(con.getParadaDestinoTrecho())) {
				lsDestinoConexao.add(con.getParadaDestinoTrecho());
			}
		}
	}

	@SuppressWarnings("unchecked")
	private boolean validarLinhaJaSelecionada() {
		
		List<Ruta> lsRutaA = rutasAList.getListData();
		List<Ruta> lsRutaB = rutasBList.getListData();
		List<Ruta> lsRutaC = rutasCList.getListData();
		
		Ruta rutaA  = (Ruta) (cmbRutaA.getSelectedItem() != null ? cmbRutaA.getSelectedItem().getValue() : null);
		Ruta rutaB  = (Ruta) (cmbRutaB.getSelectedItem() != null ? cmbRutaB.getSelectedItem().getValue() : null);
		Ruta rutaC  = (Ruta) (cmbRutaC.getSelectedItem() != null ? cmbRutaC.getSelectedItem().getValue() : null);
		
		for (Ruta rA : lsRutaA) {
			if(rutaA != null) {
				if(rA.equals(rutaA)) {
					return false;
				}
			}
			if(rutaB != null) {
				if(rA.equals(rutaB)) {
					return false;
				}
			}
			if(rutaC != null) {
				if(rA.equals(rutaC)) {
					return false;
				}
			}
		
		}
		for (Ruta rb : lsRutaB) {
			if(rutaA != null) {
				if(rb.equals(rutaA)) {
					return false;
				}
			}
			if(rutaB != null) {
				if(rb.equals(rutaB)) {
					return false;
				}
			}
			if(rutaC != null) {
				if(rb.equals(rutaC)) {
					return false;
				}
			}
		
		}
		for (Ruta rc : lsRutaC) {
			if(rutaA != null) {
				if(rc.equals(rutaA)) {
					return false;
				}
			}
			if(rutaB != null) {
				if(rc.equals(rutaB)) {
					return false;
				}
			}
			if(rutaC != null) {
				if(rc.equals(rutaC)) {
					return false;
				}
			}
		
		}
		return true;
	}
	
public void onClick$btnFiltrar(Event ev) throws Exception {
		
		Parada origem = cmbOrigemConexao.getSelectedItem() == null ? null : (Parada) cmbOrigemConexao.getSelectedItem().getValue();
		Parada destino = cmbDestinoConexao.getSelectedItem() == null ? null : (Parada) cmbDestinoConexao.getSelectedItem().getValue();
		
		localidadesGeradasFiltro.clear();
		
		for(ParadaVOConexionRuta local : localidadesGeradas) {
			boolean origemOK = false;
			boolean destinoOK = false;
			boolean pricingOK = false;
			
			if(origem == null || origem.equals(local.getParadaOrigemTrecho())) {
				origemOK = true;
			} 
			
			if(destino == null || destino.equals(local.getParadaDestinoTrecho())) {
				destinoOK = true;
			} 
			
			if(local.getConexionCtrl().getIndPricing() == chkUtilizaPricing.isChecked()) {
				pricingOK = true;
			} 
			
			if(origemOK && destinoOK && pricingOK) {
				localidadesGeradasFiltro.add(local);
			}
		}
		
		localidadesCombinadasList.clear();
		localidadesCombinadasList.setData(localidadesGeradasFiltro);
	}

private List<Parada>obterlsLocalidadesComunsAB() {
	
		List<Parada> lsLocalidadehabilitadas = new ArrayList<>();
		
		if(localidadesComunsABList!=null) {
			return localidadesComunsABList.getListData();
		}	
	
		return  lsLocalidadehabilitadas;	
	}


private List<Parada>obterlsLocalidadesComunsABHabilitadasNoMomento() {
	List<Parada> lsLocalidadehabilitadas = new ArrayList<>();
	List<Parada> lsParadaAux =obterlsLocalidadesComunsAB();		
	if(lsParadaAux!=null && !lsParadaAux.isEmpty()) {
		lsLocalidadehabilitadas = new ArrayList<>();
		for(Parada parada : lsParadaAux) {
			if(!parada.getIsParadaConexaoRutaExcluida()) {
				lsLocalidadehabilitadas.add(parada);
			}			
		}		
	}	
	return  lsLocalidadehabilitadas;	
}


private List<Parada>obterlsLocalidadesComunsABDesabilitadasNoMomento() {
	List<Parada> lsDesabilitadas = null;
	List<Parada> lsParadaAux =obterlsLocalidadesComunsAB();	
	if(lsParadaAux!=null && !lsParadaAux.isEmpty()) {
		lsDesabilitadas = new ArrayList<>();
		for(Parada parada : lsParadaAux) {
			if(parada.getIsParadaConexaoRutaExcluida()) {
				lsDesabilitadas.add(parada);
			}			
		}		
	}	
	return  lsDesabilitadas;	
}
	
	public void onClick$btnLimpraFiltros(Event ev) throws Exception {
		cmbOrigemConexao.setSelectedItem(null);
		cmbDestinoConexao.setSelectedItem(null);
		chkUtilizaPricing.setChecked(false);
		
		localidadesGeradasFiltro.clear();
		localidadesGeradasFiltro.addAll(localidadesGeradas);
		
		localidadesCombinadasList.clear();
		localidadesCombinadasList.setData(localidadesGeradasFiltro);
	}

	public Checkbox getChkUtilizaPricing() {
		return chkUtilizaPricing;
	}

	public void setChkUtilizaPricing(Checkbox chkUtilizaPricing) {
		this.chkUtilizaPricing = chkUtilizaPricing;
	}

	public List<Parada> getLsOrigemConexao() {
		return lsOrigemConexao;
	}

	public void setLsOrigemConexao(List<Parada> lsOrigemConexao) {
		this.lsOrigemConexao = lsOrigemConexao;
	}

	public List<Parada> getLsDestinoConexao() {
		return lsDestinoConexao;
	}

	public void setLsDestinoConexao(List<Parada> lsDestinoConexao) {
		this.lsDestinoConexao = lsDestinoConexao;
	}
}

