/**
  * The external ad class is designed to be used in conjuction with the Brightcove single title
  * player.  In this class we will parse out the necessary ad elements to display on the page
  * external to the player and construct the appropriate ad object to return to the player.
  *
  * This class can handle the XML that matches the rich media template for ads that have an overlay, 
  * overlay-to video, leader board (728x90), video ad and 300x250 ad.
  *
  * @author Jesse Streb (Brightcove)
  */
var External_Ad = function (pXML) {
    //private variables used by the external ad class.  These keep track of the different value to return.
    var xml = "";
    var expandedBannerURL = "";
    var expandedBannerClickURL = "";
    var collapsedBannerURL = "";
    var collapsedBannerClickURL = "";
    var ad = new Object();
    ad.type = "videoAd";
    
    //It is necessary to pass in the XML so we through an error if one wasn't passed in.
    if(pXML == undefined) 
        throw new Error('An External Ad requires the ad XML and type of ad to return');
    
    /*
     * getXML is a private funciton that is used internally in this class to retrieve the XML object.
     * we handle crossbrowser XML creation in this funciton.
     */
    function getXML() {
        if (window.ActiveXObject) {
            //parses the XML for IE browsers
            var adXML = new ActiveXObject("Microsoft.XMLDOM");
            adXML.async = false;
            adXML.loadXML(xml);
        } else if (window.XMLHttpRequest) {
            var adXML = (new DOMParser()).parseFromString(xml, "text/xml"); //parses the XML for Mozilla browsers
        }
        return adXML;
    }
    
    /*
     * createSWF is a private function used internally by this class to create the external ad if
     * it is swf file.  It takes in the URL to the creative and also the URL to open if the user
     * clicks on the ad.
     */
    function createSWF(pURL, pClickThrough) {
        var objectTag = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="300" height="250" align="middle">\n';
        objectTag += '\t<param name="allowScriptAccess" value="always" />\n';
        objectTag += '\t<param name="movie" value="' + pURL + '" />\n';
        objectTag += '\t<param name="quality" value="high" />\n';
        objectTag += '\t<param name="bgcolor" value="#ffffff" />\n';
        objectTag += '\t<param name="wmode" value="transparent" />\n'; 
        objectTag += '\t<param name="FlashVars" value="clickTag=' + pClickThrough + '" />\n';
        objectTag += '\t<embed src="' + pURL + '" quality="high" bgcolor="#ffffff" width="300" height="250" name="expandedBanner" align="middle" allowScriptAccess="always" wmode="transparent" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" FlashVars="clickTag='+pClickThrough+'" />\n';
        objectTag += '</object>\n';
        
        return objectTag;
    }
    
    /*
     * createImage is a private function used internally by this class to create the external ad if
     * it is an image rather then a .swf.  It takes in the URL to the image and also the URL to open if the user
     * clicks on the ad.
     */
    function createImage(pURL, pClickThrough) {
    	var HTML = "";
    	if(pClickThrough != "") {
        	HTML = "<a href='" + pClickThrough + "' target='_blank' ><img src='" + pURL + "' /></a>\n";
        }
        return HTML;
    }
    
    /*
     * The setXMLString function is added to this object and can be called on an instance of this. 
     * This serves as the setter for the XML that has been passed to the JavaScript and will be parsed
     * by this class to break out the different ads.
     */
    this.setXMLString = function(pXML) {
        xml = pXML;
        this.parse();
    };
    
    /*
     * A setter for the different types of ads that this could have.  This function is not currently
     * used but is here as a best practice for having a setters and getters for my private variables
     * that I do want configurable.
     */
    this.setType = function(pType) {
        ad.type = pType;
    };
    
    /* 
     * A getter for the different for the current type that this ad is.  Not currently used.
     */
    this.getType = function() {
        return ad.type;
    };
    
    /*
     * getExpandedBanner retrieves the creative for this ad type if it was passed into the XML.  Otherwise
     * an empty string is passed back. This function handles whether or not to return the flash object
     * or the HTML for the image.
     */
    this.getExpandedBanner = function() {
        return (expandedBannerURL.indexOf('.swf') !== -1) ? createSWF(expandedBannerURL, expandedBannerClickURL) : createImage(expandedBannerURL, expandedBannerClickURL);  
    }
    
    /*
     * getCollapsedAd retrieves the creative for this ad type if it was passed into the XML.  Otherwise
     * an empty string is passed back. This function handles whether or not to return the flash object
     * or the HTML for the image.
     */
    this.getCollapsedAd = function() {
        return (collapsedBannerURL.indexOf('.swf') !== -1) ? createSWF(collapsedBannerURL, collapsedBannerClickURL) : createImage(collapsedBannerURL, collapsedBannerClickURL);
    }
    
    /*
     * getPlayerAd returns the ad object that the player is to render.  Currently this supports an
     * ad type of video, overlay, overlay-to-video.  The parse function handles which type is returned.
     */
    this.getPlayerAd = function() {
        return ad;
    }
    
    /*
     * As they say this is where all the magic happens.  The parse function parses the XML that is 
     * passed into the constructor.  It is in here that we set all of the private variables that are to
     * be used to create the ads.
     */
    this.parse = function() {
        var xmlDoc = getXML();
        var nodeItems = xmlDoc.firstChild.childNodes.length;
        var currentNode = xmlDoc.firstChild.firstChild;
        ad.duration = (xmlDoc.firstChild.getAttribute("duration") !== "" && xmlDoc.firstChild.getAttribute("duration") !== null) ? Number(xmlDoc.firstChild.getAttribute("duration")) : 15;
        if(xmlDoc.firstChild.getAttribute("trackStartURLs") !== "" && xmlDoc.firstChild.getAttribute("trackStartURLs") !== null) ad.trackStartURLs = xmlDoc.firstChild.getAttribute("trackStartURLs").split(",");
        if(xmlDoc.firstChild.getAttribute("trackMidURLs") !== "" && xmlDoc.firstChild.getAttribute("trackMidURLs") !== null) ad.trackMidURLs = xmlDoc.firstChild.getAttribute("trackMidURLs").split(",");
        if(xmlDoc.firstChild.getAttribute("trackEndURLs") !== "" && xmlDoc.firstChild.getAttribute("trackEndURLs") !== null) ad.trackEndURLs = xmlDoc.firstChild.getAttribute("trackEndURLs").split(",");
        if(xmlDoc.firstChild.getAttribute("trackPointURLs") && (xmlDoc.firstChild.getAttribute("trackPointURLs") !== "")) ad.trackPointURLs = xmlDoc.firstChild.getAttribute("trackPointURLs").split(",");
        ad.trackPointTime = (xmlDoc.firstChild.getAttribute("trackPointTime") && (xmlDoc.firstChild.getAttribute("trackPointTime") !== "")) ? Number(xmlDoc.firstChild.getAttribute("trackPointTime")) : 0;
        
        for(var i = 0; i < nodeItems; i++)
        {
            //checks to see if the current nodes are in our Rich Media Templates and assigns them if they exist
        		if(currentNode.nodeName == "adSwf" && currentNode.firstChild) {
        			if (currentNode.xml) {
							   ad = currentNode.xml   // XML to String  for IE
							}else{
		        		ad = (new XMLSerializer()).serializeToString(currentNode);          
		        	}
            } else if(currentNode.nodeName == "videoURL" && currentNode.firstChild) {
                ad.videoURL = currentNode.firstChild.nodeValue; 
            } else if(currentNode.nodeName == "videoClickURL" && currentNode.firstChild) {
                ad.videoClickURL = currentNode.firstChild.nodeValue;
            } else if(currentNode.nodeName.toLowerCase() == "expandedbannerurl" && currentNode.firstChild) {
                expandedBannerURL = currentNode.firstChild.nodeValue;
            } else if(currentNode.nodeName.toLowerCase() == "expandedbannerclickurl" && currentNode.firstChild) {
                expandedBannerClickURL = currentNode.firstChild.nodeValue;
            } else if(currentNode.nodeName.toLowerCase() == "collapsedbannerurl" && currentNode.firstChild) {
                collapsedBannerURL = currentNode.firstChild.nodeValue;
            } else if(currentNode.nodeName.toLowerCase() == "collapsedbannerclickurl" && currentNode.firstChild) {
                collapsedBannerClickURL = currentNode.firstChild.nodeValue;
            } else if(currentNode.nodeName.toLowerCase() == "overlayurl" && currentNode.firstChild) {
            	ad.overlayURL = currentNode.firstChild.nodeValue;
            	ad.type = "overlay";
            } else if(currentNode.nodeName.toLowerCase() == "overlayclickurl" && currentNode.firstChild) {
            	ad.overlayClickURL = currentNode.firstChild.nodeValue;
            } else if(currentNode.nodeName.toLowerCase() == "expandedvideourl" && currentNode.firstChild) {
            	ad.expandedVideoURL = currentNode.firstChild.nodeValue;
            	ad.expandedVideoURLDuration = "13"; //TODO make this dynamic
            } else if(currentNode.nodeName.toLowerCase() == "expandedvideoclickurl" && currentNode.firstChild) {
            	ad.expandedVideoClickURL = currentNode.firstChild.nodeValue;
            }
            currentNode = currentNode.nextSibling;
        }
    };
    
    //Constructor code
    this.setXMLString(pXML);
};

/*
 * The public functions intended to be called from wherever the External_Ad object is instantiated.
 */
External_Ad.prototype = {

	/*
	 * Returns the HTML that represents the expanded ad.
	 */
    getExpandedAd: function() {
        return this.getExpandedBanner();
    },
    
    /*
     * Returns the HTML that represents the collapsed ad.
     */
    getCollapsedAd: function() {
        return this.getCollapsedAd();
    },
    
    /*
     * Returns the ad object that should be passed back into player.
     */
    getPlayerAd: function() {
        return this.getPlayerAd();
    }
};
