﻿/* code by jonne unless noted otherwise*/
/* initialisation */
/* this is the 'bootloader', functions that need to run on page load need to be added here */
function upstart(){
	window.makeMailLinks?makeMailLinks():null;
	window.enhanceIntFields?enhanceIntFields():null;
	window.contactEqualsDelivery?contactEqualsDelivery():null;
	window.modifyCart?modifyCart():null;
	window.eolasIsATroll?eolasIsATroll():null;
	window.askConfirmation()?askConfirmation():null; 			//ask for confirmation before submiting 'dangerous' forms
	window.popups()?popups():null; 								//a href="" class="popup" creates a popup (easiest method ever)
	window.xmlRequests()?xmlRequests():null; 					//this one refreshes the <div> in question according to an url  and a defined timeout (class="xmlget")
	window.xmlActions()?xmlActions():null; 						//meh
	window.imageSwitch()?imageSwitch():null; 					//image switcher for the product page
	}
/* when changing the page structure, call this */	
function refresh(){
	updateValues();
	xmlActions();
	}
/* <span class="email">x (at) x.com</span> becomes <a href="x@x.com">x@x.com</a> 
* this is an anti-spam measure
*/
function makeMailLinks()
	{
	if (!document.getElementsByTagName && !document.createElement && !document.createTextNode)
		return;
	var spans = document.getElementsByTagName("span");
	for(var i=0;i<spans.length;i++)
		{
		if (spans[i].className=="email")
			{
			var theNode = spans[i];
			var theAddress = theNode.firstChild.nodeValue;
			
			theAddress = theAddress.replace(/ \(at\) /, "@");
			theAddressNode = document.createElement('A');
			theAddressNode.setAttribute("href", "mailto:" + theAddress);
			theAddressNode.appendChild(document.createTextNode(theAddress));
			theNode.parentNode.replaceChild(theAddressNode, theNode);
			i--; /*because we implicitly removed a <span> from the spans array by making it an <a>; Otherwise it'll skip the next span*/
			}
		}
	}
/* adds arrows that allow you to increment/decrement an int field*/
var incrementImage='_images/_js/increment.png';
var decrementImage='_images/_js/decrement.png';
function enhanceIntFields()
	{
	var intFields = getElementsByClassName('input','int');
	for(i=0;i<intFields.length;i++)
		{
		/* add - */
		img = document.createElement("img");
		img.setAttribute("src",decrementImage);
		img.setAttribute("alt","-");
		img.setAttribute("title","less");
		img.setAttribute("class","fieldmodify"); //good browsers
		img.setAttribute("className","fieldmodify"); //IE
		
		img.onclick = function(){incrementField(this.previousSibling.previousSibling,-1);};
		intFields[i].parentNode.insertBefore(img,intFields[i].nextSibling);
		
		/* add + */
		img = document.createElement("img");
		img.setAttribute("class","fieldmodify"); //good browsers
		img.setAttribute("className","fieldmodify"); //IE
		img.setAttribute("src",incrementImage);
		img.setAttribute("alt","+");
		img.setAttribute("title","more");
		
		img.onclick = function(){incrementField(this.previousSibling,1);};
		intFields[i].parentNode.insertBefore(img,intFields[i].nextSibling);
		
		intFields[i].onfocus = function(){this.select();}
		}
	}
/* shopping cart functions 
* note that the cart should still function if js is disabled, don't use this to do calculations and such
*
*/

/* disable delivery fields if the checkbox  'contactequalsdelivery'is checked
and yes, i could've picked a longer id if I wanted to.
 */
function contactEqualsDelivery(){
	var checkbox=$('contactequalsdelivery');
		if(checkbox)
		{
		checkbox.onchange=function()
			{
			setDisabled('delivery',checkbox.checked);
			}
		checkbox.onclick=function(){
			this.onchange();
			}
		}	
	}
/* use this to enable/disable a bunch of input fields using their class name */	
function setDisabled(classname,which)
	{
	var fields = getElementsByClassName('input',classname);
	fields=fields.concat(getElementsByClassName('select',classname));
		for(i=0;i<fields.length;i++)
			{
			fields[i].disabled=which;
			/* needed for IE */
			if(which==true)
				{
				fields[i].style.backgroundColor='#ddd';
				}else{
				fields[i].style.backgroundColor='';
				}
			}
	}
/* onchange, submit. This is temporary* until I add real ajax 

*if you're reading this in 2010, replace this with "permanent"
*/
function modifyCart(){
	var cartmodify = getElementsByClassName('form','cartmodify');
	/* add submit onchange to every input element */
	for(var i=0;i<cartmodify.length;i++)
		{
		addSubmitOnChange(cartmodify[i]);
		}
	}
function addSubmitOnChange(form)	{
	var nodes = getInputfields(form);
	var inputfields = new Array;
	for(var i=0;i<nodes.length;i++)
		{
		if(nodes[i].tagName=='INPUT' || nodes[i].tagName=='SELECT')
			{
			nodes[i].onchange = function()
				{
				/*submit the form you're in*/
				backgroundSubmit(form);
				}
			/* IE needs this because it's standards-compliant for once */
			if(nodes[i].getAttribute('type')=='radio')
				{
				nodes[i].onclick = function (){
					//this.blur(); 
					this.onchange(); /* forces the event to fire in IE and Safari 2 after clicking a radio button. Apparently this is according to the specs*/
					/*if(this.onchange=='something'){
						}*/
					}
				}
			}else if(nodes[i].tagName=='BUTTON'){
				if(nodes[i].className=='updatebutton')
					{
					nodes[i].style.display='none';
					}
			}
		}
	}
function updateValues()
	{
	/* get all elements that can apply for an update */
	var elements = new Array('TD','TH','SPAN','DIV');
	var async = new Array; //array containing the elements we're going to ajaxify
	for(var i=0;i<elements.length;i++)
		{
		var asyncForElement = getElementsByClassName(elements[i],'async');
		async=async.concat(asyncForElement);
		}
	var root = '';
	/* loop through async, and update each element */
	for(var i=0;i<async.length;i++)
		{
		var asyncId=async[i].id;
		var asyncParams=asyncId.split('_'); //looks like a Japanese smiley ^_^
		var requesturl=root+'xml/'+asyncParams.shift()+'.lasso?params='+asyncParams.join('_');
		sendXmlHTTPRequest('GET',requesturl,null,async[i]);
		/*console.log(requesturl);*/
		}
	}
	
	
function incrementField(field,amount,negative)
	{
	if((negative!=true && (parseInt(field.value)+amount)<0) ||isNaN(parseInt(field.value)))
		{
		field.value=0;
		field.setAttribute("value",0);
		if(field.onchange)
			{
			field.onchange();
			}
		return;
		}
	field.value=parseInt(field.value)+amount;
	field.setAttribute("value",parseInt(field.value));
	if(field.onchange)
		{
		field.onchange(); // force the onchange event
		}
	}
/* /end shopping cart functions */
addLoadEvent(upstart);
/* stuff used by various functions */
/* getting sick of typing "document.getElementById' all the time (I also keep screwing up the caps).*/
function $(id)	{
	return document.getElementById(id);
	}
//inArray function, always useful...
Array.prototype.inArray = function (value) {
	var i;
	for (i=0; i < this.length; i++) {
		if (this[i] == value) {
			return true;
		//this checks if an array in an array	is the same as the array passed
		}
	}
	return false;
};

/* eolasIsATroll(), gets rid of the 'click here to activate this control */
function eolasIsATroll()
	{
	/* doesn't work in Opera yet, for some reason
	 *  */
	if(document.body.outerHTML!=undefined)
		{
		var affectedTags = new Array('object','embed','applet');
			for (var i = 0; i < affectedTags.length; i++) {
				var objects = document.getElementsByTagName(affectedTags[i]);
				for (var j = 0; j < objects.length; j++ ) {
					var tmp = objects[j].outerHTML;
					objects[j].outerHTML = tmp;
				}
			}
		}
	}

// addLoadEvent()
// Adds event to window.onload without overwriting currently assigned onload functions.
// Function found at Simon Willison's website - http://simon.incutio.com/
function addLoadEvent(func)
{	
	var oldonload = window.onload;
	if (typeof window.onload != 'function'){
    	window.onload = func;
	} else {
		window.onload = function(){
		oldonload();
		func();
		}
	}

}
//as long as browsers don't support getElementsByClassName, let's just write our own!
//extra functionality browsers won't support ever: 
//-values can be added by appending them in brackets. example: required(*@*.*),, popup(500,400), ...
function getElementsByClassName(tag, classname)	{
	var xyzzy=document.getElementsByTagName(tag);
	var elements = new Array;
	var regulexp= new RegExp("(^|\\s)"+classname+"(\\s|$|\\(.*\\))");
	for(i=0;i<xyzzy.length;i++)
		{
		if(regulexp.test(xyzzy[i].className))
			{
			elements[elements.length]=xyzzy[i];
			}
		}
	return elements;
	}
/* if you change something in the site structure, you'll need to change this function. You can hardcode it if you like too */
function getRoot()
	{
	/* get the root of the site (assuming we're not using mod_rewrite to mess up paths) */
	var url = document.location+'';
	var cleanurl = url.split('?')[0];
	return cleanurl;
	}
/* ******************************************************************************
xmlHTTPRequest stuff
****************************************************************************** */
/* submit a form in the background, instead of using a page reload */
function backgroundSubmit(form)	{
//var target=form.action;
var target=document.location+'';
/* guess which browser needed this... */
if(target.indexOf(document.domain)==-1)
	{
	var url = document.location+'';
	var cleanurl = url.split('?')[0];
	target=cleanurl+target;
	}
/* target is the target where the post should go*/
/* now get the values of the input fields in the form*/

var nodes = getInputfields(form);
var inputfields = new Array;

	for(var i=0;i<nodes.length;i++)
		{
		if(nodes[i].tagName=='INPUT'|| nodes[i].tagName=='TEXTAREA' || nodes[i].tagName=='SELECT')
			{
			var sendparam=true;
			if(nodes[i].type=='radio' && nodes[i].checked==false)
				{
				sendparam=false;
				}
			if(sendparam)
				{
				//console.log(nodes[i].value);
				inputfields.push(nodes[i]);
				}
			}
		}
/* construct a POST string */
var post = new Array;
for(var i=0;i<inputfields.length;i++)
	{
	if(inputfields[i].tagName!='SELECT')
		{
		post.push(inputfields[i].getAttribute('name')+'='+inputfields[i].value);	
		}else{
		post.push(inputfields[i].getAttribute('name')+'='+inputfields[i][inputfields[i].selectedIndex].value);
		}
	}	
var poststring = post.join('&');
sendXmlHTTPRequest('POST',target,poststring);
}
function sendXmlHTTPRequest(type,url,params,e)
	{
	var xmlhttp=createNewRequestObject();
	/* IE's cache again, just add POSIX time to the end */
		var now = new Date();
		var t = now.getTime();
		if(url.indexOf('?')>0)	{
			url+='&time='+t;
		}else{
			url+='?time='+t;
		}
	xmlhttp.open(type, url,true);	
		xmlhttp.onreadystatechange=function(eid) {
		if (xmlhttp.readyState==4) {
			if(e!=undefined)
				{
				var text = xmlhttp.responseText;
				e.innerHTML=text;
				}
			/*ultimately refresh the divs with values */
			if(type=='POST' || type=='HEAD')
				{
				refresh();
				}
			}
		}
		if(type=='POST')
			{
			/* we're doing a POST, so you need the content-type header */
			xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
			xmlhttp.send(params);
		}else{
			xmlhttp.send(null);
		}	
	}
/*create xmlHTTPRequest object*/
function createNewRequestObject()
	{
	var requestObj=false;
	/*@cc_on @*/
	/*@if (@_jscript_version >= 5)
	// JScript gives us Conditional compilation, we can cope with old IE versions.
	// and security blocked creation of the objects.
	 try {
	  requestObj = new ActiveXObject("Msxml2.XMLHTTP");
	 } catch (e) {
	  try {
	  requestObj = new ActiveXObject("Microsoft.XMLHTTP");
	  } catch (E) {
	   requestObj = false;
	  }
	 }
	@end @*/
	if (!requestObj && typeof XMLHttpRequest!='undefined') {
		try {
			requestObj = new XMLHttpRequest();
		} catch (e) {
			requestObj=false;
		}
	}
	return requestObj;
	}
/* *************************************
xmlHTTPrequest section
************************************** */
var cleared = new Array;
var xmldivs = new Array;
var timer = new Array;
//this one refreshes the <div> in question according to an url  and a defined timeout
function xmlRequests()	{
	xmldivs = getElementsByClassName('div','xmlget');
	for(i=0;i<xmldivs.length;i++){
		timer[i]=new Array;
		timer[i]['params']=getClassVariables(xmldivs[i],'xmlget');
		timer[i]['element']=xmldivs[i];
		//timer[i]['interval']=window.setInterval('getXMLText(timer['+i+'][\'params\'][0],timer['+i+'][\'element\']);',timer[i]['params'][1]*1000);
		window.setInterval('getXMLText(timer['+i+'][\'params\'][0],timer['+i+'][\'element\']);',timer[i]['params'][1]*1000);
		}
	}

//this one just loads a page (without immediate feedback)
function xmlActions()	{
	
	var xmlactions = new Array;
	xmlactions = getElementsByClassName('a','xmldo');
	for(i=0;i<xmlactions.length;i++)
		{
		//var action=xmlactions[i].href;
		xmlactions[i].onclick=function(){this.blur();XMLdo(this.href);return false;};
		}
	}
function XMLdo(url)	{
	var xmlhttp = createNewRequestObject();
	xmlhttp.open("HEAD", url,true);	
		xmlhttp.onreadystatechange=function() {
		if (xmlhttp.readyState==4) {
						
				for(i=0;i<xmldivs.length;i++)
					{
					params=getClassVariables(xmldivs[i],'xmlget');
					param=params[0];
					xmldiv=xmldivs[i];
					getXMLText(param,xmldiv);
					}
			}
		}
	xmlhttp.send(null);
	}

function flushXMLData()	{
	for(i=0;i<xmldivs.length;i++)
		{
		params=getClassVariables(xmldivs[i],'xmlget');
		param=params[0];
		xmldiv=xmldivs[i];
		getXMLText(param,xmldiv);
		}
	}
//searches for links with the 'xmlref' class, and loads new data into the element with the id in rel=""
function xmlActionRel()	{
	var xmlrefs = new Array;
	xmlrefs = getElementsByClassName('a','xmlref');
	for(i=0;i<xmlrefs.length;i++)
		{
		xmlrefs[i].onclick=function(){xmlActionRelClick(this);return false;};
		}
	}
function xmlActionRelClick(e)	{
		var relatedId=e.getAttribute('rel');
		var secondclass = e.className.split(' ')[1];
		var originalurl = e.getAttribute('href');
		//the following lines are just needed for everyone's favourite browser...
		var urlsplitter = originalurl.split("/");
		originalurl=urlsplitter.pop();
		var request = secondclass+'.lasso'+originalurl+'&load='+relatedId;
		var reloadElement = document.getElementById(relatedId);
		getXMLText(request,reloadElement);
	}
//gets the text from an url, and drops it into the innerHTML of the given element
function getXMLText(path,e)	{
		var request=createNewRequestObject();
		request.open("GET", path+"&rnd="+Math.round(Math.random()*10000),true);
		request.onreadystatechange=function() {
		if (request.readyState==4) {
			var text = request.responseText;
			e.innerHTML=text;
			//console.log('request: '+e.id+' = '+e.innerHTML);
			refresh();
			}
		}
		request.send(null);
	}
/* ************************************************************************************************
ask confirmation before submitting a form (<form class="confirm" title="are you sure you want to kill yourself?">)
************************************************************************************************ */
function askConfirmation()
	{
	confirmations = getElementsByClassName('form','confirm');
	for(i=0;i<confirmations.length;i++)
		{
		//inventing new attributes
		confirmations[i].setAttribute('confirm',confirmations[i].title);
		confirmations[i].title="";
		confirmations[i].onsubmit = function(){return window.confirm(this.getAttribute('confirm'));};
		
		}
	}
/* *******************************************
add popup events when there's a class="popup{}" on a link
******************************************** */
function popups()	{
	var popuplinks = new Array;
	popuplinks = getElementsByClassName('a','popup');
	for(i=0;i<popuplinks.length;i++)
		{
		
		popuplinks[i].onclick=function(){ popup(this);return false;};
		}
	}
function popup(e)	{
	arr=getClassVariables(e,'popup');
		if(!isNaN(arr[0]*1)){width=arr[0]*1;}else{width=600;}
		if(!isNaN(arr[1]*1)){height=arr[1]*1;}else{height=400;}
	window.open(e.href,'upload','width='+width+',height='+height);
	}
	
/* ********************************************
 * image switcher thing
 * ****************************************** */	
function imageSwitch()	{
	var links = getElementsByClassName('a','imageswitch');
	var target = 'mask';
	for(var i=0;i<links.length;i++){
		links[i].onclick = function(){
			$(target).style.backgroundImage='url('+this.href+')';
			$('active_image').id='';
			this.id='active_image';
			this.blur(); /* get rid of ugly IE outline */
			return false;
			}
		}
	}
	
	//extract the variables passed between {}'s
function getClassVariables(e,classname)	{
	vars = new Array;
	varstring = e.className;
	//var regulexp= new RegExp("(^|\\s)"+classname+"(\\s|$|{.*})");
	var regulexp= new RegExp(classname+"\\((.*)\\)");
	varr=varstring.match(regulexp);
	varstring = varr[1];
	vars=varstring.split(',');
	return vars;
	}
/* get all input fields in any form 
 * 
 * replace this by something that iterates through
 * all depths if you feel like it
 * 
 * */
function getInputfields(form)	{
	var nodes = form.childNodes;
	for(var i=0;i<nodes.length;i++)	{
			if(nodes[i].tagName=='FIELDSET')
				{
				nodes=nodes[i].childNodes;
				}
			}
	return nodes;
	}
