/*\
 | Copyright (C) 2009-2010 Link Digital
 | http://www.linkdigital.com.au/
 | All rights reserved.
 | Unauthorised copying, distribution or derivation is prohibited.
\*/


/****************************** Helper Functions ******************************/

if (typeof (String.prototype.ltrim)	=== "undefined")	{ String.prototype.ltrim		= function (chars)	{ return this.replace (new RegExp ("^[" + (chars || "\\s") + "]+",  "g"), "");	}; }
if (typeof (String.prototype.rtrim)	=== "undefined")	{ String.prototype.rtrim		= function (chars)	{ return this.replace (new RegExp ( "[" + (chars || "\\s") + "]+$", "g"), "");	}; }
if (typeof (String.prototype.trim)	=== "undefined")	{ String.prototype.trim 		= function (chars)	{ return this.ltrim (chars).rtrim (chars);					}; }

Array.min												= function (array)	{ return Math.min.apply (Math, array); };
Array.max												= function (array)	{ return Math.max.apply (Math, array); };

/****************************** General Utility *******************************/

// Set all <a> tags with rel="ext" to open in new window
function a_init_ext (element)
{
	if (!(element = $ (element)))	return;

	element.observe ("click", function (event) { window.open (this.readAttribute ("href")); event.stop (); });
}

// Set all <a> tags with rel="rmv" to delete their parent element when clicked
function a_init_rmv (element)
{
	if (!(element = $ (element)))	return;

	element.observe ("click", function (event) { this.up ().hide (); if (this.readAttribute ("href") == "#") event.stop (); });
}

// Set the font size of the elements listed in ids (can be an array or a string)
// Uses cookies for persistance
function a_onclick_fsize (ids, size, unit)
{
	if (typeof (ids) == "string")
		ids = [ids];

	for (c = 0, x = ids.length; x--; )
	{
		CookieJar.set ("fontEl_" + c++, ids[x], 90);

		if (el = document.getElementById (ids[x]))
			el.style.fontSize = size + unit;
	}

	CookieJar.set ("fontSize", size, 90);
	CookieJar.set ("fontUnit", unit, 90);
	CookieJar.set ("fontNum",  c,    90);

	return false;
}

// Load persistant font sizes set with a_onclick_fsize
function onload_fsizes ()
{
	fontElem	= [];
	fontNum		= CookieJar.get ("fontNum");
	fontSize	= CookieJar.get ("fontSize");
	fontUnit	= CookieJar.get ("fontUnit");

	if (fontNum != null && fontSize != null && fontUnit != null)
	{
		for (x = parseInt (fontNum); x--; )
			if ((e = CookieJar.get ("fontEl_" + x)) != null)
				fontElem.push (e);

		a_onclick_fsize (fontElem, fontSize, fontUnit);
	}
}

// Set an input text box to clear its default text on focus
function input_init_srch (element)
{
	if (!(element = $ (element)))	return;

	var temp		= $F (element);

	element.setValue (element.readAttribute ("title"));
	element.defaultValue	= $F (element);

	element.observe ("focus", function ()
	{
		if ($F (this) === this.defaultValue)
		{
			this.clear ();
			this.removeClassName ("dflt");
		}
	});

	element.observe ("blur",  function ()
	{
		if (!this.present ())
		{
			this.setValue (this.defaultValue);
			this.addClassName ("dflt");
		}
	});

	if (temp)
		element.setValue (temp);
	else	element.addClassName ("dflt");
}

// Set an input password box to show plaintext until focus
function input_init_pass (element)
{
	if (!(element = $ (element)))	return;
	element.removeClassName ("lc_pass");
	element.setValue ("");

	//var newelem = element.clone (); 		// IE won't let us just change the type attribute, OR clone the element >:(
	var newelem = new Element ("input",
	{
		name:		"-1",
		type:		"text",
		value:		"Password",
		title:		"Password",
		tabindex:	parseInt (element.getAttribute ("tabindex")) + 1,
		className:	element.className
	});

	element.twin = newelem;
	newelem.twin = element;

	newelem.observe ("focus", function () { this.replace (this.twin); this.twin.activate (); });	// this.twin.focus doesn't work right in IE for some reason
	element.observe ("blur",  function () { if (!this.present ()) this.replace (this.twin); });

	element.focus ();
	element.blur ();
}


/****************************** Tabbed Boxes *******************************/

/*
 * Fabtabulous! Simple tabs using Prototype
 * http://tetlaw.id.au/view/blog/fabtabulous-simple-tabs-using-prototype/
 * Andrew Tetlaw
 * version 2 2008-08-10
 * http://creativecommons.org/licenses/by-sa/2.5/
 */
var Fabtabs = Class.create({
	initialize : function(element,options)
	{
		var parent = this.element = $(element);
		this.options = Object.extend({
		  hover: false,
		  remotehover: false,
		  anchorpolicy: 'allow-remote', // 'protect', 'allow', 'allow-initial', 'allow-remote', 'disable'
		  hasNextPrev: false,
		  defaultTab: 0
		}, options || {});
		this.menu = this.element.select('a[href*="#"]');
		this.hrefs = this.menu.map(function(elm){
		  return elm.href.match(/#(\w.+)/) ? RegExp.$1 : null;
		}).compact();

		this.tabArray = this.menu.toArray();
		this.currentTab = this.options.defaultTab;

		//this.on(this.getInitialTab());	// Doesn't clear the "at" states on the other tabs
		this.activate (this.getInitialTab());

		var onLocal = function(event)
		{
			if (this.options.anchorpolicy !== 'allow'){ event.stop(); }
			var elm = event.findElement("a");
			if (elm.href.match(/#(\w.+)/))
			{
				this.activate(elm);
				if (this.options.anchorpolicy === 'protect') { window.location.hash = '.'+this.tabID(elm); }
			} else {
				document.location = elm.href;
			}
		};

		var onRemote = function(event)
		{
			if (this.options.anchorpolicy !== 'allow' && this.options.anchorpolicy !== 'allow-remote'){ event.stop(); }
			var elm = event.findElement("a");
			if (elm.href.match(/#(\w.+)/))
			{
				this.activate(this.tabID(elm));
				if (this.options.anchorpolicy === 'protect') { window.location.hash = '.'+this.tabID(elm); }
			} else {
				document.location = elm.href;
			}
		}

		var onNext = function(event)
		{
			this.currentTab = (this.currentTab + 1) % this.tabArray.length; // wrap around
			elm = this.tabArray[this.currentTab];
			this.activate(this.tabID(elm));
		}
		if (this.options.hasNextPrev && ($('tabNext') != undefined)) $('tabNext').observe('click', onNext.bindAsEventListener(this));

		var onPrev = function(event)
		{
			this.currentTab--;
			if (this.currentTab < 0) this.currentTab = this.tabArray.length - 1;
			elm = this.tabArray[this.currentTab];
			this.activate(this.tabID(elm));
		}
		if (this.options.hasNextPrev && ($('tabPrev') != undefined)) $('tabPrev').observe('click', onPrev.bindAsEventListener(this));

		this.element.observe('click', onLocal.bindAsEventListener(this));
		if (this.options.hover) {
		  this.menu.each(function(elm){elm.observe('mouseover', onLocal.bindAsEventListener(this))}.bind(this));
		}
		var triggers = [];
		this.hrefs.each(function(id){
		  $$('a[href="#' + id + '"]').reject(function(elm){
		    return elm.descendantOf(parent)
		  }).each(function(trig){
		    triggers.push(trig);
		  });
		})
		triggers.each(function(elm){
		  elm.observe('click', onRemote.bindAsEventListener(this));
		  if(this.options.remotehover) {
			elm.observe('mouseover', onRemote.bindAsEventListener(this));
		  }
		}.bind(this));
	},
	activate: function(elm) {
		if (typeof elm == 'string') {
			elm = this.element.select('a[href="#'+ elm +'"]')[0];
		}
		this.currentTab = this.tabArray.indexOf(elm);
		this.on(elm);
		this.menu.without(elm).each(this.off.bind(this));
	},
	off: function(elm) {
		$(elm).removeClassName('at');
		$(this.tabID(elm)).removeClassName('active-tab-body');
	},
	on: function(elm) {
		$(elm).addClassName('at');
		$(this.tabID(elm)).addClassName('active-tab-body');
	},
	tabID: function(elm) {
		return elm.href.match(this.re)[1];
	},
	getInitialTab: function() {
		if (this.options.anchorpolicy !== 'disable' && document.location.href.match(this.re))
		{
		  var hash = RegExp.$1;
		  if (hash.substring(0,1) == ".")
		  {
		    hash = hash.substring(1);
		  }
		  // NJM - Make sure the chosen hash actually exists in our list of tabs >:(
		  //return this.element.select('a[href="#'+ hash +'"]')[0];
		  var pick = this.element.select('a[href="#'+ hash +'"]');
		  return pick.size () ? pick[0] : this.menu[this.options.defaultTab];;
		} else {
		  //return this.menu.first();
		  return this.menu[this.options.defaultTab];
		}
	},
	re: /#(\.?\w.+)/
});


/********************************** Cookies ***********************************/

// Make cookies easier to deal with
var CookieJar =
{
	set: function (name, value, days)
	{
		var expires = "";

		if (days)
		{
			var date = new Date ();
			date.setTime (date.getTime () + (days * 86400000));
			expires = "; expires=" + date.toGMTString ();
		}

		document.cookie = name + "=" + value + expires + "; path=/";
	},

	get: function (name)
	{
		var ca		= document.cookie.split (";");

		for (var i = ca.length; i--; )
		{
			var c = ca[i].toString ().trim ().split ("=");
			if (c[0] == name) return c[1];
		}

		return null;
	},

	clr: function (name)
	{
		this.set (name, "", -1);
	}
};


/******************************* Image Rotator ********************************/

var linkCMS_Feature =
{
	fade:	1,
	hold:	4,
	leng:	0,
	curr:	0,
	elid:	"",
	targ:	null,
	offX:	"",
	offY:	"",

	init:	function (id)
	{
		linkCMS_Feature.elid	= id;

		if (!(linkCMS_Feature.targ = $ (id)))
			return false;

		linkCMS_Feature.targ.makePositioned ();
		linkCMS_Feature.offX = linkCMS_Feature.targ.getStyle ("padding-left");
		linkCMS_Feature.offY = linkCMS_Feature.targ.getStyle ("padding-top");

		return true;
	},

	queue:	function (html)
	{
		var	lst	= Math.max (linkCMS_Feature.leng - 1, 0),
			ths	= linkCMS_Feature.elid + "_" + linkCMS_Feature.leng,
			div	= new Element ("div", { "id": ths }).update (html);

		div.absolutize ();
		div.setStyle
		({
			"left": 	linkCMS_Feature.offX,
			"top":		linkCMS_Feature.offY
		});

		div.store ("prev", linkCMS_Feature.elid + "_" + lst);			// "prev" link is the last one we added
		div.store ("next", linkCMS_Feature.elid + "_0");			// "next" link is the first one

		if (linkCMS_Feature.leng)
		{
			div.hide ();							// Update the length value, also hide all but first one

			$ (linkCMS_Feature.elid + "_0"     ).store ("prev", ths);	// Update the "prev" link on the first one
			$ (linkCMS_Feature.elid + "_" + lst).store ("next", ths);	// Update the "next" link on the last one we added
		}

		linkCMS_Feature.leng++;
		linkCMS_Feature.targ.insert (div);					// Now we can add it to the container
	},

	next:	function ()
	{
		if (linkCMS_Feature.leng <= 1)	return;

		var	elI 		= $ (linkCMS_Feature.elid + "_" + linkCMS_Feature.curr),
			elP 		= $ (elI.retrieve ("prev")),
			elN 		= $ (elI.retrieve ("next"));

		linkCMS_Feature.curr	= ++linkCMS_Feature.curr % linkCMS_Feature.leng;

		elP.hide ();
		elN.hide ();

		elI.setStyle ({zIndex: 0});
		elN.setStyle ({zIndex: 1});

		new Effect.Appear (elN.id,
		{
			from:		0,
			to:		1,
			duration:	linkCMS_Feature.fade,
			delay:		linkCMS_Feature.hold,
			afterFinish:	linkCMS_Feature.next
		});
	}
};

/********************************* XML Feeder *********************************/

function linkCMS_Feed (feedID, xmlPath)
{
	if (!(feedID = $ (feedID))) return 0;

	new Ajax.Request (xmlPath,
	{
		method: 	"get",
		onSuccess:	feed_Init,
		//onFailure:	function (response) { alert ("FAIL: " + response); }
		onFailure:	function (response) { }
	});


	function feed_Init (response)
	{
		var	xml 	= response.responseXML,
			items	= xml.getElementsByTagName ("item"),
			num 	= Math.min (items.length, 3, parseInt (feedID.firstChild.data));

		// Stick to normal DOM functions for now, not quite sure if we can use nice Prototypey stuff on imported XML
		$R (0, num, true).each (function (x)
		{
			var c		= items[x].childNodes;
			var t		= $H ();

			// Fetch relevant data from the <item> and collect in a Hash
			for (var z = c.length; z--; ) switch (c[z].tagName)
			{
				case "link":
				case "title":
				case "pubDate":
				case "description":
					t.set (c[z].tagName, c[z].firstChild.nodeValue);
					break;
			}

			// Markup the collected data and add it to the container <div>
			feedID.insert (new Element ("h1").update (t.get ("title")));
			feedID.insert (new Element ("p", { className: "date" }).update (t.get ("pubDate").replace (/(\d{4}).*$/, "$1")));
			feedID.insert (new Element ("p").update (t.get ("description") + " ").insert (new Element ("a", { className: "more", /*rel: "ext",*/ href: t.get ("link") }).update ("more")));

			// Add a divider for all but the last one
			if (x < (num - 1))
				feedID.insert (new Element ("hr"));
		});
	}

	return 1;
}


/******************************** Load Things *********************************/

// Load everything
document.observe ("dom:loaded", function ()
{
	// Count AJAX objects
	var complex	= 0;
	var ajax	= 0;

	Ajax.Responders.register
	({
		onCreate:	function () { ++ajax; },
		onComplete:	function () { if (!--ajax) linkCMS_Load (); }			// Load normal stuff once AJAX has finished
	});


	// Complex stuff - uncomment as needed
	complex		+= linkCMS_Feed ("xml_blog_c",	"/blog/feed/"); 		// Import RSS feeds from blog
	complex		+= linkCMS_Feed ("xml_blog_g",	"/blog/category/geek/feed/");
	complex		+= linkCMS_Feed ("xml_blog_b",	"/blog/category/business/feed/");


	// Normal stuff
	if (!complex)	   linkCMS_Load ();
});


// Normal stuff
function linkCMS_Load ()
{
	$$ ("a[rel~=ext]").each 		(a_init_ext);		// Anchor OnClicks
	$$ ("a[rel~=rmv]").each 		(a_init_rmv);		// Anchor OnClicks

	$$ ("input.lc_srch").each		(input_init_srch);	// Search field niceness
	$$ ("input.lc_pass").each		(input_init_pass);	// Password field niceness

	$$ (".lc_hide").invoke			('hide');		// Hide stuff that can't be put in <noscript> tags.
	$$ (".lc_show").invoke			('show');		// Show stuff that is only of use to people with scripts enabled.

	if ($("tabs") != undefined) { new Fabtabs('tabs'); } // Activate the tabs, if they exist on this page
	if ($("vds_tabs") != undefined) { new Fabtabs('vds_tabs', {hasNextPrev:true, defaultTab:1} ); } // Activate the VDS tabs, if they exist on this page (this is a special case where 2 sets of tabs are on the same page)

/*
	$  ("fonts_sml").observe		("click", function (event)
	{
		a_onclick_fsize (["cnav", "qnav"],				0.9,  "em");
		a_onclick_fsize (["lnav", "rnav", "rcol", "main", "snippet"],	1.0,  "em");
		a_onclick_fsize (["intro"],					1.15, "em");
		event.stop ();
	});

	$  ("fonts_lrg").observe		("click", function (event)
	{
		a_onclick_fsize (["cnav", "qnav"],				1.1,  "em");
		a_onclick_fsize (["lnav", "rnav", "rcol", "main", "snippet"],	1.2,  "em");
		a_onclick_fsize (["intro"],					1.3,  "em");
		event.stop ();
	});

	onload_fsizes ();
*/
}



