/**
 * @author Johnny
 */
(function($){
		
	$.extend({
		queryStringToObject: function(qs){
			var params = {};
			var qs = qs || location.search.substring(1,location.search.length);
			if (!qs.length) return false;
			
			qs = qs.indexOf('?')!=-1?qs.split('?')[1]:qs;
			qs = qs.replace(/\+/g, ' ');
			var args = qs.split('&');
				
			for (var i = 0; i < args.length; i++) {
				var pair = args[i].split('=');
				var name = decodeURI(pair[0]);
				
				var value = (pair.length == 2) ? decodeURI(pair[1]) : name;
				
				params[name] = value;
			}
			return params;
		}
	});
	$.fn.formFieldValue = function(type){
		type=type || 'text';
			var el = this;
			switch(type.toLowerCase()){
				case 'ignore':
					return el.text();
					break;
				case 'text':
					return el.find('input').val();
					break;
				case 'hidden':
					return el.find('input').val();
					break;
				case 'boolean':
					return el[0].checked;
					break;
				case 'time':
					var inputs = el.find('input');	
					return inputs.eq(0).val() + ':' + inputs.eq(1).val() + ':' + inputs.eq(2).val();
					break;
				case 'date':
					var inputs = el.find('input');	
					return inputs.eq(0).val() + '-' + inputs.eq(1).val() + '-' + inputs.eq(2).val();
					break;
				case 'float':
					return el.find('input').val();
					break;
				default:
					return el.find('input').val();
					break;
			}
	};
	$.fn.fromFormField = function(type){
		type = type || 'text';
		var options = {};
		var cancel = false;
		if (typeof arguments[1] == 'boolean')
			cancel = arguments[1];
		if (typeof arguments[2] == 'boolean') {
			options = arguments[1];
			cancel = arguments[2];
		};
		
		options = $.extend({
			success:function(complete){
				complete();
			}
		},options);
		
		return this.each(function(){
			var el = $(this);
			var value;
			var oldValue;
			if(el.data('formField')){
				oldValue = el.data('formField').originalValue || '';
			}
			value = !!cancel?oldValue:el.formFieldValue(type);	
			var complete = function(){	
				el.data('formField').originalValue = value;
				el.text(value);
			};
			options.success.call(this,complete,value,oldValue,(oldValue === value));
		});

	};
	
	$.fn.toFormField = function(type,options){
		type = type || 'text';
		options = $.extend({
			label:false
		},options);
		var args = arguments;
		var ensureLength = function(str,length){
			str = str.toLocaleString();
			while(str.length < length){
				str = '0' + str;
			}
			return str;
		}

		
		return this.each(function(){
			var el = $(this);
			var value = el.text();
			el.data('formField',{type:type,originalValue:value});
			var css = {
				'border':'none',
				'font-size':el.css('font-size'),
				'font-family':el.css('font-family'),
				'color':el.css('color'),
				'background-color':el.css('background-color'),
				'text-align':el.css('text-align')
			};
			var elWidth = el.width();

			switch(type.toLowerCase()){
				case'ignore':
					
					break;
				case 'text':
					css = $.extend({'width':elWidth,'text-align':'center'},css)
					el.empty().append($('<input type="text" value="'+value+'" />').css(css));				
					break;
				case 'hidden':
					el.empty().append($('<input type="hidden" value="'+value+'" />'));				
					break;
				case 'boolean':
					switch(value.toLowerCase()){
						case 'yes':
							value=true;
							break;
						case 'no':
							value=false;
							break;
						default:
							break;
					}
					el.empty().append('<input type="checkbox" checked="'+!!value+'" />')
					break;
					case 'time':
						el.wrapInner('<span/>')
						value = value.split(':').reverse();
						css = $.extend(css,{'width':el.find('span').width()/value.length || '1.2em','text-align':'center'})
						el.empty().append($('<input type="text" maxlength="2" value="'+(value[2]||'00')+'" />:<input type="text" maxlength="2" value="'+(value[1]||'00')+'" />:<input type="text" maxlength="2" value="'+(value[0]||'00')+'"/>').css(css));
						break;
					case 'date':
						el.wrapInner('<span/>')
						var width=el.find('span').width();
						value = value.split('-').reverse();
						el.empty().append($('<input type="text" maxlength="4" value="'+(value[2]||'2000')+'" />-<input type="text" maxlength="2" value="'+(value[1]||'01')+'" />-<input type="text" maxlength="2" value="'+(value[0]||'01')+'"/>').css(css));
						el.find('input').each(function(i){
							var w = width/4 || '1.2em';
							w = !i ? (typeof w != 'string'?(w+w):'2.4em'):w;
							$(this).css({'width':w,'text-align':'center'});
						});
						break;
					case 'float':
						css = $.extend({'width':elWidth,'text-align':'center'},css)
						el.empty().append($('<input type="text" value="'+(value||'00.00')+'" />').css(css));	

					break;
			}
			if (options.label) {
				var label = $('<label for="'+options.label.id+'">'+options.label.text+'</label>');
				if(options.label.position='before') el.prepend(label);
				else el.append(label);
			}
		});
	};
	
	$.fn.oshWidgit = function(options){
		options = $.extend({
			widgitClose:function(){},
			widgitOpen:function(){}
		},options);
		return this.each(function(){
			var widgit = $(this).bind('widgitClose',options.widgitClose).bind('widgitOpen',options.widgitOpen);
			widgit.data('oshWidgit',{options:options});
			var data = widgit.data('oshWidgit');		
			widgit.resizable({
				transparent: true,
				handles: 'e,s,se',
				minWidth:184,
				minHeight:20,
				start:function(e,ui){
					widgit.find('.widgitContent').css({'overflow':'hidden','height':'auto'});
				},
				stop:function(e,ui){
					widgit.find('.widgitContent').css({'overflow':'auto','height':widgit.height()-22});
				},
				disabled:widgit.parent().is('.widgitColumn')
			})
			.draggable({
				cursor:'move',
				helper:'clone',
				handle:$(this).find('h3'),
				appendTo:'#content',
				zIndex:3000,
				opacity:.4,
				start:function(e,ui){
					$(ui.helper)
						.css({
							'height':$(this).height(),
							'width':$(this).width()
							})
					
						.find('.widgitContent')
							.css({'height':$(this).height()-22})
				}
			})
			.prepend($('<a class="widgitButton hide" href="#" title="hide"><img alt="hide" src="images/widgit-hide.png" /></a>')
				.hover(function(){
					$(this).find('img').attr('src','images/widgit-hide-over.png');
				},function(){
					$(this).find('img').attr('src','images/widgit-hide.png');
					}
				)
				.bind('click',function(e){
					e.preventDefault();
					$(this).parent().css('height','auto')
					$(this).parent().find('.widgitContent').slideFade('toggle',{});
				}))
				.prepend($('<a class="widgitButton close" href="#" title="close"><img alt="close" src="images/widgit-close.png" /></a>')
					.hover(function(){
						$(this).find('img').attr('src','images/widgit-close-over.png');
					},function(){
						$(this).find('img').attr('src','images/widgit-close.png');
						}
					)
					.bind('click',function(e){
						e.preventDefault();
						data.visible(false);
					})
				)
				.find('h3').css('cursor','move');
				

				
	
				
				$.extend(data, (function(){
					var _visible = true;
					var _minimized = false;
					return {
							visible:function(v,options){
								if (arguments.length != 0) {
									_visible = arguments[0];
									this.setVisibility(_visible,options);
									return;
								}
								return _visible;
							},
							setVisibility:function(state,options){
								if(!arguments.length) this.setVisibility(_visible);
								options = $.extend({
									speed:'normal',
									triggerEvent:true
								},options||{})
								if (!state){
									widgit.slideFade('hide', {
										duration:options.speed,
										complete:!!options.triggerEvent? function(){
											widgit.trigger('widgitClose', [widgit])
										}:function(){}
									});
								}
								else {
									widgit.slideFade('show', {
										duration:options.speed,
										complete: !!options.triggerEvent?function(){
											widgit.trigger('widgitOpen', [widgit]);
										}:function(){}
									});
								}
							},
							position:function(){
								return {
									container:widgit.parent(),
									index:widgit.parent().find('.widgit').index(widgit)
								}
							}
						}
					})()
				);

		});
	};
	
	$.fn.delegate = function(eventType, rules) {
		return this.bind(eventType, function(e) {
			var target = $(e.target);
			for(var selector in rules)
				if(target.is(selector)) 
			    	return rules[selector].apply(this, arguments)
		})
	};
	$.fn.editableRows = function(options){
		options = $.extend({
			multiRowEdit:false,
			addRowButton:true,
			rowSave:function(success,rowData){
				success();
			},
			rowAdd:function(success,rowData){
				success();
			},
			rowDelete:function(success,rowData){
				success();
			},
			rowCancel:function(){},
			rowEditMode:function(){},
			columns:false
		},options);
		
		var editCellHtml = '<td class="editRowCell">'+
			'<a href="#" title="edit this row of data" class="editRowButton">edit</a>'+
			'<a href="#" title="delete this row of data" class="deleteRowButton" style="margin-left:4px;">delete</a>'+
			'<a href="#" title="cancel editing this row" class="cancelEditRowButton" style="display:none;">cancel</a>'+
			'<a href="#" title="save changes this row" class="saveEditRowButton" style="margin-left:4px;display:none;">save</a>'+
			'</td>';
		
		
		
		this.delegate('click',{
			'a.editRowButton':function(e){
				editRow($(e.target).parent().parent());
				return false;
			},
			'a.cancelEditRowButton':function(e){
				cancelEditRow($(e.target).parent().parent());
				return false;
			},
			'a.saveEditRowButton':function(e){
				saveEditRow($(e.target).parent().parent());
				return false;
			},
			'a.addRowButton':function(e){
				var tbody = $(e.target).parent().parent().parent().parent().find('tbody');
				isOdd= tbody.find('tr').length%2?'odd':'';
				var ths = $(e.target).parent().parent().parent().parent().find('thead tr th').not('.editRowHeader');
				var row = $('<tr class="'+isOdd+' newRow inEditMode"></tr>').appendTo(tbody);
				var rowHtml = '';
				ths.each(function(){
					rowHtml += '<td></td>';
				});
				rowHtml += editCellHtml;
				row.append(rowHtml).data('editableRows',{originalValues:[]});;
				editRow(row);
				return false;
			},
			'a.deleteRowButton':function(e){
				var row = $(e.target).parent().parent();
				var success = function(){
					row.remove();
				};
				var values = {};
				row.find('td').not('.editRowCell').each(function(i){
					values[options.columns[i].name] = $(this).text();
				});
				options.rowDelete.call(row,success,values);
				return false;
			}
		});
		
		var editRow = function(row){
			if(!options.multiRowEdit) cancelEditRow(row.siblings('.inEditMode'));
			row.addClass('inEditMode');
			row.find('.editRowButton,.deleteRowButton').hide();
			row.find('.saveEditRowButton,.cancelEditRowButton').show();	
			var rowDataStore = row.data('editableRows');
			rowDataStore.originalValues = rowDataStore.originalValues || [];					
			row.find('td').not('.editRowCell').each(function(i){
				$(this).toFormField(options.columns[i].dataType ||'text');
			});
			options.rowEditMode.call(row);
		};
		
		var exitEditMode = function(row){
			row.removeClass('inEditMode');
			row.find('.editRowButton,.deleteRowButton').show();
			row.find('.saveEditRowButton,.cancelEditRowButton').hide();
		};
		
		var cancelEditRow = function(row){
			if(!row.length) return;
			if (row.hasClass('newRow')) {
				row.remove();
				return;
			};
			
			row.find('td').not('.editRowCell').each(function(i){
				var meta = options.columns[i] || null;
				$(this).fromFormField(meta.dataType||'text',false);
				
			});		
			exitEditMode(row);
		};
		

		
		var saveEditRow = function(row){
			var values = {};
				
			row.find('td').not('.editRowCell').each(function(i){
				values[options.columns[i].name] = $(this).formFieldValue(options.columns[i].dataType||'text');
			});
			var success = function(){
				row.find('td').not('.editRowCell').each(function(i){
					$(this).fromFormField(options.columns[i].dataType||'text');
				});
				row.removeClass('newRow');
				exitEditMode(row);
			};
			if(row.hasClass('newRow')) options.rowAdd.call(row,success,values);
			else options.rowSave.call(row,success,values);
			
		};
		

		if (this[0].nodeName.toLowerCase() != 'table') return;
		var table = this.eq(0);
		if (!options.columns){
			options.columns = [];
			table.find('thead tr th').each(function(){
				var th = $(this);
				options.columns.push({name:th.text(),displayName:th.text,dataType:'text'});
			});
		}
		table.find('colgroup').append('<col />');
		table.find('thead tr').append('<th class="editRowHeader"></th>');
		table.find('tfoot tr').append('<td>'+(options.addRowButton?'<a href="#" title="add a new item" class="addRowButton">new</a>':'')+'</td>')
		table.find('tbody tr').each(function(){
			$(this).data('editableRows',{originalValues:[]});
			$(this).append(editCellHtml);
		});
		return this;
	};
	$.fn.center = function(settings){	
		var settings = $.extend({
			x:true,
			y:true,
			centerTo:{x:window,	y:window},
			fixed:false
		},settings)
		
		var port =  $(settings.centerTo)
		var portY =  $(settings.centerTo.y).height();
		var portYScroll =   settings.fixed && (!$.browser.msie || $.browser.version>6)?0:$(settings.centerTo.y).scrollTop();
		var portYOffset = 0;// $(settings.centerTo.y).position().top;
		
		var portX = $(settings.centerTo.x).width();
		var portXScroll = settings.fixed?0:$(settings.centerTo.x).scrollLeft();
		var portXOffset = 0;//$(settings.centerTo.x).position().left || 0;
		
		this.css('position',settings.fixed && (!$.browser.msie || $.browser.version>6) ? 'fixed':'absolute');
		return this.each(function(){
			var el = $(this);
			if(settings.x) el.css('left',portX/2 -  el.width()/2 + portXScroll  + portXOffset);
			if(settings.y) el.css('top', portY/2  -  el.height()/2 + portYScroll + portYOffset);
	
	})
	
};
	$.fn.slideFade = function(showOrHide,options){
		var options;
		if(typeof(arguments[0])=='object'){
			options=arguments[0];
			options.showOrHide = 'toggle';
			
		}else{
			options=arguments[1] || {};
			options.showOrHide = arguments[0] || 'toggle';
		}
		
		var settings = $.extend(
			{
				duration:'normal',
				fade:true,
				slide:true,
				complete:function(){}
			},
		options);


		var toAnimate = {};
		if(settings.slide)toAnimate.height = settings.showOrHide;
		if(settings.fade)toAnimate.opacity = settings.showOrHide;
		
		return this.each(function(){
			var el = $(this);
			el.animate(toAnimate,{
				duration:settings.duration,
				complete:function(){
					if ($(this).is(':visible') && $.browser.msie){
						var st = $(this).attr('style');
						st = st.split(';')
						var out=[];
						
						$.each(st,function(){		
							if(this.search(/FILTER|ZOOM/)==-1){
								out.push(this);
							}
						});
						$(this).attr('style',out.join(';'))
					}		
					settings.complete.call(this);
				}
			});
		});
		
	};
})(jQuery)

var OldStarHotel = OldStarHotel||{};
/**
 * public static Cookie
 * A singleton that sets/gets/deletes HTTP cookies
 * @example 
 * 	ATSReports.Cookie.setValue('foo','bar'); //sets the cookie value 'foo' to 'bar'
 * 	ATSReports.Cookie.getValue('foo'); //returns 'bar'
 */
OldStarHotel.Cookie = (function(){
	/**
	 * public static string getValue(string name);
	 * @param {String} name
	 */
	var _getValue=function(name){
		var start = document.cookie.indexOf( name + "=" );
		var len = start + name.length + 1;
		if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
			return null;
		}
		if ( start == -1 ) return null;
		var end = document.cookie.indexOf( ';', len );
		if ( end == -1 ) end = document.cookie.length;
		return unescape( document.cookie.substring( len, end ) );
	};
	/**
	 * public static void setValue(string name,string value [[[[,date expires],string path],string domain],boolean secure])
	 * @param {String} name
	 * @param {String} value
	 * @param {Date} expires
	 * @param {String} path
	 * @param {String} domain
	 * @param {Boolean} secure
	 */
	var _setValue=function(name,value,expires,path,domain,secure){
		var today = new Date();
		today.setTime( today.getTime() );
		if ( expires ) {
			expires = expires * 1000 * 60 * 60 * 24;
		}
		var expires_date = new Date( today.getTime() + (expires) );
		document.cookie = name+'='+escape( value ) +
			( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString()
			( ( path ) ? ';path=' + path : '' ) +
			( ( domain ) ? ';domain=' + domain : '' ) +
			( ( secure ) ? ';secure' : '' );
	};
	/**
	 * pulic static void deleteValue(string name[[,string path],string domain])
	 * @param {String} name
	 * @param {String} path
	 * @param {String} domain
	 */
	var _deleteValue=function(name,path,domain){
		if ( _getValue( name ) ) document.cookie = name + '=' +
		( ( path ) ? ';path=' + path : '') +
		( ( domain ) ? ';domain=' + domain : '' ) +
		';expires=Thu, 01-Jan-1970 00:00:01 GMT';
	};
	return {
		getValue:_getValue,
		setValue:_setValue,
		deleteValue:_deleteValue
	};	
})();

/**
 * An object that can store key/value pairs in a single HTTP cookie
 * Accepts strings as keys and JavaScript objects as values.
 * @param {Object} name The name of the cookie
 * @param {Object} options
 * @option {Date} expires The exiration date of the cookie
 * 	Defaults to the current session.
 * @option {String} path 
 * @option {String} domain
 * @option {Boolean} secure
 * @constructor
 * @example
 * 	var myCookie = new ATSReports.CookieObject('myCookie');
 * 	myCookie.setValue('foo','bar'); //sets the key/value pair
 * 	myCookie.setValue('anArray',['this','is','an','array',{
 * 		'with':'anObject!'} ]; //sets another key/value pair
 * 	myCookie.getValue('foo'); //returns 'foo';
 *  myCookie.getValue('anArray'); //returns an Array
 */
OldStarHotel.CookieObject = function(name,options){
	this.name = name;
	this.settings=OldStarHotel.Utilities.combineObj({
		autoSave:true,
		expires:false,
		path:false,
		domain:false,
		secure:false
	},options);
	this.load();
};
OldStarHotel.CookieObject.prototype = {
	/**
	 * Loads the cookie into the object

	 */
	load:function(){
		this.obj = OldStarHotel.Utilities.deserialize(
			OldStarHotel.Cookie.getValue(this.name)) || {};
	},
	/**
	 * Saves the object into the cookie
	 */
	save:function(){
		var cookiestr = OldStarHotel.Utilities.serialize(this.obj);
		if(cookiestr.length > 4096) return false;
		//OldStarHotel.Cookie.deleteValue(this.name,this.settings.path,this.settings.domain);
		OldStarHotel.Cookie.setValue(
			this.name,
			cookiestr,
			this.settings.expires,
			this.settings.path,
			this.settings.domain,
			this.settings.secure
		);
	},
	/**
	 * Adds a key/value pair to the cookie object
	 * @param {String} key
	 * @param {Object} value
	 */
	setValue:function(key,value){
		this.obj[key] = value;
		if(this.settings.autoSave) this.save();
	},
	/**
	 * Retrieves a value from the cookie object
	 * @param {String} key
	 */
	getValue:function(key){
		return this.obj[key];
	},
	/**
	 * Deletes a value from the cookie object
	 * @param {String} key
	 */
	deleteValue:function(key){
		delete this.obj[key];
		if(this.settings.autoSave) this.save();
	}
	
};


OldStarHotel.Utilities = (function(){
	//private
	var _specialChars = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
	var _replaceChars = function(chr){
		return _specialChars[chr] ||
		 '\\u00' + Math.floor(chr.charCodeAt() / 16).toString(16) + (chr.charCodeAt() % 16).toString(16);		
	};

	/**
	 * public object combineObj([boolean deep,] object target, object options)
	 * Merges the second object into the first, overwriting any shared members.
	 * @param {Boolean} deep Causes any member object to be recursively merged
	 * @param {Object} target
	 * @param {Object} options
	 * @returns {Object} The merged object
	 */
	var _combineObj = function(deep,target,options) {
		var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
		if ( _getType(target) == 'boolean' ) {
			deep = target;
			target = arguments[1] || {};
			// skip the boolean and the target
			i = 2;
		}
		if ( typeof target != "object" && typeof target != "function" )
			target = {};
	
		for (; i < length; i++) 
			if ((options = arguments[i]) != null) {
				for (var name in options) {
					// Prevent never-ending loop
					if (target === options[name]) 
						continue;
					if (deep && options[name] && typeof options[name] == "object" && target[name] && !options[name].nodeType) 
						target[name] = _combineObj(target[name], options[name]);
					else 
						if (options[name] != undefined) 
							target[name] = options[name];
					
				}
			}
		return target;
	};	
	
	/**
	 * public string getType(object obj)
	 * And extened versin of JavaScript's typeof operator
	 * Includes the types 'array,''arguments,''element,'textnode','whitespace'
	 * Gets the type of object
	 * @param {Object} obj The object to test
	 * @returns {String} The object's type
	 */
	var _getType = function(obj){
		if (obj == undefined) return false;
		if(obj.nodeName){
			switch (obj.nodeType){
				case 1: return 'element';
				case 8: return 'comment';
				case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
			}	
		}else if (typeof obj.length == 'number'){
			if (obj.callee) return 'arguments';
			else if (obj.item) return 'collection';
		}
		switch(typeof obj){
			case 'object':
				if (obj.constructor == Array) {
					return 'array';
				}		
			default:
				return typeof obj;
		}
	};
	
	/**
	 * public boolean isDefined(object obj)
	 * @param {Object} obj
	 * @returns {Boolean}
	 */
	var _isDefined = function(obj){
		return obj!=undefined;
	};
	
	/**
	 * public string serialize(object obj)
	 * Serializes a JavaScript object into a string. Does not include undefined values or DOM objects.
	 * @param {Object} obj The object to serialize
	 * @returns{String} The serialized object as a string
	 */
	var _serialize = function(obj){	
		switch(_getType(obj)){
			case 'string':
				return '"' + obj.replace(/[\x00-\x1f\\"]/g, _replaceChars) + '"';;
			case 'array':
				var len = obj.length;
				var res = new Array();
				for (var i = 0; i < len; i++){
					if (i in obj){
						var str = _serialize.call(this, obj[i]);
			      		if(_isDefined(str))	
							res.push (str);
					}  
			    }
				return '[' + String(res) + ']';
			case 'number': case 'boolean': 
				return String(obj);	
			case 'object':
				var string = [];
				for(var prop in obj){
					var val = _serialize(obj[prop]);
					if(val) string.push(_serialize(prop) + ':' + val);
				}
				return '{' + String(string) + '}';
			case false: 
				return 'null';
		}
		return null;
	};
	
	/**
	 * public object deserialize(sring string [,boolean secure]);
	 * Evaluates a serialized JavaScript object
	 * @param {String} string The string to evaluate
	 * @param {Boolean} secure Checks the string against a regular expression if true
	 * @returns {Object} The evaluated object
	 */
	var _deserialize = function(string,secure){
		if (_getType(string) != 'string' || !string.length) return null;
		if (secure && !(/^[\],:{}\s]*$/.test(string.replace(/\\["\\\/bfnrtu]/g, '@').
                    replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
                    replace(/(?:^|:|,)(?:\s*\[)+/g, '')))) return null;
		
		
		return eval('(' + string + ')');
	};
	return {
		serialize:_serialize,
		deserialize:_deserialize,
		getType:_getType,
		isDefined:_isDefined,
		combineObj:_combineObj
	};
	
})();

OldStarHotel.Color = (function(){
	
	function d2h(d) {return d.toString(16);}
	function h2d(h) {return parseInt(h,16);} 
	function ensureLength(str,length){
		str = str.toLocaleString();
		while(str.length < length){
			str = '0' + str;
		}
		return str;
	}
	
	return {
		hexToRgb:function(hex){
			hex = hex.replace('#','');
			if (hex.length == 3) hex+=hex;
			if(hex.length!=6) return false;
			
			var r = h2d(hex[0].toString()+hex[1].toString());
			var g = h2d(hex[2].toString()+hex[3].toString());
			var b = h2d(hex[4].toString()+hex[5].toString());
			return [r,g,b];
		},
		rgbToHex:function(array){
			if (typeof array== 'string') array = array.match(/\d{1,3}/g);
			return '#'+ensureLength(d2h(array[0]),2) + ensureLength(d2h(array[1]),2) + ensureLength(d2h(array[2]),2);
		},
		saturation:function(color,amount){
			if(typeof color == 'string') color=this.hexToRgb(color);
			var result = [];
			for(var i=0;i<color.length;i++){
				var part = color[i];
				result[i] = Math.round(part*amount);
				if(result[i]>255) return saturation(color,255/color[i]);				
			}
			return result;
		}
	}
	
})();

Date.prototype.DAYNAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",  "Friday", "Saturday"];
Date.prototype.MONTHNAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

Date.prototype.getFullDay = function() {
  return this.DAYNAMES[this.getDay()];
};
Date.prototype.getDayAbbr = function() {
  return this.getFullDay().slice(0, 3);
};

Date.prototype.getFullMonth = function() {
  return this.MONTHNAMES[this.getMonth()];
};
Date.prototype.getMonthAbbr = function() {
  return this.getFullMonth().slice(0, 3);
};
Date.prototype.toUTC = function(){
	return (Date.UTC(this.getFullYear(),this.getMonth(),this.getDate(),this.getHours(),this.getMinutes(),this.getSeconds()))/1000;
};

Date.fromMySQL = function(timestamp){
	if(timestamp.search(' ')==-1)timestamp += ' 00:00:00'
	var regex=/^([0-9]{2,4})-([0-1][0-9])-([0-3][0-9]) (?:([0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/;
	var parts=timestamp.replace(regex,"$1 $2 $3 $4 $5 $6").split(' ');
	return new Date(parts[0],parts[1]-1,parts[2],parts[3],parts[4],parts[5]);
	
};

OldStarHotel.QueryInputControl = function(view,inputs){
	this.view = view;
	this.inputs = inputs || [];
};
OldStarHotel.QueryInputControl.prototype = {
	runControl:function(){
		var params = {};
		for(var i =0;i<this.inputs.length;i++){
			params[this.view.options.parameters[i].name] = this.inputs[i].formFieldValue(this.view.options.parameters[i].dataType);
		}
		this.view.query(params);
	},
	buildControl:function(){
		var that = this;
		var view = this.view;
		var runControl = this.runControl;
		if(!view.options.parameters.length) return;
		var form = $('<form action="cycling" method="get" name="'+this.view.queryName+'"></form>').bind('submit',function(e){
			e.preventDefault();
			runControl.call(that);
			
		});
		$.each(this.view.options.parameters,function(){
			that.inputs.push(
				$('<div class="queryInputControl"></div>').appendTo(form).toFormField(this.dataType,{
					label:{position:'before',id:this.name+'_control',text:this.displayName || this.name}
				})
			);
		});
		$('<input type="submit" />').appendTo(form);
		return form;
	}
};

OldStarHotel.ViewList = function(el,options){
	this.views = [];
	this.el = $(el);
	this.options = $.extend({
		buildInputControl:true
	},options)
};

OldStarHotel.ViewList.prototype = {
	addView:function(view){
		var inputControl = this.options.buildInputControl?new OldStarHotel.QueryInputControl(view):null;
		this.views.push(view);
		$('<li></li>')
		.append(
			$('<a>'+view.name +'</a>').click(function(){
				view.query();
				return false;
			})
		)
		.append(inputControl.buildControl())
		.appendTo(this.el);
		return this;
	}
	
};

OldStarHotel.View = function(name,queryName,options){
	this.name = name;
	this.queryName = queryName;
	this.currentDataSet = [];
	this.options = $.extend({
		buildTable:true,
		type:'GET',
		table:$('<table></table>'),
		viewFields:[{name:'id',displayName:'ID'}],
		parameters:[],
		success:function(){},
		headerRow:true,
		footerRow:false,
		url:'#',
		dataPath:'',
		editable:false,
		methods: {
			retrieveMethod:false,
			updateMethod: false,
			insertMethod: false,
			deleteMethod: false
		}
	},options);
};
OldStarHotel.View.prototype = {
	query:function(params){
		var that = this;
		$.ajax({
			url:this.options.url,
			data:$.extend({method:this.queryName},params),
			type:this.options.type,
			dataType:'json',
			success:function(data){
				that.options.success.call(that,data);
				that.currentDataSet = data;
				if (that.options.buildTable) that.fillTable(data,params);
			}
		});
		return this;	
	},
	updateRow:function(params){
		if(!this.options.methods.updateMethod) return this;
		else method = this.options.methods.updateMethod;
		$.ajax({
			url:this.options.url,
			data:$.extend({method:method},params),
			type:'POST',
			dataType:'json',
			success:function(data){

			}
		});
	},
	insertRow:function(params){
		if(!this.options.methods.insertMethod) return this;
		else method = this.options.methods.insertMethod;
		$.ajax({
			url:this.options.url,
			data:$.extend({method:method},params),
			type:'POST',
			dataType:'json',
			success:function(data){

			}
		});
	},
	deleteRow:function(params){
		if(!this.options.methods.deleteMethod) return this;
		else method = this.options.methods.deleteMethod;
		$.ajax({
			url:this.options.url,
			data:$.extend({method:method},params),
			type:'POST',
			dataType:'json',
			success:function(data){

			}
		});
	},
	
	fillTable:function(data,params){
		var that = this;
		var data = data || this.currentDataSet;
		var entities = data;
		var editableRowsFormatting = {};
		
		var path = this.options.dataPath.split('.');
		$.each(path,function(){			
			entities = entities[this];
		});
		var table = this.options.table.empty();
		var theadHtml = '<thead><tr>';
		var tcolHtml = '<colgroup>';
		$.each(this.options.viewFields,function(i){
			theadHtml+= '<th  class="'+ (this.dataType ||'string') + '-headercell' +'" >' + (this.displayName || this.name) +  '</th>';
			var align = '';
			align = this.dataType.match(/(int)|(float)/)?' align="right"':'';
			tcolHtml+= '<col'+align+' class="'+ (this.dataType ||'string') + '-column' +'"  />';
		});	
		theadHtml+= '</tr></thead>';
		tcolHtml+= '</colgroup>';
		table.append(tcolHtml);
		var thead = $(theadHtml).appendTo(table);		
		var tfoot = $('<tfoot><tr></tr></tfoot>').appendTo(table);
		var tbody = $('<tbody></tbody>').appendTo(table);
		
		
		$.each(entities,function(i,entity){									
			if (i == entities.length - 1) {
				var tfootrow = tfoot.find('tr');
				$.each(that.options.viewFields, function(i, viewField){
					tfootrow.append('<td  class="'+ (viewField.dataType ||'string') + '-footercell' +'"  >' + entity[viewField.name] + '</td>');
				});
				return;
			}
			
			trClass= (!(i%2))?'even':'odd'
			var row = $('<tr class="'+trClass+'"></tr>').appendTo(table);
			$.each(that.options.viewFields, function(i, viewField){
				var value = entity[viewField.name];
				if(viewField.dataType == 'float' && !(value*10%1)) {
					oldValue = value.toString().split('.');
					value = oldValue[0] + '.';
					if(!oldValue[1])oldValue[1] = '0';
					value+= oldValue[1] + '0'
					//value = (value.toString().split('.')[0]) + (value.toString().split('.')[1]||'.0')+ '0'
				}
				row.append('<td  class="'+ (viewField.dataType ||'string') + '-cell' +'"  >' + value + '</td>');
			});
		});
		
		if(this.options.editable){
			table.editableRows({
				columns:this.options.viewFields,
				rowAdd:function(success, rowData){
					that.insertRow(rowData);
					success();
				},
				rowDelete:function(success,rowData){
					that.deleteRow(rowData);
					success();
				},
				rowSave:function(success,rowData){
					that.updateRow(rowData);
					success();
				}
			});
		}
	}
};
			
