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

/**
 * The FSGetUrl2 action is used to either load a web page or movie clip or load
 * or submit variable values to/from a server.
 * 
 * <p>
 * It extends the functionality provided by the FSGetUrl action by allowing the
 * variables defined in a movie to be submitted as form values to a server.
 * Variables defined in a movie can also be initialised by loading a file
 * containing variable name / value assignments.
 * </p>
 * 
 * <table class="datasheet">
 * 
 * <tr>
 * <th align="left" colspan="2">Attributes</th>
 * </tr>
 * 
 * <tr>
 * <td>type</td>
 * <td>Identifies the action when it is encoded. Read-only.</td>
 * </tr>
 * 
 * <tr>
 * <td>requestType</td>
 * <td>The type of request generated by the action.</td>
 * </tr>
 * </table>
 * 
 * <p>
 * FSGetUrl2 is a stack-based action, however the type of request being
 * submitted to the server is defined by the requestType attribute. Two
 * arguments, <i>url</i> and <i>target/level</i> are popped from the stack.
 * The <i>url</i> is the first argument popped from the stack and is a fully
 * qualified uniform resource location where the movie clip or web page will be
 * retrieved from. The second argument is either a <i>target</i> - the name of
 * a specific movie clip, e.g. _root.movieClip or the name of a level in the
 * main movie into which a movie clip has been loaded, e.g. _level1.
 * </p>
 * 
 * <p>
 * <b>Request Types</b><br/> The <i>request type</i> is specified as an
 * attribute of the FSGetUrl2 action. Whether a new web page, movie clip or
 * variable values are loaded is specified by the following types of request:
 * </p>
 * 
 * <table class="datasheet">
 * <tr>
 * <th align="left">Type of Request</th>
 * <th align="left">Description</th>
 * </tr>
 * 
 * <tr>
 * <td>MovieToLevel</td>
 * <td>Load a movie to the specified level.</td>
 * </tr>
 * <tr>
 * <td>MovieToLevelWithGet</td>
 * <td>Load a movie submitting the movie variables using the HTTP GET method.</td>
 * </tr>
 * <tr>
 * <td>MovieToLevelWithPost</td>
 * <td>Load a movie submitting the movie variables using the HTTP POST method.</td>
 * </tr>
 * 
 * <tr>
 * <td>MovieToTarget</td>
 * <td>Load a new Flash movie or web page to the specified target.</td>
 * </tr>
 * <tr>
 * <td>MovieToTargetWithGet</td>
 * <td>Load a new Flash movie or web page to the specified target, submitting
 * the movie variables using the HTTP GET method.</td>
 * </tr>
 * <tr>
 * <td>MovieToTargetWithPost</td>
 * <td>Load a new Flash movie or web page to the specified target, submitting
 * the movie variables using the HTTP POST method.</td>
 * </tr>
 * 
 * <tr>
 * <td>VariablesToLevel</td>
 * <td>Load values for selected movie variables to the specified level.</td>
 * </tr>
 * <tr>
 * <td>VariablesToLevelWithGet</td>
 * <td>Load values for selected movie variables to the specified level,
 * submitting the movie variables using the HTTP GET method.</td>
 * </tr>
 * <tr>
 * <td>VariablesToLevelWithPost</td>
 * <td>Load values for selected movie variables to the specified level,
 * submitting the movie variables using the HTTP POST method.</td>
 * </tr>
 * 
 * <tr>
 * <td>VariablesToTarget</td>
 * <td>Load values for selected movie variables to the specified level.</td>
 * </tr>
 * <tr>
 * <td>VariablesToTargetWithGet</td>
 * <td>Load values for selected movie variables to the specified target,
 * submitting the movie variables using the HTTP GET method.</td>
 * </tr>
 * <tr>
 * <td>VariablesToTargetWithPost</td>
 * <td>Load values for selected movie variables to the specified target,
 * submitting the movie variables using the HTTP POST method.</td>
 * </tr>
 * </table>
 * 
 * <p>
 * When variables are submitted they are encoded using standard x-www-urlencoded
 * encoding.
 * </p>
 * 
 * <p>
 * <b>Targets</b><br/> The <i>target</i> can either be the name of the frame
 * can be one of the following reserved words:
 * </p>
 * 
 * <ul>
 * <li><code>"name"</code> opens the new page in the frame with the name
 * defined in the HTML &lt;frame&gt; tag.</li>
 * <li><code>_blank</code> opens the new page in a new window.</li>
 * <li><code>_self</code> opens the new page in the current window.</li>
 * <li><code>_top</code> opens the new page in the top level frame of the
 * current window.</li>
 * <li><code>_parent</code> opens the new page in the parent frame of the
 * frame where the Flash Player id displayed.</li>
 * <li><code>""</code> (blank string) opens the new page in the current frame
 * or window.</li>
 * </ul>
 * 
 * <p>
 * <b>Levels</b><br/> Levels are virtual layers (analogous to the layers in
 * the Display List). Higher levels are displayed in front of lower levels. The
 * background of each level is transparent allowing movie clips on lower levels
 * to be visible in areas not filled by the movie clip on a given level. The
 * main movie is loaded into level 0. Movie clips are loaded into any level
 * above this (1, 2, 124, etc.). If a movie clip is loaded into a level that
 * already contains a movie clip then the existing clip is replaced by the new
 * one. The level follows the general form: "_level<i>n</i>" loads a movie
 * clip into the current movie at level <i>n</i>.
 * </p>
 * 
 * <h1 class="datasheet">Examples</h1>
 * 
 * <p>
 * Display a movie in the named frame:
 * </p>
 * 
 * <pre>
 * FSDoAction frameActions = new FSDoAction();
 * 
 * // Push the target followed by the url
 * 
 * frameActions.add(new FSPush(&quot;http://www.server.com/movie.swf&quot;));
 * frameActions.add(new FSPush(&quot;aFrame&quot;));
 * frameActions.add(new FSGetUrl2(FSGetUrl2.MovieToTarget));
 * </pre>
 * 
 * <p>
 * Load a movie clip into the current movie at level 1:
 * </p>
 * 
 * <pre>
 * frameActions.add(new FSPush(&quot;http://www.server.com/movieClip.swf&quot;));
 * frameActions.add(new FSPush(&quot;_level1&quot;));
 * frameActions.add(new FSGetUrl2(FSGetUrl2.MovieToLevel));
 * </pre>
 * 
 * <p>
 * Submit the value of a variable as an argument to a server script:
 * </p>
 * 
 * <pre>
 * // Set the variable
 * 
 * frameActions.add(new FSPush(&quot;MyVariable&quot;));
 * frameActions.add(new FSPush(23));
 * frameActions.add(FSAction.SetVariable());
 * 
 * // Submit it to the server script
 * 
 * frameActions.add(new FSPush(&quot;http://www.server.com/cgi-bin/form.php&quot;));
 * frameActions.add(new FSPush(&quot;&quot;));
 * frameActions.add(new FSGetUrl2(FSGetUrl2.VariablesToTargetWithPost));
 * </pre>
 * 
 * <p>
 * Initialise the variables in a movie clip using name/value pairs returned from
 * a server script:
 * </p>
 * 
 * <pre>
 * 
 * // Specify the level where the movie clip is loaded.
 * 
 * frameActions.add(new FSPush(&quot;http://www.server.com/cgi-bin/form.php&quot;));
 * frameActions.add(new FSPush(&quot;_level1&quot;));
 * frameActions.add(new FSGetUrl2(FSGetUrl2.VariablesToLevelWithGet));
 * </pre>
 * 
 * <h1 class="datasheet">History</h1>
 * 
 * <p>
 * The FSGetUrl2 is a class for representing the ActionGetUrl2 action of the
 * Macromedia Flash (SWF) File Format Specification. It was introduced in Flash
 * 4.
 * </p>
 */
public class FSGetUrl2 extends FSActionObject
{
	/** Load a movie without submitting the movie variables. */
	public static final int MovieToLevel = 0;

	/** Load a movie submitting the movie variables using HTTP GET. */
	public static final int MovieToLevelWithGet = 1;

	/** Load a movie submitting the movie variables using HTTP POST. */
	public static final int MovieToLevelWithPost = 2;

	/** Load a movie or web page without submitting the movie variables. */
	public static final int MovieToTarget = 64;

	/** Load a movie or web page submitting the movie variables using HTTP GET. */
	public static final int MovieToTargetWithGet = 65;

	/** Load a movie or web page submitting the movie variables using HTTP POST. */
	public static final int MovieToTargetWithPost = 66;

	/** Load variables without submitting the movie variables. */
	public static final int VariablesToLevel = 128;

	/** Load variables submitting the movie variables using HTTP GET. */
	public static final int VariablesToLevelWithGet = 129;

	/** Load variables submitting the movie variables using HTTP POST. */
	public static final int VariablesToLevelWithPost = 130;

	/** Load variables without submitting the movie variables. */
	public static final int VariablesToTarget = 192;

	/** Load variables submitting the movie variables using HTTP GET. */
	public static final int VariablesToTargetWithGet = 193;

	/** Load variables submitting the movie variables using HTTP POST. */
	public static final int VariablesToTargetWithPost = 194;

	private int requestType = MovieToLevel;

	/**
	 * Construct an FSGetUrl2 object, initialising it with values decoded from an
	 * encoded object.
	 * 
	 * @param coder
	 *            an FSCoder containing the binary data.
	 */
	public FSGetUrl2(FSCoder coder)
	{
		super(GetUrl2);
		decode(coder);
	}

	/**
	 * Constructs an FSGetUrl2 using the specified request type.
	 * 
	 * @param aType
	 *            the type of request to be performed. Must be one of the
	 *            constants defined in this class.
	 */
	public FSGetUrl2(int aType)
	{
		super(GetUrl2);
		setRequestType(aType);
	}

	/**
	 * Constructs an FSGetUrl2 object by copying values from an existing object.
	 * 
	 * @param obj
	 *            an FSGetUrl2 object.
	 */
	public FSGetUrl2(FSGetUrl2 obj)
	{
		super(obj);
		requestType = obj.requestType;
	}

	/**
	 * Gets the request type.
	 * 
	 * @return the type of request to be performed.
	 */
	public int getRequestType()
	{
		return requestType;
	}

	/**
	 * Sets the request type.
	 * 
	 * @param aType
	 *            the type of request to be performed. Must be one of the
	 *            constants defined in this class.
	 */
	public void setRequestType(int aType)
	{
		requestType = aType;
	}

	public boolean equals(Object anObject)
	{
		boolean result = false;

		if (super.equals(anObject))
			result = requestType == ((FSGetUrl2) anObject).getRequestType();

		return result;
	}

	public void appendDescription(StringBuffer buffer, int depth)
	{
		buffer.append(name());

		if (depth > 0)
		{
			buffer.append(": { ");
			Transform.append(buffer, "requestType", requestType);
			buffer.append("}");
		}
	}

	public int length(FSCoder coder)
	{
		super.length(coder);

		length += 1;

		return length;
	}

	public void encode(FSCoder coder)
	{
		super.encode(coder);
		coder.writeWord(requestType, 1);
		coder.endObject(name());
	}

	public void decode(FSCoder coder)
	{
		super.decode(coder);
		requestType = coder.readWord(1, false);
		coder.endObject(name());
	}
}
