/*
 * FSTransform.java
 * Transform
 * 
 * Copyright (c) 2001-2008 Flagstone Software Ltd. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution.
 *  * Neither the name of Flagstone Software Ltd. nor the names of its contributors 
 *    may be used to endorse or promote products derived from this software 
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.flagstone.transform;

import java.util.*;

/**
 * The %Transform class defines constants and methods used throughout the
 * %Transform package.
 */
public class Transform
{
	/**
	 * @deprecated No longer required for debugging.
	 * 
	 * DEBUG is used to turn on additional logging and error checking.
	 */
	public static final boolean DEBUG = false;

	/**
	 * VERSION is used to identify the version of Flash that the edition
	 * supports.
	 */
	public static final int VERSION = 7;

	/**
	 * MAJOR is used to identify the current version of the framework. This is
	 * incremented for each new version of Flash supported.
	 */
	public static final int MAJOR = 2;

	/**
	 * MINOR is used to identify the current minor version of the framework.
	 * This is incremented when new functionality is added or API changes are
	 * made.
	 */
	public static final int MINOR = 3;

	/**
	 * The RELEASE number is used to differentiate between different releases.
	 * This number is incremented when an enhancement or bug fix has been made
	 * and the API is unchanged.
	 */
	public static final int RELEASE = 0;

	/**
	 * VALUE_NOT_SET is used to signify that a field has not yet assigned a
	 * value. Some Flash tags contain optional fields to reduce the size of the
	 * binary data when a tag is encoded. These fields are only encoded if they
	 * have been assigned a valid value. The range of valid values will depend
	 * on the number of bits used to encode the field and whether it is a signed
	 * or unsigned value. VALUE_NOT_SET was chosen to be the largest negative
	 * integer - since the largest optional field is 16-bits in length and thus
	 * no confusion will result.
	 */
	public static final int VALUE_NOT_SET = Integer.MIN_VALUE;

	/**
	 * The main method reports basic information about the package. The method
	 * prints out the version of Flash supported and the version number along
	 * with copyright and licensing information.
	 */
	public static void main(String args[])
	{
		String version = MAJOR + "." + MINOR + "." + RELEASE;

		System.out.println("/**");

		System.out.println(" * Transform For Flash " + VERSION + ", Version "
						+ version);

		System.out.println(" * ");
		System.out
						.println(" * Copyright (c) Flagstone Software Limited, 2001-2008.");
		System.out.println(" * All Rights Reserved.");
		System.out.println(" * ");
		System.out
						.println(" * Use of this software is subject to the terms in the license");
		System.out.println(" * that accompanied the software.");
		System.out.println(" * ");
		System.out.println(" */");
	}

	static void append(StringBuffer buffer, String name, int value)
	{
		buffer.append(name);
		buffer.append(" = ");

		if (value == Transform.VALUE_NOT_SET)
			buffer.append("<Value Not Set>");
		else
			buffer.append(value);

		buffer.append("; ");
	}

	static void append(StringBuffer buffer, String name, boolean value)
	{
		buffer.append(name);
		buffer.append(" = ");
		buffer.append(value);
		buffer.append("; ");
	}

	static void append(StringBuffer buffer, String name, float value)
	{
		buffer.append(name);
		buffer.append(" = ");
		buffer.append(value);
		buffer.append("; ");
	}

	static void append(StringBuffer buffer, String name, String value)
	{
		if (value == null)
			value = "null; ";
		else if (value.equals("<data>"))
			value = value + "; ";
		else
			value = '"' + value + "\"; ";

		buffer.append(name);
		buffer.append(" = ");
		buffer.append(value);
	}

	static void append(StringBuffer buffer, String name,
						FSTransformObject anObject, int indentLevel)
	{
		buffer.append(name);
		buffer.append(" = ");

		if (anObject != null)
		{
			if (indentLevel > 0)
				anObject.appendDescription(buffer, indentLevel - 1);
			else
				buffer.append(anObject.name());
		} else
		{
			buffer.append("null");
		}
		buffer.append("; ");
	}

	static void append(StringBuffer buffer, String name, ArrayList anArray,
						int indentLevel)
	{
		buffer.append(name);
		buffer.append(" = ");

		if (anArray != null)
		{
			buffer.append("Array(");
			buffer.append(anArray.size());
			buffer.append(") [ ");

			for (Iterator j = anArray.iterator(); j.hasNext();)
			{
				Object currentElement = j.next();

				if (currentElement instanceof FSTransformObject)
				{
					FSTransformObject object = (FSTransformObject) currentElement;

					if (indentLevel > 0)
						object.appendDescription(buffer, indentLevel - 1);
					else
						buffer.append(object.name());
				} else if (currentElement instanceof String)
				{
					buffer.append('"');
					buffer.append(currentElement.toString());
					buffer.append('"');
				} else
					buffer.append(currentElement.toString());

				if (j.hasNext())
					buffer.append(',');

				buffer.append(' ');
			}
			buffer.append("]; ");
		} else
		{
			buffer.append("null; ");
		}
	}

	static void append(StringBuffer buffer, String name, Hashtable table,
						int indentLevel)
	{
		buffer.append(name);
		buffer.append(" = ");

		if (table != null)
		{
			buffer.append("Table (");
			buffer.append(table.size());
			buffer.append(")");

			if (indentLevel > 0)
			{
				buffer.append(" {");

				for (Enumeration e = table.keys(); e.hasMoreElements();)
				{
					Object key = e.nextElement();
					Object value = table.get(key);

					buffer.append(key);
					buffer.append(" = ");

					if (value instanceof FSTransformObject)
						((FSTransformObject) value).appendDescription(buffer,
										indentLevel - 1);
					else if (value instanceof String)
					{
						buffer.append('"');
						buffer.append(value.toString());
						buffer.append('"');
					} else
						buffer.append(value.toString());

					if (e.hasMoreElements())
						buffer.append(',');

					buffer.append(' ');
				}
			}
			buffer.append("} ");
		} else
		{
			buffer.append("null");
		}
	}

	static boolean equals(byte[] b1, byte[] b2)
	{
		boolean result = false;

		if (b1 == null && b2 == null)
			return true;

		if (b1 != null && b2 != null)
		{
			result = b1.length == b2.length;

			if (result)
				for (int i = 0; i < b1.length; i++)
					if (b1[i] != b2[i])
						result = false;
		}
		return result;
	}

	static byte[] clone(byte[] data)
	{
		byte[] newData = null;

		if (data != null)
		{
			newData = new byte[data.length];

			for (int i = 0; i < data.length; i++)
				newData[i] = data[i];
		}
		return newData;
	}
}
