/*
 * Created on Jun 14, 2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package modelo;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import excepciones.ExcepcionArcoExistente;

/**
 * @author gas y JPG
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class AgregarCamino extends FuncionAbstracta {

	public AgregarCamino(){}
	//	Recibe como parámetro un tipo de estado origen, un tipo de estado destino , un tipo de requerimiento y un proyecto
	public Object execute(Map m) throws ExcepcionArcoExistente {
		TipoEstado tipoEstOrigen = (TipoEstado) m.get(Constants.ORIGEN);
		TipoEstado tipoEstDestino = (TipoEstado) m.get(Constants.DESTINO);
		TipoRequerimiento tipoReq =
			(TipoRequerimiento) m.get(Constants.TIPOREQ);
		Proyecto proyecto = (Proyecto) m.get(Constants.PROYECTO);
		//Recuperamos si es que existen los nodos origen y destino correspondientes a los tipos de estado recibidos
		//como parámentro
		RecorridoEstado nodoOrigen = null;
		Iterator itNodosCreados = proyecto.getNodosCreados().iterator();
		boolean found = false;
		while (itNodosCreados.hasNext() && !found) {

			nodoOrigen = (RecorridoEstado) itNodosCreados.next();
			System.out.println(nodoOrigen.getTipoEstado().getNombre());
			if (nodoOrigen
				.getTipoEstado()
				.getNombre()
				.equals(tipoEstOrigen.getNombre())) {
				System.out.println("Nodo origen encontrado");
				found = true;
			}
		}
		if (!found) {
			nodoOrigen =
				new NodoCompuesto(
					tipoEstOrigen,
					new LinkedList(),
					new LinkedList());
			System.out.println("Nodo origen creado");
			proyecto.addNodoCreado(nodoOrigen);
		}
		RecorridoEstado nodoDestino = null;
		itNodosCreados = proyecto.getNodosCreados().iterator();
		found = false;
		while (itNodosCreados.hasNext() && !found) {
			nodoDestino = (RecorridoEstado) itNodosCreados.next();
			if (nodoDestino
				.getTipoEstado()
				.getNombre()
				.equals(tipoEstDestino.getNombre())) {
				found = true;
				System.out.println("Nodo destino encontrado");
			}
		}
		if (!found) {
			if (tipoEstDestino.getNombre().equals(Constants.FINALIZADO)) {
				nodoDestino = new NodoFinal(tipoEstOrigen, new LinkedList());
			} else {
				System.out.println("Nodo destino creado");
				nodoDestino =
					new NodoCompuesto(
						tipoEstDestino,
						new LinkedList(),
						new LinkedList());
			}
			proyecto.addNodoCreado(nodoDestino);
		}

		List nodosSigtes = (List) nodoOrigen.getEstadosSigtes();
		//si la conexion a nivel de proyecto entre nodo origen y destino no existe el nodo origen debe agregar como 
		//sigiente al destino
		System.out.println(nodosSigtes.indexOf(nodoDestino));
		if (nodosSigtes.indexOf(nodoDestino) == -1) {

			nodoOrigen.addSigte(nodoDestino);
		}
		Collection tiposPermitidos = nodoDestino.getTiposReqPermitidos();
		Iterator it = tiposPermitidos.iterator();
		//Chequea que no exista una arista del grafo para ese tipo de requerimiento y ese destino a partir del origen.
		List par = null;
		while (it.hasNext()) {
			par = (List) it.next();
			NodoCompuesto nodoComp = (NodoCompuesto) par.get(0);
			TipoRequerimiento tReq = (TipoRequerimiento) par.get(1);
			if ((nodoComp.equals(nodoOrigen)) && (tReq.equals(tipoReq))) {
				throw new ExcepcionArcoExistente("la conexion que quiere crear ya existe");
			}

		}
		par = new LinkedList();
		par.add(0, nodoOrigen);
		par.add(1, tipoReq);
		nodoDestino.addTipoReqPermitido(par);
		return null;
	}

}
