var dynamicSelectBox = Class.create();
	dynamicSelectBox.prototype = {
		initialize: function(element){
				var defaults = {
						dataurl: 		"",
						parsefunction:  null, //Provide if the dataURL doesn't provide a JSON formatted response, returns a HASH object
						autocomplete:	false,
						persistvalue: 	false,
						valueHash:      new Hash(),
						onchange: 		null,
						valueSelected:	null
				}
				this.options = Object.extend(defaults, arguments[1] || {})
				this.element = $(element);
				this.element.descendants().invoke("remove"); //clear all the old options first

				this.persistCookieName = this.element.identify() + "_persist";
				
				if(this.options.dataurl == "" && this.options.valueHash.length != 0) throw new Error("You must provide a data url or value hash");
				Event.stopObserving(element, 'change'); //We've got to clobber all existing listeners, otherwise successive calls to the initilization function could chain the same listener for as many times as it was called.
				Event.observe(element, 'change', this._changeObserver.bind(this));
				if(this.options.dataurl != ""){
					this._fetchValues(this.options.dataurl);
				}else if(this.options.valueHash.length > 0){
					this._populateList(listValues);
				}
				return this;
		},
		_populateList: function(valueList){
				var selOptions;
				valueList.each(function(item){
					if(this._isValueSelected(item.value)){
							selOptions = {'value':item.value, 'selected':"selected"}
						}else{
							selOptions = {'value':item.value}
						}
						this.element.appendChild(new Element("option", selOptions).update(item.key))
					}.bind(this)
				)
			},
		_ajaxHandler: function(transport){
				var values = (transport.responseXML);
				if(!values || transport.responseJSON) values = transport.responseJSON;
				if(this.options.parsefunction != null) values = this.options.parsefunction(values);
				this._populateList(values);
		},
		_fetchValues: function(dataurl){
			new Ajax.Request(this.options.dataurl,
			  {
			    method:'get',
			    onSuccess: this._ajaxHandler.bind(this),
			    onFailure: function(){ alert('Unable to retrieve data list for element ' + this.element.identify()) }
			  });
		},
		_isValueSelected: function(value){
			if(this.options.valueSelected){return this.options.valueSelected(value)};
			if(value == Cookies.getCookie(this.persistCookieName)){
				return true;
			}
		},
		_changeObserver: function(event){
			if(this.options.persistvalue == true){
					Cookies.setCookie(this.persistCookieName, this.element.value, 3650000);
			}
			
			if(this.options.onchange != null) {
				this.options.onchange(event, this.element.value);
			}
		}	
	}
		
var _Cookies = Class.create();
	_Cookies.prototype = {
		initialize: function(){
			this._Cookies = new Hash();
			var splitCookies = String(document.cookie).split(";");
			var splitCookie;
			splitCookies.each(
				function(item){
						splitCookie	= item.split("=");
						this._Cookies.set(splitCookie[0],splitCookie[1]);
					}.bind(this)
			)
		},
		getCookie: function(cookieName){
			return this._Cookies.get(cookieName);
		},
		setCookie: function(cookieName, cookieValue, cookieExpires) {
		    cookieExpires instanceof Date ? cookieExpires = cookieExpires.toGMTString() : typeof(cookieExpires) == 'number' && (cookieExpires = (new Date(+(new Date) + cookieExpires * 1e3)).toGMTString());
		    var r = [cookieName + "=" + escape(cookieValue), 'expires=' + cookieExpires];
		    return document.cookie = r.join(";"), true;
		}
	}

var Cookies = new _Cookies;
