/** 
 * @fileOverview Base code for the button dialog method of hiding a block of content and replacing it with a button that will toggle the 
 * content visibility and keep it above the page fold.
 * @author Tom McCourt
 * @version 1.0.0
 */

YAHOO.namespace("dulux.co.uk.Widgets.Bookmarker");
/**
 * @class Create an enhanced bookmarker. Additional networks require a CSS and configuration update
 *
 * @constructor
 * @param{Object} [customConfig]	Custom configuration settings: content, button src, button alt, dialog
 * @param customConfig.content 
 * @param customConfig.src			The file path to the image for the button.
 * @param customConfig.alt			The alt text for the image.
 * @param customConfig.dialog		If set to TRUE the object will create an HTML frame for the content, if FALSE it will display only the content.
 */
YAHOO.dulux.co.uk.Widgets.Bookmarker = function(customConfig) {
	var config = {
		content: "bookmarker",
		src: "/web/images/bookmarker/bookmark.gif",
		alt: "Share this article",
		dialog: true
	};

	for (var item in customConfig) {
		if (typeof config[item] !== "undefined") {
			config[item] = customConfig[item];
		}
	}

	this.db = bdBookmarker = new YAHOO.dulux.co.uk.Widgets.ButtonDialog({
			content: config.content,
			src: config.src,
			alt: config.alt,
			dialog: config.dialog
		});

	// Make the links appear as pop up windows
	var links = this.db.content.getElementsByTagName("a"),
		instance = this;
	for (var i = 0, ix = links.length; i < ix; i++) {
		
		links[i].onclick = function() {
			return instance.open.call(instance, this);
		};

		// Apply class
		links[i].parentNode.className = links[i].innerHTML.toLowerCase().replace(/\s/g, "");
	}		
	
};

YAHOO.dulux.co.uk.Widgets.Bookmarker.prototype = {
	/**
	 * @type Object Bookmarker configuration 
	 */
	config: {
		window: {
			facebook: {width: 660, height: 400},
			delicious: {width: 890, height: 600},
			digg: {width: 970, height: 640},
			reddit: {width: 860, height: 660},
			stumbleupon: {width: 996, height: 440},
			global: {width: 860, height: 640}
		}
	},
	/**
	 * Create a new window to access an external site
	 * @param {Object} e The external link
	 */
	open: function(e) {
		// Network data
		var config = this.config.window;
		var url = location.href;
		var title = document.title;
		var w = 0;
		var h = 0;
		var network = e.parentNode.className;

		if (config[network]) {
			w = config[network].width;
			h = config[network].height;
		} else {
			w = config.global.width;
			h = config.global.height;
		}

		// Center the window
		var x = (screen.width - w) / 2;
		var y = ((screen.height - h) / 2) - 30;

		// Create the new window
		var win = window.open(e.href, "bookmarker", "toolbar=1,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=" + w + ",height=" + h + ",left=" + x + ",top=" + y);

		// Push the window to the front
		win.focus();

		// Cancel the click
		return false;
	}
};


YAHOO.namespace("dulux.co.uk.Widgets.ButtonDialog");
/**
 * @class Create a peek-a-boo content panel from content and a insert a button trigger to 
 * determine if the content should appear abover or below the button.
 * @param {Object} options An object literal of options: content, src, alt.
 */
YAHOO.dulux.co.uk.Widgets.ButtonDialog = function(options) {
	var content = document.getElementById(options.content);
	if (content) {
		this.options = options;
		this.content = content;
		this.timer	 = null;
		this.delay   = 200;
		this.state	 = {
			freeze: false
		};
		this.init();
	}
};
YAHOO.dulux.co.uk.Widgets.ButtonDialog.prototype = {
	/** 
	 * Calculate the dimensions and positions of the necessary elements.
	 * @returns {Object} The object literal of coordinates.
	 */
	position: function() {
		var Dom			= YAHOO.util.Dom,
			de			= document.documentElement,
			scrollY		= 0,
			viewportY	= 0,
			buttonXY	= 0,
			buttonX		= 0,
			buttonY		= 0,
			canvasClip  = null,
			canvasH		= 0,
			buttonClip  = null,
			buttonH		= 0;

		// Get the screen dimensions
		scrollY = YAHOO.dulux.co.uk.getScrollXY()[1];
		viewportY = Dom.getViewportHeight();

		// Get the button dimensions
		buttonXY = Dom.getXY(this.button.firstChild);
		buttonX = buttonXY[0];
		buttonY = buttonXY[1];

		// Fix the IE 2px viewport border problem
		buttonX = buttonX - (de.clientLeft || 0);
		buttonY = buttonY - (de.clientTop || 0);

		// Get the canvas dimensions
		canvasClip = Dom.getRegion(this.canvas);
		canvasH = canvasClip.bottom - canvasClip.top;		

		// Get the button dimensions
		buttonClip = Dom.getRegion(this.button);
		buttonH = buttonClip.bottom - buttonClip.top;

		// Save it for reference
		var coords = {
			"scrollY":   scrollY,
			"viewportY": viewportY,
			"buttonXY":  buttonXY,
			"buttonX":   buttonX,
			"buttonY":   buttonY,
			"canvasH":   canvasH,
			"buttonH":   buttonH
		};

		return coords;
	},
	/**
	 * Initialise functionality.
	 */
	init: function() {
		// Shorthands
		var instance	= this, 
			Dom			= YAHOO.util.Dom,
			container	= this.content.parentNode;

		// Create the canvas
		this.canvas = document.createElement("div");
		this.canvas.id = this.options.content + "-canvas";

		// Get the parent and insert a new button
		this.button				= document.createElement("a");
		this.button.className	= this.options.content + "-view";
		this.button.href		= "#" + this.options.content;
		this.button.innerHTML	= "<img src=\"" + this.options.src + "\" alt=\"" + this.options.alt + "\" />";

		// Show the canvas, calculated the dimensions and offsets and position it above the inserted button
		this.show = function() {
			// Clear the timer
			clearTimeout(instance.timer);

			var canvas = instance.canvas,
				below  = false,
				pos = instance.position.call(instance),
				below = (pos.canvasH < (pos.viewportY - ((pos.buttonY - pos.scrollY) + pos.buttonH)));

			canvas.className = (below) ? "below" : "above";

			// Default the margins
			canvas.style.marginTop = "0";
			canvas.style.marginBottom = "0";

			// Recalculate the coords
			pos = instance.position.call(instance);

			if (instance.state.below && instance.state.canvasH < pos.canvasH) {			
				var scrollOffset = pos.canvasH - instance.state.canvasH;
				instance.state.freeze = true;	
				
				below = true;

				canvas.className = "below";

				document.body.style.paddingBottom = (scrollOffset + (scrollOffset * .8)) + "px";
				window.scrollTo(0, pos.scrollY + scrollOffset);

				// Recalculate again
				pos = instance.position.call(instance);	
				
				if (window.console) {
					console.log("Offset = " + scrollOffset);
				}
			}

			if (below) {
				// If the canvas can appear below the button
				canvas.style.top = pos.buttonY + "px";
				
				// Default then apply margins
				canvas.style.marginTop = pos.buttonH + "px";
			} else {			
				// If the canvas has to appear above the button
				canvas.style.top = (pos.buttonY - (pos.canvasH)) + "px";
				
				// Default then apply margins
				canvas.style.marginBottom = pos.buttonH + "px";
			}

			canvas.style.left = pos.buttonX + "px";	
			canvas.style.zIndex = "999";

			// Set the current height in case of content changes
			instance.state.canvasH = pos.canvasH;
			instance.state.below = below;
			
			if (window.console) {
				console.log("canvasH = " + pos.canvasH);
				console.log("viewport = " + (pos.viewportY - ((pos.buttonY - pos.scrollY) + pos.buttonH)));
				console.log("class = " + canvas.className);
			}
		};	

		// Position the canvas offscreen to hide it
		this.out = function() {	
				// Create a timer for a fractional delay to prevent annoying over/out problems
				instance.timer = setTimeout(function() {
					var canvas = instance.canvas;
					
					canvas.style.left = "-999em";
					canvas.className = "";
					canvas.style.top = "0";

					instance.timer = null;
				}, instance.delay);
	
		};

		// Apply the events
		this.canvas.onmouseover = this.show;
		this.button.onmouseover = this.show;

		this.canvas.onmouseout = this.out;
		this.button.onmouseout = this.out;		
		
		if (this.options.dialog) {
			var hd = document.createElement("div");
			hd.className = "header";

			var bd = document.createElement("div");
			bd.className = "content";

			var ft = document.createElement("div");
			ft.className = "footer";

			bd.appendChild(this.content);
			this.canvas.appendChild(hd);
			this.canvas.appendChild(bd);
			this.canvas.appendChild(ft);
		} else {
			this.canvas.appendChild(this.content);
		}

		// Compose the DOM, start with copying the button for the canvas
		container.appendChild(this.canvas);
		container.appendChild(this.button);

		// Style the email-room container
		this.canvas.style.marginTop = this.position().buttonH + "px";
		this.canvas.style.position = "absolute";
		this.canvas.style.left = "-999em";
	},
	/**
	 * Update the position and content.
	 * @param {String} [content] The content to update.
	 */
	update: function(content) {
		if (content) {
			this.content.innerHTML = content;
		}
		this.show();
	}
};