/**
 * Code for the 'tips' that reveal themselves when links in diary entries are hovered over. 
 *
 * There should be a 'tipText' array of text keyed to entry IDs. The entry IDs are those
 * of the Encyclopedia entries the links take you to. eg, the '180' in:
 *    http://www.pepysdiary.com/p/180.php
 *
 * The tipText array will start something like this:
 *    var tipText = new Array();
 *    tipText[180] = "<h3>Whitehall Palace</h3><p>The main residence of the English monarchs...</p>";
 * 
 * Up to about 60 words in the paragraph works well.
 * 
 * The tip created will be a div with a class of "tip" and an id of "tip180" or similar.
 */


/* On your marks...! */
$(document).ready(tipsInit);


/** 
 * Set all the links within quoted diary text to offer tips.
 */
function tipsInit() {
	$("div.manuscript a").hover(function(){
		tipShow(this);
	},function(){
		tipHide(this);
	})
};


/** 
 * Reveal the tip for a link, if any.
 * @param object obj A dom type object. I think.
 * @return boolean False all the time apparently.
 */
function tipShow(obj) {
	
	var entryId = parseEncycUrl(obj.href);
	
	// Do we have a tip to show?
	if (typeof tipText=='undefined' || !tipText[entryId]) {
		return false;
	}
	
	// Width of the tip. Padding etc is possibly extra.
	var tipWidth = 305;
	
	includeImage = false;
	if (typeof imageIds!='undefined' && $.inArray(entryId, imageIds) >= 0) {
		// We have an image to include in the tip?
		includeImage = true;
		tipWidth += 110;
	}

	// Create the tip and its content.
	var tipContent = tipText[entryId];
	
	divOpen = '<div class="tip" id="tip'+entryId+'">';
	
	// Image
	if (includeImage) {
		divOpen = '<div class="tip tip-image" id="tip'+entryId+'">';
		tipContent = '<img src="/images/thumbnails/encyclopedia/' + entryId + '.jpg" alt="Portrait" width="100" height="120" />' + tipContent + '<div class="clear"></div>';
	}
	
	$('body').append(divOpen + '<div class="tip-inner">' + tipContent + '</div></div>');
	
	// Now we've created the div, we can get its height.
	var tipHeight = $('#tip'+entryId).height();
	
	// Get the top left position of the tip, based on the location of the link we're hovering over.
	var tipX = getAbsoluteLeft(obj);
	var tipY = getAbsoluteTop(obj) + 16;
	
	// Do we need to adjust the position of the tip if it's going to go outside the visible viewport?
	
	var windowWidth = self.innerWidth || (document.documentElement && document.documentElement.clientWidth) || document.body.clientWidth;

	if (windowWidth < (tipX + tipWidth + 12)) {
		// Tip is going over right edge of window, so shift to left.
		// -12 for padding+border, -20 for...?
		tipX = windowWidth - tipWidth - 12 - 20;
	}
	
	var windowHeight = self.innerHeight || (document.documentElement && document.documentElement.clientHeight) || document.body.clientHeight;

	if ((getScrollY() + windowHeight) < (tipY + tipHeight + 7)) {
		// Tip is going below the bottom of the window, so display it
		// above the text, rather than below.
		tipY = tipY - tipHeight - 26;
	}
	
	// Now we can position the tip in the correct location.
	$('#tip'+entryId).css({
		left: tipX-19+'px', // -19 to allow for the padding, so text still lines up.
		top: tipY+'px'
	});
	// And reveal it.
	$('#tip'+entryId).show();
	
	return false;
}


/**
 * Hide the visible tip. 
 * @param object obj A dom type object. I think.
 * @return boolean False all the time apparently.
 */
function tipHide(obj) {
	entryId = parseEncycUrl(obj.href);
	$('#tip'+entryId).hide();
	$('#tip'+entryId).remove();
	return false;
}


/**
 * Given a url like http://www.pepysdiary.com/p/150.php
 * returns the '150' (no matter how many characters the number is).
 * @param string url
 * @return string The entry ID.
 */
function parseEncycUrl(url) {
	if (!url) return '';
	return url.substring(url.lastIndexOf('/')+1, url.lastIndexOf('.'));
}



/**
 * Get an object's left position from the upper left viewport corner.
 * @param object obj A dom type object. I think.
 * @return integer Pixels.
 */
function getAbsoluteLeft(obj) {
	oLeft = obj.offsetLeft;            // Get left position from the parent object
	while(obj.offsetParent != null) {  // Parse the parent hierarchy up to the document element
		oParent = obj.offsetParent;    // Get parent object reference
		oLeft += oParent.offsetLeft;   // Add parent left position
		obj = oParent;
	}
	return oLeft;
}


/**
 * Get an object's top position from the upper left viewport corner
 * @param object obj A dom type object. I think.
 * @return integer Pixels.
 */
function getAbsoluteTop(obj) {
	oTop = obj.offsetTop;             // Get top position from the parent object
	while(obj.offsetParent != null) { // Parse the parent hierarchy up to the document element
		oParent = obj.offsetParent;   // Get parent object reference
		oTop += oParent.offsetTop;    // Add parent top position
		obj = oParent;
	}
	return oTop;
}


/**
 * Return how far the document has scrolled vertically.
 * From http://peter.michaux.ca/article/3556
 * @return integer Pixels.
 */
function getScrollY() {

	if (typeof window.pageYOffset == 'number') {
		getScrollY = function() {
			return window.pageYOffset;
		};
	} else if ((typeof document.compatMode == 'string') &&
		(document.compatMode.indexOf('CSS') >= 0) &&
		(document.documentElement) &&
		(typeof document.documentElement.scrollTop == 'number')) 
		{

		getScrollY = function() {
			return document.documentElement.scrollTop;
		};

	} else if ((document.body) && (typeof document.body.scrollTop == 'number')) {
		getScrollY = function() {
			return document.body.scrollTop;
		}
	} else {
		getScrollY = function() {
			return NaN;
		};
	}
	return getScrollY();
}

