//****************************************************************************
//Copyright (C) 2004-2005 Macromedia, Inc. All Rights Reserved.
//The following is Sample Code and is subject to all restrictions on
//such code as contained in the End User License Agreement accompanying
//this product.
//****************************************************************************

import mx.utils.Delegate;
import mx.video.*;

/**
 * <p>Handles downloading and parsing fpad xml format for
 * mx.video.NCManager.  This xml format is generated by FMS 2.0.</p>
 */

class mx.video.FPADManager {

	#include "ComponentVersion.as"

	// INCManager to ping when done
	private var _owner:INCManager;

	// fpad support
	public var xml:XML;
	public var rtmpURL:String;

	private var _url:String;
	private var _uriParam:String;
	private var _parseResults:Object;

	private static var ELEMENT_NODE:Number = 1;
	private static var TEXT_NODE:Number = 3;

	/**
	 * constructor
	 */
	public function FPADManager(owner:INCManager) {
		_owner = owner;
	} 

	/**
	 * <p>Starts download of XML file.  Will be parsed and based
	 * on that we will decide how to connect.</p>
	 *
	 * @private
	 */
	public function connectXML( urlPrefix:String, uriParam:String, urlSuffix:String,
	                            uriParamParseResults:Object ):Boolean {
		// init instance vars
		_uriParam = uriParam;
		_parseResults = uriParamParseResults;

		// put URL together
		_url = urlPrefix + "uri=" + _parseResults.protocol;
		if (_parseResults.serverName != undefined) {
			_url += "/" + _parseResults.serverName;
		}
		if (_parseResults.portNumber != undefined) {
			_url += ":" + _parseResults.portNumber;
		}
		if (_parseResults.wrappedURL != undefined) {
			_url += "/?" + _parseResults.wrappedURL;
		}
		_url += "/" + _parseResults.appName;
		_url += urlSuffix;
		//ifdef DEBUG
		//_owner.debugTrace("FPAD download xml url: " + _url);
		//endif

		xml = new XML();
		xml.onLoad = Delegate.create(this, this.xmlOnLoad);
		xml.load(_url);
		return false;
	}

	/**
	 * <p>Handles load of XML.
	 *
	 * @private
	 */
	private function xmlOnLoad(success:Boolean):Void {
		try {
			if (!success) {
				// signal failure
				_owner.helperDone(this, false);
			} else {
				// find parent node
				var parentNode:XMLNode = xml.firstChild;
				var foundNode:Boolean = false;
				while (parentNode != null) {
					if (parentNode.nodeType == ELEMENT_NODE) {
						foundNode = true;
						if (parentNode.nodeName.toLowerCase() == "fpad") break;
					}
					parentNode = parentNode.nextSibling;
				}
				if (!foundNode) {
					throw new VideoError(VideoError.INVALID_XML, "URL: \"" + _url + "\" No root node found; if url is for an flv it must have .flv extension and take no parameters");
				} else if (parentNode == null) {
					throw new VideoError(VideoError.INVALID_XML, "URL: \"" + _url + "\" Root node not fpad");
				}

				// extract proxy info
				var proxy:String = undefined;
				for (var i:Number = 0; i < parentNode.childNodes.length; i++) {
					var node:XMLNode = parentNode.childNodes[i];
					if (node.nodeType != ELEMENT_NODE) continue;
					if (node.nodeName.toLowerCase() == "proxy") {
						for (var j:Number = 0; j < node.childNodes.length; j++) {
							var childNode:XMLNode = node.childNodes[j];
							if (childNode.nodeType == TEXT_NODE) {
								proxy = trim(childNode.nodeValue);
								break;
							} // if TEXT_NODE
						} // for
						break;
					} // if "proxy"
				} // for

				// throw error if no proxy info
				if (proxy == undefined || proxy == "") {
					throw new VideoError(VideoError.INVALID_XML, "URL: \"" + _url + "\" fpad xml requires proxy tag.");
				}

				// assemble new uri
				rtmpURL = _parseResults.protocol + "/" + proxy + "/?" + _uriParam;

				//ifdef DEBUG
				//debugTrace("PROXY IS " + proxy);
				//debugTrace("ORIGURI IS " + _uriParam);
				//debugTrace("NEWURI IS " + rtmpURL);
				//endif

				_owner.helperDone(this, true);
			}
		} catch (err:Error) {
			_owner.helperDone(this, false);
			throw err;
		}
	}

	/**
	 * strip off leading and trailing whitespace
	 *
	 * @private
	 */
	private function trim(str:String):String {
		var first:Number = 0;
		while (first < str.length) {
			var theChar:String = str.charAt(first);
			if ( theChar != " " && theChar != "\t" && theChar != "\r" && theChar != "\n" ) {
				break;
			}
			first++;
		}
		if (first >= str.length) return "";
		var last:Number = str.length - 1;
		while (last > first) {
			var theChar:String = str.charAt(last);
			if ( theChar != " " && theChar != "\t" && theChar != "\r" && theChar != "\n" ) {
				break;
			}
			last--;
		}
		return str.slice(first, last + 1);
	}
}
