/*

 * Delivered to the U.S. Government in Accordance with Contract FA8650-10-C-7080.

 *

 * EXPORT CONTROLLED

 * ECCN#   EAR99

 * Warning: This document contains technical data which is controlled under the

 * Bureau of Industry & Security's Export Administration Regulations and may not be

 * exported or re-exported without authorization by the Bureau of Industry & Security.

 * Diversion contrary to US law is prohibited.

 *

 * (c) 2011 United Technologies Corp.

 * Developed with the sponsorship of the Defense Advanced Research Projects Agency (DARPA).

 *

 * Permission is hereby granted, free of charge, to any person obtaining a copy of this data,

 * including any software or models in source or binary form, as well as any drawings, 

 * specifications, and documentation (collectively "the Data"), to deal in the Data without 

 * restriction, including without limitation the rights to use, copy, modify, merge, publish,

 * distribute, sublicense, and/or sell copies of the Data, and to permit persons to whom the Data

 * is furnished to do so, subject to the following conditions:

 * 

 * The above copyright notice and this permission notice shall be included in all copies or

 * substantial portions of the Data.

 *

 * THE DATA IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING

 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS, SPONSORS, DEVELOPERS, CONTRIBUTORS, OR

 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION

 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE DATA OR THE

 * USE OR OTHER DEALINGS IN THE DATA.

*/



package aee.engine;



import java.util.ArrayList;

import java.util.List;



import org.jdom.Attribute;

import org.jdom.Element;



import aee.exception.AeeException;

import aee.util.StringUtils;





/**

 * Object representation of an input or output table. This is incarnated as a 

 * CSV file

 */

public class InOutTable extends TypedObject {

	private int[]          order;

	private List<FlowDest> flows;



	/**

	 * Constructor builds an input or output table from XML 

	 * @param root The root element

	 * @param expectedName  Expected name for the root element

	 * @throws AeeException if any unexpected XML errors detected

	 */

	@SuppressWarnings("unchecked")

	public InOutTable(Element root, String expectedName) throws AeeException {

		super(root, expectedName);

		order = null;

		flows = null;

			

		// There must be device order attribute defined

		List<Attribute> attributes = root.getAttributes();

		for (Attribute attribute : attributes) {

			String attName = attribute.getName();

			String value   = attribute.getValue().trim();

			

			if (attName.equalsIgnoreCase("deviceOrder")) {

				

				// The deviceOrder is a list in the format "i,j,k,..."

				String[] tokens = StringUtils.split(value,",");

				if (tokens.length == 0)

					throw new AeeException("Empty deviceOrder value on a \"%s\" element", 

                                  expectedName);

				

				order = new int[tokens.length];

				for (int i = 0; i < tokens.length; i++) {

					String token = tokens[i].trim();

					try {

						if ("".equals(token))

							throw new AeeException("Missing deviceOrder value %d on %s element",

									                   (i+1), expectedName);

						order[i] = Integer.parseInt(token);

						

					} catch (NumberFormatException nfex) {

						throw new AeeException("Illegal deviceOrder value %d \"%s\" on %s element",

								                   (i+1), token, expectedName);

					}

				}

			

			} else {

				throw new AeeException("Unrecognized attribute \"%s\" on a \"%s\" element",

						                   attName, expectedName);

			}

		}

		

		if (order == null)

			throw new AeeException("Missing deviceOrder on a \"%s\" element", 

					                   expectedName);

		

		// Each child must be a flow destination element

		List<Element> children = root.getChildren();

		flows                  = new ArrayList<FlowDest>(children.size());

		for (Element child : children) {

			flows.add(new FlowDest(child));

		}

	}



	/**

	 * Report all flows in the table

	 * @return A list of the flows

	 */

	public List<FlowDest> getFlows() {

		return new ArrayList<FlowDest>(flows);

	}



	/**

	 * Report the device order

	 * @return The device order

	 */

	public int[] getDeviceOrder() {

		int[] out = new int[order.length];

		System.arraycopy(order, 0, out, 0, order.length);

		return out;

	}

}

