/**
 * @author rrobinson
 */

/* Code extracted from JavaScript the Definitive Guide - 5th Edition (modified slightly)*/

/**
 * Create a new Document object. If no arguments are specified,
 * the document will be empty. If a root tag is specified, the document
 * will contain that single root tag. If the root tag has a namespace
 * prefix, the second argument must specify the URL that identifies the
 * namespace.
 */

var com;

if (!com){
	com = {};
}else if (typeof com != "object"){
	throw Error("com already exists and is not an object!")
}

if (!com.fandango){
	com.fandango = {};
}else if (typeof com.fandango != "object"){
	throw Error("com.fandango already exists and is not an object!")
}

if (com.fandango.XML){
	throw Error("com.fandango.XML already exists!");
}
com.fandango.XML = {
newDocument : function(rootTagName, namespaceURL) {
    if (!rootTagName) rootTagName = "";
    if (!namespaceURL) namespaceURL = "";

    if (document.implementation && document.implementation.createDocument) {
        // This is the W3C standard way to do it
        return document.implementation.createDocument(namespaceURL,
                                                      rootTagName, null);
    }
    else { // This is the IE way to do it
        // Create an empty document as an ActiveX object
        // If there is no root element, this is all we have to do
        var doc = new ActiveXObject("MSXML2.DOMDocument");

        // If there is a root tag, initialize the document
        if (rootTagName) {
            // Look for a namespace prefix
            var prefix = "";
            var tagname = rootTagName;
            var p = rootTagName.indexOf(':');
            if (p != -1) {
                prefix = rootTagName.substring(0, p);
                tagname = rootTagName.substring(p + 1);
            }

            // If we have a namespace, we must have a namespace prefix
            // If we don't have a namespace, we discard any prefix
            if (namespaceURL) {
                if (!prefix) prefix = "a0"; // What Firefox uses
            }
            else prefix = "";

            // Create the root element (with optional namespace) as a
            // string of text
            var text = "<" + (prefix?(prefix+":"):"") +  tagname +
                (namespaceURL
                 ?(" xmlns:" + prefix + '="' + namespaceURL +'"')
                 :"") +
                "/>";
            // And parse that text into the empty document
            doc.loadXML(text);
        }
        return doc;
    }
},

/**
 * Synchronously load the XML document at the specified URL and
 * return it as a Document object
 */
load : function(url) {
    // Create a new document with the previously defined function
    var xmldoc = com.fandango.XML.newDocument( );
    xmldoc.async = false;  // We want to load synchronously
    xmldoc.load(url);      // Load and parse
    return xmldoc;         // Return the document
},

/**
 * Asynchronously load and parse an XML document from the specified URL.
 * When the document is ready, pass it to the specified callback function.
 * This function returns immediately with no return value.
 */
loadAsync : function(url, callback) {
    var xmldoc = com.fandango.XML.newDocument( );

    // If we created the XML document using createDocument, use
    // onload to determine when it is loaded
    if (document.implementation && document.implementation.createDocument) {
        xmldoc.onload = function( ) { callback(xmldoc); };
    }
    // Otherwise, use onreadystatechange as with XMLHttpRequest
    else {
        xmldoc.onreadystatechange = function( ) {
            if (xmldoc.readyState == 4) callback(xmldoc);
        };
    }

    // Now go start the download and parsing
    xmldoc.load(url);
},

/**
 * Parse the XML document contained in the string argument and return
 * a Document object that represents it.
 */
parse : function(text) {
    if (typeof DOMParser != "undefined") {
        // Mozilla, Firefox, and related browsers
        return (new DOMParser( )).parseFromString(text, "application/xml");
    }
    else if (typeof ActiveXObject != "undefined") {
        // Internet Explorer.
        var doc = com.fandango.XML.newDocument( );  // Create an empty document
        doc.loadXML(text);            // Parse text into it
        return doc;                   // Return it
    }
    else {
        // As a last resort, try loading the document from a data: URL
        // This is supposed to work in Safari. Thanks to Manos Batsis and
        // his Sarissa library (sarissa.sourceforge.net) for this technique.
        var url = "data:text/xml;charset=utf-8," + encodeURIComponent(text);
        var request = new XMLHttpRequest( );
        request.open("GET", url, false);
        request.send(null);
        return request.responseXML;
    }
},

/**
 * Return a Document object that holds the contents of the <xml> tag 

 * with the specified id. If the <xml> tag has a src attribute, an XML
 * document is loaded from that URL and returned instead.
 *
 * Since data islands are often looked up more than once, this function caches
 * the documents it returns.
 */
getDataIsland : function(id) {
    var doc;

    // Check the cache first
    doc = com.fandango.XML.getDataIsland.cache[id];
    if (doc) return doc;

    // Look up the specified element
    doc = document.getElementById(id);

    // If there is a "src" attribute, fetch the Document from that URL
    var url = doc.getAttribute('src');
    if (url) {
        doc = com.fandango.XML.load(url);
    }
    // Otherwise, if there was no src attribute, the content of the <xml>
    // tag is the document we want to return. In Internet Explorer, doc is
    // already the document object we want. In other browsers, doc refers to
    // an HTML element, and we've got to copy the content of that element
    // into a new document object
    else if (!doc.documentElement) {// If this is not already a document...

        // First, find the document element within the <xml> tag. This is
        // the first child of the <xml> tag that is an element, rather
        // than text, comment, or processing instruction
        var docelt = doc.firstChild;
        while(docelt != null) {
            if (docelt.nodeType == 1 /*Node.ELEMENT_NODE*/) break;
            docelt = docelt.nextSibling;
        }

        // Create an empty document
        doc = com.fandango.XML.newDocument( );

        // If the <xml> node had some content, import it into the new document
        if (docelt) doc.appendChild(doc.importNode(docelt, true));
    }

    // Now cache and return the document
    com.fandango.XML.getDataIsland.cache[id] = doc;
    return doc;
},
getDataIsland: {cache : {}} // Initialize the cache
};

/**
 * This method will extract the children of the XML tag named tagname into a JavaScript Object
 * 
 * @param {string} tagName -	the name of the tag to extract into a JavaScript Object
 * @param {Object} doc	- this is the doc retrieved by com.fandango.XML.parse()
 */
com.fandango.getXMLObject = function(tagName, doc){
	var result = {};
	var objs = doc.getElementsByTagName(tagName);
	if (objs[0].childNodes.length > 0)
	{
		var children = objs[0].childNodes;
		for(var i=0; i < children.length; i++){
			var child = children[i];
			if (child.firstChild != null){
				result[child.nodeName] = child.firstChild.data; // assuming 1st and only child 	
			}
		}
	}
	return result;
};

com.fandango.dumpObj = function(obj){
	var text = '<p>';
	for(var prop in obj)
	{
		switch(typeof obj[prop]){
			case 'string': text +=  prop + ": " + obj[prop] + "<br/>";
							break;
			case 'object': text +=  prop + ": " + arguments.callee(obj[prop]) + "<br/>";
							break;
		}
	}
	text += '</p>'
	document.write(text);
};

/**
 * A very basic trace function which uses document.write
 * 
 * @param {string} str - string to write to document
 */
com.fandango.trace = function(str){
	document.write(str + "<br/>");
}

/**
 * This function will return an array of objects each representing a <video> element from the
 * playlist XML.
 * 
 * @param {Object} xmldoc	XML document created using com.fandango.XML.parse()
 */
com.fandango.getVideoObjects = function(xmldoc)
{
	var result = [];
	var videos = xmldoc.getElementsByTagName("video"); // get all the video elements|nodes
	for (var i=0; i < videos.length; i++)
	{
		// map each video element|node to an Object
		var obj = {}
		if (videos[i].childNodes.length > 0)
		{
			var children = videos[i].childNodes;
			for(var j=0; j < children.length; j++){
				var child = children[j]; // jth child
				
				// if the child has children
				if (child.childNodes.length > 0)
				{
					obj[child.nodeName] = child.firstChild.data; // assuming 1st and only child; can be undefined
					
					if (obj[child.nodeName] == undefined){// if this child has no text or CDATA children
						// handle sub elements
						var sub = {};
						for(var k=0; k < child.childNodes.length; k ++)
						{
							if ('firstChild' in child.childNodes[k] && child.childNodes[k].firstChild != null)
							{
								sub[child.childNodes[k].nodeName] = child.childNodes[k].firstChild.data;
							}
						}
						obj[child.nodeName] = sub;
					}
				}
			}
			result.push(obj);
		}
	}
	return result;
}

/**
 * The following object stores the output from com.fandango.extractPlaylist()
 * After com.fandango.extractPlaylist() runs it will have 3 properties
 * 	dart	- contains the dart information
 * 	google	- contains the google info
 *	videos	- an array containing each video/trailer in the playlist
 */
com.fandango.playlist = {};

/**
 * The function extractPlaylist specifically convertst the encoded XML playlist passed as listID into 
 * JavaScript objects to facilate manipulation in the client browser.
 * 
 * @param listID {string} - the generated video playlist 
 */
com.fandango.extractPlaylist = function(listID)
{
	com.fandango.playlist = {}; 
	var xmldoc = com.fandango.XML.parse(decodeURIComponent(listID.replace(/\+/g, " ")));
	
	com.fandango.playlist['dart'] = com.fandango.getXMLObject("dart", xmldoc);
	com.fandango.playlist['google'] = com.fandango.getXMLObject('googleadsense', xmldoc);
	com.fandango.playlist['lightningcast'] = com.fandango.getXMLObject('lightningcast', xmldoc);
	com.fandango.playlist['videos'] = com.fandango.getVideoObjects(xmldoc);
}
	




