/***************************************************************************
 * Copyright 2014 Kieker Project (http://kieker-monitoring.net)
 *
 * 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 kieker.webgui.service.impl.utility.model;

import java.util.ArrayList;
import java.util.List;

import kieker.webgui.service.impl.utility.KielerInterface;

import de.cau.cs.kieler.core.kgraph.KNode;

/**
 * This class represents the whole graph that needs to be layouted.
 * Contains lists of all {@link Node}s and {@link Edge}s as well as a general scaling
 * factor that determines the size and distance between ports.
 * 
 * @author Robin Weiss, Florian Fittkau
 * 
 */
public class Graph {

	// some global layouting settings for KIELER nodes
	public static final String EDGE_ROUTING = "ORTHOGONAL";
	public static final boolean LAYOUT_HIERARCHY = false;
	public static final String PORT_CONSTRAINTS = "FIXED_POS";

	/**
	 * Determines the size of every {@link Port}, connected to a {@link Node}.
	 * The width of a port, as well as the vertical distance between two ports of the same category
	 * is 2 times this size.
	 */
	private final int portHeight;
	private final KNode kielerGraph;
	private final List<Node> nodes;
	private final List<Edge> edges;

	/**
	 * Class constructor. Creates empty lists for future {@link Node}s and {@link Edge}s, and
	 * a parent {@link KNode} for all added nodes.
	 * 
	 * @param scale
	 *            the scaling factor for ports
	 */
	public Graph(final int scale) {
		this.portHeight = scale;
		this.nodes = new ArrayList<Node>();
		this.edges = new ArrayList<Edge>();
		this.kielerGraph = KielerInterface.makeKielerGraph();
	}

	/**
	 * Adds a {@link Node} to the list of {@link Node}s.
	 * 
	 * @param node
	 *            the added node
	 */
	public void addNode(final Node node) {
		this.nodes.add(node);
	}

	/**
	 * Adds an {@link Edge} to the list of {@link Edge}s.
	 * 
	 * @param edge
	 *            the added edge
	 */
	public void addEdge(final Edge edge) {
		this.edges.add(edge);
	}

	public static String getEdgeRouting() {
		return EDGE_ROUTING;
	}

	public static boolean isLayoutHierarchy() {
		return LAYOUT_HIERARCHY;
	}

	public static String getPortConstraints() {
		return PORT_CONSTRAINTS;
	}

	public int getPortHeight() {
		return this.portHeight;
	}

	public KNode getKielerGraph() {
		return this.kielerGraph;
	}

	public List<Node> getNodes() {
		return this.nodes;
	}

	public List<Edge> getEdges() {
		return this.edges;
	}

	/**
	 * Looks for a {@link Node} with a specific id in the list of {@link Node}s.
	 * 
	 * @param id
	 *            the id string of a node
	 * @return
	 *         the {@link Node} if it exists, or null if it does not exist
	 */
	public Node getNode(final String id) {
		for (final Node n : this.nodes) {
			if (n.getId().equals(id)) {
				return n;
			}
		}
		return null;
	}
}
