//
// Global variables
//
var presentation;
var presentationURL;
var errorCount = 0;
var debug = false;

// DIVs, etc
var linkslist;
var presentationTitleDiv;
var featureDiv;

//
// AJAX Processing of ASX Information
//

// Base Class for Feature and Prototype
var ASXClass = Class.create();
ASXClass.prototype = {
	initialize: function() {
		this.callback;
		this.xsl;
	},

	// Get ASX file
	getASX: function (url) {
		//alert('getASX ' + url);
		// Pass in playlistId to url when we have real data
		var transformUrl = 'transform.jsp';
		var pars = 'url=' + url + '&xsl=' + this.xsl;
		requestUrl = transformUrl + '?' + pars;	
		var myAjax = new Ajax.Request( transformUrl, { method: 'get',
						    parameters: pars, 
						    onComplete: this.callback,
						    onFailure: 	reload,
						    onException: reload
					  } ); 
	}
};

var FeatureClass = Class.create();
FeatureClass.prototype = (new ASXClass()).extend({
	initialize: function() {
		this.callback = this.parseFeaturesASX;
		this.xsl = 'http://www.channel4.com/player/v2/media%2Fxsl%2Ffeature.xsl';
		this.title;
		this.html;
		this.url;
	},


	// 'static member' callback function for parsing feature ASX file
	// N.B. in the callback, 'this' does not have any useful object
 	// context
	parseFeaturesASX: function(request) {
		try {
			// Get XML DOM
			var xmlResponse = request.responseXML;

			//  Thanks to bug where URL property is not sent on XMLHTTPRequest (see:
			//  MS Article ID:234460) or  http://support.microsoft.com/default.aspx?scid=kb;en-us;234460
			//  we have to pickup original ASX url from a special header set on transformer.jsp
			this.url = request.getResponseHeader("originalUrl");

			var id = presentation.getFeatureUrlToId(this.url);
			f = presentation.getFeature(id);
			f.url = url;
	
			// Extract Title tag
			var titleElements = xmlResponse.getElementsByTagName("title");
			f.title = titleElements[0].firstChild.nodeValue;

			// Extract Notes
			var htmlElements = xmlResponse.getElementsByTagName("feature-html");
			f.html = htmlElements[0].firstChild.nodeValue;

			var t = stripString(f.title);
			presentation.setFeatureTitleToId(id, t);

			presentation.createFeatureLink(t, f.title, id);

			// If this is the first link, create all episode link at end
			if (id == 0) {
				presentation.createFeatureLink(t, 'Watch whole show', presentation.getFeatureCount());
			}
		} catch (e) {
			if (debug) {
				alert('parseFeaturesASX error: ' + e.message);
				alert('parseFeaturesASX status:' + request.status);
				alert('parseFeaturesASX response:' + request.responseText);
			}
		}	
	}
});




var PresentationClass = Class.create();
PresentationClass.prototype = (new ASXClass()).extend({
	initialize: function() {
		this.callback = this.parsePresentationASX;
		this.xsl = 'http://www.channel4.com/player/v2/media%2Fxsl%2Fpresentation_generic.xsl';
		this.features = new Array();
		this.featureUrlToId = new Array();
		this.featureTitleToId = new Array();
		this.featureCount = 0;
	},

	getFeature: function(id) {
		return this.features[id];
	},

	setFeature: function(id, f) {
		this.features[id] = f;
	},

	getFeatureUrlToId: function(url) {
		return this.featureUrlToId[url];
	},

	setFeatureUrlToId: function(id, url) {
		this.featureUrlToId[url] = id;
	},

	getFeatureTitleToId: function(title) {
		return this.featureTitleToId[title];
	},

	setFeatureTitleToId: function(id, title) {
		this.featureTitleToId[title] = id;
	},

	getFeatureCount: function() {
		return this.featureCount;
	},

	setFeatureCount: function(x) {
		this.featureCount = x;
	},

	// 'static member' callback function for parsing presentation ASX file
	// N.B. in the callback, 'this' does not have any useful object
 	// context
	parsePresentationASX: function(request) {
		try {
			// Get XML DOM
			var xmlResponse = request.responseXML;

			// Extract ENTRYREF tag URLs - these correspond to the features
			var entriesElements = xmlResponse.getElementsByTagName("ref");
			presentation.setFeatureCount(entriesElements.length);
			for (var i=0; i<presentation.getFeatureCount();i++) {
				feature = new FeatureClass();
				presentation.setFeature(i, feature);

				// Lookup array to map from url to feature id
				var url = entriesElements[i].getAttribute("href");
				presentation.setFeatureUrlToId(i, url);

				// Get Feature ASX file and parse it
				feature.getASX(url);
			}

	       		// Extract Title tag
      			var titleElements = xmlResponse.getElementsByTagName("title");
        		var title = titleElements[0].firstChild.nodeValue;

			presentation.setPresentation(title);
	
			// Extract HTML
			//var playlistElements = xmlResponse.getElementsByTagName("presentation-html");
			//var playlistHTML = playlistElements[0].firstChild.nodeValue;
		} catch (e) {
			if (debug) {
				alert('parsePresentationASX error: ' + e.message);
				alert('parsePresentationASX status:' + request.status);
				alert('parsePresentationASX response:' + request.responseText);
			}
		}	
	},

	// Update presentation title and abstract/moreinfo HTML
	setPresentation: function(t) {
		presentationTitleDiv.innerHTML=t; 
		// No presentation related information yet, so ignore for now
		//$('presentationDiv').innerHTML=html; 
	},

	getFeatureFromUrl: function(asxUrl) {
		var id = this.getFeatureUrlToId(asxUrl);
		if (id != null) {
			return this.getFeature(id);
		}
	},

	getFeatureFromTitle: function(title) {
		var id = this.getFeatureTitleToId(title);
		var f = this.getFeature(id);
		return f;
	},

	// Iterate over given list of anchor tags - set active Feature on
	setFeatureOn: function(title) {
		var t = stripString(title);
		var id = this.getFeatureTitleToId(t);		
		for(i=0;i<linkslist.length;i++) {
			if (id == i) {
				linkslist[i].className="on";
			} else {
				linkslist[i].className="";
			}
		}
	},

	// Create a new Presentation ASX starting from the given
	// title
	reloadPresentationASX: function(title) {
		// Only allow user to navigate if they are not watching an Advert...
		var clipName;
		if(mac || opera || NN6 || ffox) {
			clipName = "wibble";
		} else {
			clipName = getPlayer().currentMedia.name;
		}
		
		if ((clipName != null) && (clipName != 'Advert')) {
			var t = stripString(title);
			var id = this.getFeatureTitleToId(t);		
			var url = presentationURL + '&startVideoFeatureId=' + id;
			var f = this.getFeature(id);

			// Load clip into player
			doThisClip(url);

			this.setFeatureOn(title);
		} else {
			// Disable navigation during ads
			return false;
		} 
	},	

	// Display feature abstract/moreinfo for given title using global array
	// Update Flash movie title
	// This is invoked from player event handling code
	displayFeature: function (title) {
		var strippedTitle = stripString(title);
		//alert('strippedTitle:' + strippedTitle + ' title:' + title);
		var f = this.getFeatureFromTitle(strippedTitle);
		if (f != null) {
	        	var featureHtml = convertEntities(f.html);
			featureDiv.innerHTML = featureHtml;
		}
		// Update Flash object title with current clip name (Advert, Feature title...)
		var clipName = getPlayer().currentMedia.name;
		
		// Remove XML entity refs from name
        	var s = convertEntities(clipName);
		setFlashTitle(escape(s));
		// Disable Feature Links if an advert ???
	},

	// creates anchor tag for navigation
	createFeatureLink: function(t, title, id) {
		var link = '<a href="#" onClick=\"javascript:presentation.reloadPresentationASX(\'' + t + '\');\">' + title + '</a>';

		// Add to playlist in presentationItemsDiv
		var divStr = 'feature_' + id;

		new Insertion.Bottom(divStr, link);
		new Insertion.Bottom(divStr, '<br/>');
	}
});

// Used by error-handling to try to re-load the page.  Only try
// to reload a few times to prevent excessive server load
function reload() {
	if (debug) {
		alert('error: reloading');
	}

	if (errorCount < 3) {
		// Re-load the ASX files after waiting a second
		setTimeout("location.reload()", 1000);
		errorCount++;
	}
}

// Used by onLoad()
function init(url, _debug) {
	try {
		debug = _debug;

		// Get DOM objects
		linkslist = $("filmShow").getElementsByTagName("a");
		presentationTitleDiv = $('presentationTitleDiv');
		featureDiv = $('featureDiv');
		
		// Use the presentation ASX to find the feature listings
		presentation = new PresentationClass();
		presentation.getASX(url);

		// Used by Flash Movie player
		presentationURL = url;

		// Bootstrap non-IE players
		if(mac || opera || NN6 || ffox) {
			doThisClip(presentationURL);
		} else {
			getPlayer().URL = presentationURL;
		}
	} catch (e) {
		if (debug) {
			alert('init error: ' + e.message);
		}
	}
}

// Trim and remove any non-word chars - some title strings have non-Javascript friendly
// characters which would need to be escaped
function stripString (str) {
        // Need to compare strings which have been HTML and URL escaped...
        // remove HTML entity refs first
        var s = str.replace(/&\w{2,4};/g, '');
        s = s.replace(/&#\d{2,3};/g, '');
        // remove anything which is not alphanumeric
        return s.replace(/[^A-Za-z0-9]/g, '');
}

// Replace XML entities and numeric HTML entities
function convertEntities(str) {
       	var s = str.replace(/&amp;/g, '&');
       	s = s.replace(/&lt;/g, '<');
       	s = s.replace(/&gt;/g, '>');
       	s = s.replace(/&quot;/g, '\"');
       	s = s.replace(/&apos;/g, '\'');
       	// convert HTML numeric entity ref to char values
	s = s.replace(/&#(\d{2,3});/g, function(ignore, value) {
						var i = Number(value);
						return String.fromCharCode(i)} );
	return s;	
}

function getPlayer() { 
 	try {   
	    var p = document.Player;
	    return p;
	} catch (e) {
	    if (debug) {
	     	alert('getPlayer error: ' + e.message);
	    }
    	}
}		

