﻿(function($) {

/* =====================================================================================================================================
 * News ticker plugin (BBC news style) - MESSAGE TICKER ================================================================================
 * Bryan Gullan,2007-2011
 * version 2.3.6
 * updated 2011-03-16
 * Documentation at http://www.makemineatriple.com/news-ticker-documentation/
 * Demo at http://www.makemineatriple.com/jquery/?newsTicker
 * Use and distrubute freely with this header intact.
 */
	var name='newsTicker';
	var debugMode = false; // enabling this turns on console logging for interactions
	
	function runTicker(settings) {
		$('#tickercontainer').show('slow')
		$('#tickercontainer-style2').show('slow')
		$('#messageticker').show()
		
		tickerData = $(settings.newsList).data('newsTicker');
		
		if(tickerData.currentItem > tickerData.newsItemCounter){
			// if we've looped to beyond the last item in the list, start over
			tickerData.currentItem = 0;
		}
		else if (tickerData.currentItem < 0) {
			// if we've looped back before the first item, move to the last one
			tickerData.currentItem = tickerData.newsItemCounter;
		}
		
		if(tickerData.currentPosition == 0) {
			if(tickerData.newsLinks[tickerData.currentItem].length > 0) {
				$(tickerData.newsList).empty().append('<li><a '+ tickerData.newsAttributes[tickerData.currentItem] +'></a></li>');
			}
			else {
				$(tickerData.newsList).empty().append('<li></li>');
			}
		}
		
		//only start the ticker itself if it's defined as animating: otherwise it's paused or under manual advance
		if (tickerData.animating) {
			
			if( tickerData.currentPosition % 2 == 0) {
					var placeHolder = tickerData.placeHolder1;
			}
			else {
				var placeHolder = tickerData.placeHolder2;
			}
			
			if( tickerData.currentPosition < tickerData.newsItems[tickerData.currentItem].length) {
				// we haven't completed ticking out the current item
				
				var tickerText = tickerData.newsItems[tickerData.currentItem].substring(0,tickerData.currentPosition);
				if(tickerData.newsLinks[tickerData.currentItem].length > 0) {
					$(tickerData.newsList + ' li a').text(tickerText + placeHolder);
				}
				else {
					$(tickerData.newsList + ' li').text(tickerText + placeHolder);
				}
				tickerData.currentPosition ++;
				setTimeout(function(){runTicker(settings); settings = null;},tickerData.tickerRate);
			}
			
			else {
				// we're on the last letter of the current item
				
				if(tickerData.newsLinks[tickerData.currentItem].length > 0) {
					$(tickerData.newsList + ' li a').text(tickerData.newsItems[tickerData.currentItem]);
				}
				else {
					$(tickerData.newsList + ' li').text(tickerData.newsItems[tickerData.currentItem]);
				}
				
				setTimeout(function(){
					if (tickerData.animating) {
						tickerData.currentPosition = 0;
						tickerData.currentItem ++;
						runTicker(settings); settings = null;
					}
				},tickerData.loopDelay);
				
			}
		}
		
		else {// settings.animating == false 
			
			// display the full text of the current item
			var tickerText = tickerData.newsItems[tickerData.currentItem];
			
			if(tickerData.newsLinks[tickerData.currentItem].length > 0) {
				$(tickerData.newsList + ' li a').text(tickerText);
			}
			else {
				$(tickerData.newsList + ' li').text(tickerText);
			}
					
		}
		$('#linkto').prop('disabled', '');
	
		
	}

	
	// Core plugin setup and config
	jQuery.fn[name] = function(options) {
 
	  // Add or overwrite options onto defaults
	  var settings = jQuery.extend({}, jQuery.fn.newsTicker.defaults, options);
	 
    var newsItems = new Array();
		var newsLinks = new Array();
		var newsAttributes = new Array();
		var newsItemCounter = 0;
		
		// Hide the static list items
		$(settings.newsList + ' li').hide();
		
		// Store the items and links in arrays for output
		$(settings.newsList + ' li').each(function(){
			if($(this).children('a').length) {
				newsItems[newsItemCounter] = $(this).children('a').text();
				newsLinks[newsItemCounter] = $(this).children('a').attr('href');
				
				var linkAttributes = new Object();
			  	var attrs = $(this).children('a')[0].attributes;
					for (var i=0;i<attrs.length;i++) {
					linkAttributes[attrs[i].nodeName] = attrs[i].nodeValue;
				}
				if (debugMode){ 
					console.log(linkAttributes);
				}
				
		    var linkAttributesProcessed = '';
 				for (var prop in linkAttributes) {
 					// print out the attributes as a string ready for output within the anchor tag
    			linkAttributesProcessed = linkAttributesProcessed + prop + '="' + linkAttributes[prop] + '" ';
 				}
 				if (debugMode){ 
					console.log(linkAttributesProcessed);
				}
 				
				newsAttributes[newsItemCounter] = linkAttributesProcessed;
				
			}
			else {
				newsItems[newsItemCounter] = $(this).text();
				newsLinks[newsItemCounter] = '';
				newsAttributes[newsItemCounter] = '';
			}
			newsItemCounter ++;
		});
        
        var tickerElement = $(settings.newsList); // for quick reference below
        
        tickerElement.data(name, {
        	newsList: settings.newsList,
					tickerRate: settings.tickerRate,
					startDelay: settings.startDelay,
					loopDelay: settings.loopDelay,
					placeHolder1: settings.placeHolder1,
					placeHolder2: settings.placeHolder2,
					controls: settings.controls,
					ownControls: settings.ownControls,
					stopOnHover: settings.stopOnHover,
					resumeOffHover: settings.resumeOffHover,
          newsItems: newsItems,
					newsLinks: newsLinks,
					newsAttributes: newsAttributes,
					newsItemCounter: newsItemCounter - 1, // -1 because we've incremented even after the last item (above)
					currentItem: 0,
					currentPosition: 0,
					firstRun:1
        })
        .bind({
			stop: function(event) {
				// show remainder of the current item immediately
		    	tickerData = tickerElement.data(name);
		    	if (tickerData.animating) { // only stop if not already stopped
            		tickerData.animating = false;
            		if (debugMode){ 
            			console.log('stop'+tickerData.currentItem + ' ' + tickerData.animating);
            		}
               	}
		  	},
		  	play: function(event) {
		  		// show 1st item with startdelay
		    	tickerData = tickerElement.data(name);
		    	if (!tickerData.animating) { // if already animating, don't start animating again
	            	tickerData.animating = true;
	            	if (debugMode){ 
            			console.log('play'+tickerData.currentItem + ' ' + tickerData.animating);
            		}
	            	setTimeout(function(){runTicker(tickerData); tickerData = null;},tickerData.startDelay);
	            }
		  	},
		  	resume: function(event) {
		  		// start from next item, with no delay
		    	tickerData = tickerElement.data(name);
		    	if (!tickerData.animating) { // if already animating, don't start animating again
	            	tickerData.animating = true;
	            	// set the character position as 0 to ensure on resume we start at the right point
					tickerData.currentPosition = 0;
	            	tickerData.currentItem ++;
	            	if (debugMode){ 
            			console.log('resume'+tickerData.currentItem + ' ' + tickerData.animating);
            		}
		            runTicker(tickerData); // no delay when resuming.
		        }
		  	},
		  	next: function(event) {
		  		// show whole of next item
		  		tickerData = tickerElement.data(name);
		  		// stop (which sets as non-animating), and call runticker
		  		$(tickerData.newsList).trigger("stop");
		  		// set the character position as 0 to ensure on resume we start at the right point
				tickerData.currentPosition = 0;
	            tickerData.currentItem ++;
	            if (debugMode){ 
            			console.log('next'+tickerData.currentItem + ' ' + tickerData.animating);
            		}
		  		runTicker(tickerData);
		  	},
		  	previous: function(event) {
				// show whole of previous item
				tickerData = tickerElement.data(name);
		  		// stop (which sets as non-animating), and call runticker
		  		$(tickerData.newsList).trigger("stop");
		  		// set the character position as 0 to ensure on resume we start at the right point
				tickerData.currentPosition = 0;
	            tickerData.currentItem --;
	            if (debugMode){ 
            			console.log('previous'+tickerData.currentItem + ' ' + tickerData.animating);
            		}
		  		runTicker(tickerData);
			}
		}); 	
		if (settings.stopOnHover) {
	    	tickerElement.bind({			    	
			  	mouseover: function(event) {
			  		tickerData = tickerElement.data(name);
			    	if (tickerData.animating) { // stop if not already stopped
				  		$(tickerData.newsList).trigger("stop");
				  		if (tickerData.controls) { // ensure that the ticker can be resumed if controls are enabled
				  			$('.stop').hide();
			        		$('.resume').show();
				  		}
			  		}
			  	}
			});
			if (settings.resumeOffHover) { // only allowed if stopOnHover enabled
		    	tickerElement.bind({			    	
				  	mouseout: function(event) {
				  		tickerData = tickerElement.data(name);
				    	if (!tickerData.animating) { // if already animating, don't start animating again
			            	$(tickerData.newsList).trigger("resume");
			            	if (debugMode){ 
		            			console.log('resumeoffhover'+tickerData.currentItem + ' ' + tickerData.animating);
		            		}
				        }
				  	}
				});
    		}
    	}
    	
    	tickerData = tickerElement.data(name);
    	
    	// set up control buttons if the option is on
		if (tickerData.controls || tickerData.ownControls) {
			if (!tickerData.ownControls) {
				$('<ul class="ticker-controls"><li class="play"><a href="#play">Play</a></li><li class="resume"><a href="#resume">Resume</a></li><li class="stop"><a href="#stop">Stop</a></li><li class="previous"><a href="#previous">Previous</a></li><li class="next"><a href="#next">Next</a></li></ul>').insertAfter($(tickerData.newsList));
			}
			$('.play').hide();
		    $('.resume').hide();
			
		    $('.play').click(function(event){
		        $(tickerData.newsList).trigger("play");
		        $('.play').hide();
		        $('.resume').hide();
		        $('.stop').show();
		        event.preventDefault();
		    });
		    $('.resume').click(function(event){
		        $(tickerData.newsList).trigger("resume");
		        $('.play').hide();
		        $('.resume').hide();
		        $('.stop').show();
		        event.preventDefault();
		    });
			$('.stop').click(function(event){
		        $(tickerData.newsList).trigger("stop");
		        $('.stop').hide();
		        $('.resume').show();
		        event.preventDefault();
		    });
		    $('.previous').click(function(event){
		        $(tickerData.newsList).trigger("previous");
		        $('.stop').hide();
			    $('.resume').show();
		        event.preventDefault();
		    });
		    $('.next').click(function(event){
		        $(tickerData.newsList).trigger("next");
		        $('.stop').hide();
			    $('.resume').show();
		        event.preventDefault();
		    });

	    };
    	
    	// tell it to play
    	$(tickerData.newsList).trigger("play");
	};

	// News ticker defaults 
	jQuery.fn[name].defaults = {
	  newsList: "#news",
		tickerRate: 20,
		startDelay: 100,
		loopDelay: 4000,
		placeHolder1: " |",
		placeHolder2: "_",
		controls: false,
		ownControls: true,
		stopOnHover: false,
		resumeOffHover: false
	}
	
})(jQuery);


/* =====================================================================================================================================
 * Sag Content Scroller (Aug 7th, 2010) - ROTATING IMAGES/ROTATING RSS =================================================================
 * This notice must stay intact for usage 
 * Author: Dynamic Drive at http://www.dynamicdrive.com/
 * Visit http://www.dynamicdrive.com/ for full source code
 * Updated Aug 28th, 10 to v1.3
 */

var sagscroller_constants={
	navpanel: {height:'17px', downarrow:'/Style Library/Edexcel/Images/scroll_next.png', title:'Next', background:'#E0D7C9'},
	loadingimg: {src:'', dimensions:[156,7]}
}

function sagscroller(options){

	this.setting={mode:'manual', inittype:'stunted', pause:3000, animatespeed:500, ajaxsource:null, rssdata:null, refreshsecs:0, navpanel:{show:true, cancelauto:false}} //default settings
	jQuery.extend(this.setting, options) //merge default settings with options
	options=null
	this.curmsg=0
	this.addloadingpanel(jQuery, 'preload')
	if (this.setting.rssdata) //if rss contents
		google.load("feeds", "1") //init google ajax api
	var slider=this
	jQuery(function($){ //on document.ready
		slider.$slider=$('#'+slider.setting.id)
		if (slider.setting.ajaxsource||slider.setting.rssdata)
			slider.$slider.empty()
		slider.addloadingpanel(jQuery, 'show')
		if (slider.setting.ajaxsource) //if ajax data
			slider.getajaxul(slider.setting.ajaxsource)
		else if (slider.setting.rssdata){ //if rss data
			slider.fetchfeeds()
		}
		else{ //if inline content
			if (slider.setting.inittype=="onload") //load scroller when page has completely loaded?
				$(window).load(function(){slider.init($)})
			else //load scroller immediately and get dimensions progressively instead
				slider.init($)
		}
	})
}

sagscroller.prototype={

	getajaxul:function(path){
		var $=jQuery, slider=this
		this.stopscroll() //stop animation/ scrolling of slider, in the event this is a subsequent call to getajaxul()
		this.$loadingpanel.show()
		$.ajax({
			url: path, //path to external content
			async: true,
			error:function(ajaxrequest){
				slider.$slider.html('Error fetching content.<br />Server Response: '+ajaxrequest.responseText)
			},
			success:function(content){
				slider.reloadul(content)
				if (slider.setting.refreshsecs>0) //refetch contents every x sec?
					setTimeout(function(){slider.getajaxul(path)}, slider.setting.refreshsecs*1000)
			}
		})
	},

	addloadingpanel:function($, mode){
		var loadingimgref=sagscroller_constants.loadingimg
		if (mode=="preload"){
			var loadingimg=new Image(loadingimgref.dimensions[0], loadingimgref.dimensions[1])
			loadingimg.src=loadingimgref.src
			this.$loadingimg=$(loadingimg).css({position:'absolute', zIndex:1003})
		}
		else{
			var sliderdimensions=[this.$slider.width(), this.$slider.height()]
			var $loadingpanel=$('<div />').css({position:'absolute', left:0, top:0, background:'black', opacity:0.5, width:sliderdimensions[0], height:sliderdimensions[1], zIndex:1002}).appendTo(this.$slider)
			this.$loadingimg.css({left:sliderdimensions[0]/2-loadingimgref.dimensions[0]/2, top:sliderdimensions[1]/2-loadingimgref.dimensions[1]/2}).appendTo(this.$slider)
			this.$loadingpanel=$loadingpanel.add(this.$loadingimg)
		}
	},

	addnavpanel:function(){
		var slider=this, setting=this.setting
		var $navpanel=$('<div class="sliderdesc"><div class="sliderdescbg"></div><div class="sliderdescfg"><div class="sliderdesctext"></div></div></div>')
			.css({position:'absolute', width:'100%', left:0, top:-1000, zIndex:'1001'})
			.find('div').css({position:'absolute', left:0, top:0, width:'100%'})
			.eq(0).css({background:sagscroller_constants.navpanel.background, opacity:sagscroller_constants.navpanel.opacity}).end() //"sliderdescbg" div
			.eq(1).css({color:'white'}).end() //"sliderdescfg" div
			.eq(2).css({textAlign:'center', cursor:'pointer', paddingTop:'2px'}).html('<img src="'+sagscroller_constants.navpanel.downarrow+'"/>').end().end()
			.appendTo(this.$slider)
		var $descpanel=$navpanel.find('div.sliderdesctext').attr('title', sagscroller_constants.navpanel.title).click(function(){ //action when nav bar is clicked on
			slider.stopscroll()
			slider.scrollmsg(setting.mode=="auto" && !setting.navpanel.cancelauto? true : false)
		})
		$navpanel.css({top:this.$slider.height()-parseInt(sagscroller_constants.navpanel.height), height:sagscroller_constants.navpanel.height}).find('div').css({height:'100%'})
	},

	resetuls:function(){ //function to swap between primary and secondary ul
		var $tempul=this.$mainul
		this.$mainul=this.$secul.css({zIndex:1000})
		this.$secul=$tempul.css({zIndex:999})
		this.$secul.css('top', this.ulheight)
	},

	reloadul:function(newhtml){ //function to empty out SAG scroller UL contents then reload with new contents
		this.$slider.find('ul').remove()
		this.ulheight=null
		this.curmsg=0;
		this.$slider.append(newhtml)
		this.init($)		
	},

	setgetoffset:function($li){
		var recaldimensions=(this.setting.ajaxsource || this.setting.rssdata) && this.setting.inittype=="onload" //bool to see if script should always refetch dimensions
		if (this.curmsg==this.$lis.length)
			return (!this.ulheight || recaldimensions)? this.ulheight=this.$mainul.height() : this.ulheight
		else{
			if (!$li.data('toppos') || recaldimensions)
				$li.data('toppos', $li.position().top)
			return $li.data('toppos')
		}
	},

	scrollmsg:function(repeat){
		var slider=this, setting=this.setting
		var ulheight=this.ulheight || this.$mainul.height()
		var endpoint=-this.setgetoffset(this.$lis.eq(this.curmsg))
		this.$mainul.animate({top: endpoint}, setting.animatespeed, function(){
			slider.curmsg=(slider.curmsg<slider.$lis.length+1)? slider.curmsg+1 : 0
			if (slider.curmsg==slider.$lis.length+1){ //if at end of UL
				slider.resetuls() //swap between main and sec UL
				slider.curmsg=1
			}
			if (repeat)
				slider.scrolltimer=setTimeout(function(){slider.scrollmsg(repeat)}, setting.pause)
		})
		var secendpoint=endpoint+ulheight
		this.$secul.animate({top: secendpoint}, setting.animatespeed)
	},

	stopscroll:function(){
		if (this.$mainul){
			this.$mainul.add(this.$secul).stop(true, false)
			clearTimeout(this.scrolltimer)
		}
	},

	init:function($){
		var setting=this.setting
		this.$loadingpanel.hide()
		this.$mainul=this.$slider.find('ul:eq(0)').css({zIndex:1000})
		this.$lis=this.$mainul.find('li')
		if (setting.navpanel.show)
			this.addnavpanel()
		this.$secul=this.$mainul.clone().css({top:this.$mainul.height(), zIndex:999}).appendTo(this.$slider) //create sec UL and add it to the end of main UL
		this.scrollmsg(setting.mode=="auto")
	},

	///////////////////////RSS related methods below///////////////////

	fetchfeeds:function(){
		var slider=this, rssdata=this.setting.rssdata
		this.stopscroll() //stop animation/ scrolling of slider, in the event this is a subsequent call to fetchfeeds()
		this.$loadingpanel.show()
		this.entries=[] //array holding combined RSS feeds' entries from Feed API (result.feed.entries)
		this.feedsfetched=0
		for (var i=0; i<rssdata.feeds.length; i++){ //loop through the specified RSS feeds' URLs
			var feedpointer=new google.feeds.Feed(rssdata.feeds[i][1]) //create new instance of Google Ajax Feed API
			feedpointer.setNumEntries(rssdata.entries) //set number of items to display
			feedpointer.load(function(label){
				return function(r){
					slider.storefeeds(r, label)
				}
			}(rssdata.feeds[i][0])) //call Feed.load() to retrieve and output RSS feed.
		}	
	},

	storefeeds:function(result, label){
		var thisfeed=(!result.error)? result.feed.entries : "" //get all feed entries as a JSON array or "" if failed
		if (thisfeed==""){ //if error has occured fetching feed
			alert("Google Feed API Error: "+result.error.message)
		}
		for (var i=0; i<thisfeed.length; i++){ //For each entry within feed
			result.feed.entries[i].label=label //extend it with a "label" property
		}
		this.entries=this.entries.concat(thisfeed) //add entry to array holding all feed entries
		this.feedsfetched+=1
		if (this.feedsfetched==this.setting.rssdata.feeds.length){ //if all feeds fetched
			if (this.setting.rssdata.groupbylabel){ //sort by label name?
				this.entries.sort(function(a,b){
					var fielda=a.label.toLowerCase(), fieldb=b.label.toLowerCase()
					return (fielda<fieldb)? -1 : (fielda>fieldb)? 1 : 0
				})
			}
			else{ //just sort by date
				this.entries.sort(function(a,b){return new Date(b.publishedDate)-new Date(a.publishedDate)})
			}
			this.formatfeeds()
		}
	},

	formatfeeds:function(){
		function formatdate(datestr, showoptions){
			var itemdate=new Date(datestr)
			var parseddate=(showoptions.indexOf("datetime")!=-1)? itemdate.toLocaleString() : (showoptions.indexOf("date")!=-1)? itemdate.toLocaleDateString() : ""
			return "<span class='datefield'>"+parseddate+"</span>"
		}
		var sagcontent='<ul>'
		var slider=this, rssdata=this.setting.rssdata, entries=this.entries
		for (var i=0; i<entries.length; i++){
			sagcontent+='<li><a href="'+entries[i].link+'" target="'+rssdata.linktarget+'">'+entries[i].title+'</a>'
				+'<div class="rsscontent">'
				+(/description/.test(rssdata.displayoptions)? entries[i].content : entries[i].contentSnippet)
				+'</div>'
				+'<div class="rsslabel">'
				+(/label/.test(rssdata.displayoptions)? "<b>Source("+(i+1)+"):</b> "+entries[i].label+" " : "")
				+(/date/.test(rssdata.displayoptions)? formatdate(entries[i].publishedDate, rssdata.displayoptions): "")
				+'</div>'
				+'</li>\n\n'
		}
	sagcontent+='</ul>'
	this.reloadul(sagcontent)
	if (slider.setting.refreshsecs>0) //refetch contents every x sec?
		setTimeout(function(){slider.fetchfeeds()}, slider.setting.refreshsecs*1000)
	}
}

/* =====================================================================================================================================
 * Featured Content Slider script - (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com. - PAGING BANNERS ================
 */

var featuredcontentslider={

//3 variables below you can customize if desired:
ajaxloadingmsg: '<div style="margin: 20px 0 0 20px"><img src="/Style%20Library/Edexcel/images/QualsDropDown/ajax-loader.gif" /> Fetching slider Contents. Please wait...</div>',
bustajaxcache: true, //bust caching of external ajax page after 1st request?
enablepersist: true, //persist to last content viewed when returning to page?

settingcaches: {}, //object to cache "setting" object of each script instance

jumpTo:function(fcsid, pagenumber){ //public function to go to a slide manually.
	this.turnpage(this.settingcaches[fcsid], pagenumber)
},

ajaxconnect:function(setting){
	var page_request = false
	if (window.ActiveXObject){ //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
		try {
		page_request = new ActiveXObject("Msxml2.XMLHTTP")
		} 
		catch (e){
			try{
			page_request = new ActiveXObject("Microsoft.XMLHTTP")
			}
			catch (e){}
		}
	}
	else if (window.XMLHttpRequest) // if Mozilla, Safari etc
		page_request = new XMLHttpRequest()
	else
		return false
	var pageurl=setting.contentsource[1]
	page_request.onreadystatechange=function(){
		featuredcontentslider.ajaxpopulate(page_request, setting)
	}
	document.getElementById(setting.id).innerHTML=this.ajaxloadingmsg
	var bustcache=(!this.bustajaxcache)? "" : (pageurl.indexOf("?")!=-1)? "&"+new Date().getTime() : "?"+new Date().getTime()
	page_request.open('GET', pageurl+bustcache, true)
	page_request.send(null)
},

ajaxpopulate:function(page_request, setting){
	if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1)){
		document.getElementById(setting.id).innerHTML=page_request.responseText
		this.buildpaginate(setting)
	}
},

buildcontentdivs:function(setting){
	var alldivs=document.getElementById(setting.id).getElementsByTagName("div")
	for (var i=0; i<alldivs.length; i++){
		if (this.css(alldivs[i], "contentdiv", "check")){ //check for DIVs with class "contentdiv"
			setting.contentdivs.push(alldivs[i])
				alldivs[i].style.display="none" //collapse all content DIVs to begin with
		}
	}
},

buildpaginate:function(setting){
	this.buildcontentdivs(setting)
	var sliderdiv=document.getElementById(setting.id)
	var pdiv=document.getElementById("paginate-"+setting.id)
	var phtml=""
	var toc=setting.toc
	var nextprev=setting.nextprev
	if (typeof toc=="string" && toc!="markup" || typeof toc=="object"){
		for (var i=1; i<=setting.contentdivs.length; i++){
			phtml+='<a href="#'+i+'" class="toc">'+(typeof toc=="string"? toc.replace(/#increment/, i) : toc[i-1])+'</a> '
		}
		phtml=(nextprev[0]!=''? '<a href="#prev" class="prev">'+nextprev[0]+'</a> ' : '') + phtml + (nextprev[1]!=''? '<a href="#next" class="next">'+nextprev[1]+'</a>' : '')
		pdiv.innerHTML=phtml
	}
	var pdivlinks=pdiv.getElementsByTagName("a")
	var toclinkscount=0 //var to keep track of actual # of toc links
	for (var i=0; i<pdivlinks.length; i++){
		if (this.css(pdivlinks[i], "toc", "check")){
			if (toclinkscount>setting.contentdivs.length-1){ //if this toc link is out of range (user defined more toc links then there are contents)
				pdivlinks[i].style.display="none" //hide this toc link
				continue
			}
			pdivlinks[i].setAttribute("rel", ++toclinkscount) //store page number inside toc link
			pdivlinks[i][setting.revealtype]=function(){
				featuredcontentslider.turnpage(setting, this.getAttribute("rel"))
				return false
			}
			setting.toclinks.push(pdivlinks[i])
		}
		else if (this.css(pdivlinks[i], "prev", "check") || this.css(pdivlinks[i], "next", "check")){ //check for links with class "prev" or "next"
			pdivlinks[i].onclick=function(){
				featuredcontentslider.turnpage(setting, this.className)
				return false
			}
		}
	}
	this.turnpage(setting, setting.currentpage, true)
	if (setting.autorotate[0]){ //if auto rotate enabled
		pdiv[setting.revealtype]=function(){
			featuredcontentslider.cleartimer(setting, window["fcsautorun"+setting.id])
		}
		sliderdiv["onclick"]=function(){ //stop content slider when slides themselves are clicked on
			featuredcontentslider.cleartimer(setting, window["fcsautorun"+setting.id])
		}
		setting.autorotate[1]=setting.autorotate[1]+(1/setting.enablefade[1]*50) //add time to run fade animation (roughly) to delay between rotation
	 this.autorotate(setting)
	}
},

urlparamselect:function(fcsid){
	var result=window.location.search.match(new RegExp(fcsid+"=(\\d+)", "i")) //check for "?featuredcontentsliderid=2" in URL
	return (result==null)? null : parseInt(RegExp.$1) //returns null or index, where index (int) is the selected tab's index
},

turnpage:function(setting, thepage, autocall){
	var currentpage=setting.currentpage //current page # before change
	var totalpages=setting.contentdivs.length
	var turntopage=(/prev/i.test(thepage))? currentpage-1 : (/next/i.test(thepage))? currentpage+1 : parseInt(thepage)
	turntopage=(turntopage<1)? totalpages : (turntopage>totalpages)? 1 : turntopage //test for out of bound and adjust
	if (turntopage==setting.currentpage && typeof autocall=="undefined") //if a pagination link is clicked on repeatedly
		return
	setting.currentpage=turntopage
	setting.contentdivs[turntopage-1].style.zIndex=++setting.topzindex
	this.cleartimer(setting, window["fcsfade"+setting.id])
	setting.cacheprevpage=setting.prevpage
	if (setting.enablefade[0]==true){
		setting.curopacity=0
		this.fadeup(setting)
	}
	if (setting.enablefade[0]==false){ //if fade is disabled, fire onChange event immediately (verus after fade is complete)
		setting.contentdivs[setting.prevpage-1].style.display="none" //collapse last content div shown (it was set to "block")
		setting.onChange(setting.prevpage, setting.currentpage)
	}
	setting.contentdivs[turntopage-1].style.visibility="visible"
	setting.contentdivs[turntopage-1].style.display="block"
	if (setting.prevpage<=setting.toclinks.length) //make sure pagination link exists (may not if manually defined via "markup", and user omitted)
		this.css(setting.toclinks[setting.prevpage-1], "selected", "remove")
	if (turntopage<=setting.toclinks.length) //make sure pagination link exists (may not if manually defined via "markup", and user omitted)
		this.css(setting.toclinks[turntopage-1], "selected", "add")
	setting.prevpage=turntopage
	if (this.enablepersist)
		this.setCookie("fcspersist"+setting.id, turntopage)
},

setopacity:function(setting, value){ //Sets the opacity of targetobject based on the passed in value setting (0 to 1 and in between)
	var targetobject=setting.contentdivs[setting.currentpage-1]
	if (targetobject.filters && targetobject.filters[0]){ //IE syntax
		if (typeof targetobject.filters[0].opacity=="number") //IE6
			targetobject.filters[0].opacity=value*100
		else //IE 5.5
			targetobject.style.filter="alpha(opacity="+value*100+")"
	}
	else if (typeof targetobject.style.MozOpacity!="undefined") //Old Mozilla syntax
		targetobject.style.MozOpacity=value
	else if (typeof targetobject.style.opacity!="undefined") //Standard opacity syntax
		targetobject.style.opacity=value
	setting.curopacity=value
},

fadeup:function(setting){
	if (setting.curopacity<1){
		this.setopacity(setting, setting.curopacity+setting.enablefade[1])
		window["fcsfade"+setting.id]=setTimeout(function(){featuredcontentslider.fadeup(setting)}, 50)
	}
	else{ //when fade is complete
		if (setting.cacheprevpage!=setting.currentpage) //if previous content isn't the same as the current shown div (happens the first time the page loads/ script is run)
			setting.contentdivs[setting.cacheprevpage-1].style.display="none" //collapse last content div shown (it was set to "block")
		setting.onChange(setting.cacheprevpage, setting.currentpage)
	}
},

cleartimer:function(setting, timervar){
	if (typeof timervar!="undefined"){
		clearTimeout(timervar)
		clearInterval(timervar)
		if (setting.cacheprevpage!=setting.currentpage){ //if previous content isn't the same as the current shown div
			setting.contentdivs[setting.cacheprevpage-1].style.display="none"
		}
	}
},

css:function(el, targetclass, action){
	var needle=new RegExp("(^|\\s+)"+targetclass+"($|\\s+)", "ig")
	if (action=="check")
		return needle.test(el.className)
	else if (action=="remove")
		el.className=el.className.replace(needle, "")
	else if (action=="add")
		el.className+=" "+targetclass
},

autorotate:function(setting){
 window["fcsautorun"+setting.id]=setInterval(function(){featuredcontentslider.turnpage(setting, "next")}, setting.autorotate[1])
},

getCookie:function(Name){ 
	var re=new RegExp(Name+"=[^;]+", "i"); //construct RE to search for target name/value pair
	if (document.cookie.match(re)) //if cookie found
		return document.cookie.match(re)[0].split("=")[1] //return its value
	return null
},

setCookie:function(name, value){
	document.cookie = name+"="+value

},


init:function(setting){
	var persistedpage=this.getCookie("fcspersist"+setting.id) || 1
	var urlselectedpage=this.urlparamselect(setting.id) //returns null or index from: mypage.htm?featuredcontentsliderid=index
	this.settingcaches[setting.id]=setting //cache "setting" object
	setting.contentdivs=[]
	setting.toclinks=[]
	setting.topzindex=0
	setting.currentpage=urlselectedpage || ((this.enablepersist)? persistedpage : 1)
	setting.prevpage=setting.currentpage
	setting.revealtype="on"+(setting.revealtype || "click")
	setting.curopacity=0
	setting.onChange=setting.onChange || function(){}
	if (setting.contentsource[0]=="inline")
		this.buildpaginate(setting)
	if (setting.contentsource[0]=="ajax")
		this.ajaxconnect(setting)
}

}

/* =====================================================================================================================================
 * gAjax RSS Feeds Displayer- By Dynamic Drive, available at: http://www.dynamicdrive.com - RSS FEEDS ==================================
 * Created: July 17th, 2007
 * Updated June 14th, 10': Fixed issue in IE where labels would sometimes be associated with the incorrect feed items
 */
var gfeedfetcher_loading_image="/Style%20Library/Edexcel/images/QualsDropDown/ajax-loader.gif" //Full URL to "loading" image. No need to config after this line!!

google.load("feeds", "1") //Load Google Ajax Feed API (version 1)

function gfeedfetcher(divid, divClass, linktarget){
	this.linktarget=linktarget || "" //link target of RSS entries
	this.feedlabels=[] //array holding lables for each RSS feed
	this.feedurls=[]
	this.feeds=[] //array holding combined RSS feeds' entries from Feed API (result.feed.entries)
	this.feedsfetched=0 //number of feeds fetched
	this.feedlimit=5
	this.showoptions="" //Optional components of RSS entry to show (none by default)
	this.sortstring="date" //sort by "date" by default
	document.write('<div id="'+divid+'" class="'+divClass+'"></div>') //output div to contain RSS entries
	this.feedcontainer=document.getElementById(divid)
	this.itemcontainer="<li>" //default element wrapping around each RSS entry item
}

gfeedfetcher.prototype.addFeed=function(label, url){
	this.feedlabels[this.feedlabels.length]=label
	this.feedurls[this.feedurls.length]=url
}

gfeedfetcher.prototype.filterfeed=function(feedlimit, sortstr){
	this.feedlimit=feedlimit
	if (typeof sortstr!="undefined")
	this.sortstring=sortstr
}

gfeedfetcher.prototype.displayoptions=function(parts){
	this.showoptions=parts //set RSS entry options to show ("date, datetime, time, snippet, label, description")
}

gfeedfetcher.prototype.setentrycontainer=function(containerstr){  //set element that should wrap around each RSS entry item
this.itemcontainer="<"+containerstr.toLowerCase()+">"
}

gfeedfetcher.prototype.init=function(){
	this.feedsfetched=0 //reset number of feeds fetched to 0 (in case init() is called more than once)
	this.feeds=[] //reset feeds[] array to empty (in case init() is called more than once)
	this.feedcontainer.innerHTML='<img src="'+gfeedfetcher_loading_image+'" /> Retrieving RSS feed(s)'
	var displayer=this
	for (var i=0; i<this.feedurls.length; i++){ //loop through the specified RSS feeds' URLs
		var feedpointer=new google.feeds.Feed(this.feedurls[i]) //create new instance of Google Ajax Feed API
		var items_to_show=(this.feedlimit<=this.feedurls.length)? 1 : Math.floor(this.feedlimit/this.feedurls.length) //Calculate # of entries to show for each RSS feed
		if (this.feedlimit%this.feedurls.length>0 && this.feedlimit>this.feedurls.length && i==this.feedurls.length-1) //If this is the last RSS feed, and feedlimit/feedurls.length yields a remainder
			items_to_show+=(this.feedlimit%this.feedurls.length) //Add that remainder to the number of entries to show for last RSS feed
		feedpointer.setNumEntries(items_to_show) //set number of items to display
		feedpointer.load(function(label){
			return function(r){
				displayer._fetch_data_as_array(r, label)
			}
		}(this.feedlabels[i])) //call Feed.load() to retrieve and output RSS feed.
	}
}


gfeedfetcher._formatdate=function(datestr, showoptions){
	var itemdate=new Date(datestr)
	var parseddate=(showoptions.indexOf("datetime")!=-1)? itemdate.toLocaleString() : (showoptions.indexOf("date")!=-1)? itemdate.toLocaleDateString() : (showoptions.indexOf("time")!=-1)? itemdate.toLocaleTimeString() : ""
	return "<span class='datefield'>"+parseddate+"</span>"
}

gfeedfetcher._sortarray=function(arr, sortstr){
	var sortstr=(sortstr=="label")? "ddlabel" : sortstr //change "label" string (if entered) to "ddlabel" instead, for internal use
	if (sortstr=="title" || sortstr=="ddlabel"){ //sort array by "title" or "ddlabel" property of RSS feed entries[]
		arr.sort(function(a,b){
		var fielda=a[sortstr].toLowerCase()
		var fieldb=b[sortstr].toLowerCase()
		return (fielda<fieldb)? -1 : (fielda>fieldb)? 1 : 0
		})
	}
	else{ //else, sort by "publishedDate" property (using error handling, as "publishedDate" may not be a valid date str if an error has occured while getting feed
		try{
			arr.sort(function(a,b){return new Date(b.publishedDate)-new Date(a.publishedDate)})
		}
		catch(err){}
	}
}

gfeedfetcher.prototype._fetch_data_as_array=function(result, ddlabel){	
	var thisfeed=(!result.error)? result.feed.entries : "" //get all feed entries as a JSON array or "" if failed
	if (thisfeed==""){ //if error has occured fetching feed
		alert("Google Feed API Error: "+result.error.message)
	}
	for (var i=0; i<thisfeed.length; i++){ //For each entry within feed
		result.feed.entries[i].ddlabel=ddlabel //extend it with a "ddlabel" property
	}
	this.feeds=this.feeds.concat(thisfeed) //add entry to array holding all feed entries
	this._signaldownloadcomplete() //signal the retrieval of this feed as complete (and move on to next one if defined)
}

gfeedfetcher.prototype._signaldownloadcomplete=function(){
	this.feedsfetched+=1
	if (this.feedsfetched==this.feedurls.length) //if all feeds fetched
		this._displayresult(this.feeds) //display results
}


gfeedfetcher.prototype._displayresult=function(feeds){
	var rssoutput=(this.itemcontainer=="<li>")? "<ul>\n" : ""
	gfeedfetcher._sortarray(feeds, this.sortstring)
	for (var i=0; i<feeds.length; i++){
		var itemtitle="<a href=\"" + feeds[i].link + "\" target=\"" + this.linktarget + "\" class=\"titlefield\">" + feeds[i].title + "</a>"
		var itemlabel=/label/i.test(this.showoptions)? '<span class="labelfield">['+this.feeds[i].ddlabel+']</span>' : " "
		var itemdate=gfeedfetcher._formatdate(feeds[i].publishedDate, this.showoptions)
		var itemdescription=/description/i.test(this.showoptions)? "<br />"+feeds[i].content : /snippet/i.test(this.showoptions)? "<br />"+feeds[i].contentSnippet  : ""
		rssoutput+=this.itemcontainer + itemtitle + " " + itemlabel + " " + itemdate + "\n" + itemdescription + this.itemcontainer.replace("<", "</") + "\n\n"
	}
	rssoutput+=(this.itemcontainer=="<li>")? "</ul>" : ""
	this.feedcontainer.innerHTML=rssoutput
}

/* =====================================================================================================================================
 * gAjax RSS Ticker- By Dynamic Drive - RSS Ticker =====================================================================================
 * Created: Aug 2nd, 2007 Updated: n/a
 * REQUIRES: gfeedfetcher.js class, available at http://dynamicdrive.com/dynamicindex18/gajaxrssdisplayer.htm
 */ 
var gfeedfetcher_loading_image="/Style%20Library/Edexcel/images/QualsDropDown/ajax-loader.gif" //Specify full URL to "loading" image. Overwrites same var from gfeedfetcher.js

function gfeedrssticker(divid, divClass, delay, linktarget){
	this.tickerid=divid //ID of ticker div
	this.delay=parseInt(delay) //Default delay between msg change, in miliseconds.
	this.mouseoverBol=0 //Boolean to indicate whether mouse is currently over ticker (and pause it if it is)
	this.itemsperpage=1 //Entries to show per page
	this.messagepointer=0
	gfeedfetcher.call(this, divid, divClass, linktarget) //inherit properties from "gfeedfetcher" class and also use DIV generated by "gfeedfetcher"
	this.itemcontainer="<div>" //default element wrapping around each RSS entry
	this.tickerdiv=document.getElementById(divid)
}

gfeedrssticker.prototype=new gfeedfetcher //inherit methods from gfeedfetcher class
gfeedrssticker.prototype.constructor=gfeedrssticker
gfeedrssticker.prototype._displayresult=null //Remove inherited method "_displayresult()"


// -------------------------------------------------------------------
// entries_per_page()- Sets the number of RSS entries to display per page (at once)
// -------------------------------------------------------------------

gfeedrssticker.prototype.entries_per_page=function(num){
	this.itemsperpage=num
}

// -------------------------------------------------------------------
// _signaldownloadcomplete()- Signals to the rest of the script when the fetching of all RSS feeds is complete
// -------------------------------------------------------------------

gfeedrssticker.prototype._signaldownloadcomplete=function(){ //overwrite inherited method "_signaldownloadcomplete()"
	this.feedsfetched+=1
	if (this.feedsfetched==this.feedurls.length) //if all feeds fetched
		this._initscroller(this.feeds) //Populate the two DIVs within scroller with the fetched data
}

// -------------------------------------------------------------------
// _initscroller()- Initialize the ticker by populating it with the first batch of RSS feeds, and prepare to rotate it
// -------------------------------------------------------------------

gfeedrssticker.prototype._initscroller=function(feeds){
	var scrollerinstance=this
	gfeedfetcher._sortarray(feeds, this.sortstring)
	this.itemsperpage=(this.itemsperpage>=feeds.length)? 1 : this.itemsperpage //Adjust "itemsperpage" if needed (based on total # of avail entries)
	var feedslice=feeds.slice(this.messagepointer, this.itemsperpage) //Get subsection of feed array based on how many entries to show at once
	this.tickerdiv.innerHTML=formatrssmessage(feedslice, this.showoptions, this.itemcontainer, this.linktarget)
	this.tickerdiv.onmouseover=function(){scrollerinstance.mouseoverBol=1}
	this.tickerdiv.onmouseout=function(){scrollerinstance.mouseoverBol=0}
	this.messagepointer=this.itemsperpage //increment message pointer
	if (window.attachEvent) //Clean up loose references in IE
		window.attachEvent("onunload", function(){scrollerinstance.tickerdiv.onmouseover=scrollerinstance.tickerdiv.onmouseout=null})
	setTimeout(function(){scrollerinstance._rotatemessage()}, this.delay)
}


// -------------------------------------------------------------------
// formatrssmessage()- Global function that formats a RSS entry(s) to the desired components (title, date, description etc)
// -------------------------------------------------------------------

function formatrssmessage(feedslice, showoptions, itemcontainer, linktarget){
	var rssoutput=(itemcontainer=="<li>")? "<ul>\n" : "" //if "itemcontainer" is set to "<li>", define a "<ul>" tag to wrap around the result
	for (var i=0; i<feedslice.length; i++){ //Loop through the entered slice of a RSS feed (1 or more entries)
		var itemtitle="<a href=\"" + feedslice[i].link + "\" target=\"" + linktarget + "\" class=\"titlefield\">" + feedslice[i].title + "</a>"
		var itemlabel=/label/i.test(showoptions)? '<span class="labelfield">['+feedslice[i].ddlabel+']</span>' : " "
		var itemdate=gfeedfetcher._formatdate(feedslice[i].publishedDate, showoptions)
		var itemdescription=/description/i.test(showoptions)? "<br />"+feedslice[i].content : /snippet/i.test(showoptions)? "<br />"+feedslice[i].contentSnippet  : ""
		rssoutput+=itemcontainer + itemtitle + " " + itemlabel + " " + itemdate + "\n" + itemdescription + itemcontainer.replace("<", "</") + "\n\n"
	}
	rssoutput+=(itemcontainer=="<li>")? "</ul>\n" : ""
	return rssoutput
}


// -------------------------------------------------------------------
// _rotatemessage()- Rotates the ticker with the next batch of RSS entries, plus update message pointer
// -------------------------------------------------------------------

gfeedrssticker.prototype._rotatemessage=function(){
	var scrollerinstance=this
	if (this.mouseoverBol==1) //if mouse is currently over scoller, do nothing (pause it)
		setTimeout(function(){scrollerinstance._rotatemessage()}, 100)
	else{
		var feedslice=this.feeds.slice(this.messagepointer, this.messagepointer+this.itemsperpage)
		this.tickerdiv.innerHTML=formatrssmessage(feedslice, this.showoptions, this.itemcontainer, this.linktarget)
		this.messagepointer=(this.messagepointer+this.itemsperpage > this.feeds.length-1)? 0 : this.messagepointer+this.itemsperpage
		setTimeout(function(){scrollerinstance._rotatemessage()}, this.delay)
	}
}

/* =====================================================================================================================================
 * WPSC / ie5.5.js - script fix - NF & DH 27/07/2011 ===================================================================================
 */

if(typeof(WPSC) == "undefined"){
WPSC = new Object();
WPSC.Init = function(){
//do nothing
}
WPSC.WebPartPage = new Object();
WPSC.WebPartPage.Parts = new Object();
WPSC.WebPartPage.Parts.Register = function()
{
//do nothing
}
}

