/* 	@Description: 	Browser creative Javascript framework 
	@Author:		Steven Jack
	@Date:			26/09/08
	@Version:		1.0
*/

var framework = new BcFramework();
window.onload = framework.init;

/*	Class: 			BcFramework
*	Description:	The main Browser Creative framework class.
*	Author:			Steven Jack
*	Version:		1.0
*/

function BcFramework()
{
	this.init = init; 
	this.addListener = addListener;
	this.getPage = getPage;
	this.getFade = getFade;
	/* TEST */
	
	/* Toogle related variables */
	this.startToogle = startToogle;
	var toogler;
	
	/* Fader related variables*/
	this.startFade = startFade;
	var fader = null;
	
	/* Ajax related variables */
	this.Ajax = Ajax;
	var ajaxRequest = null;
	
	/* Initialise function, put in any call to the objects you want to use within the framework. */
	function init()
	{
		startToogle();
		startFade();
	}
	function startToogle()
	{
		toogler = new Toogler();	
	}
	
	function startFade()
	{
		fader = new Fader();	
	}
	
	function getFade()
	{
		return fader;	
	}
	
	function Ajax()
	{
		if(ajaxRequest == null) ajaxRequest = new AjaxRequest();
		ajaxRequest.req(arguments[0],arguments[1],arguments[2]);
	}
	
	function addListener(element, type, expression, bubbling)
	{
		bubbling = bubbling || false;
		if(window.addEventListener)element.addEventListener(type, expression, bubbling);
		else if(window.attachEvent)element.attachEvent('on' + type, expression);
	}
	
	function getPage()
	{
		var stringVar = window.location.toString();
		var newString = stringVar.substring(stringVar.indexOf("."),stringVar.length);
		newString = newString.substring(newString.indexOf("/")+1,stringVar.length);
		newString = newString.substring(0,newString.indexOf("/"));
		return newString;	
	}
}

/*	Class: 			Toogler
*	Description:	Setups the toogling of all items with "toogleItem" and "toogleContainer" class applied to them.
*	Author:			Steven Jack
*	Version:		1.0
*	params:			string 'accordion', string 'standard'
*/

function Fader()
{
	this.setup = setup;
	var fadeToogler;
	var fadeToogleItem;
	var fadeTime = 0.5;
	var newsletterItem = document.getElementById('newsletter');
	var overlay = document.getElementById('overlay');
	
	this.hideOverlayDiv = hideOverlayDiv;
	
	function setup() 
	{
		var elements = document.getElementsByTagName("*");
	
		for (var x = 0; x < elements.length; x++){
			if(elements[x].className =="fadeToogle"){
				fadeToogler = elements[x];
				framework.addListener(elements[x],'click',toogleFade,true);
			}else if(elements[x].className =="fadeToogleItem"){
				fadeToogleItem = elements[x];
			}
		}
	}
	
	function toogleFade(e)
	{
		var targetObject;
		if(e.target===undefined) targetObject = event.srcElement;
		else targetObject = e.target;
		Effect.toggle(fadeToogleItem, 'appear',{ duration: fadeTime });
		framework.addListener(overlay,'click',hideOverlay,true);
		new Effect.Morph(overlay, {style: 'background:#474747; color: #fff;', duration: 0.8 });
		Effect.Appear(overlay, { from: 0.0, to: 0.95, duration: 0.5 });
	}
	
	function hideOverlay(e)
	{
		var targetObject;
		if(e.target===undefined) targetObject = event.srcElement;
		else targetObject = e.target;
		//alert(targetObject.constructor);
		//alert(newsletterItem+","+targetObject);
		if(overlay == targetObject){
			hideOverlayDiv();
		}else{
			newsletterSignup();
		}
	}
	
	function hideOverlayDiv()
	{
		//alert(overlay);
		new Effect.Morph(overlay, {style: 'background:#fff; color: #000; display:none;', duration: 0.8 });
		new Effect.Fade(overlay, { from: 0.5, to: 0.0, duration: 0.5 });
		Effect.toggle(fadeToogleItem, 'appear',{ duration: fadeTime });
	}
	
	function newsletterSignup()
	{
		//framework.Ajax('/test.php','hello=yes',hideOverlayDiv);
	}
	setup();
}

function Toogler()
{
	var toggleContainers = [];
	var toogleItems = [];
	this.setup = setup;
	var toogleDuration = 0.8;
	var type;
	
	function setup()
	{
		/*var elements = document.getElementsByTagName("*");
		var toogleItem;
		for (var x = 0; x < elements.length; x++) {
			if(elements[x].className == "toogleContainer"){
				toggleContainers.push(elements[x]);
			}
		}
		alert(toggleContainers.length);*/
		
		/*for(var xx = 0;xx<curElements.length;xx++){
			if(curElements[xx].className == "toogleItemS" || curElements[xx].className == "toogleItemA"){
				type = (curElements[xx].className == "toogleItemS") ? 'standard' : 'accordion';
				toogleItem = new ToogleItem(toogleDuration);
				toogleItem.setToogle(curElements[xx]);
				toogleItem.setType(type);
				framework.addListener(curElements[xx],'click',toogleSlide,true);
			}else if(curElements[xx].className == "toogleContent"){
				toogleItem.setContainer(curElements[xx]);
				//toogleItem.setContainerName(toggleContainers[x]);
				toogleItems.push(toogleItem);
			}
		}*/
		//alert(toogleItems[0].getContainerName.className);
		
		elements = document.getElementsByTagName("*");
		//alert(elements.length);
	  	for (var x = 0; x < elements.length; x++) {
			if(elements[x].className == "toogleItemS" || elements[x].className == "toogleItemA" || elements[x].className == "toogleItemStatic"){
				
				type = (elements[x].className == "toogleItemS") ? 'standard' : 'accordion';
				toogleItem = new ToogleItem(toogleDuration);
				//elements[x].style.display = 'none';
				toogleItem.setToogle(elements[x]);
				toogleItem.setType(type);
				var pageTitle = framework.getPage().toLowerCase();
				var titleToCheck = elements[x].title.toString().toLowerCase();
				if(pageTitle.indexOf("-") != -1){
					pageTitle = pageTitle.replace("-"," ");	
				}
				if(pageTitle == titleToCheck)
				{
					toogleItem.setOpen();
				}
				if(!(elements[x].className == "toogleItemStatic")) framework.addListener(elements[x],'click',toogleSlide,true);
			}else if(elements[x].className == "toogleContent"){
				toogleItem.setContainer(elements[x]);
				if(!toogleItem.getOpen()){
					//elements[x].style.display = 'none';
				}else{
					elements[x].style.display = 'block';	
				}
				toogleItems.push(toogleItem);
				//alert("pusing toogle item");
			}
	  	}
	}
	
	function toogleSlide(e)
	{	
		var targetObject;
		if(e.target===undefined) targetObject = event.srcElement;
		else targetObject = e.target;
			for(var ii=0;ii<toogleItems.length;ii++){
				itemToCheck = toogleItems[ii];
				if(itemToCheck.getToogle() == targetObject){
					itemToCheck.toogleContainer();
				}
				else if(!itemToCheck.isHidden() && toogleItems.length > 1 && itemToCheck.getType() == 'accordion') itemToCheck.hideContainer();
			
		}
		/*for(var i=0;i<toogleItems.length;i++){
			var itemToCheck = toogleItems[i];
			if(itemToCheck.getToogle() == targetObject){
				itemToCheck.toogleContainer();
				var items = itemToCheck.getContainerName().getElementsByTagName("*");
				alert(items.length);
				}
				//alert("target");
			}
			//else 
			//else if(itemToCheck.getContainerName() == targetContainer) alert("equal"+itemToCheck.getContainerName()+","+targetContainer);
		}*/
	}
	
	setup();
}



/*	Class: 			ToogleItem
*	Description:	Holds details of each toogle item, the toogler and the container which it toogles.
*					Also the toogle control is held within this class.
*	Author:			Steven Jack
*	Version:		1.0
*/

function ToogleItem()
{
	var objectToogle;
	var objectContainer;
	var toogleDuration = (arguments[0] === undefined) ? 0.7 : arguments[0];
	var hidden = true;
	var type;
	var containerName;
	var openContainer = false;
	
	this.setToogle = setToogle;
	this.getToogle = getToogle;
	this.setContainer = setContainer;
	this.getContainer = getContainer;
	this.toogleContainer = toogleContainer;
	this.hideContainer = hideContainer;
	this.isHidden = isHidden;
	this.setType = setType;
	this.getType = getType;
	this.setContainerName = setContainerName;
	this.getContainerName = getContainerName;
	this.setOpen = setOpen;
	this.getOpen = getOpen;
	
	function setOpen()
	{
		openContainer = true;
		hidden = false;
		this.objectToogle.className = "toogleItemA expanded";
	}
	
	function getOpen()
	{
		return openContainer;	
	}
	
	function setContainerName(nameIn)
	{
		containerName = nameIn;
	}
	
	function getContainerName()
	{
		return containerName;
	}
	
	function setType(typeIn)
	{
		type = typeIn;
	}
	
	function getType()
	{
		return type;	
	}
	
	function isHidden()
	{
		return hidden;	
	}
	
	function setToogle(toogleIn){
		this.objectToogle = toogleIn;	
	}
	
	function getToogle(){
		return this.objectToogle;	
	}
	
	function setContainer(containerIn){
		this.objectContainer = containerIn;
	}
	
	function getContainer(){
		return this.objectContainer;	
	}
	
	function toogleContainer(){
		//alert("toogling: "+hidden+","+this.objectToogle.title);
		if(hidden){
			Effect.BlindDown(this.objectContainer, { duration: toogleDuration });
		}else{
			Effect.BlindUp(this.objectContainer, { duration: toogleDuration });
		}
		
		//Effect.toggle(this.objectContainer, 'blind', { duration: toogleDuration });
		hidden = (hidden) ? false:true;
		if(!hidden){
			this.objectToogle.className = "toogleItemA expanded";
		}else{
			this.objectToogle.className = "toogleItemA";
		}
		/* Added so that toogle can have a property set when it is expanded */
	}
	
	function hideContainer(){
		Effect.BlindUp(this.objectContainer, { duration: toogleDuration });
		hidden = true;
		this.objectToogle.className = "toogleItemA";
	}
}

/*	Class: 			Newsletter control
*	Description:	Amiddle man between the operation of an ajax request, and what should happen once its completed.
*	Author:			Steven Jack
*	Version:		1.0
*/

function NewsletterControl()
{
	this.sendRequest = sendRequest;
	var inputItems = null;
	
	function sendRequest()
	{
		var keyValue = "";
		inputItems = arguments[0];
		for(var i=0;i<inputItems.length;i++){
			keyValue+=inputItems[i].name+"="+inputItems[i].value+"&";	
		}
		keyValue+="SiteReturnUrl="+document.URL;
		framework.Ajax('includes/ajaxPost.php',keyValue,newsletterSent);
		//framework.Ajax('includes/ajaxPost.php',keyValue,isDone);
	}
	
	function newsletterSent(xmpHTTP)
	{
		for(var i=0;i<inputItems.length;i++){
			inputItems[i].value = "";
		}
		framework.getFade().hideOverlayDiv();
	}
}


/*	Class: 			Ajax Request
*	Description:	Allows an ajax request to be posted, and then a function be called once complete.
*	Author:			Steven Jack
*	Version:		1.0
*/

function AjaxRequest()
{
	var xmlHTTP;
	this.req = req;
	
	function req(URL,information,callbackFunction)
	{
		if(window.XMLHttpRequest){
			xmlHTTP = new XMLHttpRequest();
		}else{
			xmlHTTP = new ActiveXObject("Microsoft.XMLHTTP");
		}
	
		xmlHTTP.open('POST',URL, true);
		xmlHTTP.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		xmlHTTP.onreadystatechange = checkReadState;
			
		function checkReadState(){
			//alert(xmlHTTP.readyState);
			if(xmlHTTP.readyState==4) callbackFunction(xmlHTTP);
		}
		xmlHTTP.send(information);
	}
}

/**
 * @Author:		Steven Jack
 * @Title:		Custom input field validation
 * @Date:		14/06/08
 * @Version:	1.0
 
 Class name: InputValidation
 
 Instructions for use:
 
	 First instanciate the class, and pass in the div tag to display the error message and the div tag containing the inputs.
	 
	 Then enter in each error in the format of (input Name,error Message). Note the inputname must be the same as the one used
	 on the page for the validation to work.
	 
	 Once all error messages have been added, call the .update() method. 
	 
	 To validate all textfields and display error messages, call checkFields().
	 
	 To check any fields for either only numeric, or only charachters use these operators on the input names:
	 
		To check for only numbers use: &N&, i.e phoneNumber&N&.
		To check for only charachters use: &C& i.e name&C&.
	
 */
 
var interval = null;
 
function InputValidation()
				{
					/* Setup variables to be used within class */
					var errorMsgs = new Array();
					var newInputs = new Array();
					var inputs = document.getElementById(arguments[1]).getElementsByTagName('*');
					var errorOutput = "";
					var errorDisplay = arguments[0];
					var validated = false;
					var validation = false;
					var validateType = false;
					var isForm = (arguments[2] === undefined) ? false : arguments[2];
					var numPattern = new RegExp("^(0)$|^([1-9][0-9]*)$");
					var alphaPattern = new RegExp("\\D", "g");
					var outterStart = "<ul>";
					var outterEnd = "</ul>";
					var start = "<li>";
					var end = "</li>";
					
					/* Set methods so they can be used in instances of the class. */
					this.update = update;
					this.setErrorMessage = setErrorMessage;
					this.checkFields = checkFields;
					this.validateEmail = validateEmail;
					this.validateType = validateType;
					
					function setErrorMessage(errorKeyIn,errorValueIn)
					{
						errorMsgs[errorKeyIn] = errorValueIn;	
					}
					
					function validateEmail(validateIn)
					{
						validation = validateIn;
					}
					
					function validateType(validateTypeIn)
					{
						validateType = validateTypeIn;	
					}
					
					function update()
					{
						for(var i=0;i<inputs.length;i++){
							if(inputs[i].className.indexOf("validate") != -1){
								newInputs.push(inputs[i]);
							}
						}	
					}
					
					function checkFields()
					{
						clearErrors();
						errorOutput=outterStart;
						for(var i=0;i<newInputs.length;i++){
							if(newInputs[i].value == ""){
								errorOutput +=start+errorMsgs[newInputs[i].name]+end;
							}else if(!checkEmail(newInputs[i].value) && newInputs[i].className.indexOf("email") != -1 && validation){
								errorOutput +=start+errorMsgs[newInputs[i].name]+end;
							}else if(validateType){
								var inputName = newInputs[i].className;
								if(inputName.indexOf("validate number") != -1){
									if(!numPattern.test(newInputs[i].value)){
										errorOutput +=start+errorMsgs[newInputs[i].name]+end;	
									}
								}else if(inputName.indexOf("validate character") != -1){
									if(!alphaPattern.test(newInputs[i].value)){
										errorOutput +=start+errorMsgs[newInputs[i].name]+end;	
									}
								}
							}
						}
						errorOutput+=outterEnd;
						return displayErrors();
					}
					
					function displayErrors()
					{
						if(errorOutput == ("<ul></ul>"))
						{
							document.getElementById(errorDisplay).style.display = 'none';
							if(isForm){
								validated = true;
							}else{
								var control = new NewsletterControl();
								control.sendRequest(newInputs);
								return newInputs;
							}
							clearErrors();
						}else{
							var errorDisplayLocal = document.getElementById(errorDisplay);
							errorDisplayLocal.style.display = 'block';
							errorDisplayLocal.innerHTML = errorOutput;
							validated = false;
						}
						return validated;
					}
					
					function clearErrors()
					{
						document.getElementById(errorDisplay).innerHTML = "";
					}
					
					function checkEmail(str) 
					{
						var error = document.getElementById('valError');
						var at="@"
						var dot="."
						var lat=str.indexOf(at)
						var lstr=str.length
						var ldot=str.indexOf(dot)
						var end=str.length;
				
						if (str.indexOf(at)==-1){
							 return false
						}
						if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr){
							 return false
						}
						if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr){
							return false
						}
						if (str.indexOf(at,(lat+1))!=-1){
								return false
						}
						if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot){
								return false
						}
						if (str.indexOf(dot,(lat+2))==-1){
							 return false
						}
						if (str.indexOf(" ")!=-1){
								return false
						}
						if (ldot == (end-1)){
								return false
						}
						return true					
					}
				}

