	var Classes = {
		Button: {
			imageStates: ["", "hover", "pressed"],
			onmouseover: function() {
				this.removeClassName(this.imageStates[0]);
				this.addClassName(this.imageStates[1]);
				this.removeClassName(this.imageStates[2]);
			},
			onmouseout: function() {
				this.addClassName(this.imageStates[0]);
				this.removeClassName(this.imageStates[1]);
				this.removeClassName(this.imageStates[2]);
			},
			onmousedown: function() {
				this.removeClassName(this.imageStates[0]);
				this.removeClassName(this.imageStates[1]);
				this.addClassName(this.imageStates[2]);
			},
			onmouseup: function() {
				this.removeClassName(this.imageStates[0]);
				this.addClassName(this.imageStates[1]);
				this.removeClassName(this.imageStates[2]);
			}
		},
		InputButton: {
			originalSrc: null,
			hoverSrc: null,
			initiate: function() {
				this.originalSrc = this.src;
			},
			onmouseover: function() {
				if (this.hoverSrc) this.src = this.hoverSrc;
			},
			onmouseout: function() {
				if (this.originalSrc) this.src = this.originalSrc;
			}
		},
		TextInput: {
			valid: true,
			fieldType: null,
			fieldName: null,
			errorString: null,
			timeout: null,
			initiate: function() {
				if (this.fieldType == null) this.fieldType = 'default';
				if (this.id) {
					this.checkForValue();
					this.startReCheck();
					//Events.add(window,"load",$(this.id).startReCheck);
				}
			},
			startReCheck: function() {
				this.timeout = window.setTimeout("$('" + this.id + "').checkForValue(20,100);",100);
			},
			checkForValue: function(moreTimes,pause) {
				if (this.value == '') this.addClassName('display-background');
				else this.removeClassName('display-background');
				if (moreTimes) {
					moreTimes--;
					this.timeout = window.setTimeout("$('" + this.id + "').checkForValue(" + moreTimes + ");",(pause*1.2));
				}
			},
			onfocus: function() {
				this.removeClassName('display-background');
				this.addClassName('focus');
			},
			onblur: function() {
				this.removeClassName('focus');
				this.checkForValue();
			},
			validate: function() {
				this.errorString = "";
				switch(this.fieldType) {
				case 'default':
					if (this.value != '') this.valid();
					else {
						this.error("Please enter your " + this.fieldName + ". ");
					}
				break;
				case 'email':
					if (this.value.match(/^[\w\W]+@[\w\W]+.[\w\W]+$/)) this.valid(); 
					else {
						this.error("Please check the formatting of your " + this.fieldName + ". ");
					}
				break;
				case 'date':
					if (this.value.match(/^\d{1,2}\D\d{1,2}\D\d{2,4}$/)) this.valid(); 
					else {
						this.error("Please check the formatting of your " + this.fieldName + ". It should follow the format: MM/DD/YYYY");
					}
				break;
				case 'zipcode':
					if (this.value.match(/^\d{5}$/)) this.valid(); //US, Germany (Germany may be DE-)
					else if(this.value.match(/^\d{5}\-\d{4}$/)) this.valid(); //US 10 digit and Brazil
					else if(this.value.match(/^\w{6}$/)) this.valid(); //Canada and England
					else if(this.value.match(/^\w{3}\s\w{3}$/)) this.valid(); //Canada and England again
					else if(this.value.match(/^\d{4}$/)) this.valid(); //Australia and new Zealand
					else if(this.value.match(/^\w{2}\-\d{3}\s\d{2}$/)) this.valid(); //Europe part 1
					else if(this.value.match(/^\w{1}\-\d{3}\s\d{2}$/)) this.valid(); //Europe part 2
					else if(this.value.match(/^\w{2}\-\d{5}$/)) this.valid(); //Europe part 3
					else if(this.value.match(/^\w{2}\-\d{4}$/)) this.valid(); //Europe part 4
					else if(this.value.match(/^\w{1}\-\d{4}$/)) this.valid(); //Europe part 5
					else if(this.value.match(/^\w{2}\-\d{5}$/)) this.valid(); //Europe part 6
					else if(this.value.match(/^\w{2}\-\d{6}$/)) this.valid(); //Europe part 7 (Russia pt1)
					else if(this.value.match(/^\w{2}\-\d{3}\s\d{3}$/)) this.valid(); //Europe part 4 (Russia pt2)
					else if(this.value.match(/^\w{2}\-\d{4}\s\w{2}$/)) this.valid(); //Netherlands
					else if(this.value.match(/^\d{3}\-\d{4}$/)) this.valid(); //Japan
					else {
						this.error("Please check the formatting of your " + this.fieldName + ". ");
					}
				break;
				case 'phone':
					if (this.value.length > 7 && !isNaN(this.value)) this.valid();
					else {
						this.value=this.value.replace(/\s|\(|\)|\-|\./gi,"");
						if (this.value.length > 7 && !isNaN(this.value)) this.valid();
						else {
							this.error("Please check the formatting of your " + this.fieldName + ". It should include area code, with no hyphens or dashes.");
						}
					}
				break;
				case 'trxid':
					if (this.value.length == 9 && !isNaN(this.value)) this.valid();
					else {
						this.error("Your " + this.fieldName + " must be 9 digits long.");
					}
				break;
				case 'BRNumber':
					if (this.value.match(/^BR\d{8}$/) || this.value.match(/^\d{8}$/) || this.value.match(/^\d{12}$/)) {
						if (this.value.match(/^\d{8}$/)) this.value = "BR" + this.value;
						this.valid();
					}
					else {
						this.error("Please check the formatting of your " + this.fieldName + ". It should include 8 or 12 digits.");
					}
				break;
				}
				return (valid);
			},
			error: function (explaination) {
				this.addClassName('invalid'); //invalid color class
				valid = false;
				this.errorString += explaination;
			},
			valid: function (){
				valid = true;
				this.removeClassName('invalid');
			}
		},
		Form: {
			inputValues: null,
			errorDiv: null,
			errorString: "",
			initiate: function() {
				this.inputValues = this.getElementsByClassName('TextInput');
				this.errorDiv = this.name + "-error";
			},
			validate: function(submitAtEnd) {
				var valid = true;
				var errorString = "";
				for(var c=0;c<this.inputValues.length;c++) {
					if (!this.inputValues[c].validate()) {
						valid = false;
						errorString = errorString + this.inputValues[c].errorString + "<br />";
					}
				}
				if (submitAtEnd) {
					if (valid) this.submit();
					else {
						$(this.errorDiv).removeClassName('valid');
						$(this.errorDiv).innerHTML = errorString;
					}
				}
				else {
					if (valid) return true;
					else {
						$(this.errorDiv).removeClassName('valid');
						$(this.errorDiv).innerHTML = errorString;
						return false;
					}
				}
			}	
		},
		PageSwitch: {
			numberOfSteps: null,
			nextStep: function(step) {
				this.numberOfSteps = document.getElementsByClassName('Step').length;
				for(var i=1;i<=this.numberOfSteps;i++){
					if(i==step) $('step'+i).removeClassName('hidden');
					else {
						$('step'+i).addClassName('hidden');
					}
				}
			}
		},
		EarnPointsCatagory: {
			id: null,
			initiate: function() {
				//$('details-'+this.id).hide();
				$('link-'+this.id).onclick = function() {
					this.parentNode.parentNode.open();
				};
				document.openCatagoryId = null;
			},
			open: function() {
				if (document.openCatagoryId) {
					$('details-'+document.openCatagoryId).addClassName('hidden');
					//this.endingEffect = new Effect.BlindUp('details-'+document.openCatagoryId);
				}
				//this.effect = new Effect.BlindDown('details-'+this.id);
				$('details-'+this.id).removeClassName('hidden');
				document.openCatagoryId = this.id;
			}
		},
		Reward: {
			effect: null,
			points: 0,
			resorts: new Array(),
			catagories: new Array(),
			hideCount: 0,
			hidden: false,
			initiate: function() {
				this.hideFor = new Object();
			},
			update: function(settings) {
				if (this.resorts[settings.resort]) this.hideManage('resort',false);
				else this.hideManage('resort',true);
				
				if (this.catagories[settings.catagory]) this.hideManage('catagory',false);
				else this.hideManage('catagory',true);
			},
			hideManage: function(hideReason, becomeHidden) {
				if (becomeHidden) {
					if (!this.hideFor[hideReason]) {
						if (this.effect) this.effect.cancel();
						this.hideFor[hideReason] = true; 
						if (this.hideCount == 0) {
							this.addClassName('deselected'); //this.effect = new Effect.BlindUp(this); 
							this.hidden = true;
						}
						this.hideCount++;
					}
				}
				else {
					if (this.hideFor[hideReason] == true) {
						this.hideFor[hideReason] = null;
						this.hideCount--;
						if (this.hideCount == 0) {
							this.removeClassName('deselected'); //this.effect = new Effect.Highlight(this, {startcolor: '#dfddda', endcolor: '#ffffff', restorecolor: '#ffffff'});
							this.hidden = false;
						}
					}
				}
			},
			onclick: function() {
				//getURL(this.link);
			}
		},
		RewardsList: {
			list: null,
			settings: {resort: 0, catagory: 0},
			initiate: function() {
				document.RewardsList = this;
				this.list = this.childElements();
				this.reorder();
				var filterString = Cookie.readCookie('filter');
				if (filterString) var filter = filterString.split(',');
				if (Query.resort) {
					this.settings.resort = parseInt(Query.resort);
					this.setResort();
				}
				else if (filter) {
					this.settings.resort = parseInt(filter[0]);
					this.setResort();
				}
				if (Query.category) {
					this.settings.catagory = parseInt(Query.category);
					this.setCatagory();
				}
				else if (filter) {
					this.settings.catagory = parseInt(filter[1]);
					this.setCatagory();
				}
				window.onunload = Cookie.createCookie("filter",this.settings.resort+","+this.settings.catagory,1);
			},
			update: function(updatedField, newValue) {
				this.settings[updatedField] = newValue;
				for(var c=0;c<this.list.length;c++) this.list[c].update(this.settings);
				this.reorder();
				window.onunload = Cookie.createCookie("filter",this.settings.resort+","+this.settings.catagory,1);
			},
			setResort: function() {
				for (var c=0;c<$('select-resort').options.length;c++) {
					if ($('select-resort').options[c].value == this.settings.resort) $('select-resort').selectedIndex = c;
				}
				this.update('resort', this.settings.resort);
			},
			setCatagory: function() {
				for (var c=0;c<$('select-catagory').options.length;c++) {
					if ($('select-catagory').options[c].value == this.settings.catagory) $('select-catagory').selectedIndex = c;
				}
				this.update('catagory', this.settings.catagory);
			},
			reorder: function() {
				this.list.sort(this.sort);
				for(var c=0;c<this.list.length;c++) this.appendChild(this.list[c]);
			},
			sort: function(a,b) {
				return(a.points-b.points);
				//return(a.hidden==b.hidden ? a.points-b.points : a.hidden-b.hidden);
			}
		}
	}
	
var passwordStrength = Class.create({
	initialize: function(passwordEl, strengthIndicator){
		this.passwordEl = $(passwordEl);
		this.strengthIndicator = $(strengthIndicator);
		this.score = 0;
		this.baseScore = 50;
		this.minLen = 6;
		
		//new Form.Element.Observer($(this.password1),1, function(){this.checkStrength();});
		//this.checkStrength();
		this.strengthIndicator.update('Enter a Password');
		this.watchPass();
	},
	
	watchPass:function(){
		var strenEl = this.strengthIndicator;
		var newValueChar;
		var minLen = this.minLen;
		var num = {Excess:0,Upper:0,Numbers:0,Symbols:0};
		var bonus = {Excess:3,Upper:4,Numbers:5,Symbols:5,Combo:0,FlatLower:0,FlatNumber:0};
		var score = this.score;
		var baseScore = this.baseScore;
		
		new Form.Element.Observer(this.passwordEl,.1,function(el,newValue){
			newValueChar = newValue.split("");
			
			if(newValueChar.length >= minLen){
				analyzePass(newValue,newValueChar);
				if(score<50) {
					strenEl.update('Weak');
					el.addClassName('error');
					el.removeClassName('valid');
				}else if(score>=50 && score<75) {
					strenEl.update('Average');
					el.addClassName('valid');
					el.removeClassName('error');
				}else if(score>=75 && score<100){
					strenEl.update('Strong');
					el.addClassName('valid');
					el.removeClassName('error');
				}else if(score>100){
					strenEl.update('Very Strong');
					el.addClassName('valid');
					el.removeClassName('error');
				}
			} else {
				score = 0;
				if(newValue==""){
					strenEl.update('Enter a Password');
					el.removeClassName('error');
					el.removeClassName('valid');
				} else{
					strenEl.update('Needs to be at least '+minLen+' characters.');
					el.addClassName('error');
					el.removeClassName('valid');
				}
			}
			
			
		});
		
		function analyzePass(passStr,passChr){
			
			//resetting the values to 0 for everything
			num.Excess = 0;
			num.Upper = 0;
			num.Numbers = 0;
			num.Symbols = 0;
			bonus.Excess = 3;
			bonus.Upper = 4;
			bonus.Numbers = 5;
			bonus.Symbols = 5;
			bonus.Combo = 0;
			bonus.FlatLower = 0;
			bonus.FlatNumber = 0;
			
			for (i=0; i<passChr.length;i++){
				if (passChr[i].match(/[A-Z]/g)) {num.Upper++;}
				if (passChr[i].match(/[0-9]/g)) {num.Numbers++;}
				if (passChr[i].match(/(.*[!,@,#,$,%,^,&,*,?,_,~])/)) {num.Symbols++;}
			}
			
			num.Excess = passChr.length - minLen;
			
			if (num.Upper && num.Numbers && num.Symbols) {
				bonus.Combo = 25;	
			} else if ((num.Upper && num.Numbers) || (num.Upper && num.Symbols) || (num.Numbers && num.Symbols)) {
				bonus.Combo = 15;	
			}
			
			if (passStr.match(/^[\sa-z]+$/)){bonus.FlatLower = -15;}
			if (passStr.match(/^[\s0-9]+$/)){bonus.FlatNumber = -35;}
			
			//calculating the final score
			score = baseScore + (num.Excess*bonus.Excess) + (num.Upper*bonus.Upper) + (num.Numbers * bonus.Numbers) + (num.Symbols*bonus.Symbols) + bonus.Combo + bonus.FlatLower + bonus.FlatNumber;
			
			//alert(score);
		}
	}
});
