/*
 *  Copyright 2015 Brno University of Technology 
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. 
 */
package cz.vutbr.feec.graph;

import java.io.Serializable;
import java.util.Vector;

import org.apache.log4j.Logger;

import cz.vutbr.feec.project.GlobalParameters;
import cz.vutbr.feec.stockElements.AbstractStockCell;
import cz.vutbr.feec.stockElements.CoridorCell;

public class Path implements Comparable<Path>, Serializable {
//	private static Logger log = Logger.getLogger(Path.class);
	private transient Graph graph;
	private Router lastNode = null;
	private Vector<Router> nodes = new Vector<Router>();
	private int cost; // vzdialenost
	
	private Router firstRouter;
	private Router secondRouter;
	private Vector<AbstractStockCell> path = new Vector<AbstractStockCell>();

	public Path(Graph g) {
		this.graph = g;
	}

	public int compareTo(Path c) {
		if (cost == c.cost) {
			return 0;
		} else if (cost < c.cost) {
			return -1;
		} else {
			return 1;
		}
	}

	public void setCost(int cost) {
		this.cost = cost;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((nodes == null) ? 0 : nodes.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Path other = (Path) obj;
		if (nodes == null) {
			if (other.nodes != null)
				return false;
		} else if (!nodes.equals(other.nodes))
			return false;
		return true;
	}

	/*
	 * public void addNode(String name2) { // prevod z textu nazvu uzlu na
	 * objekt Uzel Router objectNode = graph.getRouter(name2);
	 */
	public void addNode(Router objectNode) {

		if (nodes.contains(objectNode)) {
			// vkladam jiz ne poprve
			// neni zde cyklus - tj. nesmyslna cesta?
			cost = GlobalParameters.INFINITY;
		//	log.debug("Ve vytvorene ceste vnikl cyklus ");
			return;
		}

		nodes.add(objectNode);
		if (lastNode == null) {
			// vkladam poprve
			lastNode = objectNode; // zapamatuji si minuly uzel
		} else {

			cost += lastNode.getCost(objectNode); // prictu cenu
			lastNode = objectNode; // zapamatuji si minuly uzel
		}
	}

	public Path cloneAndAddNode(Router r) {
		Path kopie = new Path(graph);
		kopie.cost = cost;
		kopie.lastNode = lastNode;
		kopie.nodes.addAll(nodes);

		kopie.addNode(r);

		return kopie;
	}

	public int getCost() {
		return cost;
	}

	public Router getLast() {
		return lastNode;
	}

	public boolean isAtDestination(Router destination) {
		if (lastNode == null) {
			return false;
		}
		return lastNode.getData().equals(destination.getData());
		// return lastNode == destination;
	}

	@Override
	public String toString() {
		String s = "[";
		for (Router u : nodes) {
			s += u.getData() + ";";
		}
		return s + " |cost=" + cost + "]";
	}

	public Router getFirstRouter() {
		return firstRouter;
	}

	public void setFirstRouter(Router firstRouter) {
		this.firstRouter = firstRouter;
	}

	public Router getSecondRouter() {
		return secondRouter;
	}

	public void setSecondRouter(Router secondRouter) {
		this.secondRouter = secondRouter;
	}

	public void addCellToPath(AbstractStockCell abstractStockCell) {
		path.add(abstractStockCell);

	}

	public void addCellToIndex(CoridorCell c, int index) {
		path.add(index, c);
	}

	public Vector<AbstractStockCell> getPath() {
		return path;
	}

	public boolean contains(AbstractStockCell abstractStockCell) {
		for (int i = 0; i < path.size(); i++) {
			if (abstractStockCell.getX() == path.get(i).getX()
					&& abstractStockCell.getY() == path.get(i).getY()) {
				return true;
			}
		}
		return false;

	}
}
