package cz.vutbr.feec.stockElements;

import java.util.HashSet;
import java.util.Vector;

import cz.vutbr.feec.graph.Dijkstra;
import cz.vutbr.feec.graph.Graph;
import cz.vutbr.feec.graph.Path;
import cz.vutbr.feec.graph.Router;
import cz.vutbr.feec.graph.RoutingTable;
import cz.vutbr.feec.libraryClasses.GuiPainting;

public class Stock {

	private static final Stock STOCK = new Stock(); // singleton
	private float length = 1;
	private float width = 1;
	private short delimiter = 1;
	private AbstractStockCell[][] field;
	private Vector<Router> routers = new Vector<Router>();
	private Vector<Path> paths = new Vector<Path>();
//	private Vector<Accident> accidents = new Vector<>();
	private Dijkstra dijkstra = null;
	private Graph graph = new Graph();
	private RoutingTable routingTable;
	private AbstractStockCell isCurrent;
	private Vector<AbstractStockCell> ramps = new Vector<AbstractStockCell>();

	// accidenty po novom
	private Vector<AbstractStockCell> accidentCells = new Vector<AbstractStockCell>();

	public Vector<AbstractStockCell> getAccidentCells() {
		return accidentCells;
	}

	public boolean containsAccident(AbstractStockCell c) {
		for (int i = 0; i < accidentCells.size(); i++) {

			if ((c.getX() == accidentCells.get(i).getX())
					&& c.getY() == accidentCells.get(i).getY()) {
				return true;
			}
		}
		return false;
	}

	public void removeCellFromAccident(AbstractStockCell c) {
		for (int i = 0; i < accidentCells.size(); i++) {
			if ((c.getX() == accidentCells.get(i).getX())
					&& c.getY() == accidentCells.get(i).getY()) {
				accidentCells.remove(i);
			}
		}
	}
	
	public void clearAccidentCells() {
		accidentCells.removeAllElements();
			
	}
/*
	public Vector<Accident> getAccidents() {
		return accidents;
	}
*/
	private Stock() {
		// konstruktor na zamedzenie vytvorenia instance
	}

	public static Stock getInstance() {// vrati jedinecnou instanci
		return STOCK;
	}

	public Dijkstra getDijkstra() {
		return dijkstra;
	}

	public void setDijkstra(Dijkstra dijkstra) {
		this.dijkstra = dijkstra;
	}

	public Vector<Router> getRouters() {
		return routers;
	}

	public void addRouter(Router router) {
		routers.add(router);
	}

	public void removeRouter(int x, int y) {
		for (int i = 0; i < routers.size(); i++) {

			if ((x == routers.get(i).getxInField())
					&& y == routers.get(i).getyInField()) {
				routers.remove(i);
			}
		}
	}

	public Router getRouter(int x, int y) {
		for (int i = 0; i < routers.size(); i++) {

			if ((x == routers.get(i).getxInField())
					&& y == routers.get(i).getyInField()) {
				return routers.get(i);
			}
		}
		// tu by som sa nikdy nemal dostat
		return null;
	}

	public boolean contains(Router r) {
		for (int i = 0; i < routers.size(); i++) {

			if ((r.getxInField() == routers.get(i).getxInField())
					&& r.getyInField() == routers.get(i).getyInField()) {
				return true;
			}
		}

		return false;

	}

	public void setFieldIndex(AbstractStockCell i, int x, int y) {
		this.field[x][y] = i;
	}

	public AbstractStockCell getFieldIndex(int x, int y) {
		try {
			return this.field[x][y];

		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("No field created");
			return null;

		}

	}

	public AbstractStockCell[][] getField() {
		return field;
	}

	public void setField(AbstractStockCell[][] field) {
		this.field = field;
	}

	public void setLength(float length) {
		this.length = length;
	}

	public void setWidth(float width) {
		this.width = width;
	}

	public float getLength() {
		return length;
	}

	public float getWidth() {
		return width;
	}

	public short getDelimiter() {
		return delimiter;
	}

	public void setDelimiter(short delimiter) {
		this.delimiter = delimiter;
	}

	public Vector<Path> getPaths() {
		return paths;
	}

	public void setPaths(Vector<Path> paths) {
		this.paths = paths;
	}

	public Router getRouterFromCoordinates(int x, int y) {
		for (int i = 0; i < routers.size(); i++) {

			if ((x == routers.get(i).getxInField())
					&& y == routers.get(i).getyInField()) {
				return routers.get(i);
			}
		}
		return null;

	}

	public int getPathNumber(Router first, Router second) {
		int pathNumber = -1;
		for (int i = 0; i < paths.size(); i++) {
			if (paths.get(i).getFirstRouter() == first
					&& paths.get(i).getSecondRouter() == second) {
				pathNumber = i;
			}
			// moze byt prehodene poradie
			else if (paths.get(i).getFirstRouter() == second
					&& paths.get(i).getSecondRouter() == first) {
				pathNumber = i;
			}

		}

		return pathNumber;

	}

	public Graph getGraph() {
		return graph;
	}

	public void setGraph(Graph graph) {
		this.graph = graph;
	}

	public RoutingTable getRoutingTable() {
		return routingTable;
	}

	public void setRoutingTable(RoutingTable routingTable) {
		this.routingTable = routingTable;
	}

	public AbstractStockCell getIsCurrent() {
		return isCurrent;
	}

	public void setIsCurrent(AbstractStockCell isCurrent) {
		this.isCurrent = isCurrent;
	}
/*
	public void addAccident(AccidentCell c) {
		Accident accident = new Accident(c);
		int x = c.getX();
		int y = c.getY();
		accidents.add(accident);
		// pridaj do skladu
		field[x][y] = c;
		System.out.println("accident added");
		// treba prepocitat vsetky parametre
		// najskor nastavim cost na infinity
		accident.setCostToInfinty();
		// prepocitaj parametre
		accident.recalculatePath();
		System.out.println("accident added");
		// vykreslenie accidentu
		GuiPainting.createZoomedCanvas();
	}
*/
	/*
	public void removeAccident(AccidentCell c) {
		int x = c.getX();
		int y = c.getY();
		accidents.remove(c.getAccident());
		// vrat do skladu predchadzajucu bunku
		// setFieldIndex(c.getPreviousCell(), x, y);
		field[x][y] = c.getPreviousCell();
		// vrat metriku
		c.getAccident().setCostBefore();
		// vrat parametre
		c.getAccident().returnPath();
		GuiPainting.createZoomedCanvas();

	}
*/
	public Vector<AbstractStockCell> getRamps() {
		return ramps;
	}

	public void setRamps(Vector<AbstractStockCell> routersOnRamp) {
		this.ramps = ramps;
	}

	public void removeRamp(AbstractStockCell a) {
		System.out.println("som v mazani rampy");
		for (int i = 0; i < ramps.size(); i++) {

			if ((a.getX() == ramps.get(i).getX())
					&& a.getY() == ramps.get(i).getY()) {
				ramps.remove(i);
				System.out.println("rampa vymazana");
				return;
			}
		}
	}

	public boolean containsRamp(AbstractStockCell a) {
		for (int i = 0; i < ramps.size(); i++) {

			if ((a.getX() == ramps.get(i).getX())
					&& a.getY() == ramps.get(i).getY()) {
				return true;
			}
		}
		return false;
	}

	public boolean isCellInPath(int x, int y) {
		for (int i = 0; i < paths.size(); i++) {
			Path p = paths.get(i);
			for (int j = 0; j < p.getPath().size(); j++) {
				AbstractStockCell tmp = p.getPath().get(j);
				if ((x == tmp.getX())
						&& y == tmp.getY()) {
					return true;
				}
			}
		}

		return false;

	}

}
