/*************************************************
TITLE: Base JavaScripts
DESCRIPTION:
   A set of classes and functions required on all
   pages throughout the site.
AUTHOR: David Mingos
CONTACT: http://dmdesigns.com/contact/
*************************************************/

var autoClearingInputs = new Array();

function setAutoClearHandlers() {
   for(input in autoClearingInputs) {
      if (document.getElementById(autoClearingInputs[input]))
      autoClearInputs(autoClearingInputs[input]);
   }
}

function initAutoClearingInputs() {
   for(input in autoClearingInputs) {
      var acInput = document.getElementById(autoClearingInputs[input]);
      if (acInput) {
         if (acInput.value == acInput.defaultValue)
            acInput.style.color = '#999';
         else
            acInput.style.color = '#000';
      }
   }
};

function restoreDefault() {
   if (!this.value){
      this.value=this.defaultValue;
      this.style.color = '#999999';
   }
}

function clearDefault() {
   if (this.value==this.defaultValue){
      this.value='';
      this.style.color = '#000000';
   }
}

function autoClearInputs(input) {
   input = document.getElementById(input);
   if(input.type == 'text' || input.type == 'textarea') {
      input.onfocus=clearDefault;
      input.onblur=restoreDefault;
   }
}

function validateEmail(emailStr) {

   /** NOTE:
    * This returns true or false so not to confuse/annoy the user with 
    * overly-detailed reasons why the e-mail address was not valid.
    * This places the burden of handling required/optional checks and 
    * displaying error messages outside of this function.
    */

    if (emailStr == '') return true;

    var emailPat=/^(.+)@(.+)$/
    var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
    var validChars="\[^\\s" + specialChars + "\]"
    var quotedUser="(\"[^\"]*\")"
    var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
    var atom=validChars + '+'
    var word="(" + atom + "|" + quotedUser + ")"
    var userPat=new RegExp("^" + word + "(\\." + word + ")*$")
    var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$")

    var matchArray=emailStr.match(emailPat)

    if (matchArray==null) return false;

    var user=matchArray[1]
    var domain=matchArray[2]

    if (user.match(userPat)==null) return false;

    var IPArray=domain.match(ipDomainPat)
    if (IPArray!=null) {
        for (var i=1;i<=4;i++) {
	        if (IPArray[i]>255) {
	            return false;
	        }
        }
        return true;
    }

    var domainArray=domain.match(domainPat)
    if (domainArray==null) return false;

    var atomPat=new RegExp(atom,"g")
    var domArr=domain.match(atomPat)
    var len=domArr.length
    if (domArr[domArr.length-1].length<2 ||
        domArr[domArr.length-1].length>3) {
        return false;
    }

    if (len<2) return false;

    return true;
}

function addEvent(obj, evType, fn, useCapture){
   if (obj.addEventListener){
      obj.addEventListener(evType, fn, useCapture);
      return true;
   } else if (obj.attachEvent){
      var r = obj.attachEvent("on"+evType, fn);
      return r;
   } else {
      // be silent
      // alert("Handler could not be attached");
   }
}

function removeEvent(obj, evType, fn, useCapture){
   if (obj.removeEventListener) {
      obj.removeEventListener(evType, fn, useCapture);
      return true;
   } else if (obj.detachEvent){
      var r = obj.detachEvent("on"+evType, fn);
      return r;
   }
}

/* DEBUG DEBUG MESSAGES WINDOW
*******************************************************************************
*/

function debug(message) {
	var debuggerId = 'activity-log';
	if (!document.getElementById(debuggerId)) {
		buglog = document.createElement('div');
		buglog.id = debuggerId;

		buglog.style.position = 'absolute';
		buglog.style.top = '15px';
		buglog.style.right = '15px';
		buglog.style.backgroundColor = 'lightyellow';
		buglog.style.color = 'black';
		buglog.style.border = '1px solid black';
		buglog.style.paddingRight = '20px';
		buglog.style.opacity = '0.8';
		
		document.body.appendChild(buglog);

		drglog = new DebugDragger('drglog',buglog);
		drglog.SetEvents();
	} else {
		buglog = document.getElementById(debuggerId);
	}

	if (buglog.childNodes.length == 0) {
		logtitle = getNewElement(buglog.id, 'p');
		logtitle.style.textAlign='right';
		logtitle.style.marginLeft='15px';
		logtitle.style.borderBottom = '1px dotted black';
		logtitle.innerHTML = '<strong style=\'cursor:default\'>Activity Log</strong>';
		ol = getNewElement(buglog.id, 'ol');
		ol.onmouseover = function() {
			drglog.draggable = false;
		}
		ol.onmouseout = function() {
			drglog.draggable = true;
		}
		clearbutton = getNewElement(buglog.id, 'p');
		clearbutton.style.textAlign='right';
		//clearbutton.innerHTML += '<button onclick="document.getElementById(buglog.id).style.display=\'none\';return false;">Hide</button>\n';
		clearbutton.innerHTML += '<button onclick="document.getElementById(buglog.id).parentNode.removeChild(document.getElementById(buglog.id));return false;">Close</button>';
	} else {
		ol = buglog.childNodes[1];
	}

	var li = getNewElement(ol.id, 'li');
	li.style.whiteSpace = 'pre';
	document.getElementById(li.id).appendChild(document.createTextNode(message));
	buglog.style.display = 'block';
}

function getNewElement(parentId, eltag) {
	var parentEl = document.getElementById(parentId);
	var childEl = document.createElement(eltag);
	childEl.id = parentEl.id + '-child'+ parentEl.childNodes.length;
	parentEl.appendChild(childEl);
	return childEl;
}

function DebugDragger(id,target,handle) {	
	this.id = id;
	this.target = target; //object to drag
	handle = handle ? handle : target; //if no handle, entire object
	this.handle = handle; //object child - to drag
	
	this.dragging = false;
	this.clickable = true;
	
	this.draggable = true;
}

DebugDragger.prototype.SetEvents = function () {

	var me = this;
	
	this.handle.ondrag = function() { return false; };
	this.handle.onselectstart = function() { return false; };
	
	this.handle.onmousedown = function (evt) {		
		evt = evt ? evt : window.event;

		me.MouseDownX = evt.pageX ? evt.pageX : evt.clientX;
		me.MouseDownY = evt.pageY ? evt.pageY : evt.clientY;
		
		if (!me.draggable) return;

		me.dragging = true;
			
		me.MouseOffsetX = me.MouseDownX - me.FindPosX();
		me.MouseOffsetY = me.MouseDownY - me.FindPosY();
			
		document.onmousemove = function (evt) {
			if (me.dragging) {
				evt = evt ? evt : window.event;
					
				me.MouseX = evt.pageX ? evt.pageX : evt.clientX;
				me.MouseY = evt.pageY ? evt.pageY : evt.clientY;
					
				var x = me.MouseX - me.MouseOffsetX;
				var y = me.MouseY - me.MouseOffsetY;
				
				me.target.style.right = '';
				me.target.style.bottom = '';

				me.target.style.left = x + 'px';
				me.target.style.top = y + 'px';
			}
			return false;
		};
			
		return false;
	};
	this.handle.onmouseup = function() {
		document.onmousemove = null;
		me.dragging = false;
		
		if (me.MouseUp) { //function set
			me.MouseUp();
		}

		return false;
	};
};

DebugDragger.prototype.ClickAction = function(inFunc) {
	var me = this; //passed as object to function set
	if (!inFunc) { //passed in null
		this.handle.onclick = null;
	} else {
		this.handle.onclick = function(evt) {
			evt = evt ? evt : window.event;
			if(me.RegisterClick(evt)) {
				inFunc(me);
			}
		};
	}
};

DebugDragger.prototype.MouseOver = function(inFunc) {
	var me = this; //passed as object to function set
	this.target.onmouseover = function() {
		inFunc(me);
		
		return;
	};
};

DebugDragger.prototype.MouseOut = function(inFunc) {
	var me = this; //passed as object to function set
	this.target.onmouseout = function() {
		inFunc(me);
		
		return;
	};
};

DebugDragger.prototype.AddMouseUp = function(inFunc) {
   //not set as a handler
	var me = this; //passed as object to function set
	var tmp = this.MouseUp;
	this.MouseUp = function (tmp) {
		if (tmp) {
			tmp();
		}
		inFunc(me);
	}
	//inFunc(this); //passed as object to function set
	
	return;
};

DebugDragger.prototype.RegisterClick = function (evt) {
	if (!this.clickable) {
		return false;
	} else {
		this.MouseUpX = evt.pageX ? evt.pageX : evt.clientX;
		this.MouseUpY = evt.pageY ? evt.pageY : evt.clientY;
		
		var x = this.MouseDownX - this.MouseUpX;
		var y = this.MouseDownY - this.MouseUpY;
		
		if (Math.abs(x) < 3 && Math.abs(y) < 3) {
			this.dragging = false;
			return true;
		} else {
			return false;
		}
	}
};

DebugDragger.prototype.FindPosX = function () {
	var curleft = 0;
	var obj = this.target;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
};

DebugDragger.prototype.FindPosY = function () {
	var curtop = 0;
	var obj = this.target;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
};
/* ****************************************************************************
 * END DEBUG MESSAGES WINDOW
** ************************************************************************** */



/* SCRIPT FROM A LIST APART'S STYLESHEET SWITCHER
*******************************************************************************
Source: http://www.alistapart.com/stories/alternate/ 
Modifications:
   The window.onload and window.onunload statements have been put 
   into functions called loadActiveStylesheet() and unloadActiveStylesheet() so
   that they play well with other loading and unloading logic. Loading and 
   unloading is handled in custom.js.
*/

function setActiveStyleSheet(title) {
  var i, a, main;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
      a.disabled = true;
      if(a.getAttribute("title") == title || a.getAttribute("title") == "Employment") a.disabled = false;
    }
  }
}

function getActiveStyleSheet() {
  var i, a;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) return a.getAttribute("title");
  }
  return null;
}

function getPreferredStyleSheet() {
  var i, a;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if(a.getAttribute("rel").indexOf("style") != -1
       && a.getAttribute("rel").indexOf("alt") == -1
       && a.getAttribute("title")
       ) return a.getAttribute("title");
  }
  return null;
}

function createCookie(name,value,days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  else expires = "";
  document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  }
  return null;
}

function loadActiveStylesheet(e) {
  var cookie = readCookie("style");
  var title = cookie ? cookie : getPreferredStyleSheet();
  setActiveStyleSheet(title);
}

function unloadActiveStylesheet(e) {
  var title = getActiveStyleSheet();
  createCookie("style", title, 365);
}

var cookie = readCookie('style');
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);

/* ****************************************************************************
 * END STYLESHEET SWITCHER
** ************************************************************************** */


/* SCRIPT FROM BEN NOLAN'S BEHAVIOUR.JS
*******************************************************************************
Source: http://www.bennolan.com/behaviour/ 
*/

/*
   Behaviour v1.1 by Ben Nolan, June 2005. Based largely on the work
   of Simon Willison (see comments by Simon below).

   Description:
   	
   	Uses css selectors to apply javascript behaviours to enable
   	unobtrusive javascript in html documents.
   	
   Usage:   
   
	var myrules = {
		'b.someclass' : function(element){
			element.onclick = function(){
				alert(this.innerHTML);
			}
		},
		'#someid u' : function(element){
			element.onmouseover = function(){
				this.innerHTML = "BLAH!";
			}
		}
	};
	
	Behaviour.register(myrules);
	
	// Call Behaviour.apply() to re-apply the rules (if you
	// update the dom, etc).

   License:
   
   	This file is entirely BSD licensed.
   	
   More information:
   	
   	http://ripcord.co.nz/behaviour/
   
*/   

var Behaviour = {
	list : new Array,
	
	register : function(sheet){
		Behaviour.list.push(sheet);
	},
	
	start : function(){
		Behaviour.addLoadEvent(function(){
			Behaviour.apply();
		});
	},
	
	apply : function(){
		for (h=0;sheet=Behaviour.list[h];h++){
			for (selector in sheet){
				list = document.getElementsBySelector(selector);
				
				if (!list){
					continue;
				}

				for (i=0;element=list[i];i++){
					sheet[selector](element);
				}
			}
		}
	},
	
	addLoadEvent : function(func){
		var oldonload = window.onload;
		
		if (typeof window.onload != 'function') {
			window.onload = func;
		} else {
			window.onload = function() {
				oldonload();
				func();
			}
		}
	}
}

Behaviour.start();

/*
   The following code is Copyright (C) Simon Willison 2004.

   document.getElementsBySelector(selector)
   - returns an array of element objects from the current document
     matching the CSS selector. Selectors can contain element names, 
     class names and ids and can be nested. For example:
     
       elements = document.getElementsBySelect('div#main p a.external')
     
     Will return an array of all 'a' elements with 'external' in their 
     class attribute that are contained inside 'p' elements that are 
     contained inside the 'div' element which has id="main"

   New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
   See http://www.w3.org/TR/css3-selectors/#attribute-selectors

   Version 0.4 - Simon Willison, March 25th 2003
   -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
   -- Opera 7 fails 
*/

function getAllChildren(e) {
  // Returns all children of element. Workaround required for IE5/Windows. Ugh.
  return e.all ? e.all : e.getElementsByTagName('*');
}

document.getElementsBySelector = function(selector) {
  // Attempt to fail gracefully in lesser browsers
  if (!document.getElementsByTagName) {
    return new Array();
  }
  // Split selector in to tokens
  var tokens = selector.split(' ');
  var currentContext = new Array(document);
  for (var i = 0; i < tokens.length; i++) {
    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
    if (token.indexOf('#') > -1) {
      // Token is an ID selector
      var bits = token.split('#');
      var tagName = bits[0];
      var id = bits[1];
      var element = document.getElementById(id);
      if (tagName && element.nodeName.toLowerCase() != tagName) {
        // tag with that ID not found, return false
        return new Array();
      }
      // Set currentContext to contain just this element
      currentContext = new Array(element);
      continue; // Skip to next token
    }
    if (token.indexOf('.') > -1) {
      // Token contains a class selector
      var bits = token.split('.');
      var tagName = bits[0];
      var className = bits[1];
      if (!tagName) {
        tagName = '*';
      }
      // Get elements matching tag, filter them for class selector
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      continue; // Skip to next token
    }
    // Code to deal with attribute selectors
    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
      var tagName = RegExp.$1;
      var attrName = RegExp.$2;
      var attrOperator = RegExp.$3;
      var attrValue = RegExp.$4;
      if (!tagName) {
        tagName = '*';
      }
      // Grab all of the tagName elements within current context
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      var checkFunction; // This function will be used to filter the elements
      switch (attrOperator) {
        case '=': // Equality
          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
          break;
        case '~': // Match one of space seperated words 
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
          break;
        case '|': // Match start with value followed by optional hyphen
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
          break;
        case '^': // Match starts with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
          break;
        case '$': // Match ends with value - fails with "Warning" in Opera 7
          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
          break;
        case '*': // Match ends with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
          break;
        default :
          // Just test for existence of attribute
          checkFunction = function(e) { return e.getAttribute(attrName); };
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (checkFunction(found[k])) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
      continue; // Skip to next token
    }
    
    if (!currentContext[0]){
    	return;
    }
    
    // If we get here, token is JUST an element (not a class or ID selector)
    tagName = token;
    var found = new Array;
    var foundCount = 0;
    for (var h = 0; h < currentContext.length; h++) {
      var elements = currentContext[h].getElementsByTagName(tagName);
      for (var j = 0; j < elements.length; j++) {
        found[foundCount++] = elements[j];
      }
    }
    currentContext = found;
  }
  return currentContext;
}

/* That revolting regular expression explained 
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
  \---/  \---/\-------------/    \-------/
    |      |         |               |
    |      |         |           The value
    |      |    ~,|,^,$,* or =
    |   Attribute 
   Tag
*/
/* ****************************************************************************
 * END BEHAVIOUR
** ************************************************************************** */