/***************************************************************************
 * 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.converter;

import kieker.webgui.service.impl.utility.model.Edge;
import kieker.webgui.service.impl.utility.model.Graph;
import kieker.webgui.service.impl.utility.model.Node;
import kieker.webgui.service.impl.utility.model.Point;

/**
 * This class provides procedures for converting a {@link Graph} back to a single string.
 * 
 * @author Robin Weiss, Nils Christian Ehmke, Florian Fittkau
 * 
 */
public final class ResultStringConverter {

	private ResultStringConverter() {
		// No code necessary
	}

	/**
	 * Converts a {@link Graph} to a string.
	 * 
	 * @param graph
	 *            the {@link Graph} that is to be converted
	 * @return
	 *         the string representation of the graph
	 * @see GraphLayoutService
	 */
	public static String convertLayoutedGraphToString(final Graph graph) {
		final StringBuilder sb = new StringBuilder("autoLayout#");

		final String nodes = ResultStringConverter.getStringFromNodes(graph);
		final String edges = ResultStringConverter.getStringFromEdges(graph);

		sb.append(nodes).append('#').append(edges);
		return sb.toString();
	}

	/**
	 * Iterates all {@link Node}s from a {@link Graph} and writes the position of
	 * the center of the nodes as well as their id and size to a semicolon separated string.
	 * 
	 * @param graph
	 *            the {@link Graph} of which the nodes are converted
	 * @return
	 *         a semicolon separated string of node information
	 * @see GraphLayoutService
	 */
	private static String getStringFromNodes(final Graph graph) {
		final StringBuilder sb = new StringBuilder();

		for (final Node node : graph.getNodes()) {
			sb.append(node.getId()).append(' ');
			sb.append(node.getPosition().getX() + (node.getWidth() / 2)).append(' ');
			sb.append(node.getPosition().getY() + (node.getHeight() / 2)).append(' ');
			sb.append(node.getWidth()).append(' ');
			sb.append(node.getHeight()).append(';');
		}

		return sb.toString();
	}

	/**
	 * Iterates all {@link Edge}s from a {@link Graph} and writes the position of
	 * the bendpoints of the nodes as well as their source and targets to a semicolon separated string.
	 * 
	 * @param graph
	 *            the {@link Graph} of which the edges are converted
	 * @return
	 *         a semicolon separated string of edge information
	 * @see GraphLayoutService
	 */
	private static String getStringFromEdges(final Graph graph) {
		final StringBuilder sb = new StringBuilder();

		for (final Edge edge : graph.getEdges()) {

			String sP = "-1";
			if (edge.hasSourcePort()) {
				sP = String.valueOf(edge.getSourcePort().getIndex());
			}
			String tP = "-1";
			if (edge.hasTargetPort()) {
				tP = String.valueOf(edge.getTargetPort().getIndex());
			}

			sb.append(edge.getSource().getId()).append(' ');
			sb.append(sP).append(' ');
			sb.append(edge.getTarget().getId()).append(' ');
			sb.append(tP);

			for (final Point bendPoint : edge.getBendPoints()) {
				sb.append(' ');
				sb.append(bendPoint.getX());
				sb.append(' ');
				sb.append(bendPoint.getY());
			}
			sb.append(';');
		}

		return sb.toString();
	}
}
