/**
 * @author andrew
 * Eye candy and stuff to hide/reveal content - also some ajax stuff
 */


jQuery(document).ready(function() {
	initToggleContent();	//hide content that starts off collapsed 
	jsHover();	//apply image rollover effects
	busyStop();	//stop the busy animation once the page loads
});




//collapses content that starts off collapsed (to maximise SEO value of content) and inserts the toggle icon images 
function initToggleContent() {
	jQuery('.collapsedByDefault').slideUp(0).after('<div class="substituteDiv"></div>');		//hide content that is marked for collapse.  The extra div is inserted as a substitute block element 
	jQuery('.toggleIcon').css('cursor', 'pointer');
}




function toggleContent(toggleIconElement, expandImage, collapseImage, groupSelector) {
	var $toggleIconElement = jQuery(toggleIconElement);
	var $content = $toggleIconElement.next();
	if (!$content.is('div')) { $content = $content.next('div'); }	//the collapsing div may be one more element along 
	
	if ($content.css('display') == 'none') {
		if (typeof groupSelector != 'undefined') {
			toggleAllContent(groupSelector, false, expandImage);
		}
		$content.slideDown(500);
		$toggleIconElement.attr('src', collapseImage);
	} else {
		$content.slideUp(300);
		$toggleIconElement.attr('src', expandImage);
		if (!$content.next().hasClass('substituteDiv')) {
			$content.after('<div class="substituteDiv"></div>');	//the empty div prevents inline elements from shifting when the content is removed 
		}
	}
}

function toggleAllContent(toggleIconSelector, open, toggleImage) {
	var $toggleIconElement;
	var $content;
	if (typeof open == 'undefined') {
		open = false;
	}
	
	jQuery(toggleIconSelector).each(function() {
		$toggleIconElement = jQuery(this);
		$content = $toggleIconElement.next();
		if (!$content.is('div')) { $content = $content.next('div'); }	//the collapsing div may be one more element along 
		
		if ($content.css('display') == 'none' && open) {
			$content.slideDown(500);
			$toggleIconElement.attr('src', toggleImage);
		}
		
		if($content.css('display') != 'none' && !open) {
			$content.slideUp(300);
			$toggleIconElement.attr('src', toggleImage);
			if (!$content.next().hasClass('substituteDiv')) {
				$content.after('<div class="substituteDiv"></div>');	//the empty div prevents inline elements from shifting when the content is removed
			}
		}
		
	});
}





function jsHover() {
	var $element;
	
	jQuery('.jsHover').each(function() {
		$element = jQuery(this);
		 
		$element.css('cursor', 'pointer');

		$element.mouseover(function() {
			jQuery(this).css('opacity', 0.7);
		});

		$element.mouseout(function() {
			jQuery(this).css('opacity', 1.0);
		});
  	});
}


//show busy animation
function busyStart() {
	jQuery('#busyAnimation').css('display', 'block');	//start the busy animation 
	jQuery('body').css('cursor', 'progress');	//start the busy cursor indicator 
	jQuery('.submitButton').attr('disabled', 'disabled');	//prevent multiple submits by disabling the submit button
}

//stop busy animation
function busyStop() {
	jQuery('#busyAnimation').css('display', 'none');	//stop the busy animation now that the server has responded
	jQuery('body').css('cursor', 'default');	//stop the busy cursor indicator
	jQuery('.submitButton').attr('disabled', '');	//re-enable the submit button
}




//allows the popupDialog function to display the content at the specified url (via ajax call)   
function popupUrl(title, url, modal, data, callback) {
	busyStart();
	if (typeof data == 'undefined') {
		data = false;
	}
	
	if (jQuery('#urlModalDialog').length == 0) {
		jQuery('body').append('<div id="urlModalDialog" title="'+title+'"></div>');	
	}

	//load the specified url content via ajax call into the dialog placeholder
	jQuery('#urlModalDialog').load(url, data, function() {
		popupDialog('#urlModalDialog', '', modal, callback)
		jQuery('#urlModalDialog').dialog( "option", "title", title );	//change the title in the case that another dialog was open
		jQuery('.initialFocus').focus().select();	//select any default form element

		busyStop();
	});
}





//popup message window
var openDialogs = new Object();

function popupDialog(title, body, modal, callback) {
	modal = (typeof modal == 'undefined') ? false : modal;
	
	if (typeof body != 'undefined' && body.length > 0) {
		jQuery('#modalDialog').dialog('close').remove();	//remove any previous message
		jQuery('body').append('<div id="modalDialog" title="'+title+'"><p style="text-align:left;">'+body+'</p></div>');
		placeholder = jQuery('#modalDialog');
		openDialogs['#modalDialog'] = placeholder;	
	} else {
		if (typeof openDialogs[title] != 'undefined') {
			openDialogs[title].dialog('open');	//re-open existing dialog
			return;
		}
		placeholder = jQuery(title);
		openDialogs[title] = placeholder;
	}

	if (placeholder.length == 0) {
		alert("couldn't locate the dialog placeholder " + title);
		return;
	}	

	//initialize the dialog
	placeholder.dialog({
		modal: modal,
		resizable: true,
		width: 'auto',
		hide: 'slide',
		autoOpen: false
	})

	//execute any callback function on dialog open. Caution: if the callback script is loaded dynamically by popupUrl() then it may not execute properly in Firefox 
	if (typeof callback == 'function') {
		placeholder.bind("dialogopen", function(event, ui){
			callback();
		});
	}
	
	placeholder.dialog('open');	//open the dialog


	//maxHeight setting only applies to resizing - hence the need to manually limit the popup height to fit the viewport 
	if (placeholder.height() > (0.9*jQuery(window).height())) {
log('resize dialog height to', 0.8*jQuery(window).height());
		placeholder.dialog( "option", "height", 0.8*jQuery(window).height());
	}
}



//close any open popup dialogs
function closePopupDialogs() {
	var size = 0;
	for (key in openDialogs) {
        if (openDialogs.hasOwnProperty(key)) {
			if (openDialogs[key].dialog('isOpen')) {
log('closing dialog', key);
				openDialogs[key].dialog('close');
			}
		}
    }
}



function displayResult(selector) {
	jQuery(selector).css('display', 'inline')
		.css('opacity', 0.3)
		.css('fontSize', '0.3em')
		.animate({ fontSize: "1.5em", opacity: 1.0 }, 2000 ).animate({ opacity: 0.0 }, 8000 ).animate({ fontSize: "0em" }, 1000 );	//the fontsize reduction is because IE8 ignores the opacity fade
}






function animateResult(selector, className, message, cantWait) {
	var target = jQuery(selector);
	
	//if the result target doesn't exist then send the message to the general server-result box
	if (!target.length) {
		target = jQuery('#server-result');
	}

	//if there's already an animation running wait till it finishes 
	if (target.queue("fx").length && typeof cantWait == 'undefined') {
log('queue size', target.queue("fx").length)
	window.setTimeout ('animateResult("'+selector+'", "'+className+'", "'+message+'", true)',3000);
log('delay message by 3 secs', 'animateResult("'+selector+'", "'+className+'", "'+message+'", true)')
		return;
	} else {
		target.stop(true, true); 	//kill any queue and display this right away
	}
	
log('displaying', message);
	
	target.css('display', '');
	if ((typeof message != 'undefined' && message.length > 0 && message != 'undefined')) {
		message = message.replace(/\+/g, ' ');	//fixes an incompatibility between php url encode and javascript decode
		message = decodeURIComponent(message);
		target.html(message);
	}	
	target.attr('class', className);
	target.css('opacity', 0.3);
	target.css('fontSize', '0.3em');

   	target.animate({ fontSize: "1.5em", opacity: 1.0 }, 2000 ).animate({ opacity: 0.0 }, 8000 ).animate({ fontSize: "0em" }, 1000 );	//the fontsize reduction is because IE8 ignores the opacity fade
}





function removeElements(jQuerySelector) {	
	jQuery(jQuerySelector).fadeOut('slow').slideUp('slow', function () {
      this.remove();
    });
}




function shake(selector) {
 	jQuery(selector).fadeIn(100).animate({left:"-=20px"},100).animate({left:"+=20px"},100).animate({left:"-=20px"},100).animate({left:"+=20px"},100).animate({left:"-=20px"},100).animate({left:"+=20px"},100);
}




function reloadPage(url) {
	if (url) {
		window.open(randomiseUrl(url), '_self');	//the random element in the url prevents Internet Explorer from caching pages
	} else {
		window.location.reload(true); //force a complete reload (not using the browser cache)
	}
	//if we're using ajax page loads then check for an update to the address bar url
	if (typeof window.checkHash == 'function') {
		checkHash(); //this causes any # anchors in the url to get handled by ajax
	}
}








//Internet Explorer insists on caching pages and so we need a random element in the url to prevent caching
function randomiseUrl(url) {
	var randomQueryString = '?nocache='+Math.round(Math.random() * 10000);
	
	if (typeof url == 'undefined' || url == '_self') {
		var currentUrl = window.location.href.split('?nocache=')[0];	//remove any existing random element from url
log ('randomising url', currentUrl+randomQueryString);
		return currentUrl+randomQueryString;
	} else {
		if (typeof url != 'string') {
			alert('the randomise() function requires the url to be a string');
		}
log ('randomising url', url+randomQueryString);
		return url+randomQueryString;
	}
}





//compares the current webpage 
function updateWebpage(container, data) {
	if (typeof data == 'undefined') {
		data = false;
	}
	
	//create the temporary placeholder for the updated page
	if (!jQuery('#updatedPage').length) {
		jQuery('body').append('<div id="updatedPage" style="display:none"></div>');	
	}

	busyStart();	//start the busy cursor indicator 
	
	//re-load this page via ajax call into the placeholder (if the url contains a hash then convert it to a non-ajax url)  
	var currentUrl = window.location.href;
	var hash = document.location.hash;
	if (hash) {
		currentUrl = currentUrl.replace('#', '/page/');	//convert an ajax hash url to a proper segment based url. eg. wiki#554 --> wiki/page/554
	}

	//load the updated page and update any changed ids (for Internet Explorer we need a random element in the url to prevent caching)
	jQuery('#updatedPage').load(randomiseUrl(currentUrl)+' '+container, data, function() {

		//oncomplete ajax load step through elements that have changed
		var newElement;
		var oldElement;

		jQuery(container+' *[id]').each(function() {
		
			newContent = jQuery('#updatedPage #'+this.id);
			oldContent = jQuery(this);

log('comparing ids', this.id)
			//update changed element content
			if (oldContent.html() != newContent.html()) {
				if (!oldContent.hasClass('noUpdate')) {
					oldContent.html(newContent.html());
log('updated content for id', this.id)
				} else {
log('skipped update for id', this.id)
				}
			}

			//update changed class
			if (oldContent.attr('class') != newContent.attr('class')) {
				oldContent.attr('class', newContent.attr('class'));		//update changed content
log('updated class for id', this.id)
			}
		});
		jQuery('#updatedPage').remove();	//this page fragment causes duplicate ids which can interfere with other DOM scripts

		busyStop();	//stop the busy animation now that the server has responded
	});
	
	if (typeof initPage != undefined && typeof initPage == 'function') {
		setTimeout('initPage()', 3000);		//re-initialises any page javascript
	}
	if (typeof jsHover != undefined) {
		setTimeout('jsHover()', 4000);		//reset hover image animation
	}
}