/*******************************

 Popup.js, Version 3.1.2, 22-Jul-2009
 Copyright Northgate Information Solutions UK Limited, 2002-2009

 *******************************/

/********************
 Popup class
 
 Constructor:
	Popup()
 Properties:
	controlFolder		Inherited from DataObject class.
	data				Inherited from DataObject class.
	files				Inherited from DataObject class.
	lastPopup			Reference to clicked node.
	maxPopupWidth		(default 400)
	parent				Inherited from DataObject class.
	popup				Reference to popup element.
	popupID				(default "popup")
	target				Inherited from DataObject class.
	targetMarginLeft
	targetMarginTop
	targetMarginRight
	targetMarginBottom
	topicFolder			Inherited from DataObject class.
	window				Inherited from DataObject class.
 Methods:
 	setup(files)		Inherited from DataObject class.
	initialise()		Inherited from DataObject class.
	load()				Inherited from DataObject class.
	mouseEvent(event)
	
 ********************/
 
// *** Constructor for Popup class ***
function Popup() {
	// Initialise the object.
	this.maxPopupWidth = 400;
	this.popupID = "popup";
	this.lastPopup = null;
	this.popup = null;
}

// *** Popup inherits from DataObject ***
Popup.prototype = new DataObject();
Popup.prototype.constructor = Popup;

// *** Popup instance methods ***
	// Handle a mouse event.
Popup.prototype.mouseEvent = function puMouseEvent(e) {
	var obj;
	var el;
	
	if (this.targetMarginLeft == null) {
		this.targetMarginLeft = 
			parseInt(DHTML.getComputedStyle(this.target.document, 
				this.target.document.body, 
				"marginLeft"));
		this.targetMarginRight = 
			parseInt(DHTML.getComputedStyle(this.target.document, 
				this.target.document.body, 
				"marginRight"));
		this.targetMarginTop = 
			parseInt(DHTML.getComputedStyle(this.target.document, 
				this.target.document.body, 
				"marginTop"));
		this.targetMarginBottom = 
			parseInt(DHTML.getComputedStyle(this.target.document, 
				this.target.document.body, 
				"marginBottom"));
	}

	if (document.all)	// IE
		obj = e.srcElement;
	else {				// Netscape, Mozilla.
		obj = e.target;
		// In Netscape the target is a Text node.
		if (obj.nodeType == Node.TEXT_NODE)
			 obj = e.target.parentNode;
	}

	// Popup link.
	if (obj.className.search(/\bpopup\b/i) != -1) {
		return(this.show(obj));
	}
	// Normal link inside a popup.
	else {
		if (obj.tagName.toUpperCase() != "HTML") {
			el = obj;
			while(el.tagName.toUpperCase() != "BODY") {
    			if (el == this.popup) {
    				this.linkClick(obj);
    				this.remove();	// Remove the popup.
    				return(true);
    			}
    			el = DHTML.getParent(el);
			}
		}
		
    	// Click anywhere else.
   		this.remove();	// Remove the popup, if any.
   		return(false);
    }
}

	/* Display a popup.
		Parameters:
			obj - A reference to the clicked link.
	*/
Popup.prototype.show = function puShow(node) {
	// If visible, but same link...
	if (node == this.lastPopup) {
		this.remove();
		this.lastPopup = null;
	}
	// Otherwise (hidden or different link)...
	else {
		// Remove any visible popup.
		this.remove();

		// Set the text of the popup.
		var ptxt = this.getPopupText(node);
		if (!ptxt)
			return(false);
		this.create(node, ptxt);

		this.lastPopup = node;
	}
	
	return(true);
}

Popup.prototype.create = function puCreate(node, text) {
	// node is the popup link that has been clicked.
	// text is the text of the popup.
	// left is the horizontal position of the popup, relative to the clicked link.
	// top is the vertical position of the popup, relative to the clicked link.
	
	// Get the position of the clicked node.
	var osl = DHTML.getOffsetLeft(node);
	var ost = DHTML.getOffsetTop(node);
	
	// Create a new p element to use as a popup.
//	this.popup = this.target.document.createElement("p");
	this.popup = this.target.document.createElement("div");
	this.popup.id = "popup";
	this.popup.innerHTML = text;
	
	// Insert the popup at the beginning of the document.
	var b = this.target.document.body;
	b.insertBefore(this.popup, b.firstChild);

	// Set the width of the popup.
	this.setWidth();
	
	// Insert it before the clicked node.
//	span.insertBefore(this.popup, span.firstChild);
	
	// Set the position of the popup.
	this.popup.style.left = this.left(node, osl);
	this.popup.style.top = this.top(node, ost);

	// Display it.
	this.popup.style.visibility = "visible";
}

Popup.prototype.remove = function puRemove() {
	if (!this.popup)
		return;
	
	// Hide the popup.
	this.popup.style.visibility = "hidden";
	
	var pn = this.popup.parentNode;
	if (!pn)
		return;

	// Remove the popup element.
	pn.removeChild(this.popup);
	
	this.popup = null;
	this.lastPopup = null;
}

Popup.prototype.left = function puLeft(node, os) {
	/* Set the horizontal position of the popup.
	   node is a reference to the clicked link.
	   os is the horizontal position of left-hand edge of
			the clicked link. */
	
	// Position of left-hand edge of popup.
	var psl;
	// Width of frame minus margins plus scroll offset.
	var cwsl = DHTML.getFrameDimensions(this.target).width
		- this.targetMarginLeft - this.targetMarginRight
		+ DHTML.getScrollLeft(this.target);
	// Width of popup.
	var psw = parseInt(this.popup.style.width);

	// Left align the popup with the clicked link.
	psl = 0;

	// If the popup would overhang on the right...
	if (os + psw > cwsl) {
		// Align the right-hand edges of the popup and link.
		psl = node.offsetWidth - psw;
		/* If the link occupies two lines, the popup might still
		   overhang on the right. */
		// If the popup still overhangs on the right...
		if (os + psl + psw > cwsl) {
			/* Attempt to align the right-hand edge of the popup 
			   with the left-hand edge of the link. */
			psl = -psw;
			// If it now overhangs on the left...
			if (os + psl < 0)
				// Left align the popup with the page margin.
				psl = -os;
		}
		// If the popup overhangs on the left...
		else if (os + psl < 0)
			// Left align the popup with the page margin.
			psl = -os;
	}
		
	// Make the offset relative to the body of the document.
	psl += os;
		
	return(psl + "px");
}

Popup.prototype.top = function puTop(node, os) {
	// Set the vertical position of the popup.
	var pst;
	
	// Height of frame minus margins plus scroll offset.
	var chst = DHTML.getFrameDimensions(this.target).height
		- this.targetMarginTop - this.targetMarginBottom
		+ DHTML.getScrollTop(this.target);

	// Position the popup below the clicked element.
	pst = node.offsetHeight;

	// If the popup would overhang the bottom of the frame...
	if (os + node.offsetHeight + this.popup.offsetHeight > chst)
	{
		// Position the popup above the clicked element.
		pst = -this.popup.offsetHeight;
		
		// If the popup would now overhang the top of the frame...
		if (pst + os < 0)
			// Position the popup at the top of the frame.
			pst = -os;
	}
	
	// Make the offset relative to the body of the document.
	pst += os;

	return(pst + "px");
}

Popup.prototype.setWidth = function puSetWidth() {
	// Set the width of the popup.
	if (this.popup.offsetWidth > this.maxPopupWidth)
		this.popup.style.width = this.maxPopupWidth + "px";
	else
		this.popup.style.width = this.popup.offsetWidth + "px";
}

	/* Get the text of the required popup.
	   node is a reference to the clicked element.
	   Returns the text of the popup or undefined if the popup
	   was not found. */
Popup.prototype.getPopupText = function puGetPopupText(node) {
	// Get the id of the clicked element.
	var nid = node.id.toLowerCase();
	// Get the text of the popup.
	var txt = this.data[nid];
	/* If no popup with that id was found, Front Page might have
	   made the id unique by appending one or more digits. */
	// So, while the text is undefined and the id ends in a digit...
	while (!txt && nid.charAt(nid.length - 1).search(/\d/) != -1) {
		// Strip off the digit.
		nid = nid.substring(0, nid.length -1);
		// Try getting the text for the new id.
		var txt = this.data[nid];
	}
	// Return the result.
	return(txt);
}

Popup.prototype.linkClick = function puLinkClick(link) {
	var hs = this.parent.helpSystem;
	var cfg = hs.configuration;
	var topic = hs.topic;
	var temp;
	
	if (link.tagName != "A" || !link.href) {
		return;
	}

	// Save the query string and bookmark.
	var qry = link.search;
	var bmk = link.hash;
	var path = link.href.split(/[\?#]/g)[0];

	// Get the link destination, relative to the popup file.
	var href = hs.relativeToTopic(path);
	var lr = "../" + hs.getLocalRoot(topic.url);
	
	// Make it into an absolute URL.
	// If the popup file is global, href will start with ../topics/
	if (href.startsWith("../topics/", true)) {
		// Get the path to the global control folder.
		temp = hs.rootFolder + cfg.controlFolder;
	}
	else {
		// Get the root of the subweb (2 levels down from root).
		temp = topic.url.split("/").slice(0, 2).join("/");
		temp += "/";
		// Append the control folder.
		temp += cfg.controlFolder;
		// Make it an absolute URL.
		temp = hs.rootFolder + temp;
	}
	
	href = hs.absoluteUrl(temp + href);
	
	// Restore the query string and bookmark.
	href += qry + bmk;

	switch (link.target) {
	case "_blank":
		// Open a new window.
		var w = window.open(href, "example");
		w.focus();
		break;
	case "_top":
		top.location.href = href;
		break;
	case "_self":
	default:
		this.target.location.href = href;
		break;
	}
}

