var menu;

$(function() {
	function Menu() {
		this.init();
	}
	
	Menu.prototype = {
		settings: {
			root: 'https://www.snowywilderness.com.au/',
			remotePath: 'cfc/menu.cfc?method=ajaxMenu',
			imagePath: 'assets/images/menu/large/',
			printSheetPath: 'assets/css/printmenu.css',
			scrollDistance: 5,
			title: 'Snowy Wilderness - Fine Dining Menu'
		},
		
		scrolling: null,
		
		init: function() {
			this.construct();
		},
		
		construct: function() {
			this.menu = $('<div class="menu"><div class="wrap"><span class="tb"><a href="javascript:;" class="c" title="Close Menu">Close</a><a href="javascript:;" class="p" title="Print Menu">Print</a></span><h1 class="title">' + this.settings.title + '</h1><div><a href="javascript:;" class="up">Up</a> <a href="javascript:;" class="down">Down</a></div><div class="content"><div class="inner"></div></div></div></div>');
			this.menu.appendTo(document.body);			
			this.content = this.menu.find('div.content');
			this.content.addClass('loading');			
			this.inner = this.content.find('div.inner');			
			this.overlay = $('<div id="overlay"></div>');
			this.overlay.appendTo(document.body);			
			
			this.hide();
			this.handlePrint();				
			this.center();
			this.bind();
			this.populate();
		},
		
		bind: function() {
			var self = this;
			
			$(window).bind(
				'resize',
				function() {
					self.center.call(self);
				}
			);
			
			this.overlay.bind(
				'click',
				function() {
					self.close.call(self);	
				}
			);
			
			this.menu.find('a.up').bind(
				'mouseover',
				function() {
					self.scrollUp.call(self);
				}
			).bind(
				'mouseout',
				function() {
					self.scrollOut.call(self);	
				}
			);
			this.menu.find('a.down').bind(
				'mouseover',
				function() {
					self.scrollDown.call(self);
				}
			).bind(
				'mouseout',
				function() {
					self.scrollOut.call(self);	
				}
			);		
			
			this.menu.find('span.tb a.c').bind(
				'click',
				function() {
					self.close.call(self);
				}
			);
			this.menu.find('span.tb a.p').bind(
				'click',
				function() {
					self.print.call(self);
				}
			);			
		},
		
		populate: function() {
			var self = this;
			
			$.ajax(
				{
					url: this.settings.remotePath,
					type: 'GET',
					dataType: 'json',
					cache: false,
					success: function(json) { 
						setTimeout(function() { self.insert(json); }, 1000);
					}
				}
			);
		},
		
		insert: function(json) {
			var self = this;
			
			this.content.removeClass('loading');
			
			$.each(json,
				function(i, n) {
					self.addItem(i, n);
				}
			);
		},
		
		addItem: function(index, data) {
			this.inner.append('<div class="item"><h1 class="c">' + data.name + '</h1>' + (data.image.length ? '<img src="' + this.settings.imagePath + data.image + '" />' : '') + '<div class="c">' + data.text + '</div></div>');
		},
		
		getSize: function() {
			return [this.menu.width(), this.menu.height()];
		},		
		
		moveTo: function(x, y) {
			this.moveToX(x).moveToY(y);
		},
		
		moveToX: function(x) {
			if (typeof x == 'number') this.menu.css({ left: x });
			else this.centerX();
		},
		
		moveToY: function(y) {
			if (typeof y == 'number') this.menu.css({top: y});
			else this.centerY();
		},
		
		centerAt: function(x, y) {
			var s = this.getSize();

			if (typeof x == 'number') this.moveToX(x - s[0] / 2);
			if (typeof y == 'number') this.moveToY(y - s[1] / 2);
		},
		
		centerAtX: function(x) {
			this.centerAt(x, null);
		},
		
		centerAtY: function(y) {
			this.centerAt(null, y);
		},
		
		center: function(axis) {
			var o = $.browser.msie ?
					[document.documentElement.scrollLeft, document.documentElement.scrollTop] :
					[window.pageXOffset, window.pageYOffset];
			var s = [$(window).width(), $(window).height()];
			
			if (!axis || axis == 'x') this.centerAt(o[0] + s[0] / 2, null);
			if (!axis || axis == 'y') this.centerAt(null, o[1] + s[1] / 2);
		},
		
		centerX: function() {
			this.center('x');
		},
		
		centerY: function() {
			this.center('y');
		},	
		
		scrollUp: function() {
			this.scroll('up');			
		},
		
		scrollDown: function() {
			this.scroll('down');
		},
		
		scrollOut: function() {
			this.scroll('out');
		},		
		
		scroll: function(dir) {
			var self = this;
			var a = arguments;
			var top = parseInt(this.inner.css('top'), 10);
			var height =  parseInt(this.inner.height(), 10);
			var contentHeight =  parseInt(this.content.height(), 10);			
			var s = function() { self.scroll.apply(self, a); };
			
			switch (dir) {
				case 'up': {
					if (top < 0) {
						this.inner.css('top', top + this.settings.scrollDistance); 
					}
					
					this.scrolling = setTimeout(s, 1);
					break;					
				}
				case 'down': {
					if (Math.max(0, height - contentHeight) > Math.abs(top)) {
						this.inner.css('top', top - this.settings.scrollDistance); 
					}
					
					this.scrolling = setTimeout(s, 1);
					break;
				}	
				case 'out': {
					clearTimeout(this.scrolling);
					break;	
				}
			}
		},		
		
		hide: function() {
			this.menu.hide();	
			this.overlay.hide();
			
			this.handlePrint();				
		},
		
		show: function() {			
			this.center();
			
			this.menu.show();
			this.overlay.show();			
			
			this.handlePrint();				
		},
		
		close: function() {
			this.hide();	
		},
		
		remove: function() {
			this.menu.remove();	
		},
		
		handlePrint: function() {
			if (!this.printStyle) {
				this.printStyle = $('<link type="text/css" rel="stylesheet" media="print" href="' + this.settings.root + this.settings.printSheetPath + '" />');
				this.printStyle.appendTo('head');
			} else if (!this.menu.is(':visible')) {
				this.printStyle.remove();
				this.printStyle = null;
			}
		},
		
		print: function() {
			window.print();	
		}
	};
	
	menu = new Menu();
});