var loadingDlg;
var loadingCount = 0 ;
var errorDlg;
var messages = new Array();
var playerProfileDlg;
var helpDlg;
var generalDlg;

function globalInit()
{

	//Set error handler to handle timeout
	DWREngine.setErrorHandler(errorHandler);

}

//Custom error handler
function errorHandler(msg,exception)
{
	//Redirect on a not logged in exception - session timeout
	if(exception.name=="org.directwebremoting.extend.LoginRequiredException")
	{
		window.location="NotLoggedIn.do"
	}
	else
	{
		//Invoke the default handler
		dwr.engine.defaultErrorHandler(msg,exception);
	}
	
}

//Shows information on the page, but with the title of the dialog as 'Information'
function showInformation()
{
	var errorText;
	errorText = $("div.information").html();
	if(errorText != "" && errorText!=null)
		showInformationDlg(errorText);

}

//Shows errors on the page, but with the title of the dialog as 'Information'
function showErrorsAsInformation()
{
	var errorText;
	errorText = $("div.errors").html();
	if(errorText != "" && errorText!=null)
		showInformationDlg(errorText);

}


//Shows erros placed in a div.errors section on the page as a popup
function showErrors()
{
	var errorText;
	errorText = $("div.errors").html();
	if(errorText != "" && errorText!=null)
		showErrorDlg(errorText);

}

//Utility function to extract an number from a indexed variable string
//e.g. extractindex("myVar:12") will return 12
function extractIndex(s)
{
	var start = s.indexOf(":");
	return s.substring(start+1);
	
}

//Extracts the data to the left of the colon.  If no colon gives the whole string
function extractName(s)
{
	var start = s.indexOf(":");
	if(start == -1) 
		return s;
	else
		return s.substring(0, start);
	
}

//Utility function to extract an number from a indexed variable string
//e.g. extractindex("myVar_12") will return 12
function extractIndexUS(s)
{
	var start = s.indexOf("_");
	return s.substring(start+1);
	
}

//Extracts the data to the left of the underscore.  If no _ gives the whole string
function extractNameUS(s)
{
	var start = s.indexOf("_");
	if(start == -1) 
		return s;
	else
		return s.substring(0, start);
	
}

function searchArray(findIn,item)
{
	for(e in findIn)
	{
		if(findIn[e]==item)
			return e;
	}
	return -1;
}

function arrayLength(array)
{
	var l = 0;
	for (var object in array) {
		l++;
	}
	return l;
}
//Returns the message with the args substituted
function message_with_args(msg_id, arg0, arg1, arg2)
{
var message; 

	message = messages[msg_id];

	if(arg0 != null)
		message = message.replace(/\{0\}/,arg0);
		
	if(arg1 != null)
		message = message.replace(/\{1\}/,arg1);

	if(arg2 != null)
		message = message.replace(/\{2\}/,arg2);

return message;
}


function handleOK()
{
	this.hide();
	this.destroy();
}

//Shows a warning dialog before navigating
function showDoubleConfirmNavigate(msg1, msg2, url)
{

		var myButtons = [ { text: messages["com.OK"],  
	                    handler:function(){this.hide(); this.destroy(); showConfirmNavigate(msg2, url);} }, 
	                  { text: messages["com.cancel"],  
	                    handler:function() {this.hide(); this.destroy();} }
	                    ];	                  	                  
		showWarningDlg(msg1, myButtons);
		return false;

}


//Shows a warning dialog before navigating
function showConfirmNavigate(msg, url)
{

		var myButtons = [ { text: messages["com.OK"],  
	                    handler:function(){window.location=url} }, 
	                  { text: messages["com.cancel"],  
	                    handler:function() {this.hide(); this.destroy();} }
	                    ];	                  	                  
		showWarningDlg(msg, myButtons);
		return false;

}

//Shows a warning dialog before carrying out the confirm action
function showConfirmDlg(msg, confirmAction)
{

		var myButtons = [ { text: messages["com.OK"],  
	                    handler:function() {this.hide(); this.destroy(); confirmAction(); }}, 
	                  { text: messages["com.cancel"],  
	                    handler:function() {this.hide(); this.destroy();} }
	                    ];	                  	                  
		showWarningDlg(msg, myButtons);
		return false;

}

function showErrorDlg(msg)
{
		errorDlg = new YAHOO.widget.SimpleDialog("dlg", { visible: false, width: "20em", close:false, fixedcenter:true, modal:true, draggable:false });
		errorDlg.setHeader(messages["com.error"]);
		errorDlg.setBody(msg);
		errorDlg.cfg.setProperty("icon",YAHOO.widget.SimpleDialog.ICON_ERROR);
		var myButtons = [ { text: messages["com.OK"],  
	                    handler:handleOK } ];
		errorDlg.cfg.queueProperty("buttons", myButtons);
		
		errorDlg.render(document.body); 
		errorDlg.show();
}

function showInformationDlg(msg)
{
		errorDlg = new YAHOO.widget.SimpleDialog("dlg", { visible: false, width: "20em", close:false, fixedcenter:true, modal:true, draggable:false });
		errorDlg.setHeader(messages["com.information"]);
		errorDlg.setBody(msg);
		errorDlg.cfg.setProperty("icon",YAHOO.widget.SimpleDialog.ICON_ERROR);
		var myButtons = [ { text: messages["com.OK"],  
	                    handler:handleOK } ];
		errorDlg.cfg.queueProperty("buttons", myButtons);
		
		errorDlg.render(document.body); 
		errorDlg.show();
}

//Shows a warning dialog with options
function showWarningDlg(msg, myButtons)
{
		errorDlg = new YAHOO.widget.SimpleDialog("dlg", { visible: false, width: "20em", close:false, fixedcenter:true, modal:true, draggable:false });
		errorDlg.setHeader(messages["com.warning"]);
		errorDlg.setBody(msg);
		errorDlg.cfg.setProperty("icon",YAHOO.widget.SimpleDialog.ICON_ERROR);
		errorDlg.cfg.queueProperty("buttons", myButtons);
		
		errorDlg.render(document.body); 
		errorDlg.show();
}

//Shows a dialog with a message with no buttons to be displayed while another page loads
function showWaitDlg(msg)
{
		loadingDlg = new YAHOO.widget.SimpleDialog("dlg", { visible: false, width: "20em", fixedcenter:true, modal:true, close:false, draggable:false });
		loadingDlg.buttons = null;
		loadingDlg.setHeader(messages["com.pleaseWait"]);
		loadingDlg.setBody(msg);
		loadingDlg.render(document.body); 
		loadingDlg.show();
}

//Updates the message on the dialog
function updateWaitDlg(msg)
{
		loadingDlg.setBody(msg);
}

function showLoadingDlg()
{
	if(loadingCount==0)
	{
		loadingDlg = new YAHOO.widget.SimpleDialog("dlg", { visible: false, width: "20em", fixedcenter:true, modal:true, close:false, draggable:false });
		loadingDlg.buttons = null;
		loadingDlg.setHeader(messages["com.loading"]);
		loadingDlg.setBody(messages["com.pleaseWait"]);
//		loadingDlg.cfg.setProperty("icon",YAHOO.widget.SimpleDialog.ICON_INFO);
		loadingDlg.render(document.body); 
		loadingDlg.show();
	}
	loadingCount++
}


function hideLoadingDlg()
{
	loadingCount--;
	if(loadingCount==0)
	{
		loadingDlg.hide();
		loadingDlg.destroy();
		loadingDlg=null;
	}
	//Just for safety in case it has got <0
	if(loadingCount<0)
		loadingCount=0;
}

//Checks if contains only alphanumeric and space
function isAlphaNumericSpace(val)
{
	return val.match(/^[a-zA-Z0-9 ]+$/);
}

//Checks if contains only alphanumeric
function isAlphaNumeric(val)
{
	return val.match(/^[a-zA-Z0-9]+$/);
}

//Checks if only numeric characters
function isNumeric(val)
{
	return val.match(/^[0-9]+$/);
}

/**
* Reference: Sandeep V. Tamhankar (stamhankar@hotmail.com),
* http://javascript.internet.com
*/
function isEmail(emailStr) {
    if (emailStr.length == 0) {
        return true;
    }
    // TLD checking turned off by default
    var checkTLD=0;
    var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;
    var emailPat=/^(.+)@(.+)$/;
    var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
    var validChars="\[^\\s" + specialChars + "\]";
    var quotedUser="(\"[^\"]*\")";
    var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
    var atom=validChars + '+';
    var word="(" + atom + "|" + quotedUser + ")";
    var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
    var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
    var matchArray=emailStr.match(emailPat);
    if (matchArray==null) {
        return false;
    }
    var user=matchArray[1];
    var domain=matchArray[2];
    for (i=0; i<user.length; i++) {
        if (user.charCodeAt(i)>127) {
            return false;
        }
    }
    for (i=0; i<domain.length; i++) {
        if (domain.charCodeAt(i)>127) {
            return false;
        }
    }
    if (user.match(userPat)==null) {
        return false;
    }
    var IPArray=domain.match(ipDomainPat);
    if (IPArray!=null) {
        for (var i=1;i<=4;i++) {
            if (IPArray[i]>255) {
                return false;
            }
        }
        return true;
    }
    var atomPat=new RegExp("^" + atom + "$");
    var domArr=domain.split(".");
    var len=domArr.length;
    for (i=0;i<len;i++) {
        if (domArr[i].search(atomPat)==-1) {
            return false;
        }
    }
    if (checkTLD && domArr[domArr.length-1].length!=2 && 
        domArr[domArr.length-1].search(knownDomsPat)==-1) {
        return false;
    }
    if (len<2) {
        return false;
    }
    return true;
}


/* Player Profile pop-up functions*/

//This requires that the tile for the player profile dialog is included at the bottom of the page
function initPlayerProfileDlg()
{
	playerProfileDlg= new YAHOO.widget.Dialog("playerProfileDlg",{ x: 400, y: 100, close:false, modal:true, draggable:false });

	//Can remove the loading class after the dialogs have been created
	$("#dialogs").removeClass("loading");

	//Don't cache pages in browser (ie7 does this)
	//N.B.  may be able to remove this see Bug409
	
	//Also setup generic callback function - this will be needed if the session on session timeout
	$.ajaxSetup({cache: false,error:callbackAjaxDlgError});
}

//Shows the player profile popup - optional mch_id to get availability
function showPlayerProfileDlg(sfp_id,mch_id)
{
	
	showLoadingDlg();
	//Invoke the AJAX call
	var url;
	url="PlayerProfileDlg.do?sfp_id="+sfp_id;
	if(mch_id != null) url+="&mch_id="+mch_id;
	$.get(url,null,callbackShowPlayerProfileDlg);
}

//Callback if the ajax call fails.  This will happen if the session times out while the user is on the page
function callbackAjaxDlgError(request, textStatus, errorThrown) 
{
	if(request.status==401)
	{
		window.location="NotLoggedIn.do";
	}
	else
	{
		alert("Ajax call failed request.status="+request.status);
	}
}

//Called when ajax call returns
function callbackShowPlayerProfileDlg(data, textStatus) 
{

	$("#playerProfileDlg .bd").html(data);	
	var myButtons = [ { text: messages["com.OK"],  
	                    handler: function() {this.hide();} } ];                    
	playerProfileDlg.cfg.queueProperty("buttons", myButtons);
	
	hideLoadingDlg();

	playerProfileDlg.render();

	initCollapsiblePanels($("#playerProfileDlg .bd"));
	activateCollapsiblePanels($("#playerProfileDlg .bd"));
	
	//Set the title to the players name
	$("#playerProfileDlg .hd").html( $(".hiddenData.long_name").html() );
	


	playerProfileDlg.show();
	$("#playerProfileDlg .loading").removeClass("loading");
}


//This requires that the tile for the help dialog is included at the bottom of the page
function initHelpDlg()
{
	
	helpDlg= new YAHOO.widget.Dialog("helpDlg",{ x: 400, y: 100, close:false, modal:true, draggable:false });

	//Can remove the loading class after the dialogs have been created
	$("#commonDialogs").removeClass("loading");

	//Cache pages in browser 
	$.ajaxSetup({cache: true});
}

//Shows the help dialog
function showHelpDlg(hlp_id)
{
	
	showLoadingDlg();
	//Invoke the AJAX call
	var url;
	url="HelpDlg.do?hlp_id="+hlp_id+"&rev="+rev;
	$.get(url,null,callbackShowHelpDlg);
	return false;
}

//PreProcesses help markup
//1. replaces <hl:youtube videoID=""/> tags with code for Youtube videos
function preProcessHelpMarkup(html)
{
	var youtubeHTML='<object width="425" height="355">';
		youtubeHTML+='<param name="movie" value="http://www.youtube.com/v/$1?color1=0x000000&color2=0xF1C832"></param>';
		youtubeHTML+='<param name="allowFullScreen" value="true"></param>';
		youtubeHTML+='<param name="allowScriptAccess" value="always"></param>';
		youtubeHTML+='<embed src="http://www.youtube.com/v/$1?color1=0x000000&color2=0xF1C832"';
		youtubeHTML+='type="application/x-shockwave-flash"';
		youtubeHTML+='allowscriptaccess="always"';
		youtubeHTML+='width="425" height="355"';
		youtubeHTML+='allowfullscreen="true"></embed>';
		youtubeHTML+='</object>';

	//N.B. Need to escape forward slash.  g at the end is to do a global match
	var hlVideoRegex=/<hl:youtube videoID="(.*?)"\/>/g;
	return html.replace(hlVideoRegex,youtubeHTML);
}

//Called when ajax call returns
function callbackShowHelpDlg(data, textStatus) 
{
	
	data=preProcessHelpMarkup(data);
	
	$("#helpDlg .bd").html(data);
	//Need to remove html to stop any video
	var myButtons = [ { text: messages["com.OK"],  
	                    handler: function() {$("#helpDlg .bd").html(""); this.hide();} } ];                    
	helpDlg.cfg.queueProperty("buttons", myButtons);
	
	hideLoadingDlg();

	helpDlg.render();	

	helpDlg.show();
	$("#helpDlg .loading").removeClass("loading");
}



//This requires that the tile for the help dialog is included at the bottom of the page
function initGeneralDlg()
{
	
	generalDlg= new YAHOO.widget.Panel("generalDlg",{ fixedcenter: true, close:false, modal:true, draggable:false, underlay:"none"});

	//Can remove the loading class after the dialogs have been created
	$("#commonDialogs").removeClass("loading");

	//Cache pages in browser 
	$.ajaxSetup({cache: true});
}

//Shows the help dialog
function showGeneralDlg(url)
{
	
	showLoadingDlg();
	//Invoke the AJAX call
	$.get(url,null,callbackShowGeneralDlg);
}

//Called when ajax call returns
function callbackShowGeneralDlg(data, textStatus) 
{

	$("#generalDlg").html(data);	
	
	hideLoadingDlg();

	generalDlg.render();	
	generalDlg.show();
	$("#generalDlg .loading").removeClass("loading");
	
	init_magic_buttons("#generalDlg");
	alt_rows("#generalDlg");
	FB.XFBML.parse();
}

function hideGeneralDlg()
{
	generalDlg.hide();
	return false;
}	


//Fixes Bug724 which causes borders not to be shown on empty <td>s in IE7
//Apparently fixed in IE8
function initFixIE7TableBorderBug()
{
	var module = new YAHOO.widget.Module;
	//ie = ie6, ie7=ie7
	if(module.browser=="ie" || module.browser=="ie7")
	{
		$("td:empty").html("&nbsp");
	}
}

//Fixes Bug356 where scroll bars poke through dialogs
function initFixMacFirefoxBug()
{
	
	//Construct object to be able to call the platform/browser methods
	var module = new YAHOO.widget.Module;

	//Only implement fixes for mac firefox
	if (module.platform == "mac" && module.browser == "gecko")
	{

		//Override hide/show methods
		YAHOO.widget.Module.prototype.show = function()
		{
			fixMacFirefoxBugShow();
			this.cfg.setProperty("visible", true);
			
		};


		YAHOO.widget.Module.prototype.hide = function()
		{
			this.cfg.setProperty("visible", false);
			fixMacFirefoxBugHide();
		};

	}
}

//Add the class to any classes marked as having a scrollbar
function fixMacFirefoxBugShow()
{
		$(".overflowYScroll").addClass("macFirefoxBugFix");
}

//Remove the class
function fixMacFirefoxBugHide()
{
		$(".macFirefoxBugFix").removeClass("macFirefoxBugFix");
}

//Creates an LI element representing a player with the given id
//The mch_id is the match of the availablity to check the player for
function createPlayerLI(id, player,mch_id)
{
	var htmlClass;
	
	var obj=createPlayerHTML(id, player,mch_id,true);

	var li = document.createElement("li");
	li.id = id;
	li.innerHTML = obj.html;
			
	li.className = obj.htmlClass;
	return li;
}

//Creates HTML for the player
//Returns an object with the html and the class
//if showPositions is true then a pos list is included
function createPlayerHTML(id, player,mch_id,showPositions)
{
	var html = "";
	var htmlClass = "playerDetails";

	//TODO: Need symbols here in place of letters
	html+="<span class='ic' id='ic"+id+"'>&nbsp;</span>"
	html+="<span class='pl'>"+player.shirt_no +"." + " " + player.long_name + "</span>";
	html+="<a  class='info' href='javascript:showPlayerProfileDlg("+player.sfp_id+","+mch_id+")'>&nbsp;</a>";

	//The classes need to be added twice here ie.g "form charValueVeryGood" and "form_charValueVeryGood" as IE6 cannot select on .form.charValueVeryGood
	html+= "<span title='"+messages["SFPCharLabel.RecentForm"]+"' class='kc form "+player.form+" form_"+player.form+"'>&nbsp;</span>";
	html+= "<span title='"+messages["SFPCharLabel.Fitness"]+"' class='kc fitness "+player.fitness+" fitness_"+player.fitness+"'>&nbsp;</span>";
	html+= "<span title='"+messages["SFPCharLabel.SquadStatus"]+"' class='kc ss "+player.squad+" ss_"+player.squad+"'>&nbsp;</span>";
	
	if(showPositions)
		html+= "<span class='posList'>"+player.posList+"&nbsp;</span>";


	//Work out cards
	if(player.sent_off_event_no !=null && player.sent_off_event_no > 0)
	{
		html+="<span class='cards redCard'>&nbsp;</span>";
		htmlClass+=" sentOff";
	}
	else if(player.yellow_cards !=null && player.yellow_cards > 0) 
	{
		html+="<span class='cards yellowCard'>&nbsp;</span>";
	}


	//Add status.  If permanent injury or serious potential injury picked up in the match
	if ((player.injured != null && player.injured) || (player.suspected_injury_type != null && player.suspected_injury_type=="S"))
	{
		html+= "<span title='"+messages["com.injured"]+"' class='status injured_serious'>&nbsp;</span>";
	}
	
	//If minor injury picked up in the match
	if (player.suspected_injury_type != null && player.suspected_injury_type=="M")
	{
		html+= "<span title='"+messages["com.injured"]+"' class='status injured_minor'>&nbsp;</span>";
	}

	if (player.cup_tied != null && player.cup_tied)
	{
		html+= "<span title='"+messages["com.cupTied"]+"' class='status cup_tied'>&nbsp;</span>";
	}

	if (player.suspended != null && player.suspended)
	{
		html+= "<span title='"+messages["com.suspended"]+"' class='status suspended'>&nbsp;</span>";
	}

	if(player.avail != null && !player.avail)
	{
		htmlClass+=" playerNotAvailable";
	}
	return {html:html, htmlClass:htmlClass};
	
}

//Fixes PNG if necessary for IE6
function fixPNG(target)
{
	//Probably a JQuery equivalent of this
	var module = new YAHOO.widget.Module;
	
	if(isIE6())
		return DD_belatedPNG.fix(target);
}

/* True if IE6 */
function isIE6()
{
	var module = new YAHOO.widget.Module;
	//ie = ie6, ie7=ie7
	return(module.browser=="ie" || module.browser=="ie6");
}

function isIE7()
{
	var module = new YAHOO.widget.Module;
	//ie = ie6, ie7=ie7
	return(module.browser=="ie7");
}

/* From w3schools.com */
function setCookie(c_name,value,expiredays)
{
var exdate=new Date();
exdate.setDate(exdate.getDate()+expiredays);
document.cookie=c_name+ "=" +escape(value)+
((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
}

function getCookie(c_name)
{
if (document.cookie.length>0)
  {
  c_start=document.cookie.indexOf(c_name + "=");
  if (c_start!=-1)
    {
    c_start=c_start + c_name.length+1;
    c_end=document.cookie.indexOf(";",c_start);
    if (c_end==-1) c_end=document.cookie.length;
    return unescape(document.cookie.substring(c_start,c_end));
    }
  }
return "";
}

var dayCountdownMillis;
function updateDayCountdown()
{
	if(dayCountdownMillis<0)
		dayCountdownMillis=0;
	var d=separateMillis(dayCountdownMillis);
	$("#cdDays").html(d.days);
	$("#cdHours").html(d.hours);
	$("#cdMins").html(d.minutes);
	$("#cdSecs").html(d.seconds);
	
	//Don't count past zero
	if(dayCountdownMillis!=0)
	{
		dayCountdownMillis-=1000;
		setTimeout("updateDayCountdown()", 1000);	
	}
}

function separateMillis(millis)
{
	var seconds=(millis)/1000;
	var days=Math.floor((seconds)/(60*60*24));
	var hours=Math.floor(seconds/(60*60))%24;
	var mins=Math.floor(seconds/60)%60;
	var secs=Math.floor(seconds%60);
	return {days: days, hours: hours, minutes: mins, seconds: secs};
}

//Returns the date from a date picker
function getDateFromPicker(context)
{
return new Date(
		$(".datePickerYear",context).val(),
		$(".datePickerMonth",context).val()-1,
		$(".datePickerDay",context).val())
}

function formatDate(d,format)
{
	var day=d.getDate() < 10 ? "0"+d.getDate() : ""+d.getDate();
	var month=d.getMonth() < 9 ? "0"+(d.getMonth()+1) : ""+(d.getMonth()+1);	

	if(format=="dd-MM-yyyy")
		return day+"-"+month+"-"+d.getFullYear();
	if(format=="yyyy-MM-dd")
		return d.getFullYear()+"-"+month+"-"+day;
}

//Show context help hovering tooltip
//Position = left/right
//CloseStepID = optional step to complete on closing
var contextHelpInit=false;
var globalCloseStepID;
function tutorialContextHelp(selector,message,position,closeStepID)
{
	if(position==null) position="left";
	$("#contextHelpContainer").stop(); 
	$("#contextHelpContainer").find("span.top").html(message);
	$("#contextHelpContainer .contextHelpDlg").removeClass("left right");
	$("#contextHelpContainer .contextHelpDlg").addClass(position);
	$("#contextHelpContainer").show();
	var pos=$(selector).eq(0).offset();
	if(position=="left")
		pos.left = pos.left - 180;
	else if(position=="right")
		pos.left=pos.left + $(selector).eq(0).width();
	$("#contextHelpContainer").css(pos);
	globalCloseStepID=closeStepID;
	//Initialise
	if(!contextHelpInit)
	{
		$(".contextHelpClose").click(
			function(){
				$("#contextHelpContainer").hide(); 
				$("#contextHelpContainer").stop();
				if(globalCloseStepID!=null)
					updateTutorialProgress(globalCloseStepID);
				});
				
		$(".contextHelpClose").hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")});
		contextHelpInit=true;
	}
	tutorialHelpMoveLeft();	//Start anim
	
	//Scroll if not visible
	if(!isScrolledIntoView($(selector).eq(0))) self.scrollTo(pos.left,pos.top);
	return false;
}

//Anim funcs
function tutorialHelpMoveRight()
{
		$("#contextHelpContainer").animate({left:'+=5'},300,"linear",tutorialHelpMoveLeft);
}

function tutorialHelpMoveLeft()
{
		$("#contextHelpContainer").animate({left:'-=5'},800,"linear",tutorialHelpMoveRight);
}


function hideTutorialPanel(stepID,panelSelector)
{
	$("#contextHelpContainer").stop();
	$("#contextHelpContainer").hide();
	$(panelSelector).hide();
	
	updateTutorialProgress(stepID);
}

//Marks a tutorial step complete on the server
function updateTutorialProgress(stepID)
{
	
	$.ajaxSetup({cache: false,error:callbackAjaxDlgError});
	//Invoke the AJAX call
	var url;
	url="UpdateTutorialProgress.do";
	var data = {action:"complete", stepID: stepID};
	$.post(url,data,callbackUpdateTutorialProgress,"html");
	return false;
}

function callbackUpdateTutorialProgress(data, textStatus) 
{
	var data = $(data);
}

//Checks if item is visible
function isScrolledIntoView(elem) {
    var docViewTop = $(window).scrollTop(),
        docViewBottom = docViewTop + $(window).height(),
        elemTop = $(elem).offset().top,
     elemBottom = elemTop + $(elem).height();
   //Is more than half of the element visible
   return ((elemTop + ((elemBottom - elemTop)/2)) >= docViewTop && ((elemTop + ((elemBottom - elemTop)/2)) <= docViewBottom));
}
