/*	General Purpose Routines

	Written by Mark Simon
	email: mark@manngo.net
	Copyright (c) Manngo Net Pty Ltd
	Feel free to use these. Acknowledgement would be nice...

*/

	function routinesTest() { alert(0); }

//	String Routines

	String.prototype.sprintf=function() {
		//	Clayton's sprintf routine.
		//	Usage:		'....%0...%1 ...'.sprintf(var0,var1 etc)

		var part=this.split('%');
		var theResult=part[0];
		if(part.length>1) {
			for (var i=1;i<part.length;i++) {
				var c=part[i].charAt(0);
				if(c>='0' && c<='9') {
					if (c<=sprintf.arguments.length)
					theResult+= sprintf.arguments[c];
					theResult+=part[i].substring(1);
				}
				if(c=='s') {
					if (i<=sprintf.arguments.length)
					theResult+= sprintf.arguments[i-1];
					theResult+=part[i].substring(1);
				}
			}
		}
		return theResult;
	};

	String.prototype.last=function(n) {
		//	Returns the last part of the string
		//	Usage:	string.last(n)
		return this.substring(this.length-n,this.length);
	};

	String.prototype.interpolate=function() {
		// eg: a=1; b=2; alert('[a]+[b]=[a+b]'.interpolate());
		return this.replace(/(\[)(.*?)(\])/g,function() {
			return eval(arguments[2]);
		});
	};
						
	String.prototype.subst=function(n,c) {
		//	Returns a new string with a character replaced in the nth position
		//	Usage:	'abcde'.subst(2,x) -> 'abxde'
		if (n<this.length) return this.substring(0,n)+c+this.substring(n+1);
		else return this;
	};

	String.prototype.toTitleCase=function() {
		var s='', words=this.split(' ');
		for (var i=0;i<words.length;i++) {
			if(!words[i].mixed()) words[i]=words[i][0].toUpperCase()+words[i].substr(1).toLowerCase();
		}
		return words.join(' ');
	}

	String.prototype.mixed=function() {
		return this!=this.toLowerCase()&&this!=this.toUpperCase();
	}

//	Cross Platform DHTML routines
//	Thank God we don't need them anymore, so just an outline here:

	function testDOM() {
		if(document.getElementById) return 'W3C'
       	else if (document.all) return 'MSIE';
		else if (document.layers) return 'NN'
		else return false;
	}

//	Input Filters

	function numericKey(me,e) {
		var theKey=(e.which)?e.which:e.keyCode;
		return (theKey>47&&theKey<58);
		return true;
	}

//	Misc

	function validEmail(e) {
		return e.match(/.+\@.+\..+/)!=null;
	}

	function pick(choice,possibilities,result) {
		for (i=0;i<possibilities.length;i++) {
			if (choice==possibilities[i]) return result[i];
		}
		return '';
	}

	//	animal:	return year's animal
	//	Usage:	animal(year)


	function zodiac(date) {
		//	ref: http://www.vpcalendar.net/QuickRef/Zodiac.html
		var tropical=[	['aries',3,21],		['taurus',4,20],	['gemini',5,21],
						['cancer',6,21],	['leo',7,23],		['virgo',8,23],
						['libra',9,23],		['scorpio',10,23],	['sagittarius',11,22],
						['capricorn',12,22],['aquarius',1,20],	['pisces',2,19]];
		var siderial=[	['aries',4,14],		['taurus',5,15],	['gemini',6,15],
						['cancer',7,17],	['leo',8,17],		['virgo',9,17],
						['libra',10,18],	['scorpio',11,17],	['sagittarius',12,16],
						['capricorn',1,15],	['aquarius',2,13],	['pisces',3,15]];
		var actual	=[	['aries',4,19],		['taurus',5,14],	['gemini',6,20],
						['cancer',7,21],	['leo',8,10],		['virgo',9,16],
						['libra',10,31],	['scorpio',11,23],	['opchiuchus',11,30],	['sagittarius',12,18],
						['capricorn',1,19],	['aquarius',2,16],	['pisces',3,12]];
	}

	function queryString(item) {
		var qs=new Array();
		var theData=unescape(window.location.search.substring(1)).split(/[&;]/);
		for (var i=0;i<theData.length;i++) {
			var data=theData[i].split('=');
			if(data[1]==undefined)data[1]=true;
			qs[data[0]]=data[1];
		}
		if(item) return qs[item];
		else return qs;
	}

//	Forms

	function whichButton(name) {
		var buttons=document.getElementsByName(name);
		for(var b in buttons) {
			if(buttons[b].checked) return buttons[b].value;
		}
		return undefined;
	}

	String.prototype.isPostcode=function() {
		return this.match(/^\d\d\d\d$/)!=null;
	}

	String.prototype.isEmail=function() {
		return this.match(/.+\@.+\..+/)!=null;
	}

	String.prototype.isNumber=function() {
		return this.match(/^[\+-]?\d+(\.\d+)?$/)!=null;
	}

	function checkForm(f) {
		//	forms[].element[].requred
		//	forms[].element[].postcode
		//	forms[].element[].email

		var ok=true;
		var i;
		var error='';
		for(i=0;i<f.elements.length;i++) {
			var e=f.elements[i];
			if(e.required && e.value=='') {
				ok=false;
				error+='Missing: '+e.name+'\n';
			}
			if(e.postcode) {
				if(!e.value.isPostCode()) {
					ok=false;
					error+=e.name+' should be 4 digits\n';
				}
			}
			if(e.email) {
				if(!e.value && !e.value.isEmail()) {
					if(e.required) error+=e.name+' invalid: please enter a valid email address\n';
					else error+=e.name+' invalid: please enter a valid email address or leave blank\n';
					ok=false;
				}
			}
		}
		if(!ok) return error;
		else return ok;
	}

	function getLabelFor(id) {
		var label, labels;
		for (label in labels=document.getElementsByTagName('label')) {
			if(labels[label]['htmlFor']==id) return labels[label];
		}
		return false;
	}

/*	document.HTMLFormElement.prototype.names=function() {
		var i, n;
		var a=new Array();
		for (i=0;i<this.elements.length;i++)  {
			n=this.elements[i].name;
			if (n) a[n]=n;
		}
		return a;
	}
*/
	function formNames(theForm) {
		var i, n;
		var a=new Array();
		for (i=0;i<theForm.elements.length;i++)  {
			n=theForm.elements[i].name;
			if (n) a[n]=n;
		}
		return a;
	}

//	Cookies

	function setCookie(name,value,date) {
		if(!name||!value) return false;
		value=escape(value);
		date=new Date(date);
		if(isNaN(date)) date='';
		else date='; expires='+date.toGMTString();
		var cookie=name+'='+value+date;
		document.cookie=cookie;
		return true;
	}

	function getCookies(name) {
		var item, items, i, c;
		c=new Array();
		items=document.cookie.split('; ');
		for (i in items) {
			item=items[i].split('=');
			c[item[0]]=item[1];
		}
		if(name) return c[name];
		else return c;
	}

//	Generic HTML Elements

/*	Element.prototype.next=function(tag) {
		var e=this;
		while(e=e.nextSibling) if(e.tagName && e.tagName.toLowerCase()==tag.toLowerCase()) return e;
		return false;
	}

	Element.prototype.removeNodes=function() {
	    while (this.hasChildNodes()) this.removeChild(this.firstChild);
	}

	Element.prototype.replaceText=function(message) {
    	var textNode=document.createTextNode(message);
    	if (this.hasChildNodes()) this.removeNodes();
    	this.appendChild(textNode);
    }
*/

	function nextElement(element,tag) {
        tag=tag||element.tagName;
        while(element=element.nextSibling)
			if(element.tagName && element.tagName.toLowerCase()==tag.toLowerCase()) return element;
        return false;
    }

	function removeNodes(element) {
	    while (element.hasChildNodes()) element.removeChild(element.firstChild);
	}

	function replaceText(element,message) {
    	var textNode=document.createTextNode(message);
    	if (element.hasChildNodes()) removeNodes(element);
    	element.appendChild(textNode);
    }

//	Randomise Functions

	function random(max) {
		if(max) return Math.floor(Math.random()*max);
		else return(Math.random()>=.5);
	}

	String.prototype.random=function() {
		var l=this.length;
		if(l>1) return this.charAt(random(l));
		else return this;
	}

	Boolean.prototype.random=function() {
		return (Math.random()>=.5);
	}

//	Strings

	String.prototype.array=function (r,c) {
		var rows=this.split(r);
		var result=new Array();
		for (var e in rows) {
			var cols=rows[e].split(c);
			result[cols[0]]=cols.length?cols[1]:true;
		}
		return result;
	}

	String.prototype.replaceWord=function (word,replacement) {
		if(replacement===undefined) return this.replace(new RegExp(word+' | '+word+'| '+word+' '),'');
		var r=new RegExp(word);
		if (this.match(r)) return this.replace(r,replacement);
		else return this+' '+replacement;
	}

	String.prototype.toggleWord=function (word,replacement) {
		var r=new RegExp(word);
		if(this.match(r)) return this.replace(r,replacement);
		var r=new RegExp(replacement);
		if(this.match(r)) return this.replace(r,word);
		else return this;
	}
 
	String.prototype.format=function(mask) {
		var i,j;
		var s='';
		for(i=0,j=0;i<this.length,j<mask.length;j++) {
			switch(mask[j]) {
				case '0':	s+=this[i++];
							break;
				default:	s+=mask[j];
			}
		}
		return s;
	}

	String.prototype.removeWord=function(word) {
		return this.replace(new RegExp('\\b'+word+'\\b |\\b'+word+'\\b|\\b '+word+'\\b'),'');
	}
	String.prototype.addWord=function(word) {
		var text=this.removeWord(word);
		return text+(text.length?' ':'')+word;
	}
	String.prototype.hasWord=function(word) {
		return this.match(new RegExp('\\b'+word+'\\b'))!=null;
	}
	String.prototype.swapWord=function(word) {
		if(this.hasWord(word)) return this.removeWord(word);
		else return this.addWord(word);
	}

//	Misc

	function showHide(element) {
		if(element.style) element.style.display=element.style.display=='none'?'block':'none';
		else element.style.display='none';
	}

	var areaCode= {
		nt:'08',nsw:'02',act:'02',vic:'03',qld:'07',sa:'08',wa:'08',tas:'03'
	};

	function getPhone(phone,state) {
		state=state||'vic';
		phone=phone.replace(/[^\d]/g,'');
		if(phone.charAt(0)=='0') {
			if(phone.length!=10) return;
		}
		else {
			if(phone.length!=8) return;
			phone=areaCode[state]+phone;
		}
		//if(phone.charAt(1)=='4') phone=phone.format('0000 000 000');
		//else phone=phone.format('(00) 0000 0000');
		//if(phone.charAt(1)=='4') phone=phone.substring(0,4)+' '+phone.substring(4,7)+' '+phone.substring(7);
		//else phone='('+phone.substring(0,2)+') '+phone.substring(2,6)+' '+phone.substring(6)
		return phone;
	}

	//document.prototype.rules=new Array();
	function getRules() {
		var i,j,r;
		var allRules='';
		var rules=new Array();
		var theRules=new Array();
		for (i=0;i<document.styleSheets.length;i++) {
			theRules=document.styleSheets[i];
			theRules=document.styleSheets[i].rules;
			theRules=document.styleSheets[i].cssRules?document.styleSheets[i].cssRules:document.styleSheets[i].rules;
			for(j=0;j<theRules.length;j++) {
				r=theRules[j].selectorText+'';
				if(r.charAt(0)!='.'&&r.charAt(0)!='#') r=r.toLowerCase();
				rules[r]=theRules[j].style;
			}
		}
		return rules;
	}

	function encrypt (text,key) {
		var k=0;
		var result='';
		for (var c=0;c<text.length;c++) {
			result+=String.fromCharCode((64+key.charCodeAt(k++)-text.charCodeAt(c))%96+32);
			k%=key.length;
		}
		return result;
	}
	function fixEmail(anchor,key) {
		var email=encrypt(anchor.innerHTML,key);
		anchor.href='mailto:'+email;
		anchor.innerHTML=email;
	}

	if(typeof HTMLElement!='undefined') {
	//	HTMLElement.prototype.__defineGetter__('innerText', 
	//			  function () { return(this.textContent); });
	//	HTMLElement.prototype.__defineSetter__('innerText', 
	//			  function (txt) { this.textContent = txt; });
	}

	function changeText(element,message) {
		element=document.getElementById(element);
		var textNode=document.createTextNode(message);
		element.replaceChild(textNode,element.childNodes[0]);
	}


	function getElementsByClassName(className,tag) {
		tag=tag||'*';
		var	array=Array(),
			r=new RegExp('\\b'+className+'\\b'),
			elements=document.getElementsByTagName(tag),
			e, l=elements.length;
		for (e=0; e<l; e++)
			if(elements[e].className && elements[e].className.match(r)) array.push(elements[e]);
		return array;
	}

	function getElementsByAttribute(attribute,tag,value) {
		tag=tag||'*';
		var	array=Array(),
			elements=document.getElementsByTagName(tag),
			e, l;
		for (e=0,l=elements.length; e<l; e++)
			if(elements[e][attribute]) if(!value || elements[e][attribute]==value) array.push(elements[e]);
		return array;
	}

	//	Date

	Date.prototype.format=function(string) {
		// uses PHP date strings
		string=string.replace(/j/,this.getDay());
		string=string.replace(/d/,('0'+this.getDay()).slice(-2));
		string=string.replace(/D/,this.getShortDayName());
		string=string.replace(/l/,this.getFullDayName());

		string=string.replace(/n/,this.getDate());
		string=string.replace(/m/,('0'+this.getDate()).slice(-2));
		string=string.replace(/M/,this.getShortMonthName());
		string=string.replace(/F/,this.getFullMonthName());
		return string;
	}

	Date.prototype.fullMonthNames=
		['January','February','March','April','May','June','July','August','September','October','November','December']
	Date.prototype.shortMonthNames=
		['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
	Date.prototype.fullDayNames=
		['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']
	Date.prototype.shortDayNames=
		['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
	
	Date.prototype.getFullMonthName=function() {
		return this.fullMonthNames[this.getDate()];
	}
	Date.prototype.getShortMonthName=function() {
		return this.shortMonthNames[this.getDate()];
	}
	Date.prototype.getFullDayName=function() {
		return this.fullDayNames[this.getDay()];
	}
	Date.prototype.getShortDayName=function() {
		return this.shortDayNames[this.getDay()];
	}
	Date.prototype.parse8=function(s) {
		s+='';
		this.setFullYear(s.substr(0,4));
		this.setMonth(s.substr(4,2)-1);
		this.setDate(s.substr(6,2));
	}

	Date.prototype.animals=['rat','ox','tiger','rabbit','dragon','snake','horse','goat','monkey','rooster','dog','pig'];
	Date.prototype.animal=function() {
		return this.animals[(this.getFullYear()+8)%12];
	}


function makeSelectOptions(id,values,append) {
	//append=append?append:false;
	if(!append) append=false;
	var select=document.getElementById(id);
	if(!append && select.options.length)
		for(var i=select.options.length-1;i>=0;i--)
			select.remove(i);
	var options=values.split(';');
	for(var oo in options) {
		var o=options[oo].split(':');
		select.options[select.options.length]=new Option(o[0],o[1]||o[0]);
	}
}

function childOf(parent,child) {
	if(parent===child) return false;
	while(child&&child!==parent) child=child.parentNode;
	return child===parent;
}

function xoxoCollapse(e) {
	if(!e) e = window.event;
	var target=(e.target)?e.target:e.srcElement;
	target.className=target.className.swapWord('collapse');
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return false;
}
function xoxoInit() {
	var lists=getElementsByClass('xoxo','ol');
	for (var l=0;l<lists.length;l++) {
		var tags=lists[l].getElementsByTagName('li');
		for(var t=0;t<tags.length;t++) {
			if(tags[t].getElementsByTagName('ol').length>0) {
				tags[t].className='collapse more';
				if(tags[t].addEventListener) tags[t].addEventListener('click',xoxoCollapse,false);
				else if(tags[t].attachEvent) tags[t].attachEvent('onclick',xoxoCollapse);
			}
		}
	}
}

//alert('done');

