/**
 * Use this function to get the selected value of a radio button group.
 * Ex:
 * 			getValueMap: function() {
 *				return { // make sure to return something in order to actually submit.
 *					customization: Form.getRadioValue('registryForm', 'customization')
 *				};
 *			}
 *
 * @author <a href="mailto:eric@evite.com">Eric Berry</a>
 * @param form The form element or ID of the form.
 * @param name The name of the radio button group.
 * @return The selected value of the radio button group.
 */
Form.getRadioValue = function(form, name) {
	// get radio button Array.
	var radioElements = Form.getInputs(form, 'radio', name);
	var radioValue = "";
	if(radioElements && radioElements != null && radioElements.length > 0) {
		var radioCount = radioElements.length;
		// loop through and find the selected (checked) one.
		for(var radioIndex = 0; radioIndex < radioCount && radioValue == ""; radioIndex++) {
			if(radioElements[radioIndex].checked) {
				radioValue = radioElements[radioIndex].value;
			}
		}
	}
	// return empty string or the selected value.
	return radioValue;
}

Form.Element.setValue = function(element, value) {
	element = $(element);
	if(typeof(element.value) != 'undefined') {
		element.value = value;
	} else if (typeof(element.innerHTML) != 'undefined') {
		element.innerHTML = value;
	}
}

// this is like Element.show(), except it sets it to display: inline
Element.showInline = function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = 'inline';
    }
 }
 
Element.isHidden = function(element)	{
	return (Element.getStyle(element,'display')=='none')?true:false;
}
 
Element.getCenteredOffset = function(enclosingElement, overlayElement) {
    var positionLeftTop = Position.cumulativeOffset(enclosingElement);
    var dimensions = Element.getDimensions(enclosingElement);    
    var left = positionLeftTop[0];
    var top = positionLeftTop[1];
    
    // find the center point
    var centerLeft = left + (dimensions.width / 2);
    var centerTop = top + (dimensions.height / 2);
    
    // adjust for the width of the div to position
    centerLeft -= Element.getDimensions(overlayElement)['width'] / 2;
    centerTop -= Element.getDimensions(overlayElement)['height'] / 2;    
    return { offsetLeft: centerLeft, offsetTop: centerTop };
}

Element.setPosition = function(element, left, top) {
    element = $(element);
    var style = {};
    style['left'] = left+'px';
    style['top'] = top+'px';
   	Element.setStyle(element, style);
}

Element.getStyleValue = function(element, style) {
	var styleValue = Element.getStyle(element, style);
	if(styleValue && styleValue != null) {
		if(styleValue.substring(styleValue.length - 2) == 'px') {
			styleValue = styleValue.substring(0, styleValue.length - 2);
			styleValue = parseFloat(styleValue);
		} else {
			try {
				styleValue = parseFloat(styleValue);
			} catch(exception) {
				styleValue = null;
				if(Logger) {
					Logger.logDebug("Bad value, could not parse numeric value from: " + styleValue);
				}
			}
		}
	} else {
		styleValue = null;
	}
	return styleValue;
}

/**
 * This method sort of solves the super issue.
 */
Object.subClass = function(destination, source) {
	// create a copy of source into a separate instance so we don't screw up
	// the original prototype when actually calling the superf function.
	var tempSuperObj = Class.create();
	Object.extend(tempSuperObj, source); 
	Object.extend(destination, tempSuperObj);
	Object.extend(destination, {
		// hidden variable (not really) - don't use directly.
		superObj: tempSuperObj,
		// creates a "super" ability much like java's call to the super object.
		superf: function() {
			var args = $A(arguments);
			var methodName = args.shift();
			// copy all properties that are not functions
			for (var property in this) {
				// no overriding the super objects functions now y'hear!
				if(property != 'superObj' && typeof(this[property]) != 'function') {
					this.superObj[property] = this[property];
				}
			}
			var returnValue = this.superObj[methodName].apply(this.superObj, args.concat($A(arguments)));
			// copy all super.properties that are not functions back into this one
			// will allow your super method to modify any values and they will
			// be present in your instance of your subclass.
			for (var property in this.superObj) {
				// no overriding your subclasses functions with the super's!
				if(property != 'superObj' && typeof(this[property]) != 'function') {
					this[property] = this.superObj[property];
				}
			}
			return returnValue;
		}
	});
	return destination;
}

// returns the value of an element (&nbsp; = '' blank)
function $EV(element) {
	var el = $(element);
	if( el == null ) return null;
	
	var value = "";
	if(typeof(el.value) != 'undefined') {
		value = el.value;
	} else if(typeof(el.innerHTML) != 'undefined') {
		value = el.innerHTML;
	}
	// this is a weird Safari bug
	if( encodeURIComponent(value) == '%C2%A0' ) value = '';

	var trimmedValue = value.replace(/^\s+|\s+$/, '');
	if( trimmedValue == '&nbsp;' ) {
		value = '';
	}
	
	return value;
}

/**
 * This should fix an error that was popping up in IE when you try to load
 * multiple script tag js (they couldn't see eachother's vars).
 */
Object.extend(String.prototype, {
  evalScripts: function() {
    var scriptArray = this.extractScripts();
	var allScripts = scriptArray.join('\n');
	//prompt('',allScripts); 
	return eval(allScripts);
  }
});

// This will create and submit a hidden form as a POST. Very handy
// if you really need to do a POST for a link instead of the usual GET
var Utils= {};
Utils.Post = Class.create();
Utils.Post.prototype = {
	initialize: function(url, params, options) {
		this.url = url;
		this.params = new $H(params);
		this.options = new $H(options);
	},
	submit: function() {
		var form = this.createHiddenForm(this.url, this.params);
		document.body.appendChild(form);
		form.submit();
	},
	createHiddenForm: function(url, params) {
	    var form = document.createElement("form");
   		// hide it 
   		form.style.display = '';
   		if( this.options['formId'] ) {
			form.id = this.options['formId'];
		}
		if( this.options['formName'] ) {
			form.id = this.options['formName'];
		}
	    
	    form.method = 'POST';
	    form.action = url;
		this._addDataToHiddenForm(params, form);
		
		return form;
	},
	_addDataToHiddenForm: function(valueMap, form) {
		if(!valueMap.keys || valueMap.keys().length == 0) {
			return false;
		}
		valueMap.keys().each( (function(key) { 
			var paramName = key;
			var value = unescape(valueMap[key]);
			if( typeof value == 'string' ) {
				this._createHiddenTextInput(paramName, value, form); 
			} else if( value instanceof Array ){
				// it's an array
				value.each( (function(singleVal) {
					this._createHiddenTextInput(paramName, singleVal, form);
				}).bind(this));
			}
		}).bind(this) );

		return true;
	},
	_createHiddenTextInput: function(name, value, form) {
        var hiddenField = document.createElement("input");
        hiddenField.type = "hidden";
        hiddenField.name = name;
        hiddenField.value = value;
	    form.appendChild(hiddenField);
	}
}

/**
 * A LinkOverrider will override any links onclick event handler with a 
 * function that is provided in linkOverrides, or by a defaultLink override 
 * function.
 */
Utils.LinkOverrider = Class.create();
Object.extend(Utils.LinkOverrider.prototype, Object.prototype);
Object.extend(Utils.LinkOverrider.prototype, {
	initialize: function() {},
	linkOverrides: null,
	getLinkOverrides: function() {
		return this.linkOverrides;
	},
	setLinkOverrides: function(linkOverrides) {
		this.linkOverrides = $H(linkOverrides);
	},
	overrideLinks: function() {
		var documentLinks = $A(document.links);
		documentLinks.each(function(link, index) {
			this.overrideLink(link);
		}.bind(this));
	},
	// This function can be easily overridden to provide different functionality.
	overrideLink: function(link) {
		var linkOverrides = $H(this.getLinkOverrides());
		// if the link id exists in the override list, it's onclick event is 
		// replaced with the given function.
		if(linkOverrides[link.id] && linkOverrides[link.id] != null) {
			link.onclick = linkOverrides[link.id];
		} else if (link.name && link.name != null) {
			// try looking for the link.name (allows for grouping).
			if(linkOverrides[link.name] && linkOverrides[link.name] != null) {
				link.onclick = linkOverrides[link.name];
			} else {
				// otherwise it's replaced with the function marked as the defaultLink.
				link.onclick = linkOverrides['defaultLink'];
			}
		} else {
			// otherwise it's replaced with the function marked as the defaultLink.
			link.onclick = linkOverrides['defaultLink'];
		}
	}
});

var LoginUtils = {
	getUserId: function() {
		var cookie = new HTTP.Cookies;
		var userId = cookie.read('eviteAuth');
		return userId;
	},
	isLoggedIn: function() {
		var userId = this.getUserId();
		return (userId != null && userId.length == 20);
	}
};

//
// The Redirector.executeLoggedInFunction 
// will take a piece of code and 
// execute it *only* if the user is logged in.
// If the user is not logged in, the function will
// be saved in a cookie and the user take to the
// login/registration page. Upon their return, 
// the LoginUtils.Redirector.checkForQueuedFunctions
// method should be called, which will execute the
// original function now that the user is logged in.
LoginUtils.Redirector = {
	cookie: new HTTP.Cookies,
	
	// fn is the function to be called, id
	// is an unique id for this fn to be matched
	// with the id in checkForQueuedFunctions
	executeLoggedInFunction: function(fn, uniqueId, otherParams) {
		otherParams = new $H(otherParams);	
		if( LoginUtils.isLoggedIn() ) {
			// user is logged in, execute the function
			return fn();
		} else {
			// save the function and send them to the login/reg
			// page
			var cookie = new HTTP.Cookies;			
			cookie.write(this._buildCookieName(uniqueId), this._buildCallableFunction(fn), -1);
			// now redirect them to the login page
			location.href = this.buildLoginUrl(otherParams.toQueryString());
		}
	},
	buildLoginUrl: function(otherParams) {
		otherParams = new $H(otherParams);
		var loc = location.href;
		if( loc.indexOf('#') == (loc.length - 1) ) {
			loc = loc.substring(0, loc.length - 1);
		}
		
		if( loc.indexOf('?') > 0 ) {
			loc += '&'
		} else {
			loc += '?';
		}
		loc += otherParams.toQueryString();
		var url = '/pages/profile/registration.jsp?redirect='+escape(loc);
		return url;
	},
	checkForQueuedFunctions: function(uniqueId) {
		var fn = this.retrieveQueuedFunction(uniqueId);
		if( fn != null && fn != '') {
			// first remove the cookie
			this.cookie.remove(this.retrieveCookieName(uniqueId));
			
			// now execute the function, provided they've logged in
			eval(fn);
			
			// the function should be held in a var called _fn
			if(lrfn) {
				lrfn();
			}
		}
	},
	retrieveQueuedFunction: function(uniqueId) {
		// if they are still not logged in then do nothing
		if( !LoginUtils.isLoggedIn() ) {
			return;
		}
		var fn = this.cookie.read(this.retrieveCookieName(uniqueId));
		return fn;
	},
	retrieveCookieName: function(uniqueId) {
		var cookieName = this._buildCookieName(uniqueId);
		return cookieName;
	},
	_buildCookieName: function(uniqueId) {
		return 'LoginUtils.Redirector.'+uniqueId;
	},
	_buildCallableFunction: function(fn) {
		return 'lrfn='+fn;
	}	
};

var Ads = {};

var Logger = { 
	_debug : false,
	_useWindow : true,
	setDebug: function(debug) {
		this._debug = debug;
	},
	setUseWindow: function(useWindow) {
		this._useWindow = useWindow;
	},
	clearDebug: function() {
		Element.update('debugDiv', '');
	},
	logDebug : function(text) {
		if(!this._debug) return;
		
		//setTimeout(function() { throw new Error("[debug] " + text); }, 0); 
		
		if( !this._useWindow ) return;
		
		var debugWindow = Windows.getWindow('debug_window');
		if( debugWindow == null ){
			debugWindow = new Window('debug_window', {height:350, width: 300, top:0, left:0, zIndex:1000, opacity:.8, showEffect: Element.show, resizable: true, title: "Debug"});
			debugWindow.getContent().innerHTML = "<div id='header'><a style='color:yellow;' href='javascript:moduleManager.clearDebug()'>clear</a><br></div><div id='debugDiv' style='height:300;text-align:left;overflow:auto;white-space:nowrap;padding:3px'></div>";
		}
		time = "-"; //new Date();
		debugWindow.show();
		$('debugDiv').innerHTML +=  time + " " + text + "<br>";
	}
}

var Tracker = {
	sendTrackingEvent: function(eventName) {
		var s=s_gi(s_account);
		var eventName = eventName;
		s.linkTrackVars="prop6";
		s.tl(true, 'o', eventName);
	}
}


var Templatizer = {
	generate : function(templateText, replacements) {
		replacements = $H(replacements);
		replacements.each( function(entry){
			var replName = entry.key;
			var replValue = entry.value;
			while(templateText.indexOf(replName) > -1) {
				templateText = templateText.replace("[["+replName+"]]", replValue);
			}
		})
		return templateText;
	}
}


// Field        | Full Form          | Short Form
// -------------+--------------------+-----------------------
// Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
// Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
//              | NNN (abbr.)        |
// Day of Month | dd (2 digits)      | d (1 or 2 digits)
// Day of Week  | EE (name)          | E (abbr)
// Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
// Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
// Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
// Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
// Minute       | mm (2 digits)      | m (1 or 2 digits)
// Second       | ss (2 digits)      | s (1 or 2 digits)
// AM/PM        | a  
var DateFormatter = {
	MONTH_NAMES:new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'),
	DAY_NAMES:new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat'),
	LZ : function(x) {return(x<0||x>9?"":"0")+x},
	formatDate : function(date,format) {
		format=format+"";
		var result="";
		var i_format=0;
		var c="";
		var token="";
		var y=date.getYear()+"";
		var M=date.getMonth()+1;
		var d=date.getDate();
		var E=date.getDay();
		var H=date.getHours();
		var m=date.getMinutes();
		var s=date.getSeconds();
		var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
		var value=new Object();
		if (y.length < 4) {y=""+(y-0+1900);}
		value["y"]=""+y;
		value["yyyy"]=y;
		value["yy"]=y.substring(2,4);
		value["M"]=M;
		value["MM"]=this.LZ(M);
		value["MMM"]=this.MONTH_NAMES[M-1];
		value["NNN"]=this.MONTH_NAMES[M+11];
		value["d"]=d;
		value["dd"]=this.LZ(d);
		value["E"]=this.DAY_NAMES[E+7];
		value["EE"]=this.DAY_NAMES[E];
		value["H"]=H;
		value["HH"]=this.LZ(H);
		if (H==0){value["h"]=12;}
		else if (H>12){value["h"]=H-12;}
		else {value["h"]=H;}
		value["hh"]=this.LZ(value["h"]);
		if (H>11){value["K"]=H-12;} else {value["K"]=H;}
		value["k"]=H+1;
		value["KK"]=this.LZ(value["K"]);
		value["kk"]=this.LZ(value["k"]);
		if (H > 11) { value["a"]="PM"; }
		else { value["a"]="AM"; }
		value["m"]=m;
		value["mm"]=this.LZ(m);
		value["s"]=s;
		value["ss"]=this.LZ(s);
		while (i_format < format.length) {
			c=format.charAt(i_format);
			token="";
			while ((format.charAt(i_format)==c) && (i_format < format.length)) {
				token += format.charAt(i_format++);
				}
			if (value[token] != null) { result=result + value[token]; }
			else { result=result + token; }
			}
		return result;
	}
		

}