/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rjconsultores.ventaboletos.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.rjconsultores.ventaboletos.dao.CorridaDAO;
import com.rjconsultores.ventaboletos.dao.EsquemaCorridaDAO;
import com.rjconsultores.ventaboletos.dao.RutaDAO;
import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.OrgaoConcedente;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.ParadaSecuencia;
import com.rjconsultores.ventaboletos.entidad.ParadaSecuenciaCombinacaoLinha;
import com.rjconsultores.ventaboletos.entidad.Ruta;
import com.rjconsultores.ventaboletos.entidad.RutaCaseta;
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.Via;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.service.ParadaService;
import com.rjconsultores.ventaboletos.service.RutaCombinacionService;
import com.rjconsultores.ventaboletos.service.RutaSecuenciaService;
import com.rjconsultores.ventaboletos.service.RutaService;
import com.rjconsultores.ventaboletos.service.TramoRutaService;
import com.rjconsultores.ventaboletos.service.TramoService;
import com.rjconsultores.ventaboletos.utilerias.RegistroConDependenciaException;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.vo.ruta.RutaVO;

/**
 * 
 * @author Rafius
 */
@Service("rutaService")
public class RutaServiceImpl implements RutaService {

	@Autowired
	private RutaDAO rutaDAO;
	@Autowired
	private TramoService tramoService;
	@Autowired
	private RutaCombinacionService rutaCombinacionService;
	@Autowired
	private RutaSecuenciaService rutaSecuenciaService;
	@Autowired
	private CorridaDAO corridaDAO;
	@Autowired
	private EsquemaCorridaDAO esquemaCorridaDAO;
	@Autowired
	private ParadaService paradaService;
	@Autowired
    private TramoRutaService tramoRutaService;

	private static final Logger log = LogManager.getLogger(RutaServiceImpl.class);

	public List<Ruta> obtenerTodos() {
		return rutaDAO.obtenerTodos();
	}

	public Ruta obtenerID(Integer id) {
		return rutaDAO.obtenerID(id);
	}

	@Override
	@Transactional(rollbackFor = BusinessException.class)
	public Parada validaParada(String descripcionParada, Parada paradaAntiga) throws Exception {

		String cve = extrairCodigoOuLocalidade(descripcionParada, true, false);
		String descparada = extrairCodigoOuLocalidade(descripcionParada, false, true);

		if (cve == null || descparada == null)
			throw new BusinessException("editarCatalogoDeRutaController.actionCanbiarParada.businessException");
		try {
			List<Parada> paradas = paradaService.buscarCVE(cve);
			paradas.addAll(paradaService.buscar(descparada));
			if (!paradas.isEmpty()) {
				return paradas.iterator().next();
			} else {
				return null;
			}
		} catch (Exception e) {
			throw e;
		}
	}

	private String extrairCodigoOuLocalidade(String descripcionParada, boolean isCodigo, boolean isLocalidade) throws Exception {
		try {
			String arraySplit[] = new String[2];
			arraySplit = descripcionParada.split(" - ");
			if (isCodigo)
				return arraySplit[0];
			if (isLocalidade)
				return arraySplit[1];
		} catch (Exception e) {
			throw new BusinessException("editarCatalogoDeRutaController.actionCanbiarParada.businessException");
		}
		return null;
	}

	@Override
	@Transactional(rollbackFor = BusinessException.class)
	public boolean cambiarParadaRuta(Ruta ruta, Parada paradaAntiga, Parada nuevaParada, String descripcionParada) throws Exception {

		try {
			String cve = extrairCodigoOuLocalidade(descripcionParada, true, false);
			String descparada = extrairCodigoOuLocalidade(descripcionParada, false, true);

			if (nuevaParada == null) {
				nuevaParada = crearNuevaParada(paradaAntiga, cve, descparada);
				paradaService.suscribirActualizar(nuevaParada);
			}

			List<Tramo> tramos = validaTramosRuta(ruta);
			List<CambioRutaTramo> cambios = new ArrayList<CambioRutaTramo>();
			for (Tramo tramo : tramos) {
				Tramo nTramo = crearNuevoTramo(tramo, paradaAntiga, nuevaParada);
				if (nTramo != null) {
					cambios.add(new CambioRutaTramo(tramo, nTramo, paradaAntiga, nuevaParada));
					tramoService.suscribirActualizar(nTramo);
				}
			}

			for (CambioRutaTramo crt : cambios) {
				rutaDAO.updateAsientosVendibles(ruta, crt.getViejoTramo(), crt.getNuevoTramo());
			}

			return true;

		} catch (Exception e) {
			throw e;
		}
	}

	private List<Tramo> validaTramosRuta(Ruta ruta) {

		List<Tramo> tramosRuta = new ArrayList<Tramo>();

		for (RutaCombinacion rc : ruta.getRutaCombinacionList()) {
			if (!tramosRuta.contains(rc.getTramo()))
				tramosRuta.add(rc.getTramo());
		}

		for (RutaSecuencia rs : ruta.getRutaSecuenciaList()) {
			if (!tramosRuta.contains(rs.getTramo()))
				tramosRuta.add(rs.getTramo());
		}

		return tramosRuta;
	}

	private Tramo crearNuevoTramo(Tramo tramo, Parada viejaParada, Parada nuevaParada) {

		Tramo viejoTramo = tramoService.obtenerID(tramo.getTramoId());
		if (viejoTramo.getOrigem().equals(viejaParada) || viejoTramo.getDestino().equals(viejaParada)) {

			Tramo ptramo = null;
			if (viejoTramo.getOrigem().equals(viejaParada)) {
				ptramo = tramoService.obtenerTramotPorOrigemDestinoVia(nuevaParada, viejoTramo.getDestino(), viejoTramo.getVia());
			}

			if (viejoTramo.getDestino().equals(viejaParada)) {
				ptramo = tramoService.obtenerTramotPorOrigemDestinoVia(viejoTramo.getOrigem(), nuevaParada, viejoTramo.getVia());
			}

			if (ptramo == null) {

				Tramo nuevoTramo = new Tramo();
				nuevoTramo.setDesctramo(viejoTramo.getDesctramo() + " II");
				nuevoTramo.setVia(viejoTramo.getVia());
				nuevoTramo.setKmPagoConductor(viejoTramo.getKmPagoConductor());
				nuevoTramo.setKmReal(viejoTramo.getKmReal());

				nuevoTramo.setLsTramoTiempo(viejoTramo.getLsTramoTiempo());
				nuevoTramo.setLsOrgaoTramo(viejoTramo.getLsOrgaoTramo());

				nuevoTramo.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
				nuevoTramo.setFecmodif(Calendar.getInstance().getTime());
				nuevoTramo.setActivo(Boolean.TRUE);

				if (viejoTramo.getOrigem().equals(viejaParada)) {
					nuevoTramo.setOrigem(nuevaParada);
					nuevoTramo.setDestino(viejoTramo.getDestino());
				}
				if (viejoTramo.getDestino().equals(viejaParada)) {
					nuevoTramo.setDestino(nuevaParada);
					nuevoTramo.setOrigem(viejoTramo.getOrigem());
				}

				return nuevoTramo;
			} else {
				return ptramo;
			}
		} else {
			return null;
		}
	}

	private Parada crearNuevaParada(Parada parada, String cve, String descparada) {
		Parada nuevaParada = new Parada();
		nuevaParada.setCveparada(cve);
		nuevaParada.setDescparada(descparada);
		nuevaParada.setCiudad(parada.getCiudad());
		nuevaParada.setRegionMetropolitana(parada.getRegionMetropolitana());
		nuevaParada.setNodo(parada.getNodo());
		nuevaParada.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		nuevaParada.setFecmodif(Calendar.getInstance().getTime());
		nuevaParada.setActivo(Boolean.TRUE);

		return nuevaParada;
	}

	@Transactional(rollbackFor = BusinessException.class)
	public Ruta suscribir(Ruta entidad, List<ParadaSecuencia> lsParadasSequencia) throws BusinessException {
		entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		entidad.setFecmodif(Calendar.getInstance().getTime());
		entidad.setActivo(Boolean.TRUE);

		if (entidad.getVentaOffLine() == null) {
			entidad.setVentaOffLine(false);
		}

		Boolean isClone = entidad.getIsClone() != null ? entidad.getIsClone() : Boolean.FALSE;
		Boolean isCadastro = entidad.getIsCadastro();
		
		if (entidad.getRutaId() == null) {
			entidad = rutaDAO.suscribir(entidad);
		} else {
			entidad = rutaDAO.actualizacion(entidad);			
		}
		if (lsParadasSequencia != null) {
			if (!isClone && !isCadastro) {
				generarSecuencias(entidad, lsParadasSequencia);
			}
			generarCombinacion(entidad);
		}

		return entidad;
	}

	private void generarSecuencias(Ruta ruta, List<ParadaSecuencia> lsParadasSequencia) throws BusinessException {

		tramoRutaService.limparInconsistenciasTramo();
		if (lsParadasSequencia != null) {
			List<RutaSecuencia> lsRutaSecuencia = new ArrayList<RutaSecuencia>();
			HashMap<Integer, List<RutaCaseta>> rutaSecuenciaBackup = new HashMap<Integer, List<RutaCaseta>>();
			for (RutaSecuencia rutaSecuencia : ruta.getRutaSecuenciaList()) {
				rutaSecuenciaBackup.put(rutaSecuencia.getTramo().getTramoId(), rutaSecuencia.getLsRutaCase() );
			}

			// Desativo todas as secuencias e gero novamente.
			rutaSecuenciaService.borrarSecuencias(ruta);
			ruta.setRutaSecuenciaList(null);

			log.info("geração de Secuencia!");
			log.info("Ruta: " + ruta.getRutaId() + " - " + ruta.getDescruta());

			lsRutaSecuencia.clear();
			StringBuilder sb = new StringBuilder("Tramo(s) inexistente(s):");
			sb.append("\n");
			for (int i = 0; i < lsParadasSequencia.size() - 1; i++) {
				Parada ori = lsParadasSequencia.get(i).getParada();
				Via via = lsParadasSequencia.get(i).getVia();
				Integer sec1 = lsParadasSequencia.get(i).getSecuencia().intValue();
				log.info("Secuencia: " + sec1 + " origen " + ori.getDescparada() + " - " + ori.getCveparada() + " Via: " + via.getNombvia());

				Parada des = lsParadasSequencia.get(i + 1).getParada();
				Integer sec2 = lsParadasSequencia.get(i + 1).getSecuencia().intValue();
				log.info("Secuencia: " + sec2 + " destino " + des.getDescparada() + " - " + des.getCveparada() + " Via: " + via.getNombvia());

				ClaseServicio claseServicio = ruta.getClaseServicio();

				Tramo tramo = tramoService.obtenerTramoUnicoRuta(ori, des, via, claseServicio);
				if (tramo == null && isCopiaComAlteracaoDeClasse(ruta)) {
					tramo = tramoService.obtenerTramoUnicoRuta(ori, des, via, ruta.getClaseServicioRutaOrigem());
				}
				if (tramo != null ) {
					RutaSecuencia rutaSecuencia = new RutaSecuencia();
					rutaSecuencia.setRuta(ruta);
					rutaSecuencia.setTramo(tramo);
					rutaSecuencia.setNumsecuencia(sec1.shortValue());
					rutaSecuencia.setActivo(Boolean.TRUE);
					rutaSecuencia.setFecmodif(Calendar.getInstance().getTime());
					rutaSecuencia.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
					rutaSecuencia.setKmOriginal(tramo.getKmReal());
					rutaSecuencia = rutaSecuenciaService.suscribir(rutaSecuencia);
				
					List<RutaCaseta> lsRutaCaseta;
					if (ruta.getIsClone()) {
						lsRutaCaseta = lsParadasSequencia.get(i).getCasetas();
						if (lsRutaCaseta != null && !lsRutaCaseta.isEmpty()) {
							List<RutaCaseta> rutasCaseta = new ArrayList<RutaCaseta>();

							for (RutaCaseta rc : lsRutaCaseta) {
								RutaCaseta rutaCaseta = new RutaCaseta();
								rutaCaseta.setRutaSecuencia(rutaSecuencia);
								rutaCaseta.setCasetaPeaje(rc.getCasetaPeaje());
								rutaCaseta.setActivo(Boolean.TRUE);
								rutaCaseta.setFecmodif(new Date());
								rutaCaseta.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
								rutasCaseta.add(rutaCaseta);
							}

							rutaSecuencia.setLsRutaCase(rutasCaseta);
						}
					} else {
						lsRutaCaseta = rutaSecuenciaBackup.get(tramo.getTramoId());
						if (lsRutaCaseta != null && !lsRutaCaseta.isEmpty()) {
							rutaSecuencia.setLsRutaCase(lsRutaCaseta);
						}
					}
					
					
					lsRutaSecuencia.add(rutaSecuencia);

				} else {
					throw new BusinessException("rutaServiceImpl.msg.validacionTRamo", new Object[] { ori.getCveparada(), des.getCveparada(), via.getNombvia(), claseServicio.getDescclase() });
				}
			}
			ruta.setRutaSecuenciaList(lsRutaSecuencia);
		}
	}

	private boolean isCopiaComAlteracaoDeClasse(Ruta ruta) {
		return ruta.getIsClone() && ruta.getClaseServicioRutaOrigem() != null && (ruta.getClaseServicioRutaOrigem().getClaseservicioId() != ruta.getClaseServicio().getClaseservicioId());
	}

	@Transactional(rollbackFor = BusinessException.class)
	public Ruta actualizacion(Ruta ruta, List<ParadaSecuencia> lsParadasSequencia) throws BusinessException {
		if (lsParadasSequencia != null) {
			generarSecuencias(ruta, lsParadasSequencia);
			generarCombinacion(ruta);
		}

		ruta.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		ruta.setFecmodif(Calendar.getInstance().getTime());
		ruta.setActivo(Boolean.TRUE);

		return rutaDAO.actualizacion(ruta);
	}

	@Transactional(rollbackFor = RegistroConDependenciaException.class)
	public void borrar(Ruta entidad) throws RegistroConDependenciaException {
		if ((corridaDAO.count(entidad) > 0l) || (esquemaCorridaDAO.count("ruta", entidad) > 0l)) {
			throw new RegistroConDependenciaException();
		}

		entidad = this.obtenerID(entidad.getRutaId());
		for (RutaCombinacion rutaCombinacion : entidad.getRutaCombinacionList()) {
			rutaCombinacion.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
			rutaCombinacion.setFecmodif(Calendar.getInstance().getTime());
			rutaCombinacion.setActivo(Boolean.FALSE);
		}

		for (RutaSecuencia rutaSecuencia : entidad.getRutaSecuenciaList()) {
			rutaSecuencia.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
			rutaSecuencia.setFecmodif(Calendar.getInstance().getTime());
			rutaSecuencia.setActivo(Boolean.FALSE);
		}

		for (RutaEmpresa rutaEmpresa : entidad.getLsRutaEmpresa()) {
			rutaEmpresa.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
			rutaEmpresa.setFecmodif(Calendar.getInstance().getTime());
			rutaEmpresa.setActivo(Boolean.FALSE);
		}

		entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		entidad.setFecmodif(Calendar.getInstance().getTime());
		entidad.setActivo(Boolean.FALSE);

		rutaDAO.actualizacion(entidad);
	}

	@Transactional(rollbackFor = BusinessException.class)
	public void generarCombinacion(Ruta ruta) throws BusinessException {


		List<RutaCombinacion> listRutaCombinacion = new ArrayList<RutaCombinacion>();
		List<RutaSecuencia> lsRutaSecuencia = new ArrayList<RutaSecuencia>();
		if (ruta.getRutaId() != null) {
			listRutaCombinacion = rutaCombinacionService.obtenerPorRuta(ruta);
		}
		
		rutaCombinacionService.borrarCombinaciones(ruta);
		
		ruta.setRutaCombinacionList(listRutaCombinacion);

		lsRutaSecuencia = rutaSecuenciaService.buscarSecuenciaOrdenado(ruta);

		for (int i = 0; i < lsRutaSecuencia.size(); i++) {
			Tramo tramoSecuencia1 = lsRutaSecuencia.get(i).getTramo();
			Parada origem = tramoSecuencia1.getOrigem();

			for (int x = 0; x < lsRutaSecuencia.size(); x++) {
				Tramo tramoSecuencia2 = lsRutaSecuencia.get(x).getTramo();
				Parada destinoOrigem = tramoSecuencia2.getDestino();

				// Numero secuencia anterior > Numero secuencia atual não deve fazer.
				// Essa condição não permiti gerar uma volta.
				if (lsRutaSecuencia.get(i).getNumsecuencia().intValue() > lsRutaSecuencia.get(x).getNumsecuencia().intValue()) {
					continue;
				}

				// IDA - A x B - A x C
				if (origem == destinoOrigem) {
					continue;
				}

				List<Tramo> listTramo = tramoService.obtenerPorOrigemDestinoFetchLazy(origem, destinoOrigem);

				if (listTramo.isEmpty()) {
					throw new BusinessException("rutaServiceImpl.msg.validacionTRamoCombinacion", new Object[] { origem.getDescparada(), origem.getCveparada(), destinoOrigem.getDescparada(), destinoOrigem.getCveparada() });
				}

				Tramo trBuscaOrigemDestino = new Tramo();
				for (Tramo tm : listTramo) {
					if (tm.getVia().equals(tramoSecuencia2.getVia())) {
						trBuscaOrigemDestino = tm;
						break;
					} else if (tm.getVia().equals(tramoSecuencia1.getVia())) {
						trBuscaOrigemDestino = tm;
						break;
					} else {
						trBuscaOrigemDestino = tm;
					}
				}

				log.debug("Tramo:" + trBuscaOrigemDestino.getDesctramo());

				RutaCombinacion rc = new RutaCombinacion();
				rc.setActivo(Boolean.TRUE);
				rc.setFecmodif(Calendar.getInstance().getTime());
				rc.setIndventa(indVenta(ruta, trBuscaOrigemDestino));
				rc.setRuta(ruta);
				rc.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
				rc.setTramo(trBuscaOrigemDestino);

				// Verifica se já existe o registro INATIVO para Reativa-lo e manter a configuração se vende.
				// if (!rutaCombinacionService.busquedaRutaTramo(ruta, trBuscaOrigemDestino, Boolean.FALSE)) {
				rc = rutaCombinacionService.suscribir(rc);
				// } else {
				// rutaCombinacionService.activar(ruta, trBuscaOrigemDestino);
				// }

			}
		}
	}

	private boolean indVenta(Ruta ruta, Tramo trBuscaOrigemDestino) {
		if (!ruta.getIsClone()) {
			for (RutaCombinacion rc : ruta.getRutaCombinacionList()) {
				if (rc.getTramo().equals(trBuscaOrigemDestino)) {
					return rc.getIndventa();
				}
			}
		} else {
			for (RutaCombinacion rcTemporaria : ruta.getRutaCombinacionTemporariaList()) {
				if (rcTemporaria.getTramo().equals(trBuscaOrigemDestino)) {
					return rcTemporaria.getIndventa();
				}
			}
		}
		return true;
	}

	public Parada getDestino(Ruta ruta) {
		return rutaDAO.buscarDestino(ruta);
	}

	public Parada getOrigem(Ruta ruta) {
		return rutaDAO.buscarOrigen(ruta);
	}

	public List<Ruta> buscarPorClaseServicioEmpresa(ClaseServicio claseServicio, Empresa empresa) {
		return rutaDAO.buscarPorClaseServicioEmpresa(claseServicio, empresa);
	}

	public List<Ruta> buscarPorClaseServicio(ClaseServicio claseServicio) {
		return rutaDAO.buscarPorClaseServicio(claseServicio);
	}

	public List<Ruta> buscar(String nomeRuta, ClaseServicio claseServicio, Boolean nomeObrigatorio) {
		return rutaDAO.buscar(nomeRuta, claseServicio, nomeObrigatorio);
	}

	public List<Ruta> obtenerPorEmpresa(Empresa empresa) {
		return rutaDAO.obtenerPorEmpresa(empresa);
	}

	public List<Ruta> buscarTodosExceto(Integer... idRuta) {
		return rutaDAO.buscarTodosExceto(idRuta);
	}

	public List<Ruta> buscarTodosEstos(Integer[] idRutas) {
		return rutaDAO.buscarTodosEstos(idRutas);
	}

	public List<Ruta> buscarNumRuta(String numRuta) {
		return rutaDAO.buscarNumRuta(numRuta);
	}

	@Override
	public boolean paradaExisteEnLaRuta(Parada parada, Ruta ruta) {
		ruta = obtenerID(ruta.getRutaId());
		boolean existe = false;
		for (int i = 0; (i < ruta.getRutaSecuenciaList().size()) && !existe; i++) {
			RutaSecuencia rutaSecuencia = ruta.getRutaSecuenciaList().get(i);
			Tramo tramo = rutaSecuencia.getTramo();
			if (tramo != null) {
				if (tramo.getOrigem().equals(parada) || tramo.getDestino().equals(parada)) {
					existe = true;
				}
			}
		}
		return existe;
	}

	@Override
	public List<RutaVO> buscaRutaPorNumeroSemDadoRepetido(String palavraPesquisaRuta) {
		return rutaDAO.buscaRutaPorNumeroSemDadoRepetido(palavraPesquisaRuta);
	}
	
	@Override
	public List<RutaVO> buscaRutaParadas(Integer rotaId) {
		return rutaDAO.buscaRutaParadas(rotaId);
	}

	public List<Ruta> buscaRuta(String palavraPesquisaRuta) {
		return rutaDAO.buscaRuta(palavraPesquisaRuta);
	}

	@Override
	public List<Ruta> buscaRuta(String palavraPesquisaRuta, OrgaoConcedente orgao) {
		return rutaDAO.buscaRuta(palavraPesquisaRuta, orgao);
	}

	public List<Ruta> buscaRutasFromOrgao(OrgaoConcedente orgao) {
		return rutaDAO.buscaRutasFromOrgao(orgao);
	}
	
	public List<Ruta> buscaSomenteRutasFromOrgao(OrgaoConcedente orgao) {
		return rutaDAO.buscaSomenteRutasFromOrgao(orgao);
	}

	@Override
	public List<Ruta> buscarRutasPorEmpresas(List<Empresa> lsEmp) {
		return rutaDAO.buscarPorRutaPorEmpresas(lsEmp);
	}

//	private class RutaComparator implements Comparator<Ruta> {
//		@Override
//		public int compare(Ruta r1, Ruta r2) {
//			String name1 = r1.getDescruta();
//			String name2 = r2.getDescruta();
//			return name1.compareTo(name2);
//		}
//	}

	@Override
	public Integer getNumSecuenciaOrigen(Integer rutaId, Integer origenId) {
		return obtenerID(rutaId).numSecuenciaOrigen(origenId);
	}

	@Override
	public Integer getNumSecuenciaDestino(Integer rutaId, Integer destinoId) {
		return obtenerID(rutaId).numSecuenciaDestino(destinoId);
	}

	@Override
	public List<ParadaSecuenciaCombinacaoLinha> verificarSeqRutaNaoGerada(Ruta ruta, List<ParadaSecuencia> lsParadasSecuencia) {

		List<ParadaSecuenciaCombinacaoLinha> sequencias = null;

		if (lsParadasSecuencia != null) {
			sequencias = new ArrayList<ParadaSecuenciaCombinacaoLinha>();

			for (ParadaSecuencia sequenciaInformada : lsParadasSecuencia) {

				Via via = sequenciaInformada.getVia();

				ParadaSecuenciaCombinacaoLinha paradaSecuenciaCombinacaoLinha = new ParadaSecuenciaCombinacaoLinha();
				paradaSecuenciaCombinacaoLinha.setOrigem(sequenciaInformada);
				paradaSecuenciaCombinacaoLinha.setVia(via);
				paradaSecuenciaCombinacaoLinha.setDestinos(new ArrayList<ParadaSecuencia>());
				paradaSecuenciaCombinacaoLinha.setKmReal(sequenciaInformada.getKmReal());
				paradaSecuenciaCombinacaoLinha.setKmEntradaSaida(sequenciaInformada.getKmEntradaSaida());
				paradaSecuenciaCombinacaoLinha.setTempoReal(sequenciaInformada.getTempoReal());

				for (ParadaSecuencia sequenciaExistente : lsParadasSecuencia) {
					if (sequenciaInformada.getParada().getParadaId() == sequenciaExistente.getParada().getParadaId()) {
						continue;
					}

					paradaSecuenciaCombinacaoLinha.getDestinos().add(sequenciaExistente);
				}

				sequencias.add(paradaSecuenciaCombinacaoLinha);
			}
		}

		return sequencias;
	}

	@Override
	public List<Ruta> buscarRutasPorEmpresaOrgaoConcedente(Empresa empresa, OrgaoConcedente orgao) {
		return rutaDAO.buscarRutasPorEmpresaOrgaoConcedente(empresa, orgao);
	}
	
	@Override
	public List<Ruta> buscarRutasPorEmpresaOrgaoConcedenteClaseServicio(Empresa empresa, OrgaoConcedente orgao, ClaseServicio claseServicio) {
		return rutaDAO.buscarRutasPorEmpresaOrgaoConcedenteClaseServicio(empresa, orgao, claseServicio);
	}

	class CambioRutaTramo {
		private Tramo viejoTramo;
		private Tramo nuevoTramo;
		private Parada viejaParada;
		private Parada nuevaParada;

		public CambioRutaTramo(Tramo viejoTramo, Tramo nuevoTramo, Parada viejaParada, Parada nuevaParada) {
			super();
			this.viejoTramo = viejoTramo;
			this.nuevoTramo = nuevoTramo;
			this.viejaParada = viejaParada;
			this.nuevaParada = nuevaParada;
		}

		public Tramo getViejoTramo() {
			return viejoTramo;
		}

		public void setViejoTramo(Tramo viejoTramo) {
			this.viejoTramo = viejoTramo;
		}

		public Tramo getNuevoTramo() {
			return nuevoTramo;
		}

		public void setNuevoTramo(Tramo nuevoTramo) {
			this.nuevoTramo = nuevoTramo;
		}

		public Parada getViejaParada() {
			return viejaParada;
		}

		public void setViejaParada(Parada viejaParada) {
			this.viejaParada = viejaParada;
		}

		public Parada getNuevaParada() {
			return nuevaParada;
		}

		public void setNuevaParada(Parada nuevaParada) {
			this.nuevaParada = nuevaParada;
		}
	}

	@Override
	public List<Ruta> buscaLikeComboBox(String stringConsulta) {
		return rutaDAO.buscaLikeComboBox(stringConsulta);
	}
	
	@Override
	public List<Ruta> buscarPorIds(Integer[] rutaIds){
		return rutaDAO.buscarPorIds(rutaIds);
		
	}
	
	@Override
	public List<Ruta> buscarPorOrgaoEcasetaPeaje(OrgaoConcedente orgao, Integer[] listCasetaPeaje){
		return buscarPorOrgaoEcasetaPeaje(orgao,listCasetaPeaje,null);
	}
	
	@Override
	public List<Ruta> buscarRutasPorEmpresaOrgaoConcedenteParadaIds(Empresa empresa, OrgaoConcedente orgao, Integer[] lsParadaIds) {
		return rutaDAO.buscarRutasPorEmpresaOrgaoConcedenteParadaIds(empresa,orgao,lsParadaIds);
	}
	
	@Override
	public List<Ruta> buscarPorOrgaoEcasetaPeaje(OrgaoConcedente orgao, Integer[] listCasetaPeaje, Empresa empresa){
		return rutaDAO.buscarPorOrgaoEcasetaPeaje(orgao,listCasetaPeaje,empresa);
	}

	}
