

/* emg.js.php */
/*
12:25 PM 1/6/2011 - added tokenInit() and toggleClassArray()
3:38 PM 12/13/2010
2:04 PM 10/14/2010
3:52 PM 10/12/2010
/*
Copyright © 2008 Eckx Media Group, LLC. All rights reserved.
Eckx Media Group respects the intellectual property of others, and we ask our users to do the same.
*/
/*<script>*/

var emgInit = function(){
			BrowserDetect.init();				EmgAjax.init($('body').first());				loginTimer.init();				initValForm();				modal.init();				ImageHover.init();			ie6Check();
	//emg link
	$('#emg-link').hide();
	
	if(window.siteInit){
		siteInit();
	}
	
	$('.hide').hide(); //hide all elements with class hide
	
	markupInit();
	setEventHandlers('body'); // set event handlers
};

$(document).ready(emgInit);

//function to run initial function that changes markup
function markupInit(){
	var bodyElement = $('body')[0]; // cant use document.body because error in IE7, no .select
	// confirmInit(bodyElement); moved to setEventHandlers
	externalLinks(bodyElement);
	autoCompleteOff(bodyElement);
	defaultClear(bodyElement);
	
	ieSelectExpand();
}

function setEventHandlers(container){
	// confirm2
	$('a[rel~="confirm"]', container).click(function() {
		//event.preventDefault();
		var url = $(this)[0].href;
		var message = $(this)[0].title;
		var target = $(this)[0].target;
		if (target == '_blank') { // open link in new window
			confirm2(null, message, 'window.open(\'' + url + '\')'); 
		}
		else {
			confirm2(null, message, 'window.location = \'' + url + '\';'); 
		}
		return false;

	});
	
	//focus specified field when max length has been entered, good for phone numbers
	$('input[type="text"].max-length-next').keyup(function(event){
		if(event.keyCode == 9){ //ignore tabs
			return;	
		}
		if(this.value.length == this.maxLength){
			var focusid = classAfter('max-length-next', this.className);
			$('#' + focusid).focus();
		}
	});
	
	// Form address fields
	emgFormAddressFields();
	
	// Captcha
	emgFormCaptchaRefresh();
	
	// site specific event handlers
	if (window.setSiteEventHandlers) { 
		setSiteEventHandlers(container);
	}
	
	// ecommerce event handlers
	if (window.setEcommerceEventHandlers) { 
		setEcommerceEventHandlers(container);
	}
	
	// Span nav parents
	$("ul#nav li.parent > span").click(function() {
		$(this).closest('li.parent').toggleClass('hover');
	});
}

function emgFormAddressFields() {
	// Input names
	var provinceName = 'province';
	var stateName = 'stateid';
	var countryName = 'countryid';
	var zipName = 'zip';
	
	//comment out because auto trigger below should handle it
	//$('.emg-form input[name="' + provinceName + '"], .emg-form input[name^="' + provinceName + '["]').closest('li').hide();
	
	// Account for names and name arrays
	$('.emg-form select[name="' + countryName + '"], .emg-form select[name^="' + countryName + '["]').change(function() {
																													  
		// Id strings
		var provinceId = this.id.replace(countryName, provinceName);
		var stateId = this.id.replace(countryName, stateName);
		var zipId = this.id.replace(countryName, zipName);
		
		// Input fields
		var provinceInput = $('#' + provinceId);
		var stateSelect = $('#' + stateId);
		var zipInput = $('#' + zipId);
		
		// Check if state & zip are initially required
		// doesnt make sense
		//var stateIsRequired = stateSelect.hasClass('val_req');
		//var zipIsRequired = zipInput.hasClass('val_req');
		
		// Element containers
		var provinceContainer = $('#' + provinceId + '-container');
		var stateContainer = $('#' + stateId + '-container');
				
		// 1 => United States
		// Require state/zip if they are initially required
		if (this.value == 1) {
			provinceContainer.hide();
			provinceInput.removeClass('val_req');
			
			stateSelect.addClass('val_req'); // if country is US, require state
			stateContainer.show();
			
			zipInput.addClass('val_req val_exist zip'); // if country is US, require zip
			
		}
		else {
			stateContainer.hide();
			stateSelect.removeClass('val_req');
			
			provinceInput.addClass('val_req');
			provinceContainer.show();
			
			zipInput.removeClass('val_req val_exist zip');
		}
	});
	
	//set based on default value
	var ul = $('.emg-form input[name="' + provinceName + '"], .emg-form input[name^="' + provinceName + '["]').closest('ul.fields');
	var countryField = $('[name="' + countryName + '"], [name^="' + countryName + '["]', ul);
	countryField.trigger('change');
	
}

function emgFormCaptchaRefresh() {
	$('p.new-image a.captcha-hint').click(function() {
		var inputId = getHash(this.href);
		var input = $('#' + inputId);
		
		if (input) {
			var form = input.closest('form');
			var formId = $(form).attr('id');
			
			refreshCaptcha(formId);
		}
		
		return false;
	});
}

function classAfter(needle, haystack){
	var classes = haystack.split(' ');
	for(var i = 0; i < classes.length; i++){
		if(classes[i] == needle){
			return classes[i + 1];
		}
	}
}

//Event.observe(window, 'load', emgInit);
//document.observe('dom:loaded', emgInit);

// Show / Hide object
function toggle(obj) {
	alert('Deprecated - use toggleClass with css');
	return;
	
	var el = $(obj);
	el.style.display = (el.style.display != 'block' ? 'block' : 'none' );
	el.blur();
}
function toggle2(obj) {
	alert('Deprecated - use toggleClass with css');
	return;
	
	var el = $(obj);
	el.style.display = (el.style.display != 'block' ? 'block' : 'none' );
	el.blur();
}

function toggleClass(id, className) {
	$('#' + id).toggleClass(className);
	/*
	var el = $(id);
	if (el.hasClassName(className)) {
		el.removeClassName(className);
	}
	else {
		el.addClassName(className);
	}*/
}

function toggleClassArray(ids, className){
	for(var i = 0; i < ids.length; i++){
		toggleClass(ids[i], className);	
	}
}

// Reset form fields
function clearForm(id, skipids) {
	if(!skipids){
		skipids = new Array();
	}
	var form = byId(id);
	for (var i = 0; i < form.length; i++) {
		if(inArray(form[i].id, skipids) || form[i].type == 'submit' || form[i].type == 'button' ){
			continue;
		}
		if(form[i].type == 'checkbox' || form[i].type == 'radio') {
			form[i].checked = false;	
		}
		if(form[i].options){ // drop downs
			form[i].selectedIndex = 0;
		}
		else {
			form[i].value = '';
		}
		
	}
}

// Reset form fieldset fields
function clearFieldset(id) {
	var fieldset = $('#' + id + ' input[type="text"], ' + '#' + id + ' input[type="password"], ' + '#' + id + ' input[type="file"], ' + '#' + id + ' select, ' + '#' + id + ' textarea');
	
	for (var i = 0; i < fieldset.length; i++) {
		clearField(fieldset[i]);
	}
}
// Clear individual field
function clearField (field) {
	if(field.type == 'checkbox' || field.type == 'radio') {
		field.checked = false;	
	}
	else {
		field.value = '';
	}
}

function popUpA(URL) { //allow all features
	day = new Date();
	id = "aboutUS";
	eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=1,scrollbars=1,location=1,statusbar=1,menubar=1,resizable=1,width=900,height=400,left = 240,top = 212');");
}

function popUpB(URL) { // disable all features
	day = new Date();
	id = "aboutUS";
	eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=300,height=300,left = 240,top = 212');");
}

function isset(obj){
	if(typeof obj == 'undefined'){
		return false;
	}
	else{
		return true;	
	}
}


function getMousePos(e) {
	var IE = document.all?true:false
	var scrollXY = getScrollXY();
	var mousePos = new Array();
	if (IE) { // grab the x-y pos.s if browser is IE
		tempX = e.x;
		tempY = e.y;
	} 
	else {  // grab the x-y pos.s if browser is NS
		tempX = e.clientX;
		tempY = e.clientY;
	}
	// catch possible negative values in NS4
	if (tempX < 0){tempX = 0}
	if (tempY < 0){tempY = 0}  
	mousePos['x'] = tempX + scrollXY[0];
	mousePos['y'] = tempY + scrollXY[1];
	return mousePos;
}


function getScrollXY() {
  var scrOfX = 0, scrOfY = 0;
  if( typeof( window.pageYOffset ) == 'number' ) {
    //Netscape compliant
    scrOfY = window.pageYOffset;
    scrOfX = window.pageXOffset;
  } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
    //DOM compliant
    scrOfY = document.body.scrollTop;
    scrOfX = document.body.scrollLeft;
  } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
    //IE6 standards compliant mode
    scrOfY = document.documentElement.scrollTop;
    scrOfX = document.documentElement.scrollLeft;
  }
  return [ scrOfX, scrOfY ];
}

function getPageDim(){
	/*if(document.all?true:false){ // IE
		if(document.body.clientHeight > document.body.scrollHeight){
			var height = document.body.clientHeight;
			var width = document.body.clientWidth;
		}
		else{
			var height = document.body.scrollHeight;
			var width = document.body.scrollWidth;
		}
	}
	else{
		var height = document.height;
		var width = document.weidth;
	}
	
	// Gecko 6.0
	if (height === undefined) {
		height = document.body.clientHeight;
	}
	if (width === undefined) {
		width = document.body.clientWidth;
	}	
	
	var viewPortHeight = document.viewport.height();
	if(height < viewPortHeight){
		height = viewPortHeight;
	}*/
	return [ $(document).width(), $(document).height() ];
}

function getVisibleDim(){ alert('function getVisibleDim() decremented, use prototype viewport');
	if(!$('getTopLeft-fake-body')){ //generate fake div to get screen size
		var fakeDiv = document.createElement('div');
		fakeDiv.id = 'getTopLeft-fake-body';
		fakeDiv.style.visibility = 'hidden';
		fakeDiv.style.margin = '0';
		fakeDiv.style.padding = '0';
		fakeDiv.style.position = 'absolute';
		fakeDiv.style.top = '0';
		fakeDiv.style.bottom = '0';
		fakeDiv.style.left = '0';
		fakeDiv.style.right = '0';
		fakeDiv.style.width = '100%';
		fakeDiv.style.height = '100%';
		fakeDiv.style.zIndex = '-1';
		document.body.appendChild(fakeDiv);
	}
	
	var fakeDiv = $('getTopLeft-fake-body');
	var width = fakeDiv.getWidth();
	var height = fakeDiv.height();
	return [ width, height ];
}


function alert2(text, dim, alertTime, className){ 
	//check if alert 2 already exist
	
	var i = 0;
	while(byId('alert2_' + i)){
		i++;
	}
	
	var alert2 = document.createElement('div');
	
	alert2.id = 'alert2_' + i;
	alert2.style.visibility = 'hidden';
	document.body.appendChild(alert2);
	
	alert2 = byId('alert2_' + i);
	if (className === undefined) {
		$(alert2).addClass('alert2');
	}
	else {
		$(alert2).addClass(className);	
	}
	
	alert2.innerHTML = text;
	
	if (dim) {
		width = dim[0];
		height = dim[1];
		alert2.style.width = width + 'px';
		alert2.style.height = height + 'px';
	}
	else {
		width = $(alert2).width();
		height = $(alert2).height();
	}
	
	if(isNaN(width) || isNaN(height)){
		alert('Alert2() error, width or height isNaN');	
	}
	
	var xy = getScrollXY();
	var topLeft = getTopLeft(width, height);
	alert2.style.top = topLeft[0]+'%';
	alert2.style.left = topLeft[1]+'%';
	alert2.style.visibility = 'visible';
	if (!alertTime) {
		alertTime = 2000;	
	}
	setTimeout("document.body.removeChild(document.getElementById('alert2_" + i + "'))", alertTime);
}


//return the top left percentage for an absolute centered layer, req 100% body height
function getTopLeft(width, height){
	var windowWidth = $(window).width();
	var windowHeight = $(window).height();
	var ie = getIEVerNum();
	
	//compensate for scroll
	var xy = getScrollXY();
	
	//get %
	var top = (windowHeight/2 + xy[1] - (height/2)) / windowHeight;
	var left = (windowWidth/2 + xy[0] - (width/2)) / windowWidth;

	if(top < 0){
		top = 0;	
	}
	if(left <0){
		left = 0;	
	}
	
	//compensate for ie 6 usage of %, the entire document not just what u see is 100%
	if(ie == 6){ // ie 6
		var pxHeight = windowHeight * top; //get pixel height
		top = pxHeight/document.body.clientHeight; // get decimal height
	}
	
	top  = Math.round(top * 100); 
	left  = Math.round(left * 100);
			
	return [ top, left ];
}

function money(num){
	var formated = Math.round(num*1000)/1000; //use 1000 for partial cents
	formated = formated.toString();
	if(formated.indexOf('.') == -1){
		formated += '.00';
	}
	else{
		var parts = formated.split('.');
		if(parts[1].length == 1){
			formated += '0';	
		}
	}
	return formated;
}

function urlencode(str) { alert('use encodeURIComponent()');
	str = escape(str);
	str = str.replace('+', '%2B');
	str = str.replace('%20', '+');
	str = str.replace('*', '%2A');
	str = str.replace('/', '%2F');
	str = str.replace('@', '%40');
	return str;
}

function urldecode(str) {
	str = str.replace('+', ' ');
	str = unescape(str);
	return str;
}

function htmlentities(html) {
	html = html.replace('<','&lt;');
	html = html.replace('>','&gt;');
	html = html.replace('"','&quot;');
	return html;
} 

function getJs(url){
	if(!inString(url, '?')){
		url += '?';	
	}
	var jsel = document.createElement('SCRIPT');
	jsel.type = 'text/javascript';
	jsel.src = url+'&klioe='+Math.random()*10000;
	document.body.appendChild(jsel);
}

//Get IE Version Number
function getIEVerNum() {
    var ua = navigator.userAgent;
    var MSIEOffset = ua.indexOf("MSIE ");
    
    if (MSIEOffset == -1) {
        return 0;
    } else {
        return parseFloat(ua.substring(MSIEOffset + 5, ua.indexOf(";", MSIEOffset)));
    }
}

function confirm2(e, title, yesEval, noEval, yesTitle){
	var yesText = (yesTitle) ? yesTitle : 'Yes';
	var noText = (yesTitle) ? 'Cancel' : 'No';
	
	var delConfirm = document.createElement('div');
	delConfirm.id = 'confirm2';
	document.body.appendChild(delConfirm);
	modal.load();
	modal.content('<p><strong>'+title+'</strong></p><ul class="tools confirm"><li class="yes"><span><a href="#" id="confirm2-yes">'+yesText+'</a></span></li><li class="no"><span><a href="#" id="confirm2-no">'+noText+'</a></span></li></ul>');
	//delConfirm = $('confirm2');
	//delConfirm.addClassName('confirm2');
	//delConfirm.innerHTML = '<div>'+title+'</div><input type="button" id="confirm2_yes" value="Yes"/><br/><input type="button" id="confirm2_no" value="No" />';
	
	//var mousePos = getMousePos(e);
	//delConfirm.style.left=mousePos['x']+'px';
	//delConfirm.style.top=mousePos['y']+'px';
	$('#confirm2-yes')[0].onclick= function(){ 
		//document.body.removeChild($('confirm2'));
		eval(yesEval);
		modal.close();
		return false;
	}
	$('#confirm2-no')[0].onclick= function(){ 
		//document.body.removeChild($('confirm2'));
		eval(noEval); 
		modal.close();
		return false;
	}
}

function checkAll(name, trueFalse){
	var checkBoxes = document.getElementsByName(name);
	var len = checkBoxes.length;
	for(var i=0; i<len; i++){
		checkBoxes[i].checked = trueFalse;
	}
}

function confirmInit(container){
	var anchors = $('a[rel~="confirm"]', container);
	for(var i = 0; i < anchors.length; i++){
		anchors[i].href  = 'javascript:confirm2(null, \'' + anchors[i].title + '\', \'window.location=\\\'' + anchors[i].href + '\\\'\', \'\')';
	}
}

function externalLinks(container) {
	var anchors = $('a[rel~="external"]', container);
	
	for (var i=0; i<anchors.length; i++) {
		anchors[i].target = "_blank";
	}
}

function autoCompleteOff(container){
	var inputs = $('input[class~="autocomplete-off"]', container);
	for (var i=0; i<inputs.length; i++) {
		inputs[i].setAttribute("autocomplete", "off");
	}
}

function defaultClear(container){	
	var inputs = $('[class~="default-clear"]', container);
	
	var defaultClassName = 'default';
	
	
	inputs.focus(function() {
		if(this.value == this.defaultValue){
			this.value = '';
			$(this).removeClass(defaultClassName);
		}
	}).blur(function() {
		if(this.value == ''){
			this.value = this.defaultValue;
			$(this).addClass(defaultClassName);
		}
	});
}

function bookMark(url, title){
	if(document.all?true:false){ // IE
		window.external.AddFavorite(url, title);
	}
	else{
		window.sidebar.addPanel(title, url, '')
	}
}

function ajaxFill(url, containerid, callback){
	alert('depercated, please use EmgAjax.call()');
	return;
	var container = $(containerid);
	if(!container){
		alert('ajaxFill(): '+containerid+' id dosnt exist');
		return;
	}
	container.innerHTML = '<div style="text-align:center"><img src="'+window.CR+'/images/library/loading.gif" /></div>';
	new Ajax.Request(url, { method: 'get', onSuccess: function(ajaxReturn) {
		if(ajaxReturn.responseText == 'died'){
			window.location = window.CR + '/died';
			return;
		}
		container.innerHTML = ajaxReturn.responseText;
		curtain.initLinks(container); //curtain reference
		eval(callback);
	}}); 
}

function ie6Check() {
	if (BrowserDetect.browser == 'Explorer' && BrowserDetect.version < 7) {
		var ie6Notice = document.createElement('div');
		ie6Notice.id = 'ie6-notice';
		ie6Notice.innerHTML = '<p class="title">It seems like you are using Internet Explorer 6 or lower.</p><p>IE6 is an outdated web browser that cannot provide the rich web experience that a modern web browser is able to.  This site may not display and function correctly as a result.</p><p>You may want to upgrade to one of these newer web browsers:</p><ul class="browsers"><li><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx" title="Download Internet Explorer 9">Download Internet Explorer 9</a></li><li><a href="http://www.mozilla.com/en-US/firefox/" title="Download Mozilla Firefox">Download Mozilla Firefox</a></li><li><a href="http://www.google.com/chrome" title="Download Google Chrome">Download Google Chrome</a></li></ul><p class="hide-notice"><a href="#" onclick="document.getElementById(\'ie6-notice\').style.display = \'none\'; return false;" title="Hide this notice" rel="external">Hide this notice</a></p>';
		document.body.appendChild(ie6Notice);
	}
}

// verify the captcha
function verifyCaptcha(captchaFieldid){
	var url = window.CR + '/ajax/verify-captcha?area=' + captchaFieldid + '&captcha=' + $('#' + captchaFieldid)[0].value;
	var valFormIndex = getValFormIndex(captchaFieldid);
	valForms[valFormIndex].ajaxRunning[captchaFieldid] = true;

	$.ajax({
		   url: url
		   , type: 'get'
		   , dataType: 'text'
		   , cache: false
		   , complete: function(ajaxReturn) {
			   				var response = ajaxReturn.responseText;
							var error = response == '0' ? ' is incorrect.' : false;
							
							valForms[valFormIndex].errorHandler($('#' + captchaFieldid)[0], error);
							valForms[valFormIndex].ajaxRunning[captchaFieldid] = false;
						}
			});
	
}

function refreshCaptcha(formid) {
	var textInput = byId(formid + '-captcha');
	textInput.value = '';
	byId(formid + '-captcha-img').src = '/ajax/show-captcha?area=' + formid + '-captcha&amp;k=' + Math.random();
	textInput.focus();
}

function refreshImg(id){
	var img = byId(id);
	if(inString(img.src, '?')){
		img.src = img.src + '&k='+Math.random();
	}
	else{
		img.src = img.src + '?k='+Math.random();
	}
}

function showFlash(src, w, h, container, parameters, variables){
	alert('decremented, use swfobject.embedSWF(window.CR + \'/swf/player.swf\', containerid, w, h, \'9.0.0\', \'expressInstall.swf\', variables, parameters);'); return;
	var s1 = new SWFObject(src, 'mediaplayer', w, h,'7');
	if(parameters){
		parameters = parameters.split('&');
		for(var i = 0; i < parameters.length; i++){
			var parts = parameters[i].split('=');
			s1.addParam(parts[0], parts[1]);
		}
	}
	if(variables){
		s1.addParam('flashvars', variables);
	} 
	if(!s1.write(container)){
		$(container).innerHTML = '<a href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Click here to get the flash player.</a>';
	}
}

//controlbar: over, under
function showPlayer(flv, w, h, containerid, preview, skin, controlbar){
	var parameters = {};
	parameters.allowfullscreen = true;
	parameters.allowscriptaccess = 'always';
	parameters.wmode = 'opaque';
	
	var variables = {file: flv};
	if(preview){
		variables.image = preview;
	}
	if(skin){
		variables.skin = skin;
	}
	if(controlbar){
		variables.controlbar = controlbar;
	}
	swfobject.embedSWF(window.CR + '/swf/player.swf', containerid, w, h, '9.0.0', 'expressInstall.swf', variables, parameters);
}

// skin: (default) | bekle
// controlbar: bottom (default) | top | over | none
// autostart: false (default) | true
// stretching: uniform (default) | fill | exactfit | none
// volume: (integer)
// mute: false (default) | true
function showVideo(flv, w, h, containerid, image, skin, controlbar, autostart, stretching, volume, mute) {
	var parameters = {};
	// Standard parameters
	parameters.allowfullscreen = true;
	parameters.allowscriptaccess = 'always';
	parameters.wmode = 'opaque';
	
	// Flash variables
	var variables = {file: flv};
	if (image !== undefined){
		variables.image = window.CR + '/images/video-previews/' + image;
	}
	if (skin !== undefined){
		variables.skin = window.CR + '/swf/skins/' + skin + '/overlay.swf';
	}
	variables.controlbar = controlbar === undefined ? 'bottom' : controlbar;
	variables.autostart = autostart === undefined ? 'false' : autostart;
	variables.stretching = stretching === undefined ? 'uniform' : stretching;
	variables.volume = volume === undefined ? 100 : volume;
	variables.mute = mute === undefined ? 'false' : mute;
	
	swfobject.embedSWF(window.CR + '/swf/player.swf', containerid, w, h, '9.0.0', 'expressInstall.swf', variables, parameters);
}


function textAreaExp(id){
	var label = $('label[for="' + id + '"]');
	var header = '';
	if(label){
		header = '<h3>' + label[0].innerHTML + '</h3>';
	}

	var html = '<div class="emg-form">' + header + '<textarea rows="25" cols="100" id="' + id + '-expanded" class="fluid">' + $('#' + id)[0].value + '</textarea><br /><button onclick="$(\'#' + id + '\')[0].value = $(\'#' + id + '-expanded\')[0].value; modal.close();">Finish</button></div>';
	modal.load();
	modal.content(html);
}

//use to show all the properties of an object;
function alerto(obj, hideValues){
	var output = '';
	for (var prop in obj ) {
		output += 'object.' + prop;
		if(hideValues != true){
			output += ' = ' + obj[prop] 
		}
		output += "\n";
	}
	alert(output);
}


function checkedToStr(inputName){
	var checkboxes = document.getElementsByName(inputName);
	var values = new Array();
	for(var i=0; i<checkboxes.length; i++){
		if(checkboxes[i].checked){
			values[values.length] = checkboxes[i].value;
		}
	}
	return values.join('-');
}

function moneyFormat(value, nosymbol, cents) {
	if (isNaN(value)) {
		var formatted = '0.00';
	}
	else {
		//var formatted = Math.round(value*100)/100;
		var formatted = Math.round(value*1000)/1000; //use 1000 for partial cents
		formatted = formatted.toString();
		
		if (formatted.indexOf('.') == -1) {
			formatted += '.00';
		}
		else {
			var parts = formatted.split('.');
			if (parts[1].length == 1) {
				formatted += '0';
			}
		}
		// Thousands commas
		if (formatted.length >= 7) {
			var parts = formatted.split('.');
			var integer = parts[0];
			var rgx = /(\d+)(\d{3})/;
			while (rgx.test(integer)) {
				integer = integer.replace(rgx, '$1' + ',' + '$2');
			}
			formatted = integer + '.' + parts[1];
		}
	}
	if(!nosymbol && !cents){
		formatted = '$' + formatted;
	}
	// Cent symbol
	else if (cents && formatted < 1) {
		return formatted * 100 + '\u00a2';
	}
	return formatted;
}

function emailInUse(emailFieldid){
	checkExist('email', emailFieldid, false);
}

function emailNotExist(emailFieldid){
	checkExist('email', emailFieldid, true);
}

function zipExist(zipFieldid){
	checkExist('zip', zipFieldid, true);
}

function checkExist(field, fieldid, valExists){
	if($('#' + fieldid)[0].value == ''){
		return;
	}
	var url = window.CR + '/ajax/check-exist/' + field + '?check-value=' + $('#' + fieldid)[0].value;
	var valFormIndex = getValFormIndex(fieldid);
	valForms[valFormIndex].ajaxRunning[fieldid] = true;
	$.ajax({
		   url: url
		   , type: 'get'
		   , dataType: 'text'
		   , cache: false
		   , complete: function(ajaxReturn) {
						   	if (ajaxReturn.status == '404') { // page not found
								window.location = window.CR + '/error';
								return;
							}
							
			   				var response = ajaxReturn.responseText;
							//alert(response);
							if(valExists){  // for reset password form
								var error = response == '0' ? ' does not exist.' : false;
							}
							else{
								var error = response == '1' ? ' already in use.' : false;
							}
							
							valForms[valFormIndex].errorHandler($('#' + fieldid)[0], error);
							valForms[valFormIndex].ajaxRunning[fieldid] = false;
						}
		   });
}

// Scrolls to hash instead of instant jump
// Also doesn't append hash to current url
// Requires jquery
// Usage: enableHashScroll('a');
// Usage: enableHashScroll(['a', '.nav a]], 1, 16);
function enableHashScroll(anchorSelectors, duration, offset) {	
	// Set default duration to 1 second
	duration = isNaN(duration) ? 1000 : duration * 1000;
	offset = isNaN(offset) ? 0 : offset;
	if (!isArray(anchorSelectors)) {
		anchorSelectors = [anchorSelectors];
	}
	
	// For each group of anchor selectors
	$(anchorSelectors).each(function() {
		anchorSelector = $(this).get();
		anchorSelector = anchorSelector === undefined || anchorSelector == '' ? 'a' : String(anchorSelector);
		
		// Anchor events
		$(anchorSelector + '[href*="#"]:not([href="#"])').click(function() {
			var target = $(this.hash);
			if (target[0]) {
				this.blur();
				$('html, body').animate({scrollTop: target.offset().top - offset}, duration);
				return false;
			}
		});
	});
}

// Get hash value from url
function getHash(href) {
	return href.split(/#/)[1];
}

// Get document height, or viewport if body height is less
function getDocHeight() {
	return Math.max(
		Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
		Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
		Math.max(document.body.clientHeight, document.documentElement.clientHeight)
	);
}

// IE select expand
// Usage: ieSelectExpand('select.ie-expand')
function ieSelectExpand(selectSelector) {
	if (selectSelector === undefined) {
		selectSelector = 'select.ie-expand';
	}
	if ($.browser.msie) {
		$(selectSelector).bind('mouseover focus', function() {
			$(this).addClass('expanded').removeClass('clicked');
		}).bind('click', function() {
			$(this).toggleClass('clicked');
		}).bind('mouseout', function() {
			if (!$(this).hasClass('clicked')) {
				$(this).removeClass('expanded');
			}
		}).bind('blur', function() {
			$(this).removeClass('expanded clicked');
		});
	}
}

// Set/append return false
function setOnclickFalse(el, replaceOnclick) {
	if (replaceOnclick == true) {
		el.setAttribute('onclick', 'return false;');
	}
	else {
		var originalOnclick = el.onclick;
		el.onclick = (function(e) {
			if (originalOnclick) {
				originalOnclick();
			}
			return false;
		});
	}
}

// Trim
if (typeof(String.prototype.trim) === "undefined") {
	String.prototype.trim = function() {
		return String(this).replace(/^\s+|\s+$/g, '');
	};
}

//use to concat token to action requests
//function is useful when using ajax to login
//currently being used in checkout.js
function tokenInit(){
	var url = window.CR + '/ajax/account/token';
	var callBackComplete = function(ajaxReturn) {				
		if(!inString(ajaxReturn.responseText, 'lv2-token=')){ //token not available, something could be wrong
			window.TOKEN = '';
			return;
		}
		
		window.TOKEN = ajaxReturn.responseText;
		
		//handle forms
		var forms = $('form');
		for(var i = 0; i < forms.length; i++){
			if(inString(forms[i].action, 'lv2-token=')){ //already has token, potential bugs with user logging in n out with differnt accounts
				continue;	
			}
			if(inString(forms[i].action, window.CR + '/action')){ //if request is an action page
				if(inString(forms[i].action, '?')){
					forms[i].action += '&' + ajaxReturn.responseText;
				}
				else{
					forms[i].action += '?' + ajaxReturn.responseText;
				}
			}
		}
		
		//handle anchors
		var anchors = $('a');
		for(var i = 0; i < anchors.length; i++){
			if(inString(anchors[i].href, 'lv2-token=')){ //already has token, potential bugs with user logging in n out with differnt accounts
				continue;	
			}
			if(inString(anchors[i].href, window.CR + '/action')){ //if request is an action page
				if(inString(anchors[i].href, '?')){
					anchors[i].href += '&' + ajaxReturn.responseText;
				}
				else{
					anchors[i].href += '?' + ajaxReturn.responseText;
				}
			}
		}
	};
	//use ajax to grab token
	$.ajax({url: url, complete: callBackComplete});
	
}

function isArray(o) {
	return Object.prototype.toString.call(o) === '[object Array]';
}

function inString(haystack, needle){
	if(isArray(haystack)){
		alert('use inArray() for ' + needle);
		return false;
	}
	var index = haystack.indexOf(needle);
	
	if (index != -1) {
		return true;	
	}
	
	return false;	
}

function inArray(needle, haystack){
	var index = $.inArray(needle, haystack);
	
	if (index != -1) {
		return true;	
	}
	
	return false;
}

function byId(id){
	return document.getElementById(id);
}

// The .bind method from Prototype.js 
if (!Function.prototype.bind) { // check if native implementation available
  Function.prototype.bind = function(){ 
    var fn = this, args = Array.prototype.slice.call(arguments),
        object = args.shift(); 
    return function(){ 
      return fn.apply(object, 
        args.concat(Array.prototype.slice.call(arguments))); 
    }; 
  };
}

// Scrollbar Width
function getScrollBarWidth() {  
	var inner = document.createElement('p');
	inner.style.width = "100%";
	inner.style.height = "200px";
	
	var outer = document.createElement('div');
	outer.style.position = "absolute";
	outer.style.top = "0px";
	outer.style.left = "0px";
	outer.style.visibility = "hidden";
	outer.style.width = "200px";
	outer.style.height = "150px";
	outer.style.overflow = "hidden";
	outer.appendChild (inner);
	
	document.body.appendChild (outer);
	var w1 = inner.offsetWidth;
	outer.style.overflow = 'scroll';
	var w2 = inner.offsetWidth;
	if (w1 == w2) w2 = outer.clientWidth;
	
	document.body.removeChild (outer);
	
	return (w1 - w2);
};

function youtubeEmbed(selector, url, w, h, autoplay){
	//get video id
	var parts = url.split('?');
	var variables = parts[1].split('&');
	for(var i = 0; i < variables.length; i++){
		var variableParts = variables[i].split('=');
		if(variableParts[0] == 'v'){
			var id = variableParts[1];
		}
	}
	
	if(id == null){
		return;	
	}
	
	if(autoplay == null || !autoplay){
		autoplay = '0';
	}
	else if(autoplay){
		autoplay = '1';	
	}
	
	var html = '<object width="' + w + '" height="' + h + '">';
	html += '<param name="movie" value="http://www.youtube.com/v/' + id + '?fs=1&amp;hl=en_US&autoplay=' + autoplay + '"></param>';
	html += '<param name="allowFullScreen" value="true"></param>';
	html += '<param name="allowscriptaccess" value="always"></param>';
	html += '<param name="wmode" value="opaque"></param>';
	html += '<embed src="http://www.youtube.com/v/' + id + '?fs=1&amp;hl=en_US&autoplay=' + autoplay + '" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="opaque" width="' + w + '" height="' + h + '"></embed>';
	html += '</object>';

	$(selector)[0].innerHTML = html;
}

function youtubeIframe(selector, url, w, h, autoplay) {
	//get video id
	var parts = url.split('?');
	var variables = parts[1].split('&');
	for(var i = 0; i < variables.length; i++){
		var variableParts = variables[i].split('=');
		if(variableParts[0] == 'v'){
			var id = variableParts[1];
		}
	}
	
	if(id == null){
		return;	
	}
	
	if(autoplay == null || !autoplay){
		autoplay = '0';
	}
	else if(autoplay){
		autoplay = '1';	
	}
	
	var html = '<iframe title="YouTube video player" width="' + w + '" height="' + h + '" src="http' + (isSSL() ? 's' : '') + '://www.youtube.com/embed/' + id + '?wmode=opaque&autoplay=' + autoplay + '" frameborder="0" allowfullscreen></iframe>';
	
	$(selector)[0].innerHTML = html;
}

function isSSL() {
	return location.protocol == 'https:';
}

String.prototype.getUrlParam = function (name){
	var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(this);
	return results[1] || 0;
}

/* browser-detect.js.php */
/*<script>*/
// Browser name:	BrowserDetect.browser
// Browser version:	BrowserDetect.version
// OS name:			BrowserDetect.OS
/* July 16 09 */ 
/*
Copyright Â© 2008 Eckx Media Group, LLC. All rights reserved.
Eckx Media Group respects the intellectual property of others, and we ask our users to do the same.
*/

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari",
			versionSearch: "Version"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.userAgent,
			subString: "iPhone",
			identity: "iPhone/iPod"
	    },
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};

/* checkout.js.php */
/*<script>*/
// 11:22 AM 5/26/2011
//5:35 PM 2/22/2011
//12:25 PM 1/6/2011
function checkoutInitForm(containerid){ //need this function because cant use '.' for call back function in class markup
	checkout.initForm(containerid);
}
var checkout = {
	status: 0
	, statuses: new Array()
	, init: function(status){
		//get statuses base on step markup
		this.statuses = new Array();
		$('#checkout-steps .checkout-steps li[id*="-step"]').each(
			function(index, value){
				checkout.statuses[index] = value.id.replace('-step', '');
			}
		);
		
		//set css class for steps
		for (var i = 0; i < this.statuses.length; i++) {
			if (!$('#' + this.statuses[i] + '-step').hasClass('visited')) {
				$('#' + this.statuses[i] + '-step').addClass('visited');
			}
			
			if (status == this.statuses[i]) {
				$('#' + this.statuses[i] + '-step').addClass('current');
				break;	
			}
		}
	}
	, open: function(status){
		
		this.closeAll(status);
		
		if (status == 'billing') { // opening billing, show payment methods
			this.showPaymentMethods();
		}
		
		$('#' + status + '-container-close').addClass('hidden');
		$('#' + status + '-container-open').removeClass('hidden');
		if (!$('#' + status + '-step').hasClass('visited')) {
			$('#' + status + '-step').addClass('visited');
		}
		$('#' + status + '-step').addClass('current');
		
		EmgAjax.refresh(status + '-container-open');
	}
	, close: function(status){
		$('#' + status + '-container-close').removeClass('hidden');
		$('#' + status + '-container-open').addClass('hidden');
		$('#' + status + '-step').removeClass('current');
		if (!$('#' + status + '-step').hasClass('visited')) {
			$('#' + status + '-step').addClass('visited');
		}
		
		EmgAjax.refresh(status + '-container-close');
	}
	, currentOpen: function(){
		//close current open status
		for (var i = 0; i < this.statuses.length; i++) {
			if (!$('#' + this.statuses[i] + '-container-open').hasClass('hidden')) {
				return this.statuses[i];
			}
		}
	}
	, closeAll: function(except){
		for (var i = 0; i < this.statuses.length; i++) {
			if (this.statuses[i] == except) {
				continue;
			}
			this.close(this.statuses[i]);	
		}
		
		//close payment methods
		this.close('payment-methods');
	}
	, initForm: function(containerid){ //need to make form run our script (ajax) when submitting
		var forms = $('form', byId(containerid));
		if (forms.length > 0) {
			//need to find the correct valform and set the onsubmit to run checkout.submit instead of submitting the form
			for (var i = 0; i < valForms.length; i++) {
				if (valForms[i].form.id == forms[0].id) {
					valForms[i].originalSubmit = function(){
						checkout.submit(this);
						return 'dont reset';
					};
					return;
				}
			}
			
			//if no valform
			forms[0].onsubmit = function(){
				checkout.submit(this);
				return false;
			};
		}
	}
	, editCancel: function(){
		var url = window.CR + '/ajax/checkout/status';
		var callBackComplete = function(data) {
									if (data.responseText == 'died') {
										window.location = window.CR + '/died';
										return;
									}
									checkout.open(data.responseText);
								};
		
		var callBackFailed = function(response){
			alert('failed, try to refresh the page.');
		}
		
		$.ajax({
			   url: url
			   , type: 'get'
			   , dataType: 'text'
			   , error: checkout.errorHandler
			   , error: callBackFailed
			   , complete: callBackComplete
			   , cache: false
		}); 
	
	}
	, submit: function(form){
		var validate = this.validate();
		if (!validate) {
			return false;	
		}
		
		//show loading for order submit since it may take awhile
		if (this.currentOpen() == 'confirmation') {
			modal.load();
			modal.content('<div style="text-align:center">Please wait while we process your order. <br/ ><img src="' + window.CR + '/images/library/loading.gif" /></div>');
		}
		
		// submit the form with ajax
		$.ajax({
			   url: form.action
			   , type: form.method
			   , data: $(form).serialize()
			   , dataType: 'text'
			   , error: checkout.submitFailed
			   , complete: checkout.submitDone
			   , cache: false
		});
	}
	, validate: function(){
		switch (this.currentOpen()) {
			case 'login':
				//validate
				/*
				if (byId('checkout-login-login').value == '' && byId('checkout-login-new-email').value == '') {
					alert('Please sign in if you are an existing customer or enter your email address for guest checkout.');
					byId('checkout-login-login').focus();
					valFormsResetSubmit();
					return false;
				}
				*/
			break;
		}
		return true;
	}
	, submitDone: function(ajaxReturn){
		var currentStatus = checkout.currentOpen();
		var nextStatus = ajaxReturn.responseText;
		
		//hide loading
		if (currentStatus == 'confirmation') {
			modal.close();
		}
		
		if (ajaxReturn.responseText == 'died') {
			window.location = window.CR + '/died';
			return;
		}
		
		if (currentStatus == 'login' && inArray(nextStatus, checkout.statuses)) { //login was successful
		   tokenInit(); //need to attach token to action pages
		}
		
		valFormsResetSubmit();
		
		switch (ajaxReturn.responseText) {
			case 'Good Promo':
				byId('promo-status').innerHTML = 'Promo Code <strong>"' + byId('promo').value + '"</strong> was applied.';
				byId('promo').value = ''; // clear the promo code
				nextStatus = currentStatus; // load the current step
				if (nextStatus == 'payment-methods') {
					nextStatus = 'billing';
				}
			break;
			case 'Bad Login':
				alert('Your email address or the password was invalid.');
				byId('checkout-login-login').focus();
				return;
			case 'Missing New Password':
				alert('Please enter a password for your new account.');
				byId('checkout-login-new-password').focus();
				return;
			case 'You cannot use an administrator portal login.':
				alert('You cannot use an administrator portal login.');
				byId('checkout-login-login').focus();
				return;
			case 'Use Guest Checkout':
				alert('Please sign in if you are an existing customer or enter your email address for guest checkout.');
				byId('checkout-login-login').focus();
				return;
			case 'Create New Account':
				alert('Please sign in if you are an existing customer or enter your email address and a new password to create a new account.');
				byId('checkout-login-login').focus();
				return;
			case 'Bad Email':
				alert('The email address is already in use.');
				byId('checkout-login-new-email').focus();
				return;
			case 'Bad Shipping Address':
				alert('The shipping address is invalid.');
				return;
			case 'Bad Billing Information':
				alert('The billing information is invalid.');
				return;
			case 'No Billing Provided':
				alert('Please provide billing information.');
				EmgAjax.refresh('cart-container');
				nextStatus = 'billing';
			break;
			case 'No Shipping Method':
				alert('Please select a shipping method.');
				nextStatus = 'shipping-methods';
			break;
			case 'billing':
				if (currentStatus == 'login') { //user logged in and status skipped to billing
					//show shipping that was auto filled
					//checkout.close('shipping');
				}
			break;
			case 'confirmation':
				if (currentStatus == 'login') { //user logged in and status skipped to confirmation
					//show shipping/billing that was auto filled
					//checkout.close('shipping');
					//checkout.close('billing');
				}
			break;
			case 'Google Checkout':
				//alert('We have submitted your order; however, you still need to make payment via Google Checkout, please wait while we redirect you.  If any problems occur, please give us a call.');
				window.location = window.CR + '/redirect-to-google';
				return;
			case 'Amazon Checkout':
				//	alert('We have submitted your order; however, you still need to make payment via Amazon Checkout, please wait while we redirect you.  If any problems occur, please give us a call.');
				window.location = window.CR + '/redirect-to-amazon';
				return;
			case 'Receipt':
				window.location = window.CR + '/invoice-receipt';
				return;
			default:
				// check for custom promo msg
				var badPromoMsg = new RegExp('^Bad Promo:');
				var badPromo = ajaxReturn.responseText.match(badPromoMsg);
				if (badPromo) {
					var promoError = ajaxReturn.responseText.replace(badPromoMsg, "");
					alert(promoError);
					byId('promo').focus();
					return;
				}
		}
		
		if (!inArray(nextStatus, checkout.statuses)) {
			checkout.errorHandler(ajaxReturn.responseText);
		}
		
		//checkoutCartUpdate();
		updateCartCount();
		EmgAjax.refresh('checkout-cart-promo');
		EmgAjax.refresh('totals-container');
		checkout.closeAll();
		checkout.open(nextStatus);
	}
	, submitFailed: function(){
		alert('Connection failed, please wait while we reload the page.');
		location.reload(1);
	}
	, changePaymentMethod: function(paymentMethod){
		var url = window.CR + '/action/checkout/change-payment-method?payment_method=' + encodeURIComponent(paymentMethod);
		
		if (window.TOKEN != '') {
			url += '&' + window.TOKEN;
		}
		
		var callBackComplete = function(ajaxReturn) { 
			var nextStatus = ajaxReturn.responseText;
			
			if (ajaxReturn.responseText == 'died') {
				window.location = window.CR + '/died';
				return;
			}
			
			/*
			switch (ajaxReturn.responseText) {
				case 'confirmation':
					checkout.close('billing');
				break;
			}
			*/
			if (!inArray(nextStatus, checkout.statuses)) {
				checkout.errorHandler(ajaxReturn.responseText);
			}
			
			checkout.open(nextStatus);
		}
		
		$.ajax({
			   url: url
			   , type: 'get'
			   , dataType: 'text'
			   , error: checkout.errorHandler
			   , complete: callBackComplete
			   , cache: false
		}); 
		
	}
	, showPaymentMethods: function(){
		if (!$('#payment-methods-container-close').hasClass('hidden')) {
			$('#payment-methods-container-close').addClass('hidden');
		}
		$('#payment-methods-container-open').removeClass('hidden');
		
		EmgAjax.refresh('payment-methods-container-open');
		
	}
	, useCustomerShipping: function(shippingid){
		// show loading
		EmgAjax.showLoading('modal-' + modal.index + '-loading', false);
		
		var url = window.CR + '/action/checkout/use-customer-shipping?customer_shippingid=' + shippingid;
		if (window.TOKEN != '') {
			url += '&' + window.TOKEN;
		}
		
		var callBackComplete = function(ajaxReturn) {
			if (ajaxReturn.responseText == 'died') {
				window.location = window.CR + '/died';
				return;
			}
			
			//remove loading
			EmgAjax.removeLoading('modal-' + modal.index + '-loading');
					
			switch (ajaxReturn.responseText) {
				case 'Use Customer Shipping: Error': // bad shipping info
					alert('The shipping address is invalid.');
				break;
				case 'Use Customer Shipping: Success': // copy was successfull
					parent.modal.close();
					EmgAjax.refresh('shipping-container-close'); // close customer shipping page
					EmgAjax.refresh('totals-container'); // update shipping totals
				break;
				default: 
					checkout.errorHandler(ajaxReturn.responseText);
			}
		}
		
		$.ajax({
			   url: url
			   , type: 'get'
			   , dataType: 'text'
			   , error: checkout.errorHandler
			   , complete: callBackComplete
			   , cache: false
		}); 
		
	}
	, useCustomerCreditCard: function(creditCardid){
		// show loading
		EmgAjax.showLoading('modal-' + modal.index + '-loading', false);
		
		var url = window.CR + '/action/checkout/use-customer-credit-card?customer_credit_cardid=' + creditCardid;
		if (window.TOKEN != '') {
			url += '&' + window.TOKEN;
		}
		
		var callBackComplete = function(ajaxReturn) {
			if (ajaxReturn.responseText == 'died') {
				window.location = window.CR + '/died';
				return;
			}
			
			//remove loading
			EmgAjax.removeLoading('modal-' + modal.index + '-loading');
			
			switch(ajaxReturn.responseText){
				case 'Use Customer Credit Card: Error': // bad credit card info
					alert('The credit card information is invalid.');
				break;
				case 'Use Customer Credit Card: Success': // copy was successfull
					parent.modal.close(); // close customer credit card page
					EmgAjax.refresh('billing-container-close');
				break;
				default: 
					checkout.errorHandler(ajaxReturn.responseText);
			}
		};
		
		$.ajax({
			   url: url
			   , type: 'get'
			   , dataType: 'text'
			   , error: checkout.errorHandler
			   , complete: callBackComplete
			   , cache: false
		}); 
		
	}
	, checkBillingRequired: function(){
		var url = window.CR + '/action/checkout/check-billing-required';
		
		if (window.TOKEN != '') {
			url += '?' + window.TOKEN;
		}
		
		var callBackComplete = function(ajaxReturn) {
			var nextStatus = ajaxReturn.responseText;
			var currentOpen = checkout.currentOpen();
			if (ajaxReturn.responseText == 'died') {
				window.location = window.CR + '/died';
				return;
			}
			//alert(ajaxReturn.responseText);
			switch (ajaxReturn.responseText) {
				case 'billing':
					if (currentOpen == 'confirmation') {
						alert('Please provide billing information.');
						checkout.open('billing');
					}
				break;
				
				case 'confirmation':
					if (currentOpen == 'confirmation') { 
						// refresh the billing info
						checkout.close('payment-methods');
						checkout.close('billing');
						
						// refresh confirmation
						EmgAjax.refresh('confirmation-container-open');
					}
				break;
				
				case 'confirmation no billing required':
					// no billing required, refresh billing info container
					checkout.close('payment-methods');
					checkout.close('billing');
					
					// refresh confirmation
					if (currentOpen == 'payment-methods' || currentOpen == 'billing' || currentOpen == 'confirmation') {
						$('#confirmation-container-open').removeClass('hidden');
						if (!$('#confirmation-step').hasClass('visited')) {
							$('#confirmation-step').addClass('visited');
						}
						$('#confirmation-step').addClass('current');
						
						EmgAjax.refresh('confirmation-container-open');
					}
				break;
				
				case '':
				break;
				
				default: 
					checkout.errorHandler(ajaxReturn.responseText);
			}
			
		}
		
		$.ajax({
			   url: url
			   , type: 'get'
			   , dataType: 'text'
			   , error: checkout.errorHandler
			   , complete: callBackComplete
			   , cache: false
		}); 
	}
	/*
	, copyShipping: function(){
		var billingFormid = 'billing-info';
		var fillFields = new Array('first_name'
								   , 'last_name'
								   , 'phone'
								   , 'address'
								   , 'address2'
								   , 'city'
								   , 'stateid'
								   , 'province'
								   , 'countryid'
								   , 'zip'
								   );
		var url = window.CR + '/ajax/checkout/shipping';
		
		var callBackComplete = function(data) {
			if (data.responseText == 'died') {
				window.location = window.CR + '/died';
				return;
			}
			
			if (data.responseText == '') {
				return;
			}
			else {
				var shipping = $.parseJSON(data.responseText); // get shipping details from response
				
				for (var i = 0; i < fillFields.length; i++) { // auto fill billing fields
					var billingField = $('#' + billingFormid + ' input[name="' + fillFields[i] + '"], #' + billingFormid + ' select[name="' + fillFields[i] + '"]')[0];
					if (shipping[fillFields[i]] == null) { // need for ie, otherwise will set value to "null"
						billingField.value = '';
					}
					else {
						billingField.value = shipping[fillFields[i]];
					}
				}
				
				// show or hide state/province
				//var countryField = byId(fieldPrefix + 'countryid');
				//changeCountry(countryField.value, fieldPrefix);
				var countryField = $('#' + billingFormid + ' select[name="countryid"]');
				countryField.trigger('change');
			}
		};
		
		$.ajax({url: url
			   , type: 'get'
			   , dataType: 'text'
			   , error: checkout.errorHandler
			   , complete: callBackComplete
			   , cache: false
		}); 
		
	}
	*/
	, billingAutoFill: function(billingFormid, useShipping){
		var fillFields = new Array('first_name'
								   , 'last_name'
								   , 'phone'
								   , 'address'
								   , 'address2'
								   , 'city'
								   , 'stateid'
								   , 'province'
								   , 'countryid'
								   , 'zip'
								   );
		var url = window.CR + '/ajax/checkout/shipping';
		
		var callBackComplete = function(data) {
			if (data.responseText == 'died') {
				window.location = window.CR + '/died';
				return;
			}
			
			if (data.responseText == '') {
				return;
			}
			else {
				var shipping = $.parseJSON(data.responseText); // get shipping details from response
				
				for (var i = 0; i < fillFields.length; i++) { // auto fill billing fields
					var billingField = $('#' + billingFormid + ' input[name="' + fillFields[i] + '"], #' + billingFormid + ' select[name="' + fillFields[i] + '"]')[0];
					if (shipping[fillFields[i]] == null) { // need for ie, otherwise will set value to "null"
						billingField.value = '';
					}
					else {
						billingField.value = shipping[fillFields[i]];
					}
				}
				
				// show or hide state/province
				var countryField = $('#' + billingFormid + ' select[name="countryid"]');
				countryField.trigger('change');
			}
		};
		
		if (useShipping) {
			$.ajax({url: url
				   , type: 'get'
				   , dataType: 'text'
				   , error: checkout.errorHandler
				   , complete: callBackComplete
				   , cache: false
			}); 
		}
		else {
			for (var i = 0; i < fillFields.length; i++) { // auto fill billing fields
				var billingField = $('#' + billingFormid + ' input[name="' + fillFields[i] + '"], #' + billingFormid + ' select[name="' + fillFields[i] + '"]')[0];
				billingField.value = '';
			}
		}
		
	}
	, errorHandler: function(error) {
		alert('Connection failed, please wait while we reload the page.');
		location.reload(1);
	}
}

/* ecommerce.js.php */
/* 
4:24 PM 8/31/2010
*/ 
/*<script>*/

function setEcommerceEventHandlers(container){
	// event handler for use shipping info checkbox
	$('#billing-info-use-shipping-info-use-shipping-address').click(function() {
		checkout.billingAutoFill(this.form.id, this.checked);
	});
}

function updateCartCount(){
	var url = window.CR + '/ajax/cart-details';
	
	$.ajax({
		   url: url
		   , type: 'get'
		   , dataType: 'text'
		   , success: function(response) {
							var containers = $('.cart-item-count');
							for(var i = 0; i < containers.length; i++){
								containers[i].innerHTML = response;
							}
						}
	}); 
}

function changeCountry(countryid, pre){
	if (countryid == '1') {
		$('#' + pre + 'province-container').addClass('hidden');
		$('#' + pre + 'stateid-container').removeClass('hidden');
		$('#' + pre + 'stateid').addClass('val_req');
		$('#' + pre + 'province').removeClass('val_req');
		byId(pre + 'province').value = '';
		$('#' + pre + 'zip').addClass('val_req');
		$('#' + pre + 'zip').addClass('val_exist zip');
	}
	else {
		$('#' + pre + 'province').addClass('val_req');
		$('#' + pre + 'province-container').removeClass('hidden');
		$('#' + pre + 'stateid-container').addClass('hidden');
		$('#' + pre + 'stateid').removeClass('val_req');
		byId(pre + 'stateid').value = '';
		$('#' + pre + 'zip').removeClass('val_req');
		$('#' + pre + 'zip').removeClass('val_exist zip');
	}
}

/*
function valCC(){
	if (byId('credit_card_type').value == '') { // no cc type, let cc type req validation take over
		return false;
	}
	var ccNumField = byId('credit_card_number');
	if (ccNumField.value.length == 0) { // no cc, let req validation take over
		return false;
	}
	if (checkCreditCard(ccNumField.value, byId('credit_card_type').value)) { //valid cc
		return false;
	}
	else { // invalid cc
		return " is invalid.";
	}
}
*/


function valCC(ccFieldid){
	var ccNumInput = $('#' + ccFieldid)[0];
	var ccForm = ccNumInput.form;
	var ccTypeInput = $('#' + ccForm.id + ' select[name="credit_card_type"]')[0];
	
	if (ccTypeInput.value == '') { // no cc type, let cc type req validation take over
		return false;
	}
	
	if (ccNumInput.value.length == 0) { // no cc, let req validation take over
		return false;
	}
	
	if (checkCreditCard(ccNumInput.value, ccTypeInput.value)) { //valid cc
		return false;
	}
	else { // invalid cc
		return " is invalid.";
	}
}

function setBillingInfoReq(req){
	var reqFields = new Array('credit-card-info-first_name', 'credit-card-info-last_name', 'credit-card-info-address1', 'credit-card-info-city', 'credit-card-info-countryid', 'credit-card-info-zip', 'cctype', 'ccnumber', 'cccode', 'ccexp0', 'ccexp1');
	if (byId('countryid').value == 'US') {
		reqFields[reqFields.length] = 'credit-card-info-stateid';
	}
	else {
		reqFields[reqFields.length] = 'credit-card-info-province';
	}

	for (var i = 0; i < reqFields.length; i++) {
		if (req) {
			$('#' + reqFields[i]).addClass('val_req');
		}
		else {
			$('#' + reqFields[i]).removeClass('val_req');
		}
	}
	//changeCountry($('countryid').value); would set state/zip back to required, plust dont even think this is needed
}

/* no longer needed since function is in checkout.js
function changePaymentMethod(){
	if (byId('payment-method-credit-card').checked) {
		$('#' + 'ccfields').show(); //hide cc fields
		setBillingInfoReq(true);
	}
	else {
		$('#' + 'ccfields').hide(); //hide cc fields
		setBillingInfoReq(false);
	}
}
*/

//function used to update price when an option is selected in items details
function optionChange(){
	var addToCartForm = byId('add-to-cart-form');
	var oldAction = addToCartForm.action;
	addToCartForm.action = window.CR + '/ajax/item/price-quantity-check'; //need to reset form aciton so it has ajax in it
	var callBackSuccess = function(ajaxReturn) {
			if (ajaxReturn.responseText == 'died') { //in case something died in ajax
				window.location = window.CR + '/died';
				return;
			}
			var parts = ajaxReturn.responseText.split(' ');
			var price = parts[0];
			var inStock = parts[1];
			
			if (byId('item-current-price')) {
				byId('item-current-price').innerHTML = price;
			}
			if (byId('add-to-cart-fieldset')) {
				if (inStock == '0') {
					$('#' + 'add-to-cart-fieldset').addClass('out-of-stock');
				}
				else {
					$('#' + 'add-to-cart-fieldset').removeClass('out-of-stock');
				}
			}
			addToCartForm.action = oldAction;
		};
	
	var callBackFailed = function(){
		addToCartForm.action = oldAction;
		alert2('Failed to update price, please try again.');
	};
	
	// submit the form with ajax
	$.ajax({
		   url: addToCartForm.action
		   , type: addToCartForm.method
		   , data: $(addToCartForm).serialize()
		   , dataType: 'text'
		   , error: callBackFailed
		   , complete: callBackSuccess
	});
}

//need to verify 

function starSelect(containerid, inputidPrefix, value){
	var startContainer = byId(containerid);
	var starSelectidPrefix = 'selected-';
	//remove existing class that dictates the amount of stars
	var classNames = startContainer.className.split(' ');
	for (var i = 0; i < classNames.length; i++) {
		if (classNames[i].match(/^selected-/)) {
			$(startContainer).removeClass(classNames[i]);
		}
	}
	
	$(startContainer).addClass(starSelectidPrefix + value);
	byId(inputidPrefix + value).checked = true;
}

function swapMainItemImg(psml, pmed, pbig, position){
	var mainImg = byId('image-main-img');
	var mainLink = byId('image-main-link');
	var smlImg = byId('item-img-' + position);
	var smlLink = byId('item-img-link-' + position);
	var mainImgName = mainImg.src.replace(document.location.protocol + '//' + document.domain + pmed, '');
	var smlImgName = smlImg.src.replace(document.location.protocol + '//' + document.domain + psml, '');
	mainImg.src = pmed + smlImgName;
	mainLink.href = pbig + smlImgName;
	//smlImg.src = psml + mainImgName;
	//smlLink.href = pbig + mainImgName;
}

function checkoutCartUpdate(){
	updateCartCount();
	if(byId('empty-cart-checkout')){
		window.location	= window.CR + '/checkout';
	}
	else{
		EmgAjax.refresh('checkout-cart-promo');
		EmgAjax.refresh('totals-container');
		
		checkout.checkBillingRequired();			
	}
}

function updateCheckoutPage(){
	EmgAjax.refresh('cart-container', 'checkoutCartUpdate()');
}

function quantityChange(){
	var quantity = parseFloat(byId('add-to-cart-quantity').value);
	
	//handle min quantity
	var minQ = parseFloat(byId('item-minimum-quantity').value);
	if(quantity < minQ){
		byId('add-to-cart-quantity').value = minQ;	
	}
	
	//handle price breaks
	var defaultPrice = parseFloat(byId('item-default-unit-price').value);
	var quantity = parseFloat(byId('add-to-cart-quantity').value);
	var breaks = byId('item-price-break-str').value.split(', ');
	
	//default price break
	var parts = breaks[0].split('-');
	
	var threshHold = parseFloat(parts[0]);
	//var unitPrice = parts[1];
	//var totalPrice = quantity * unitPrice;
	var unitPrice = defaultPrice;
	var totalPrice = quantity * defaultPrice;

	for(var i = 0; i < breaks.length; i++){
		var parts = breaks[i].split('-');
		var threshHold = parseFloat(parts[0]);
		
		if(quantity >= threshHold){
			var unitPrice = parts[1];
			var totalPrice = quantity * unitPrice;
		}
	}
	
	$('#item-unit-price').text(moneyFormat(unitPrice));
	$('#item-total-price').text(moneyFormat(totalPrice));
	
	//byId('item-unit-price').innerHTML = '$' + money(unitPrice);
	//byId('item-total-price').innerHTML ='$' +  money(totalPrice);
}

/* emg-ajax-v1.js.php */
/*
5:49 PM 5/27/2011 (change refreshModal(prev) to offeset
5:10 PM 1/18/2011
*/
/*
Copyright Â© 2010 Eckx Media Group, LLC. All rights reserved.
Eckx Media Group respects the intellectual property of others, and we ask our users to do the same.
*/
/*<script>*/
//usage, flag str: ajax, modal, same, callback {function}, modal-close-callback {function}, container {id}, skip-rewrite, ajax-autofill
//replace: anchors containers flagstrs thisIndex ajaxid urlParts callBackComplete callBackFailed callBackSuccess

var EmgAjax = {
	
	//for refreshing
	urls: new Array(),
	flags: new Array(),
	forms: new Object(),
	
	init: function(container){
		if(!container){
			alert('EmgAjax.init(): container is null');	
		}
		
		//change all anchors related to modal
		var anchors = $('a[rel~="ajax"]', container).click(function() {
			EmgAjax.call(this.href, this.rel);
			return false;
		});
		
		/*
		//change all anchors related to modal
		for(var i = 0; i < anchors.length; i++){
			var normalizedHref = EmgAjax.normalizeUrl(anchors[i].href);
			anchors[i].href  = 'javascript:EmgAjax.call(\'' + normalizedHref + '\', \'' + anchors[i].rel + '\')';
		}
		*/
		
		//set all forms to use modal
		var forms = $('form[class~="ajax"]', container);
		for(var i = 0;  i < forms.length; i++){
			forms[i].onsubmit = function(){
				EmgAjax.call(this.action, this.className, this);
				return false
			};
		}
		
		//auto ajax calls to fill out containers
		var containers = $('[class~="ajax-autofill"]', container);
		for(var i = 0; i < containers.length; i++){
			if(containers[i].id.length == 0){
				alert('ajax-container missing id');	
			}
			var containerAnchors = $('a', containers[i]);
			var url = containerAnchors[0].href;
			if(!inString(url, '?')){
				url += '?';	
			}
			containerAnchors[0].innerHTML = ''; //no need to show anchor text
			EmgAjax.call(url + '&ajax-container=' + containers[i].id, 'ajax container ' + containers[i].id  + ' ' + containers[i].className);
		}
		
	},
	
	//make url consistent
	normalizeUrl: function (url){
		url = url.replace('%27', '\\%27'); //prevent js error from single quote
		url = url.replace(document.location.protocol+'//'+document.domain, ''); //remove domain name and protocol
		return url;
	},
	
	//id is used when flags are out of scope
	getFlags : function(flagstr){

		var flags = { modal : false, samemodal: false, callback:false, modalCloseCallback: false, skipRewrite: false, container: false, containerid: false }; //was having problmes with arrays
		var flagstrs = flagstr.split(' ');
		
		flags.modal = inArray('modal', flagstrs);
		flags.samemodal = inArray('same', flagstrs);
		flags.skipRewrite = inArray('skip-rewrite', flagstrs);
		
		flags.container = $.inArray('container', flagstrs);
		if(flags.container != -1){
			flags.containerid = flagstrs[flags.container + 1];
			if($(flags.containerid)){ // need to make sure the container exists
				flags.container = true;
				flags.modal = false; // if the container exists then it has higher priority, in case if both modal and container is set
			}
			else{ // else set all flags to false because other functions use them
				flags.container = false;
				flags.containerid = false;
			}
		}
		else{
			flags.container = false;
			flags.containerid = false;
		}
		
		flags.callback = $.inArray('callback', flagstrs);
		if(flags.callback != -1){
			flags.callback = flagstrs[flags.callback + 1];
			//include container id if available
			if(flags.containerid){
				flags.callback += '(\'' + flags.containerid + '\')';
			}
			else{
				flags.callback += '()';
			}
		}
		else{
			flags.callback = false;	
		}
		
		flags.modalCloseCallback = $.inArray('modal-close-callback', flagstrs);
		if(flags.modalCloseCallback != -1){
			flags.modalCloseCallback = flagstrs[flags.modalCloseCallback + 1];
			if(flags.containerid){
				flags.modalCloseCallback += '(\'' + flags.containerid + '\')';
			}
			else{
				flags.modalCloseCallback += '()';
			}
		}
		else{
			flags.modalCloseCallback = false;	
		}

		return flags;
	},
	
	refresh: function(ajaxid, callback){ //alert(ajaxid);
		if(!this.urls[ajaxid]){
			//alert('ajaxid:' + ajaxid + ' does not exist');
			<!-- Codes by Quackit.com -->
			location.reload(true);
			return;
		}
		if(!callback){ //callback is optional, set it to false so wont cause error if we use it
			var callback = false;	
		}
		this.call(this.urls[ajaxid], this.flags[ajaxid], this.forms[ajaxid], false, callback);
	},
	
	
	refreshModal: function(offset){ //alert('red');
		if(!offset){
			offset = 0;	
		}
		var thisIndex = modal.index - (offset * 2);	
		var ajaxid = 'modal-' + thisIndex;
		this.flags[ajaxid] += ' same'; //replace original flag so that refresh can occur in the same modal
		this.refresh(ajaxid);	
	},
	
	showLoading: function(loadingid, containerid) {
		//loading image
		var loading = $('<p><img src="' + window.CR + '/images/library/loading.gif" /></p>');
		
		if (containerid) {
		}
		else {
			//show loading
			loading[0].id = loadingid;
			loading.appendTo('body');			
			loading.addClass('modal-load'); 
			topLeft = getTopLeft(loading.width(), loading.height());
			loading[0].style.top = topLeft[0] + '%';
			loading[0].style.left = topLeft[1] + '%';
			loading[0].style.zIndex = modal.index + 1;
		}
	},
	
	removeLoading: function(loadingid) {
		//remove loading
		var loading = $('#' + loadingid);
		loading.remove();
	},
		
	//be careful with run time, the init from emgInit might come after if this function is called manually 
	call : function(url, flagstr, form, post, callback){ //alert(flagstr);
		
		url = EmgAjax.normalizeUrl(url);
	
		if(!form){
			form = false;	
		}
		if(!post){
			post = false;	
		}
		
		var flags = this.getFlags(flagstr);
		
		//loading image
		var loading = $('<p><img src="' + window.CR + '/images/library/loading.gif" /></p>');
		
		//alert(flags.containerid);
		if(flags.containerid){ //filling a container
			var container = $('#' + flags.containerid);
			var containerHeight = container.height(); //used to center loading graphic
			//have to append loading since we canot replace html with loading html due to forms submitting
			container[0].style.height = containerHeight + 'px';
			//.setStyle({height : containerHeight + 'px'}); //prevent scroll bar from jumping around
			/* clearing the container causes a bug in ie
			container[0].innerHTML = '';
			*/
			//show loading
			loading.addClass('ajax-container-loading');
			loading.appendTo(container);
			var ajaxid = flags.containerid;
			loading.id = ajaxid + '-loading';
		}
		else{ //using modal
			if(!flags.samemodal){
				modal.openBlinds(); // has to be before using modal.index
			}
			
			var ajaxid = 'modal-' + modal.index;
			
			//show loading
			loading[0].id = ajaxid + '-loading';
			loading.appendTo('body');			
			//loading = $(ajaxid);
			loading.addClass('modal-load'); 
			topLeft = getTopLeft(loading.width(), loading.height());
			loading[0].style.top = topLeft[0] + '%';
			loading[0].style.left = topLeft[1] + '%';
			loading[0].style.zIndex = modal.index + 1;
		}
		
		//save for refresh
		this.urls[ajaxid] = url;
		this.flags[ajaxid] = flagstr;
		this.forms[ajaxid] = form;
		//alert('*' + objProperties(this.forms, 'forms'));

		if(!flags.skipRewrite){
			//add ajax to url
			if(window.CR.length > 0){
				var crpos = url.indexOf(window.CR);
				var urla = url.substring(0, crpos);
				var urlb = url.substring(crpos + window.CR.length);
				url = urla + window.CR + '/ajax' + urlb;
			}
			else{
				url = '/ajax' + url;
			}
		}
		
		if(!inString(url, '?')){
			url += '?';
		}

		if(flags.containerid){
			url += '&ajax-container=' + flags.containerid;
		}
		else{
			url += '&ajax-modal=true';
		}
			
		//alert(url);
		
		//only complete will work with redirect
		var callBackComplete = function(ajaxid) {
			return function(data, textStatus) { // alert(data.status)
				if (data.status == '404') { // page not found
					window.location = window.CR + '/error';
					return;
				}
				//remove loading
				var loading = $('#' + ajaxid + '-loading');
				loading.remove();
				 
				if(data.responseText == 'died'){ //in case something died in ajax
					window.location = window.CR + '/died';
					return;
				}
				if(flags.modal){
					var classStr = modal.urlToClassStr(url);
					modal.content(data.responseText, classStr, flags.samemodal, false, false, false, flags.modalCloseCallback);
					var container = $('#modal-contentLayer' + modal.index)[0];
				}
				else{ //container
					//alert(1);
					var container = $('#' + flags.containerid)[0];
					if(container.length == 0){
						alert('EmgAjax.call(): error, `' + flags.containerid + '` container id dosnt exist');	
					}
					container.innerHTML = data.responseText;
					container.style.height = null; //make height fluid again
				}
				
				EmgAjax.init(container);
				markupInit(container); //external reference
				setEventHandlers(container); // set event handlers for the container
				
				if(window.initValForm){ //function exists
					initValForm($(container));
				}
				
				//theres two ways to use callback, more flexible way is not to use the flagstr
				
				if(typeof callback == 'function') {
					callback();
				}
				else if(callback){
					eval(callback);	
				}
				//flagstr is available if using class or rel for markup
				if(flags.callback){
					eval(flags.callback);	
				}
			};
		};
		
		var callBackFailed = function(data){ //cant use because redirect will call this function
			return false;
			alert('callBackFailed() ' + url);
		};
		
		var callBackSuccess = function(data){
		};
		
		if(form){ //alert(this.forms);
			form.action = url; //need to reset form aciton so it has ajax in it
			// submit the form with ajax
			$.ajax({
				   url: form.action
				   , type: form.method
				   , data: $(form).serialize()
				   , dataType: 'text'
				   , error: callBackFailed
				   , complete: callBackComplete(ajaxid)
				   , cache: false
			});
		}
		else{
			var method = post ? 'post' : 'get';
			var postBody = post ? post : '';
			$.ajax({
				   url: url
				   , type: method
				   , data: postBody
				   , complete: callBackComplete(ajaxid)
				   , error: callBackFailed
				   , cache: false
				   }); 
		}
	}
};

/* functions.js.php */
/*<script>*/
function siteInit(){
	updateCartCount();
	
	if($("[rel*='jqzoom']").jqzoom != null){
		var options = {
					zoomWidth: 200
					, zoomHeight: 200
					, xOffset: 10
					, yOffset: 0
					, title: false
					, position: "right"
				};
		$("[rel*='jqzoom']").jqzoom(options);
	}
	
	// Homepage slideshow
	if ($('slideshow')) {
		var homeSlideshow = new Slideshow(
			{
				navClass: '#slideshow ul.nav'
				, previousNextNavClass: '#slideshow ul.previous-next-nav'
				, slidesClass: '#slideshow ul.slides'
				, autoplay: true
				, slideDuration: 5
				, transition: 'fade'
				, transitionDuration: 0.5
			}
		);
	}
	
	// Sidebar nav submenus
	$('.sidebar ul.nav ul li.current').closest('li.parent').addClass('current');
	$('.sidebar ul.nav > li.parent > span').click(function() {
		$(this).next('ul').slideToggle();
	})
	
	// Product images
	var productImagesTabbed = new Tabbed(
		{
			navClass: '.product-details .images .thumbnails ul'
			, currentItem: 1
		}
	);
	
	// Product additional details
	var tabbed = new Tabbed(
		{
			navClass: 'h3.details'
			, toggle: true
			, noDefaultCurrent: true
		}
	);
}

function setSiteEventHandlers(container){
}


/* image-hover.js.php */
/*
4:48 PM 8/18/2010
*/
/*
Copyright Â© 2010 Eckx Media Group, LLC. All rights reserved.
Eckx Media Group respects the intellectual property of others, and we ask our users to do the same.
*/
/*<script>*/
//need anchor to bigger image, set rel = image-hover
var ImageHover = {
	spacing: 4, //px between source and zoom
	staticImageDim: new Array(500, 500), //help with slow pre loading, set to false for auto
	init: function(){
		var anchors = $('a[rel~="image-hover"]', document.body);
		var images = new Array();
		for(var i = 0; i < anchors.length; i++){
			//preload image
			images[i] = new Image();
			images[i].src = anchors[i].href;
				
			anchors[i].onmouseover = function (){	
				var html = '<div id="image-hover-container">';
				html += '<img src="' + this.href + '" id="image-hover-img"';
				//static image dim
				if(ImageHover.staticImageDim[0]){
					html += ' width="' + ImageHover.staticImageDim[0] + '" height="' + ImageHover.staticImageDim[1] + '"';	
				}
				html += ' />';
				html += '</div>';
				
				var hoverContainer = $(html);
				hoverContainer.appendTo('body');
				
				var image = $('#image-hover-img');
				var imageH = image.height();
				var imageW = image.width();

				//set top offset relative to anchor, try to get hover image vertically centered in the viewport
				var offset = $(this).offset();
				
				var topOffset =  ((offset.top - $(window).scrollTop()) * -1); //top of viewport
				
				var vcenterOffset = ($(window).height() - imageH) / 2;
				topOffset += vcenterOffset;
				
				//clone position base on anchor with offset and adjustments
				hoverContainer.clonePosition(this, {offsetLeft: $(this).width() + ImageHover.spacing, offsetTop: topOffset});
				
				//absolute to make it hover, w/h for the borders
				hoverContainer.css({position: 'absolute', width: imageW + 'px', height: imageH + 'px'});
			}
			
			//disable anchor
			anchors[i].onclick = function (){
				return false;
			}
			
			anchors[i].onmouseout = function (){
				$('#' + 'image-hover-container').remove();
			}
		}
	}
}

/* jqzoo.js.php */


/* login-timer.js.php */
/*1/13/2010 9:35*/
/*
Copyright Â© 2009 Eckx Media Group, LLC. All rights reserved.
Eckx Media Group respects the intellectual property of others, and we ask our users to do the same.
*/
/*<script>*/
var loginTimer = {
	init: function(){
		loginTimer.extendTimeout(0, false);
	},
	setExtendTimeout: function setExtendTimeout(){
		var keepLoggedIn = ($('#' + 'keep-logged-in')[0].checked) ? '1' : '0';
		var url = window.CR + '/ajax/set-extend-timeout?extend=' + keepLoggedIn;
		
		$.ajax({
			   url: url
			   , type: 'get'
			   , dataType: 'text'
			   , cache: false
			   , success: function(response) {
								location.reload(true);
							}
		}); 
		
	},
	extendTimeout: function (showAlert, extendOneTime){
		var loginInterval, promptInterval, timeRemaining, numIdleSeconds, numIdleMinutes, loginInterval;
		loginInterval 		= 0;
		promptInterval 		= timeRemaining = numIdleSeconds = numIdleMinutes = loginInterval;
					return false;
					if (showAlert) {
			var time 		= new Date();
			var curHour 	= (time.getHours() > 12) ? time.getHours() - 12 : time.getHours();
			var curTime 	= curHour + ' : ' + time.getMinutes() + ' : ' + time.getSeconds();
			var seconds 	= time.getSeconds();
			seconds 		+= timeRemaining;
			time.setSeconds(seconds);
			var logoutHour 	= (time.getHours() > 12) ? time.getHours() - 12 : time.getHours();
			var idleStr 	= numIdleMinutes + ' minutes';
			//== SHOW CURTAIN
			timeRemaining 	= timeRemaining - 5; // 5 second padding
			
			var html 		= '<p>You have been idle for ' + idleStr + '.</p><p><strong>You will be logged out in:<br /><span id="time-remaining">0:00</span></strong></p><p class="go keep-me-logged-in"><a href="javascript:loginTimer.extendTimeout(1, true);">Keep Me Logged In</a></p>';
							if (extendOneTime == true) {
					modal.close();
					var url = window.CR + '/ajax/extend-timeout?k=' + Math.round(100000*Math.random());
					
					$.ajax({
					   url: url
					   , type: 'get'
					   , dataType: 'text'
					   , success: function(response) {
										setTimeout('loginTimer.extendTimeout(1, false)', promptInterval);
									}
					});
					
				}
				else {
					var url = window.CR + '/ajax/check-last-active?k=' + Math.round(100000*Math.random());
					
					$.ajax({
						   url: url
						   , type: 'get'
						   , dataType: 'text'
						   , success: function(response) {
											if (parseInt(response) < numIdleSeconds) {
												setTimeout('loginTimer.extendTimeout(1, false)', promptInterval);
											}
											else {
												modal.load();
												modal.content(html);
												window.focus();
												var minRemaining = (timeRemaining > 60) ? timeRemaining / 60 : 0;
												minRemaining	 = parseInt(minRemaining);
												var secRemaining = (timeRemaining > 60) ? timeRemaining % 60 : timeRemaining;
												loginTimer.countdown(secRemaining, minRemaining, promptInterval);
											}
										}
					});
					
				}
						} // end if
	},
	
	countdown:	function(seconds, minutes, promptTime){
		
		if (seconds == 0 && minutes == 0) {
			window.location = window.CR + '/action/logout?k=' + Math.round(100000*Math.random());
		}
		else {
			if (seconds <= 0){
				seconds =  59;
				minutes -= 1;
			}
			if (minutes <= -1){
				seconds =  0;
				minutes += 1;
			}
			else {
				seconds -= 1;
			}
			
			secondsRemaining = seconds + (minutes * 60);
			
			if ($('#' + 'time-remaining')[0] != null) {
				var url = window.CR + '/ajax/check-last-active?k=' + Math.round(100000*Math.random());
				$.ajax({
					   url: url
					   , type: 'get'
					   , dataType: 'text'
					   , success: function(response) {
										if (parseInt(response) <= 2) {
											modal.close();
											setTimeout('loginTimer.extendTimeout(1, false)', promptTime);
										}
										else {
											$('#' + 'time-remaining')[0].innerHTML = minutes + ':' + seconds;
											setTimeout('loginTimer.countdown(' + seconds + ', ' + minutes + ', ' + promptTime + ')', 1000);
										}
									}
				});
			}
		}
	}
};

/* modal-v1.js.php */
/*
3:22 PM 5/23/2011 - fix double click issue
4:03 PM 3/7/2011 - prevent height constraint
10:07 AM 2/2/2011
5:10 PM 1/18/2011
*/
/*
Copyright © 2010 Eckx Media Group, LLC. All rights reserved.
Eckx Media Group respects the intellectual property of others, and we ask our users to do the same.
*/
/*<script>*/
//replace str: blinds cr loadPop closeLayer contentInner contentLayer scripts headTag allSel topLeft selects modal_blinds pageDim
var modal = {
	index: -1,
	expandLink: false, // show/hide expand link
	expandView: false, //memorize expand view
	hideSelects: new Array(),
	closeCallBacks: new Array(), //list of code to eval when curtain is closed
	
	//urls: new Array(), //memorize urls to allow refresh
	init: function(){
		modal.index = -1;
		var blinds = $('<div id="modal-blinds"></div>');
		blinds.width(blinds.width() - getScrollBarWidth())
		blinds.appendTo('body');
	},
	
	urlToClassStr: function (url) {
		var cr = window.CR;
		var classStr = url;
		
		// Remove CR & query string, replace ajax|action, space-separated classes
		if (cr.length > 0) {
			classStr = classStr.split(cr)[1];
		}
		classStr = classStr.split('?')[0].replace('ajax/', '').replace('action/', '').replace(/\//g, ' ').trim();
		
		return classStr;
	},
	
	load: function(){ //function is needed for backward compatible
		this.openBlinds();
	},
	
	content: function(html, classStr, sameLayer, width, height, noPadding, closeCallBack){
		
		if(closeCallBack){
			this.closeCallBacks[this.index] = closeCallBack;
		}
		
		if(sameLayer == true){ // same layer dont create another layer
			var currentLayer = $('#modal-popUp' + this.index);
			if(currentLayer.length == 0){
				alert('modal error: samelayer is set, but theres no modal layer yet');	
			}
			$('#modal-popUp' + this.index).remove();
		}
		
		//create layers
		var popUpid = 'modal-popUp' + this.index;
		var closeid = 'modal-closeLayer' + this.index;
		var contentid = 'modal-contentLayer' + this.index;
		var bodyid = 'modal-bodyLayer' + this.index;
		var popupHtml = '<div id="' + popUpid + '" class="modal-popUp' + (classStr ? ' ' + classStr : '') + '" style="z-index:' + (this.index + 1 ) +'; visibility: hidden;">'; //popup
		popupHtml += '<div id="' + closeid + '" class="modal-close">';
		if (this.expandLink) {
			popupHtml += '<a href="javascript:modal.expand()" id="modal_expand' + this.index + '" class="expand" title="Expand / Contract"></a>';
		}
		popupHtml += '<a href="javascript:modal.close()" class="close" title="Close"></a>';
		popupHtml += '</div>'; // close
		popupHtml += '<div id="' + contentid + '" class="modal-content' + (noPadding ? ' no-padding' : '') + '">'; //content
		popupHtml += '<div id="' + bodyid + '" class="modal-body">' + html + '</div>'; //body
		popupHtml += '</div></div>'; //content, popup
		var popUp = $(popupHtml);
		popUp.appendTo('body');

		if(this.expandView){ //memorize expand view
			this.expand();
		}
		else if(parseFloat(width) != width || parseFloat(height) != height){ //w x h not given, auto adjust to fit content
			this.autoSize();
		}
		else{ // w x h given
			this.resizeContent(width, height);
		}
		popUp[0].style.visibility = 'visible';
		
		//setting on click function here to only allow closing went content has displayed, prevent fast double click
		$('#modal-blinds')[0].onclick = function (){
			modal.close();
		};
	},
	
	//removed scrolling and added resize for blinds
	autoSize: function(){
			//get demension for popUp
		var popUp = $('#modal-popUp' + this.index);
		var contentLayer = $('#modal-contentLayer' + this.index);
		var contentInner = $(contentLayer.children()[0]);
		var closeLayer = $('#modal-closeLayer' + this.index);
		var scrollBarW = getScrollBarWidth();
		closeH = closeLayer.height();
		
		contentW = contentInner.outerWidth(); // outerWidth is used for padding
		contentH = contentInner.outerHeight() + closeH; //add the height of the close layer, + 1 to prevent scrollbar from showing up a little (believe it has to do with border/padding)
		
		contentLayer[0].style.height = (contentH - closeH) + 'px'; //need to constraint container in case content expands
		
		popUp[0].style.width = contentW + 'px';
		popUp[0].style.height = contentH + 'px';
		//position the modal window in the center
		var topLeft = getTopLeft(contentW, contentH);
		popUp[0].style.top = topLeft[0] + '%';
		popUp[0].style.left = topLeft[1] + '%';
		
		this.resize(); //resize blinds because content may increase document height
	},
	
	resizeContent: function(width, height){;
		var popUp = $('#modal-popUp' + this.index)[0];
		var contentLayer = $('#modal-contentLayer' + this.index)[0];
		var closeLayer = $('#modal-closeLayer' + this.index[0]);
		
		var topLeft = getTopLeft(width, height);
	
		popUp.style.width = width + 'px';
		popUp.style.height = height + 'px';
		popUp.style.top = topLeft[0] + '%';
		popUp.style.left = topLeft[1] + '%';

		contentLayer.style.height = (height - closeLayer.height()) + 'px';
	},
	
	close: function(){
		//eval any code on close event
		if(this.closeCallBacks[this.index]){
			eval(this.closeCallBacks[this.index]);	
		}
		$('#modal-popUp' + this.index).remove();
		this.closeBlinds();
	},
	
	resize: function(){
		var modal_blinds = $('#modal-blinds')[0];
		var pageDim = getPageDim();
		modal_blinds.style.width = pageDim[0] + 'px';
		modal_blinds.style.height = pageDim[1] + 'px';
	},
	
	expand: function(){
		this.expandView = true; //memorize expand view
		var width = document.viewport.getWidth() - 25;
		var height = document.viewport.height() - 50;
		this.resizeContent(width, height);
		$('#modal-expand' + this.index)[0].href = 'javascript:modal.shrink()';
		
	},
	
	shrink: function(){
		this.expandView = false; //memorize expand view
		$('#modal-expand' + this.index)[0].href = 'javascript:modal.expand()';
		this.autoSize();
	},
	
	openBlinds: function(){
		if( getIEVerNum() == 6){   
			this.hideSelects(); // fix the selects showing up
		}
		var blinds = $('#modal-blinds')[0];
		this.index += 2;
		blinds.style.zIndex = this.index;
		blinds.style.display='block';
		var pageDim = getPageDim();
		blinds.style.width = pageDim[0] + 'px';
		blinds.style.height = pageDim[1] + 'px';
		blinds.onclick = null; //onclick function is ready when content loads, prevent fast double click
		
		$(window).bind('resize', this.resize);
	},
	
	closeBlinds: function(){
		var blinds = $('#modal-blinds');
		this.index -= 2;
		blinds[0].style.zIndex = this.index;
		if(this.index == -1){
			blinds[0].style.display='none';
			$(window).unbind('resize', this.resize);
		}
		
		if( getIEVerNum() == 6){
			this.showSelects(); // fix the selects showing up
		}
	},
	
	hideSelects: function(){
		this.hideSelects[this.index] = new Array(); //hold new selects that will hide
		if(this.index != -1){ //get previous modal selects
			var allSel = $('#select', $('modal-popUp' + this.index));
		}
		else{ //get all body selects
			var allSel = $('select');
		}
		for(var i=0; i < allSel.length; i++){
			if(allSel[i].style.visibility != 'hidden'){
				allSel[i].style.visibility = 'hidden';
				this.hideSelects[this.index][i] = allSel[i];
			}
		}
	},
	
	showSelects: function(){
		var selects = this.hideSelects[this.index];
		for(var i=0; i < selects.length; i++){
			selects[i].style.visibility = 'visible';
		}
	}
	
	/* user Emgajax refresh
	, refresh: function(prev){
		if(prev){
			var thisIndex = modal.index - 2;
		}
		else{
			var thisIndex = modal.index;
		}
		modal.ajax(modal.urls[thisIndex], true);	
	}*/

};

//Event.observe(window, 'load', modal.init); 


/* select.js.php */
//07/17/2009
/*<script>*/
function sel(url, sameLayer){
	
	if(!sameLayer){
		modal.load();	
	}
	$.ajax({
		   url: url
		   , complete: function(sel2) {
					if(sel2.responseText == 'died'){ //in case something died in ajax
						window.location = window.CR + '/action/died';
						return;
					}
					if(sameLayer == true){
						modal.content(sel2.responseText, false, true);
					}
					else{
						modal.content(sel2.responseText);
					}
				}
		   }); 	
}

function sel2(name, fieldid, formid2Submit){
	var field = $('#' + fieldid)[0];
	field.value = name;
	if(field.type.toLowerCase() !=  'hidden'){
		field.focus(); //fake as if a user entered the value
		field.blur();
	}
	//customTitle.hide();
	modal.close();
	if(byId(formid2Submit)){
		byId(formid2Submit).submit();	
	}
}

/* slideshow-v5.js.php */
/*<script>*/
// Requires jquery
// Usage:
/* var slideshow = new Slideshow({previousNextNavClass: '#slideshow ul.previous-next-nav'
								, navClass: '#slideshow ul.nav'
								, slidesClass: '#slideshow ul.slides'
								, autoplay: true
								, slideDuration: 5
								, transition: 'scroll'
								, transitionDuration: 0.5
								//, replaceOnlick = false
								});
*/
function Slideshow(args) {
	// Constructor
	this.construct = function(args) {
		// Required Parameters
		this.previousNextNavClass = args.previousNextNavClass;
		this.navClass = args.navClass;
		this.slidesClass = args.slidesClass;
		// Optional parameters (set default values in 'else' condition)
		this.autoplay = args.autoplay == true ? true : false;
		this.slideDuration = args.slideDuration > 0 ? args.slideDuration : 4;
		this.transition = args.transition;
		this.transitionDuration = args.transitionDuration > 0 ? args.transitionDuration : 1;
		
		// Navs & Slides
		this.previousNextNavs = $(this.previousNextNavClass + ' > li');
		this.navs = $(this.navClass + ' > li');
		this.slides = $(this.slidesClass + ' > li');
		this.count = this.slides.length;
		// Need slides container for 'scroll'
		this.slidesContainer = $(this.slidesClass)[0];
		
		this.scrollAmount = $(this.slidesClass + ' > li:first-child').width();
		
		this.current = args.current > 0 ? args.current : 1;
		this.currentClass = 'current';
		this.currentPreviousClass = 'current-previous';
		this.previousClass = 'previous';
		this.nextClass = 'next';
		
		// Tabbed class for classname handling
		this.tabbed = false;
		
		// Window focus for setTimeout
		this.windowFocus = true;
		
		// Return if elements don't exist
		if (this.slides.length < 1 || (this.navs.length + this.previousNextNavs.length < 1)) {
			return;
		}
		// Create Tabbed instance
		else {
			this.tabbed = new Tabbed({navClass: this.navClass});
		}
		
		// Set slides container width for scroll transition
		if (this.transition == 'scroll') {
			$(this.slidesContainer).width($(this.slides[0]).width() * $(this.slides).length);
		}
		
		this.setEvents();
		
		//setEvents should take care of initial play now
		this.waitPlay(this.slideDuration);
	}
	
	// Play after timeout
	this.waitPlay = function(duration) {
		setTimeout((function() {
			this.play();
		}).bind(this), duration * 1000);
	}
	
	// Event handlers
	this.setEvents = function() {
		// Stop autoplay if list item is clicked on
		this.slides.click((function() {
			this.stop();
		}).bind(this));
		
		// Swap events
		$(this.navClass + ' > li > a').each((function(i, el) {
			// Click event
			$(el).click((function() {
				this.swap(el.hash);
				return false;
			}).bind(this, el))
		}).bind(this));
		
		// Previous / Next links
		$(this.previousNextNavClass + ' > li > a').each((function(i, el) {
			$(el).click((function() {
				if ($(el).parent().hasClass(this.previousClass)) {
					this.previous(false);
				}
				else if ($(el).parent().hasClass(this.nextClass)) {
					this.next(false);
				}
				return false;
			}).bind(this, el))
		}).bind(this));
		
		// Window focus
		$(window).blur((function() {
			this.windowFocus = false;
		}).bind(this));
		$(window).focus((function() {
			if(!this.windowFocus) {
				this.windowFocus = true;
				this.waitPlay(this.slideDuration);
			}
		}).bind(this));
	}
	
	// Autoplay
	this.play = function() {
		if (!this.autoplay || !this.windowFocus) {
			return;
		}
		
		// Go to next slide
		this.next(true);
		
		// Continue autoplay
		this.waitPlay(this.slideDuration + this.transitionDuration);
	}
	
	// Swap target slide with current
	this.swap = function(target, autoplay) {
		if (!autoplay) {
			this.stop();
		}
		
		// Target slide <li> element
		var targetSlide = $(target);
		var currentSlide = $(this.slides[this.current - 1]);
		
		// Do nothing if swap target is current
		var newCurrent = $(this.slides).index(targetSlide) + 1;
		if (this.current == newCurrent) {
			return;
		}
		
		// Fade
		if (this.transition == 'fade') {
			// Fade out
			// Add currentPreviousClass so we can fade out from the current slide			
			$(currentSlide).addClass(this.currentPreviousClass);
			
			// Fade in			
			$(targetSlide).hide();
			$(targetSlide).fadeIn(this.transitionDuration * 1000, (function() {
				$(this.slides).removeClass(this.currentPreviousClass);
			}).bind(this));
		}
		// Scroll
		else if (this.transition == 'scroll') {
			var displacement = -(this.scrollAmount) * (newCurrent - 1);
			$(this.slidesContainer).animate({marginLeft: displacement}, this.transitionDuration * 1000, 'swing');
		}
		
		// Set new current
		this.current = newCurrent;
	}
	
	// Go to previous slide
	this.previous = function(autoplay) {
		this.traverse(false, autoplay);
	}
	// Go to next slide
	this.next = function(autoplay) {
		this.traverse(true, autoplay);
	}
	
	// Traverse (Previous/Next) slides
	// previous: direction = 0
	// next: direction = 1
	this.traverse = function(direction, autoplay) {
		// Default autoplay is false
		autoplay = autoplay == true ? true : false;
		
		// Default direction is true (next)
		var targetAnchorIndex = 0;
		if (direction == false) {
			targetAnchorIndex = (this.current == 1) ? this.count - 1 : this.current - 2;
		}
		else {
			targetAnchorIndex = (this.current == this.count) ? 0 : this.current;
		}
		// Swap
		var targetAnchor = $(this.navClass + ' > li > a')[targetAnchorIndex];
		
		this.tabbed.setCurrents(targetAnchor);
		this.swap(targetAnchor.hash, autoplay);
	}
	
	// Stop autoplay
	this.stop = function() {
		if (this.autoplay) {
			this.autoplay = false;
		}
	}
	
	this.construct(args);
}


/* tabbed-v2.js.php */
/*<script>*/
// Requires jquery
// Usage:
/* var tabbed = new Tabbed({navClass: '.tabbed-content ul.nav'
							, currentItem: 1
							//, currentClass: 'current'
							//, tabbedClass: 'tabbed'
							//, toggle: true
							//, noDefaultCurrent: false
							//, callback: functionName
							});
*/
function Tabbed(args) {
	// Constructor
	this.construct = function(args) {
		// Required Parameters
		this.navClass = args.navClass;
		// Optional Parameters
		this.toggle = args.toggle == true ? true : false;
		this.noDefaultCurrent = args.noDefaultCurrent == true ? true : false;
		this.currentItem = args.currentItem > 0 ? args.currentItem : (this.toggle || this.noDefaultCurrent ? 0 : 1);
		this.currentClass = args.currentClass !== undefined ? args.currentClass : 'current';
		this.tabbedClass = args.tabbedClass !== undefined ? args.tabbedClass : 'tabbed';
		this.callback = args.callback;
	
		this.currentNav = false;
		this.currentContent = false;
		
		// Use parent <li>s when applicable
		this.navs = $(this.navClass + ' > li');
		// Don't force anchors to be within <li>
		this.navAnchors = $(this.navClass + ' a[href*="#"]:not([href$="#"])');
		this.contents = [];
		
		// Get content containers based on anchor hashes
		var contentIds = [];
		$(this.navAnchors).each(function() {
			if (this.hash) {
				contentIds.push(this.hash);
			}
		});
		this.contents = $(contentIds.join(', '));
		
		// If not toggle, set current to be first <li> that is expanded
		if (!this.toggle) {
			var firstExpand = $(this.navs).filter('.' + this.currentClass).first();
			var firstExpandIndex = $(this.navs).index(firstExpand);
			if (firstExpandIndex >= 0) {
				this.currentItem = firstExpandIndex + 1;
			}
		}
		
		// Return if contents don't exist
		if (this.contents.length < 1) {
			return;
		}
		
		// Append tabbed class to hide
		$([this.navs, this.navAnchors, this.contents]).each((function(i, el) {
			$(el).addClass(this.tabbedClass);
		}).bind(this));
		
		// Set current class to currentItem's nav & content
		$(this.navAnchors).each((function(i, el) {
			if (i + 1 == this.currentItem) {
				this.setCurrents(el);
			}
		}).bind(this));
		
		this.setEvents();
	}
	
	// Set click events on anchors
	this.setEvents = function() {
		var thisClass = this;
		$(this.navAnchors).click(function() {
			this.blur();
				
			// Clear 'current' class from navs and contents
			// Set current nav and content
			// Apply 'current' class
			thisClass.setCurrents(this);
			return false;
		});
	};
	
	// Remove 'current' class name from navs and contents
	this.clearCurrents = function() {
		$([this.navs, this.navAnchors, this.contents]).each((function(i, el) {
			$(el).removeClass(this.currentClass);
		}).bind(this));
	};
	
	// Add 'current' class name on current nav and content
	this.setCurrents = function(targetAnchor) {
		var target = targetAnchor.hash;
		if (!this.toggle) {
			this.clearCurrents();
		}
		
		// Set current on <li> (parent) nav, <a>, and content
		this.currentNav = $(targetAnchor).closest('li');
		this.currentContent = $(target);
		$([this.currentNav, targetAnchor, this.currentContent]).each((function(i, el) {
			if (!this.toggle) {
				$(el).addClass(this.currentClass);
			}
			else {
				$(el).toggleClass(this.currentClass);
			}
		}).bind(this));
		
		if(this.callback != null){
			this.callback.call(this, this.currentNav);
		}
	}
	
	this.construct(args);
}


/* val-cc.js.php */
/*<script>*/
//11:15 AM 7/21/2009
/*============================================================================*/

/*

This routine checks the credit card number. The following checks are made:

1. A number has been provided
2. The number is a right length for the card
3. The number has an appropriate prefix for the card
4. The number has a valid modulus 10 number check digit if required

If the validation fails an error is reported.

The structure of credit card formats was gleaned from a variety of sources on 
the web, although the best is probably on Wikepedia ("Credit card number"):

  http://en.wikipedia.org/wiki/Credit_card_number

Parameters:
            cardnumber           number on the card
            cardname             name of card as defined in the card list below

Author:     John Gardner
Date:       1st November 2003
Updated:    26th Feb. 2005      Additional cards added by request
Updated:    27th Nov. 2006      Additional cards added from Wikipedia

*/

/*
   If a credit card number is invalid, an error reason is loaded into the 
   global ccErrorNo variable. This can be be used to index into the global error  
   string array to report the reason to the user if required:
   
   e.g. if (!checkCreditCard (number, name) alert (ccErrors(ccErrorNo);
*/

var ccErrorNo = 0;
var ccErrors = new Array ()

ccErrors [0] = "Unknown card type";
ccErrors [1] = "No card number provided";
ccErrors [2] = "Credit card number is in invalid format";
ccErrors [3] = "Credit card number is invalid";
ccErrors [4] = "Credit card number has an inappropriate number of digits";

function checkCreditCard (cardnumber, cardname) {
     
  // Array to hold the permitted card characteristics
  var cards = new Array();

  // Define the cards we support. You may add addtional card types.
  
  //  Name:      As in the selection box of the form - must be same as user's
  //  Length:    List of possible valid lengths of the card number for the card
  //  prefixes:  List of possible prefixes for the card
  //  checkdigit Boolean to say whether there is a check digit
  
  cards [0] = {name: "Visa", 
               length: "13,16", 
               prefixes: "4",
               checkdigit: true};
  cards [1] = {name: "MasterCard", 
               length: "16", 
               prefixes: "51,52,53,54,55",
               checkdigit: true};
  cards [2] = {name: "Diners Club", 
               length: "14,16", 
               prefixes: "300,301,302,303,304,305,36,38,55",
               checkdigit: true};
  cards [3] = {name: "Carte Blanche", 
               length: "14", 
               prefixes: "300,301,302,303,304,305,36,38",
               checkdigit: true};
  cards [4] = {name: "American Express", 
               length: "15", 
               prefixes: "34,37",
               checkdigit: true};
  cards [5] = {name: "Discover", 
               length: "16", 
               prefixes: "6011,650",
               checkdigit: true};
  cards [6] = {name: "JCB", 
               length: "15,16", 
               prefixes: "3,1800,2131",
               checkdigit: true};
  cards [7] = {name: "Enroute", 
               length: "15", 
               prefixes: "2014,2149",
               checkdigit: true};
  cards [8] = {name: "Solo", 
               length: "16,18,19", 
               prefixes: "6334, 6767",
               checkdigit: true};
  cards [9] = {name: "Switch", 
               length: "16,18,19", 
               prefixes: "4903,4905,4911,4936,564182,633110,6333,6759",
               checkdigit: true};
  cards [10] = {name: "Maestro", 
               length: "16", 
               prefixes: "5020,6",
               checkdigit: true};
  cards [11] = {name: "VisaElectron", 
               length: "16", 
               prefixes: "417500,4917,4913",
               checkdigit: true};
               
  // Establish card type
  var cardType = -1;
  for (var i=0; i<cards.length; i++) {

    // See if it is this card (ignoring the case of the string)
    if (cardname.toLowerCase () == cards[i].name.toLowerCase()) {
      cardType = i;
      break;
    }
  }
  
  // If card type not found, report an error
  if (cardType == -1) {
     ccErrorNo = 0;
     return false; 
  }
   
  // Ensure that the user has provided a credit card number
  if (cardnumber.length == 0)  {
     ccErrorNo = 1;
     return false; 
  }
    
  // Now remove any spaces from the credit card number
  cardnumber = cardnumber.replace (/\s/g, "");
  
  // Check that the number is numeric
  var cardNo = cardnumber
  var cardexp = /^[0-9]{13,19}$/;
  if (!cardexp.exec(cardNo))  {
     ccErrorNo = 2;
     return false; 
  }
       
  // Now check the modulus 10 check digit - if required
  if (cards[cardType].checkdigit) {
    var checksum = 0;                                  // running checksum total
    var mychar = "";                                   // next char to process
    var j = 1;                                         // takes value of 1 or 2
  
    // Process each digit one by one starting at the right
    var calc;
    for (i = cardNo.length - 1; i >= 0; i--) {
    
      // Extract the next digit and multiply by 1 or 2 on alternative digits.
      calc = Number(cardNo.charAt(i)) * j;
    
      // If the result is in two digits add 1 to the checksum total
      if (calc > 9) {
        checksum = checksum + 1;
        calc = calc - 10;
      }
    
      // Add the units element to the checksum total
      checksum = checksum + calc;
    
      // Switch the value of j
      if (j ==1) {j = 2} else {j = 1};
    } 
  
    // All done - if checksum is divisible by 10, it is a valid modulus 10.
    // If not, report an error.
    if (checksum % 10 != 0)  {
     ccErrorNo = 3;
     return false; 
    }
  }  

  // The following are the card-specific checks we undertake.
  var LengthValid = false;
  var PrefixValid = false; 
  var undefined; 

  // We use these for holding the valid lengths and prefixes of a card type
  var prefix = new Array ();
  var lengths = new Array ();
    
  // Load an array with the valid prefixes for this card
  prefix = cards[cardType].prefixes.split(",");
      
  // Now see if any of them match what we have in the card number
  for (i=0; i<prefix.length; i++) {
    var exp = new RegExp ("^" + prefix[i]);
    if (exp.test (cardNo)) PrefixValid = true;
  }
      
  // If it isn't a valid prefix there's no point at looking at the length
  if (!PrefixValid) {
     ccErrorNo = 3;
     return false; 
  }
    
  // See if the length is valid for this card
  lengths = cards[cardType].length.split(",");
  for (j=0; j<lengths.length; j++) {
    if (cardNo.length == lengths[j]) LengthValid = true;
  }
  
  // See if all is OK by seeing if the length was valid. We only check the 
  // length if all else was hunky dory.
  if (!LengthValid) {
     ccErrorNo = 4;
     return false; 
  };   
  
  // The credit card is in the required format.
  return true;
}

/*============================================================================*/

/* valform-v2.js.php */
/* 
5:37 PM 6/24/2011 - allow submit btns values get passed over
3:44 PM 5/19/2011 - added error msg to use default value, did not thourghly tested.
3:29 PM 3/10/2011 - added this.inputs = $('input:enabled,select:enabled,textarea:enabled', this.form);

 */
/*
Copyright Â© 2008 Eckx Media Group, LLC. All rights reserved.
Eckx Media Group respects the intellectual property of others, and we ask our users to do the same.
*/
/*<script>*/
/*
PACK:
	replace JS Variables: formClasses waitFlag errorStr locate errorField labelFor focusThisFlag validNodes args colonPos
	after pack, need to replace $Vxxxxxx with $w or $A
*/
/*key words

class names
val-form
alert-errors
hide-errors
dont-disable
auto-focus-on

validators
==========
val_req
val_default
val_checked (int)(checkboxes only)
val_checked_min (int) (checkboxes only)
val_checked_max (int) (checkboxes only)
val_min(int)
val_max(int)
val_maxNum(int)
val_minNum(int)
val_alpha
val_alpha_num
val_alpha_space
val_alpha_num_space
val_num
val_int
val_email
val_len
val_same(input id)
val_notSame(input id); // id of input(hidden) containing ids of fields to check
val_url
val_ajax(function)
val_func(function)
val_date
val_datetime
val_phone
val_ceil
val_exist
val_not_exist
key words
=========
val_combo(input id): combine multiple elements to a single output error base on input id, elements should have a single name to allow access to lable name
	usage: label for should match with first input id, val_comboe (id of last input)
	ie:
		<label for="register-birthdate-month">Birthdate:</label>
		<select id="register-birthdate-month" name="dob[]" class="month val_req val_combo register-birthdate-year"></select>
		<select id="register-birthdate-day" name="dob[]" class="day val_req val_combo register-birthdate-year"></select>
		<select id="register-birthdate-year" name="dob[]" class="year val_req val_combo register-birthdate-year"></select>
		
val_money: turn into money format
val_errorAfter(element id): errors would be displayed after a html element
val_skipifis(input id): ignore validations if the value is the same as the provided input 
*/

/* bugs
	- error appears then disappears, try placing val_ajax check at the end.


*/
var valForms = new Array(); //global scope
function initValForm(container){
	//getting new forms to initialize valform
	if(container){
		var forms = $('form[class~="val-form"]', container[0]);
	}
	else{
		var forms = $('form[class~="val-form"]');
	};
	
	//adding the valform object to a global list
	for(var i = forms.length; i > 0; i--){
		//check if formid already exist
		var existFlag = false;
		for(var j = 0; j < valForms.length; j++){
			if(valForms[j].form.id == forms[i - 1].id){
				//form id already exist, need to reset event observation and stuff
				valForms[j].reset();
				valForms[j].init(forms[i - 1]);
				existFlag = true;
			}
		}
		if(!existFlag){
			var nextIndex = valForms.length;
			valForms[nextIndex] = new Valform();
			valForms[nextIndex].init(forms[i - 1]);
		}
	}
}

function valFormsResetSubmit(){
	for(var i = 0; i < valForms.length; i++){
		valForms[i].resetSubmit();
	}	
}

function getValFormIndex(nodeid){ // gets valform index based of form id or an input id
	for(var valFormIndex = 0; valFormIndex < valForms.length; valFormIndex++){
		if(valForms[valFormIndex].form.id == nodeid){
			return valFormIndex;
		}
		
		for(var i = 0; i < valForms[valFormIndex].inputs.length; i++){
			if(valForms[valFormIndex].inputs[i].id == nodeid){
				return valFormIndex;
			}
		}
	}
	alert('valform index not found');
}

function Valform() { 
	//config
	this.errorClass = 'val-error';
	this.errorContainerTag = 'div';
	this.errorContainerClass = 'val_error';
	//!config
	
	//all validator and key words
	this.classList = new Array('val_req', 'val_default', 'val_min', 'val_max', 'val_maxNum', 'val_minNum', 'val_alpha', 'val_alpha_num', 'val_alpha_num_sym', 'val_alpha_space', 'val_alpha_num_space', 'val_num', 'val_int', 'val_email', 'val_len', 'val_same', 'val_notSame', 'val_url', 'val_ajax', 'val_money', 'val_func',  'val_checked', 'val_checked_min', 'val_checked_max', 'val_date', 'val_datetime', 'val_phone', 'val_ceil', 'val_exist', 'val_not_exist', 'val_decimal');
	//key words that are dependent on next class
	this.dependents = new Array('val_len', 'val_min', 'val_max', 'val_maxNum', 'val_minNum', 'val_same', 'val_notSame', 'val_ajax', 'val_func', 'val_checked', 'val_checked_min', 'val_checked_max', 'val_ceil', 'val_exist', 'val_not_exist', 'val_decimal');
	this.ajaxClasses = new Array('val_ajax', 'val_exist', 'val_not_exist');
	this.failed = true; // flag for submitting
	this.form = null;	// form obj
	this.formObsFunc = null; //holds event observer function to stop observing
	
	this.ajaxRunning = new Object(); //flag to signal if ajax check is running
	this.alertErrorsFlag = false; //flag to alert errors when submitting
	this.containerErrorsFlag = false; //flag to show errors in a container when submitting
	this.hideErrorsFlag = false; // flag to not display errors next to field
	this.errors = new Object();
	this.errorFocusedFlag = false; //flag to focus on first error field only when submitting
	this.inputs = new Array(); //holds all the form inputs that will be validated
	
	this.originalSubmit = null; //the onsubmit of the form before its overwritten, will run before valform submits
	this.clickedButton = null; //keep track of which button was clicked to submit the form
	
	//arg[0]: form id, arg[1]: options
	//options: ae - alert errors on submit, he = dont display errors next to field
	
	
	this.init = function(form){
		
		if(!form){
			alert('Valform.init(), form object dosnt exist');
			return false;
		}
		
		this.form = form;
		
		//handle options
		if($(form).hasClass('alert-errors')){
			this.alertErrorsFlag = true;
		}
		if($(form).hasClass('container-errors')){
			this.containerErrorsFlag = true;
		}
		if($(form).hasClass('hide-errors')){
			this.hideErrorsFlag = true;
		}
		
		this.createSubmitWait();
		
		//get inputs from form elements
		var validNodes = new Array('INPUT', 'TEXTAREA', 'SELECT');
		
		//this.inputs = $('input:enabled:visible,select:enabled,textarea:enabled', this.form);
		//this.inputs = $('input:not([type="hidden"]),select,textarea', this.form);
		this.inputs = $('input,select,textarea', this.form);
		/* bug in ie when input name = length
		
		for(var i = 0; i < formLength; i++){
			/* does not work in ie

			if(this.form.elements[i].disabled || !inArray(this.form.elements[i].nodeName, validNodes)){ //no point of checking if disabled or if not valid tag;
				continue;	
			}
			this.inputs[this.inputs.length] = this.form.elements[i];
		}*/
		
		//set event for inputs
		var focusThisFlag = true;
		if($(form).hasClass('auto-focus-on')){
			focusThisFlag = false;
		}
		for(var i = 0; i < this.inputs.length; i++){
			var inputType = this.inputs[i].type.toLowerCase();
			//determine which field to focus first<br />
			if(!focusThisFlag && this.inputs[i].name){
				focusThisFlag = true;
				/* not practical to focus on the first one
				if(inputType != 'radio' && inputType != 'checkbox'){ //radio & checkbox causes blur event to occurw when selecting options
					this.inputs[i].focus();
				}
				*/
			}
			
			//setting up events
			$(this.inputs[i]).bind('blur', {parent:this}, this.fieldCheck);
			//$(this.inputs[i]).live('blur', {parent:this}, this.fieldCheck);
			
			//get all ajax check and initialize the running flag
			for (var j = 0; j < this.ajaxClasses.length; j++) {
				if ($(this.inputs[i]).hasClass(this.ajaxClasses[j])) {
					this.ajaxRunning[this.inputs[i].id] = false;
				}
			}
		}
		
		//set submit event
		this.originalSubmit = this.form.onsubmit; //save original onsubmit function
		this.form.onsubmit = null; // remove it
		this.formObsFunc = 1;
		$(this.form).bind('submit', {parent:this}, this.submitCheck);
		$('input[type="submit"]', this.form).bind('click', {parent:this}, this.submitCheck);
	};
	
	//when forms get submited
	//make it so the furst btn gets clicked
	this.submitCheck = function(event){
		var parent = event.data.parent; //because out of scope because function is called on event
		
		parent.clickedButton = null;
		if(event.type == 'click'){
			parent.clickedButton = this;
		}
		else{ //if enter was used to submit form, use first button	
			var submitBtns = $('input[type="submit"]', parent.form);
			if(submitBtns[0] != null){
				parent.clickedButton = submitBtns[0];
			}
		}
		
		parent.errorFocusedFlag = false; //not focused on any errors yet
		if(!$(parent.form).hasClass('dont-disable')){
			parent.submitWait();
		}
		
		parent.errors = new Object(); // clean error list
		
		parent.failed = false;
		for(var fieldID in this.ajaxRunning){
			this.ajaxRunning[fieldID] = true;	
		}
		
		for(var i = 0; i < parent.inputs.length; i++){
			parent.fieldCheckSubmit(parent.inputs[i]);
			if(parent.errors[parent.inputs[i].id] && !parent.errorFocusedFlag){ // focusing on error input
				parent.inputs[i].focus();
				parent.errorFocusedFlag = true;
			}
		}
		
		parent.submitAjaxCheck();
		return false;
	}
	
	//make sure ajax function is complete
	this.submitAjaxCheck = function(){
	
		var waitFlag = false;
		for(var fieldID in this.ajaxRunning){
			if(this.ajaxRunning[fieldID]){
				waitFlag = true;
			}
			else{
				if(this.errors[fieldID] && !this.errorFocusedFlag){ // focusing on error fields
					$('#' + fieldID)[0].focus();
					this.errorFocusedFlag = true;
					waitFlag = true;
				}
			}
		}
		
		if(waitFlag){
			var valFormIndex = getValFormIndex(this.form.id);
			setTimeout('valForms[' + valFormIndex + '].submitAjaxCheck()', 100);
		}
		else{
			this.submit();
		}
	};
	
	this.submit = function(){
		
		if(this.failed){ //if something set the flag to fail, ie. ajax
			this.submitFail();
			return false;
		}
		
		var tosubmit = true;  //alert(this.originalSubmit);
		if(this.originalSubmit){
			tosubmit = this.originalSubmit.call(this.form);
		}
		if(tosubmit == 'dont reset'){ //special case where originalSubmit is submitting the form
			//nothing
		}
		else if(tosubmit){ //if getting error "this.form.submit is not a function", then something has name="submit"
			if(this.clickedButton != null){ //clickedButton should of been set in submitCheck
				//since this.form.submit(); will not send over submit button value, we will use a hidden field instead
				var submitDup = '<input id="val-form-submit-dup" type="hidden" name="' + this.clickedButton.name + '" value="' + this.clickedButton.value + '">';
				$(submitDup).insertAfter(this.clickedButton);
			}
			this.form.submit();
		}
		else{ //originalSubmit dosnt want to submit form
			this.resetSubmit();
		}
	};
	
	this.reset = function(){
		//reset member variables
		this.failed = true;
		this.ajaxRunning = new Object();
		
		if(this.inputs){ // unset event observation
			for(var i = 0; i < this.inputs.length; i++){
				$(this.inputs[i]).unbind('blur', {parent:this}, this.fieldCheck); //stop input obs
			}
		}
		this.inputs = new Array();
		
		if(this.formObsFunc){
			$(this.form).unbind('submit', {parent:this}, this.submitCheck); //stop submit obs
		}
		
		//remove the dup submit button created in this.submit()
		$('#val-form-submit-dup').remove();
		
	};
	
	this.createSubmitWait = function(){
		// Append any existing classes
		$('input[type="submit"]', this.form).each(function() {
			var waitBtn = '<input type="submit" disabled="disabled" value="Please Wait&hellip;" class="hidden please-wait ' + $(this).attr('class') + '">';
			$(waitBtn).insertAfter($(this));
		});
	};
	
	this.submitWait = function(){
		$('input[type="submit"]', this.form).hide();
		$('input[class*="please-wait"]', this.form).show();
	};
	
	this.resetSubmit = function(){
		$('input[type="submit"]', this.form).show();
		$('input[class*="please-wait"]', this.form).hide();
	};


	
	this.submitFail = function(){
		if (this.alertErrorsFlag) {
			var errorStr = '';
			for (var fieldID in this.errors) {
				errorStr += this.errors[fieldID] + "\n";
			}
			
			alert(errorStr);
		}
		
		if (this.containerErrorsFlag && byId(this.form.id + '-errors-cont') != null) {
			var errorStr = '<ul class="' + this.errorContainerClass + '">';
			for (var fieldID in this.errors) {
				errorStr += '<li>' + this.errors[fieldID] + '</li>';
			}
			
			errorStr += '</ul>';
			
			byId(this.form.id + '-errors-cont').innerHTML = errorStr;
		}
		
		this.resetSubmit();
	};
	
	this.fieldCheck= function(event){ //check event
		var parent = event.data.parent; //out of scope because function is called on event
		
		var classes = this.className.split(' ');
		//handle combo
		/* does not work in ie
		var index = classes.indexOf('val_combo');
		*/
		var index = $.inArray('val_combo', classes);
		if(index != -1){ // found key word
			if(index + 1 == classes.length){ // dosnt have combo id
				alert('val_combo id required');
				return;
			}
			var comboID = classes[index + 1];
			
			if($('#' + parent.comboID + '_error')){ //clear combo error
				$('#' + parent.comboID + '_error').remove();
			}
			if(parent.errors[comboID]){ //clear combo error
				parent.errors[comboID] = false;
			}
			var comboFields = $('.val_combo.' + comboID, parent.form); //get all fields with combo id in class
			// need to only display one error from any of the combo inputs
			for(var i = 0; i < comboFields.length; i++){
				//parent.validate(comboFields[i], comboID);
				parent.validate(comboFields[i]);
				
				//if(parent.errors[comboID]){
				if(parent.errors[comboFields[i].id]){
					// one of the combo inputs has error, no need to check rest
					return;	
				}
			}
			return;
		}
		
		parent.validate(this);
		return;
	};
	
	this.fieldCheckSubmit= function(field){ //check event
		var classes = field.className.split(' '); //make sure to get the latest class name sice it may have changed
		//handle combo
		/* does not work in ie
		var index = classes.indexOf('val_combo');
		*/
		var index = $.inArray('val_combo', classes);
		if(index != -1){ // found key word
			if(index + 1 == classes.length){ // dosnt have combo id
				alert('val_combo id required');
				return;
			}
			var comboID = classes[index + 1];
			
			if($('#' + this.comboID + '_error')){ //clear combo error
				$('#' + this.comboID + '_error').remove();
			}
			if(this.errors[comboID]){ //clear combo error
				this.errors[comboID] = false;
			}
			
			var comboFields = $('.val_combo.' + comboID, this.form); //get all fields with combo id in class
			
			for(var i = 0; i < comboFields.length; i++){
				//this.validate(comboFields[i], comboID);
				this.validate(comboFields[i]);
				if(this.errors[comboFields[i].id]){
					return;	
				}
			}
			return;
		}
		
		this.validate(field);
		return;
	};
	
	//this.validate= function(field, comboID){ // validate function
	this.validate= function(field){ // validate function	
		if(field.value && field.type.toLowerCase() != 'file'){ //security error for file inputs
			field.value = $.trim(field.value); //auto strip whitespaces
		}
		var classes = field.className.split(' ');
		//check for val_skipifis
		/* does not work in ie
		var locate = classes.indexOf('val_skipifis');
		*/
		
		var locate = $.inArray('val_skipifis', classes);
		if(locate != -1 && locate != (classes.length - 1)){ // exist and not the last class name
			var ifisInput = $('#' + classes[locate + 1])[0];
			if(ifisInput.value != '' && field.value == ifisInput.value){
				/* does not work in ie
				if(classes.indexOf('val_ajax') != -1 ){ // top ajax running, because of submit check
				*/
				for (var j = 0; j < this.ajaxClasses.length; j++) {
					if (inArray(this.ajaxClasses[j], classes)) { // top ajax running, because of submit check
						this.ajaxRunning[field.id] = false;
					}
				}
				this.errorHandler(field, false);
				return;	
			}
		}
		
		for(var i = 0; i < classes.length; i++){
			/*
			does not work in ie
			if(this.classList.indexOf(classes[i]) == -1){ //not a keyword
			*/
			if(!inArray(classes[i], this.classList)){ //not a keyword
				continue;
			}
			/*
			does not work in ie
			if(this.dependents.indexOf(classes[i]) == -1){ //not a dependant
			*/
			if(!inArray(classes[i], this.dependents)){ //not a dependant
				var run = 'var error = this.' + classes[i] + '(field);';
			}
			else{ //dependent on next class
				if(i + 1 == classes.length){
					alert('valForm dependent required');
					return false;
				}
				var run = 'var error = this.' + classes[i] + '(field, "' + classes[i + 1] + '");';
			}
			eval(run); //alert(run);
			
			//if(classes[i] == 'val_ajax'){
			if(inArray(classes[i], this.ajaxClasses)){
				continue;	
			}
			/*
			var errorField = field;
			if(comboID){ // display error for combo 
				errorField = $('#' + comboID)[0];
			}
			if(this.errorHandler(errorField, error)){
				break;	
			}
			*/
			
			if(this.errorHandler(field, error)){
				break;	
			}
		}
	};
	
	this.errorHandler= function(field, error){ // function to display error	
		var fieldType = field.type.toLowerCase();
		if(fieldType == 'checkbox' && field.name.indexOf('[') != -1 ){ //for checkboxes, name is an array, get label base on first index id 
			var labelFor = $('[name="' + field.name + '"]', this.form)[0].id;
		}
		else{
			// check for val_combo
			var classes = field.className.split(' '); //make sure to get the latest class name sice it may have changed
			var index = $.inArray('val_combo', classes);
			if(index != -1){ // found key word
				var labelFor = classes[index + 1];
			}
			else {
				var labelFor = field.id;
			}
		}
		
		if(labelFor == null){
			alert(field.name + ': label not found');
			return;
		}
				
		var label = $('label[for=' + labelFor  + ']', this.form)[0];
		
		// clear errors
		this.errors[field.id] = null;
		
		if($('#' + field.id + '_error')[0]){
			$('#' + field.id + '_error').remove();
		}
		
		if(label != ''){
			$([label, field]).removeClass(this.errorClass);
		}
		
		if (!error) { // no error
			return false;	
		}
		this.failed = true;
		
		 //when submiting, ajax running are set, but there is an error, so ajax function will not start, therefore ajax running will never be unset
		if (this.ajaxRunning[field.id]) {
			this.ajaxRunning[field.id] = false;
		}
		
		/* comment out because some forms may use default value as the label
		if (!label) {
			alert(field.id + ' label is missing, check label id');
			return;
		}*/
		//remove html between label tags or remove a colon and after
		if(label != ''){ //msg comes from label
			var errorMsg = label.innerHTML;
		}
		else{ //msg comes from default value
			var errorMsg = $('#' + labelFor)[0].defaultValue;
		}
		
		// Remove <em>*</em>, tooltip
		errorMsg = errorMsg.replace(/<em>\*<\/em>|<span class="hint">.+<\/span>|<span class="tip">.+<\/span>/gi, '');
		
		// Strip tags
		errorMsg = $('<tag>' + errorMsg + '</tag>').text(); // .text() will only work when string starts with html tag
		
		// Trim whitespace and ending colon
		errorMsg = $.trim(errorMsg);
		errorMsg = errorMsg.replace(/:$/gi, '') + ' ' + error;
		
		if(!this.hideErrorsFlag){
			//check to place error after a diferent element
			var classNames = field.className.split(' ');
			/* does not work in ie
			var findKeyword = classNames.indexOf('val_errorAfter');
			*/
			var findKeyword = $.inArray('val_errorAfter', classNames);
			if (findKeyword != -1){
				if (findKeyword == (classNames.length - 1)) { //missing id for error element
					alert('val_form: val_errorAfter is missing an id');
				}
				else {
					var errorMsgHtml = '<' + this.errorContainerTag + ' id="' + field.id + '_error" class="' + this.errorContainerClass + '">' + errorMsg + '</' + this.errorContainerTag + '>';
					$(errorMsgHtml).insertAfter($('#' + classNames[findKeyword + 1]));
				}
			}
			else { //place error after field element
				var errorMsgHtml = '<' + this.errorContainerTag + ' id="' + field.id + '_error" class="' + this.errorContainerClass + '">' + errorMsg + '</' + this.errorContainerTag + '>';
				$(errorMsgHtml).insertAfter(field);
			}
		}
		
		if(label != ''){
			$([label, field]).addClass(this.errorClass);
		}
		
		this.errors[field.id] = errorMsg;
		
		return true;
	};
	
	
	//-------------- VALIDATORS
	
	this.val_num = function(field) {
		if(field.value.match(/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/) || field.value == '') {
			return false;
		} 
		else {
			return 'needs to be a number.';
		}
	};
	
	this.val_req = function(field) {
		var fieldType = field.type.toLowerCase();
		if(fieldType == 'checkbox' || fieldType == 'radio'){
			var values = $('[name="' + field.name + '"]', this.form);
			for(var i = 0; i < values.length; i++){
				if(values[i].checked){
					return false;	
				}
			}
		}  
		else if(field.value.length != 0) {
			return false;
		} 
		
		return 'is required.';
	};
	
	// Compare with default value (ex. fields without labels)
	this.val_default = function(field) {
		if(field.value == field.defaultValue){
			return 'is required.';	
		}
		return false;
	}
	
	this.val_min = function(field, minLen) {
		if(field.value.length < parseFloat(minLen) && field.value != ''){
			return 'must be at least ' + minLen + ' characters long.';
		}
		else{
			return false;	
		}
	};
	
	this.val_max = function(field, maxLen) {
		if(field.value.length > parseFloat(maxLen) && field.value != ''){
			return 'must be at most ' + maxLen + ' characters long.';
		}
		else{
			return false;	
		}
	};
	
	this.val_maxNum = function(field, maxNum){
		if(!isNaN(field.value) && field.value > parseFloat(maxNum)){ 
			return 'must be ' + maxNum + ' or less.';
		}
		else{
			return false;	
		}
	};
	
	this.val_minNum = function(field, minNum){
		if(!isNaN(field.value) && (field.value < parseFloat(minNum)) && field.value != ''){
			return 'must be ' + minNum + ' or greater.';
		}
		else{
			return false;	
		}
	};
	
	this.val_len = function(field, len) {
		if(field.value.length != parseFloat(len) && field.value != ''){
			return 'must be ' + len + ' characters long.';
		}
		else{
			return false;	
		}
	};
	
	this.val_same = function(field, field2){
		var field2Obj = $('#' + field2)[0];
		if(!field2Obj){
			alert('val_same: ' + field2 + ' is not defined');
			return true;
		}
		if(field.value != field2Obj.value && field2Obj.value != ''){
			var field2Label = $('label[for=' + field2Obj.id + ']', this.form)[0].innerHTML;
			field2Label = field2Label.replace(/^<em>\*<\/em>|<span class="tip">.+<\/span>/gi, '');
			field2Label = $.trim($('<tag>' + field2Label + '</tag>').text()); // .text() will only work when string starts with html tag
			field2Label = field2Label.replace(/:$/gi, ''); // remove ending colon
			return 'does not match ' + field2Label + '.';
		}
		return false;
	};
	
	this.val_notSame = function(field, field2){
		var field2Obj = $('#' + field2)[0];
		if(!field2Obj){
			alert('val_notSame: ' + field2 + ' is not defined');
			return 'error';
		}
		if(field.value.length == 0){ //blank
			return false;	
		}
		if(field.value == field2Obj.value){
			var field2Label = $('label[for=' + field2Obj.id + ']', this.form)[0].innerHTML;
			field2Label = field2Label.replace(/^<em>\*<\/em>|<span class="tip">.+<\/span>/gi, '');
			field2Label = $.trim($('<tag>' + field2Label + '</tag>').text()); // .text() will only work when string starts with html tag
			field2Label = field2Label.replace(/:$/gi, ''); // remove ending colon
			return ' must not match ' + field2Label;	
		}
		return false;
	};
	
	this.val_email = function(field){
		if(field.value.match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})$/) || field.value == '') {
			return false;
		} 
		else {
			return 'is not a valid email address.';
		}
	};
	
	this.val_alpha = function(field) {
		if(field.value.match(/^[a-zA-Z]+$/) || field.value == '') {
			return false;
		} 
		else {
			return 'should contain only letters.';
		}
	};
	
	this.val_alpha_space = function(field) {
		if(field.value.match(/^[a-zA-Z\s]*$/) || field.value == '') {
			return false;
		} 
		else {
			return 'should contain only letters and spaces.';
		}
	};
	
	this.val_alpha_num = function(field) {
		if(field.value.match(/^[a-zA-Z0-9]*$/) || field.value == '') {
			return false;
		} 
		else {
			return 'should contain only letters and numbers.';
		}
	};
	
	this.val_alpha_num_space = function(field) {
		if(field.value.match(/^[a-zA-Z0-9\s]*$/) || field.value == '') {
			return false;
		} 
		else {
			return 'value should contain only letters, numbers, and spaces.';
		}
	};
	
	this.val_alpha_num_sym = function(field) {
		if(field.value.match(/^[a-zA-Z0-9_\-.]*$/) || field.value == '') {
			return false;
		} 
		else {
			return 'should contain only letters, numbers, and "-", "_", or ".".';
		}
	};
	
	this.val_int = function(field) {
		//if (field.value.match(/^\d+(,[\d]{3})*$/) || field.value == '') { // more strict
		if (field.value.match(/^[\d\-,]*$/) || field.value == '') {
			field.value = field.value.replace(/[^0-9\-]/g, '');
			return false;
		}
		else {
			return 'needs to be a whole number.';
		}
		
		/*
		if(field.value.match(/(^-?\d\d*$)/) || field.value == '') {
			return false;
		} 
		else {
			return 'needs to be a whole number.';
		}
		*/
	};
	
	this.val_url = function(field) {
		if(field.value.match(/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i) || field.value == '') {
			return false;
		} 
		else {
			return 'needs to be a valid url.';
		}


	};
	
	this.val_checked = function(field, len){
		var checked = 0;
		var values = $('[name="' + field.name + '"]', this.form);
		for(var i = 0; i < values.length; i++){
			if(values[i].checked){
				checked++;
			}
		}
		if(checked != len){
			return 'requires ' + len + ' selections.';
		}
		return false;
	};
	
	this.val_checked_min = function(field, len){
		var checked = 0;
		var values = $('[name="' + field.name + '"]', this.form);
		for(var i = 0; i < values.length; i++){
			if(values[i].checked){
				checked++;
			}
		}
		if(checked < len){
			return 'requires at least ' + len + ' selections.';
		}
		return false;
	};

	this.val_checked_max = function(field, len){
		var checked = 0;
		var values = $('[name="' + field.name + '"]', this.form);
		for(var i = 0; i < values.length; i++){
			if(values[i].checked){
				checked++;
			}
		}
		if(checked > len){
			return 'requires at most ' + len + ' selections.';
		}
		return false;
	};

	this.val_ajax = function(field, func){
		eval(func + "('" + field.id + "')");
		return true;
	};
	
	this.val_func = function(field, func){
		eval('var valForm_error = ' + func + "('" + field.id + "')");
		if(valForm_error){
			return valForm_error;
		}
		else{
			return false;
		}
	};
	
	this.val_exist = function(field, fieldToCheck){
		eval("checkExist('" + fieldToCheck + "', '" + field.id + "', true)");
		return true;
	};
	
	this.val_not_exist = function(field, fieldToCheck){
		eval("checkExist('" + fieldToCheck + "', '" + field.id + "', false)");
		return true;
	};
	
	//action key words	
	this.val_money = function(field){
		field.value = field.value.replace(/[^0-9\-\.]/g, '');
		if(field.value == ''){
			return;	
		}
		if(isNaN(field.value)){
			formated = '0.00';
		}
		else{
			var formated = Math.round(field.value * 1000) / 1000; //1000 for partial cents
			formated = formated.toString();
			if(formated.indexOf('.') == -1){
				formated += '.00';
			}
			else{
				var parts = formated.split('.');
				if(parts[1].length == 1){
					formated += '0';	
				}
			}
		}
		field.value = formated;
	};
	
	this.val_decimal = function(field, precision){
		field.value = field.value.replace(/[^0-9\-\.]/g, '');
		if(field.value == ''){
			return;	
		}
		if(isNaN(field.value)){
			formated = '0.00';
		}
		else{
			var formated = Math.round(field.value * Math.pow(10, precision)) / Math.pow(10, precision);
			formated = formated.toString();
			if(formated.indexOf('.') == -1){
				formated += '.00';
			}
			else{
				var parts = formated.split('.');
				if(parts[1].length == 1){
					formated += '0';	
				}
			}
		}
		field.value = formated;
	};
	
	this.val_date = function(field) {
		if(field.value == ''){
			return false;	
		}
		else if(field.value.match(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/)) {
			//make sure date is valid
			var dateParts = field.value.split('/');
			var day = dateParts[1];
			var month = dateParts[0];
			var year = dateParts[2];
			var dteDate = new Date(year, month - 1, day);
			if(day == dteDate.getDate() && (month == dteDate.getMonth() + 1) && year == dteDate.getFullYear()){
				return false;
			}
			return 'is an invalid date.';
		} 
		else {
			return 'needs to be mm/dd/yyyy.';
		}
	};
	
	this.val_datetime = function(field) {
		if(field.value.match(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4} [0-9]{2}:[0-9]{2}(:[0-9]{2})? (am|pm|AM|PM)$/) || field.value == '') {
			return false;
		} 
		else {
			return 'needs to be mm/dd/yyyy hh:mm:ss am/pm.';
		}
	};
	
	this.val_phone = function(field) {
		if(field.value == ''){
			return false;	
		}
		var numbers = field.value.replace(/[^0-9]/g, ''); //remove all non numerics
		if(numbers.length < 10){
			return 'needs to be 10 digits.';	
		}
		field.value = numbers.substr(0, 3) + '-' + numbers.substr(3, 3) + '-' + numbers.substr(6, 4);
		// handle extensions
		if(numbers.length > 10){
			field.value += ' x ' + numbers.substr(10);
		}
		return false;
	};
	
	this.val_ceil = function(field, multiple) {
		if(field.value == ''){
			return false;	
		}
		var factor = Math.floor(field.value / multiple);
		var remainder = field.value % multiple;
		if(remainder > 0){
			factor++;	
		}
		field.value = factor * multiple;
	};
}

//Event.observe(window, 'load', this.init);
