RiverbendMap2 = Class.create(Papercut.Base, {
	mapImage: ''
	,contentContainer: ''
	,mapContainer: ''
	,mapContent: ''
	,controlsContainer: ''
	,calendarContainer: ''
	,itineraryContainer: ''
	,messageContainer: ''
	,ratio: 1
	,startDate:{}
	,endDate:{}
	,width:960
	,height:500
	,animating: false
	
	,init: function(){
		this.initItems();
		this.initMessageBox();
		this.loadMap();
		this.initKeys();
		this.initTools();
		this.initControls();
		this.initLocations();
		this.initItinerary();
		this.initDetailsWindow();
		Ext.QuickTips.init();
		
	}
	,initItems: function(){
		this.contentContainer = Ext.get(this.contentContainer);
		this.mapContainer = Ext.get(this.mapContainer);
		this.mapContent = Ext.get(this.mapContent);
		this.controlsContainer = Ext.get(this.controlsContainer);
		this.mapContainer = Ext.get(this.mapContainer);
		this.itineraryContainer = Ext.get(this.itineraryContainer);
		this.messageContainer = Ext.get(this.messageContainer);
	}
	,loadMap: function(){
		//Show loading message
		this.showMessage('Loading...');
		
		//Create the map panel
		this.mapPanel = new Ext.Panel({
			contentEl: this.mapContent,
			width: this.width,
			height: this.height,
			disabled: true
		});
		
		//Create the map
		this.mapImage = Ext.get(Ext.DomHelper.append(this.mapContainer, {
			tag: "img",
			src: this.mapImage + '?' + new Date().getTime(),
			style:{
				display: 'none'
			}
		}));
		this.mapImage.on('load', function(){
			this.mapImage.fadeIn({
				callback: function(){
					this.mapPanel.enable();
					this.initMap();
				}.createDelegate(this)
			});
			this.messageBox.fadeOut();
			this.hideMessage();
		}, this);
	}
	,initMessageBox: function(){
		this.messageBox = Ext.get(Ext.DomHelper.append(this.contentContainer, {
			tag:'div',
			html: '<img src="/js/ext/resources/icons/loading.gif" align="top" /> Loading...',
			'class': 'map-message-box'
		}));
		this.messageBox.center(this.contentContainer);
	}
	,initKeys: function(){
		this.keyMap = new Ext.KeyMap(document, [{
			scope: this,
		    key: 37,
		    fn: function(key, event){
		    	this.moveLeft();
		    	event.preventDefault();
		    }
		},{
			scope: this,
		    key: 39,
		    fn: function(key, event){
		    	this.moveRight();
		    	event.preventDefault();
		    }
		},{
			scope: this,
		    key: 38,
		    fn: function(key, event){
		    	this.moveUp();
		    	event.preventDefault();
		    }
		},{
			scope: this,
		    key: 40,
		    fn: function(key, event){
		    	this.moveDown();
		    	event.preventDefault();
		    }
		}]);
		this.keyMap.disable();
		
		this.mapContainer.on('mouseover', function(){
			this.keyMap.enable();
		}, this);
		
		this.mapContainer.on('mouseout', function(){
			this.keyMap.disable();
		}, this);
	}
	,initMap: function(){		
		//create the map drag
		this.mapDrag = new Ext.dd.DD(this.mapContainer);
		this.mapDrag.scroll = false;
		this.mapDrag.onMouseDown = function(){
			this.mapContainer.addClass('grabbing');
			this.mapContainer.removeClass('grab');
		}.createDelegate(this);
		this.mapDrag.onMouseUp = function(){
			this.mapContainer.addClass('grab');
			this.mapContainer.removeClass('grabbing');
		}.createDelegate(this);
		this.mapDrag.endDrag = function(){
			this.updateMap();
		}.createDelegate(this);
		//Hide the window when dragging
		this.mapDrag.onDrag = function(){
			this.detailsWindow.hide(null)
		}.createDelegate(this);
		
		var mapBox = this.mapImage.getBox();
		
		//Set the map container to the width and height of the map image
		this.mapContainer.setWidth(mapBox.width);
		this.mapContainer.setHeight(mapBox.height);
		this.updateMap();
		
		//Lisetner for browser resize
		Ext.EventManager.onWindowResize(this.updateMap, this);
		
	}
	,initControls: function(){
		//Create the location item
		this.controls = Ext.get(Ext.DomHelper.append(this.contentContainer, {
			tag: "div",
			'class': 'controls'
		}));
		
		this.leftControl = Ext.get(Ext.DomHelper.append(this.controls, {
			tag: "div",
			'class': 'left-control'
		}));
		this.rightControl = Ext.get(Ext.DomHelper.append(this.controls, {
			tag: "div",
			'class': 'right-control'
		}));
		this.upControl = Ext.get(Ext.DomHelper.append(this.controls, {
			tag: "div",
			'class': 'up-control'
		}));
		this.downControl = Ext.get(Ext.DomHelper.append(this.controls, {
			tag: "div",
			'class': 'down-control'
		}));
		
		
		
		this.leftControl.on('click', this.moveLeft, this);
		this.rightControl.on('click', this.moveRight, this);
		this.upControl.on('click', this.moveUp, this);
		this.downControl.on('click', this.moveDown, this);
	}
	,moveRight: function(){
		var t = this;
		var amount = 300;
		var max = this.mapDrag.maxLeft;
		if(amount > max){
			amount = max;
		}

		//Animate
		if(!this.animating){
			this.animating = true;
			this.mapContainer.animate(
			    { left: { by: -amount } },
			    0.5,
			    function(){
			    	t.animating = false;
			    	t.updateMap();
			    },
			    'easeBoth',
			    'motion'
			);
		}
	}
	,moveLeft: function(){
		var t = this;
		var amount = 300;
		var max = this.mapDrag.maxRight;
		if(amount > max){
			amount = max;
		}
		
		//Animate
		if(!this.animating){
			this.animating = true;
			this.mapContainer.animate(
			    { left: { by: amount } },
			    0.5,
			    function(){
			    	t.animating = false;
			    	t.updateMap();
			    },
			    'easeBoth',
			    'motion'
			);
		}
	}
	,moveUp: function(){
		var t = this;
		var amount = 300;
		var max = this.mapDrag.maxDown;
		if(amount > max){
			amount = max;
		}
		
		//Animate
		if(!this.animating){
			this.animating = true;
			this.mapContainer.animate(
			    { top: { by: amount } },
			    0.5,
			    function(){
			    	t.animating = false;
			    	t.updateMap();
			    },
			    'easeBoth',
			    'motion'
			);
		}
	}
	,moveDown: function(){
		var t = this;
		var amount = 300;
		var max = this.mapDrag.maxUp;
		if(amount > max){
			amount = max;
		}
		
		//Animate
		if(!this.animating){
			this.animating = true;
			this.mapContainer.animate(
			    { top: { by: -amount } },
			    0.5,
			    function(){
			    	t.animating = false;
			    	t.updateMap();
			    },
			    'easeBoth',
			    'motion'
			);
		}
	}
	,initLocations: function(){
		this.locationStore = new Ext.data.JsonStore({
		    autoDestroy: true,
		    url: '/ajax/locations/public/get/',
		    root: 'locations',
		    fields: ['locationId', 'title', 'description', 'mapX', 'mapY', 'mapWidth', 'mapHeight']
		});
		this.locationStore.on('load', this.createLocations, this);
		this.locationStore.load();
	}
	,initItinerary: function(){
		this.itineraryStore = new Ext.data.JsonStore({
	        url: '/ajax/performance/public/view-itinerary/',
	        root: 'performances',
	        fields: ['performanceId', 'locationId', 'date', 'html']
	    });
	    
	    this.itineraryStore.on('load', this.createItineraryToolbar, this);
	    
	}
	,initDetailsWindow: function(){
		this.performanceStore = new Ext.data.JsonStore({
	        url: '/ajax/performance/public/performances/',
	        root: 'performances',
	        fields: ['performanceId', 'locationId', 'title', 'date', 'html']
	    });
	    
	    
	    var tpl = new Ext.XTemplate(
			'<tpl for=".">',
	            '{html}',
	        '</tpl><div class="clear"></div>'
		);
		
		this.performanceView = new Ext.DataView({
            store: this.performanceStore,
            tpl: tpl,
            singleSelect: false,
			multiSelect: false,
            overClass:'performance-item-over',
            itemSelector:'div.performance-item',
            loadingText: 'Loading...',
            emptyText: '<div style="padding:10px; font-style:italic;">No performances to display...</div>',
            refresh: function(){
				this.performanceView.constructor.prototype.refresh.call(this.performanceView, arguments);
				if(this.detailsWindow != null && this.detailsWindow.isVisible()){
					this.dateSelected();
				}
            }.createDelegate(this),
            listeners: {
            	scope:this,
            	mouseenter: this.onPerformanceOver,
            	mouseleave: this.onPerformanceOut
            }
		});
		
		this.performanceStore.on('load', this.createPerformanceToolbar, this);
		
		this.performancePanel = new Ext.Panel({
			cls: 'performance-panel',
			autoScroll: true,
			items:this.performanceView
		});
		
		if(Ext.isIE6 || Ext.isIE7){
			this.performancePanel.layout = 'fit';
		}
		
		var unstyled = true;
		var cls = 'details-window'
		if(Ext.isIE6 || Ext.isIE7){
			unstyled = false;
			cls = '';
			
		}
		
		this.detailsWindow = new Ext.Window({
			scope:this,
			title: 'Details Window',
			layout:'fit',
			cls: cls,
			unstyled: unstyled,
			renderTo: this.contentContainer,
			shadow: false,
			width:this.width - 100,
			height:this.height - 100,
			items:[this.performancePanel],
			closeAction:'hide',
			resizable: false,
			//collapsible: true,
			draggable: false,
			tbar: new Ext.Toolbar(),
			listeners:{
				scope: this,
				show: function(win){
					if(this.performanceView.getStore() == this.performanceStore){
						this.dateSelected();
					}
				}
			}
		});
		
		this.detailsWindow.show();
		this.detailsWindow.hide();
	}
	,initTools: function(){
		
		//Create the date selection
		//new Date(year, month, day, hours, minutes, seconds, milliseconds)
		this.dateMenu = new Ext.form.DateField({
			scope: this,
			renderTo: this.calendarContainer,
			width:180,
			value: new Date(this.startDate.year, this.startDate.month, this.startDate.day),
			minValue: new Date(this.startDate.year, this.startDate.month, this.startDate.day),
			maxValue: new Date(this.endDate.year, this.endDate.month, this.endDate.day),
			cls: 'map-control',
			showToday: false,
			listeners: {
				scope: this,
				select : function(picker, date){
					this.dateSelected();
				}
			}
		});
		
		
		//View Itinerary
		this.itineraryContainer.on('click', function(){
			//Set the title
			this.detailsWindow.setTitle('My Itinerary');
			
			//Flir
			FLIR.replace( '.details-window .x-plain-header-text' , new FLIRStyle({ cFont:'gunplay' }) );
			
			//Set the store
			this.performanceView.bindStore(this.itineraryStore);
			this.itineraryStore.load();
			
			//Add the toolbar
			this.detailsWindow.getTopToolbar().removeAll(true);
			this.detailsWindow.getTopToolbar().add(new Ext.Button({
				text:'Print',
				icon:'/js/ext/resources/icons/print_16.png',
				handler: function(){
					window.open('/pages/print/action/map/type/preview/','print','width=900,height=600,scrollbars=yes')
				}
			}));
			this.detailsWindow.getTopToolbar().add(new Ext.Button({
				scope: this,
				text:'Clear',
				icon:'/js/ext/resources/icons/trash_16.png',
				handler:function(button, e){
					Ext.Msg.show({
		        		scope: this,
					   	title:'Confirm Clear',
					   	msg: 'Are you sure you want to clear your itinerary?',
					   	buttons: Ext.Msg.YESNOCANCEL,
					   	animEl: 'elId',
					   	fn: function(id){
					   		if(id == "yes"){
					   			Ext.Ajax.request({
									scope: this,
									url: '/ajax/performance/public/clear-itinerary/',
									params: { },
									success: function(r){
										this.itineraryStore.load();
									}
								});
					   		}
					   }
					});						
				}
			}));
			this.detailsWindow.getTopToolbar().show();
			
			if(!this.detailsWindow.isVisible()){
				this.detailsWindow.show(this.itineraryContainer);
			}
			this.detailsWindow.doLayout();
			
		}, this);
		
		/*
		this.topToolbar = new Ext.Toolbar({
			scope: this,
			renderTo: this.toolbarContainer,
			items: [this.dateMenu, this.itineraryButton]
		})
		*/
		
		//FF fix
		Ext.override(Ext.form.DateField, {
		    onMenuHide: function() {
		        this.focus();
		        this.focus(false, 60);
		        this.menuEvents('un');
		    }
		});
		
	}
	,createLocations: function(){
		this.locationStore.each(function(record){
			
			//Create the location item
			var locationItem = Ext.get(Ext.DomHelper.append(this.mapContainer, {
				tag: "div",
				id: 'map-location-' + record.data.locationId,
				cls: "map-location",
				html: '<div style="position:absolute; top:0px; right:0px;"></div>',
				style: {
					height: (record.data.mapHeight * this.ratio) + "px",
					width: (record.data.mapWidth * this.ratio) + "px",
					top: (record.data.mapY * this.ratio) + "px",
					left: (record.data.mapX * this.ratio) + "px"
				}
			}));
			locationItem.record = record;
			
			//Setup event listeners for the location item
			locationItem.on('click', this.onLocationClick, this);
			
			//Create the tooltip for the location item
			new Ext.ToolTip({
			 	scope: this,
		        target: locationItem,
		        title: '<h1>' + record.data.title + '</h1>',
		        width:300,
		        html: record.data.description,
		        trackMouse:true,
		        //autoHide: false,
		        baseCls: 'map-tooltip'
		    });

			
		}, this);
	}
	,createPerformanceToolbar: function(){
		this.performanceView.getEl().select('.performance-toolbar').each(function(el){
			
			var btn = Ext.get(Ext.DomHelper.append(el, {
				tag: 'a',
				'class': 'add-itinerary-button'
			}));
			btn.on('click', this.addToItinerary, this);
			
		}, this);
	}
	,createItineraryToolbar: function(){
		this.performanceView.getEl().select('.performance-toolbar').each(function(el){
			
			var btn = Ext.get(Ext.DomHelper.append(el, {
				tag: 'a',
				'class': 'remove-itinerary-button'
			}));
			btn.on('click', this.removeFromItinerary, this);
			
		}, this);
	}
	,updateMap: function(){
		var containerBox = this.mapContainer.getBox();
		var mapBox = this.mapImage.getBox();
		var contentBox = this.contentContainer.getBox();
		var maxLeft = mapBox.width - this.width - (-mapBox.x) - contentBox.x;
		var maxRight = contentBox.x + (-mapBox.x);
		var maxUp = mapBox.height - this.height - (-mapBox.y) - contentBox.y;
		var maxDown = contentBox.y + (-mapBox.y);
		if(maxLeft < 0){
			maxLeft = 0;
		}
		if(maxRight < 0){
			maxRight = 0;
		}
		if(maxUp < 0){
			maxUp = 0;
		}
		if(maxDown < 0){
			maxDown = 0;
		}
		
		//save position
		this.mapDrag.maxLeft = maxLeft;
		this.mapDrag.maxRight = maxRight;
		this.mapDrag.maxUp = maxUp;
		this.mapDrag.maxDown = maxDown;
				
		this.mapDrag.clearConstraints();
		this.mapDrag.resetConstraints();
		this.mapDrag.setXConstraint(maxLeft, maxRight);
		this.mapDrag.setYConstraint(maxUp, maxDown);
	}
	
	,showMessage: function(text, fadeOut){
		this.messageContainer.setVisibilityMode(Ext.Element.DISPLAY);
		if(this.messageTimeout != null){
			clearTimeout(this.messageTimeout);
		}
		
		//fade in the message
		this.messageContainer.dom.innerHTML = text;
		if(!this.messageContainer.isVisible()){
			this.messageContainer.show(true);
			this.messageContainer.fadeIn();
		}
		
		//Fade out in 5 seconds
		if(fadeOut != null && fadeOut == true){
			this.messageTimeout = setTimeout(function(){
				this.hideMessage();
			}.createDelegate(this), 5000);
		}
	}
	,hideMessage: function(){
		this.messageContainer.fadeOut({callback: function(){ this.messageContainer.hide(true); }.createDelegate(this)});
	}
	
	,addToItinerary: function(event, element, object){
		//get the record
		var record = this.performanceView.getRecord(this.performanceView.getNode(Ext.get(element).parent('.performance-item').dom.id));
		
		//Show message
		this.showMessage(String.format('Adding <i>{0}</i>...', record.data.title));
		
		//add request
		Ext.Ajax.request({
			scope: this,
			url: '/ajax/performance/public/add-itinerary/',
			params: { performanceId: record.data.performanceId },
			success: function(r){
				this.showMessage(String.format('Added <i>{0}</i> to your itinerary.', record.data.title), true);
			}
		});
	}
	,removeFromItinerary: function(event, element, object){
		var record = this.performanceView.getRecord(this.performanceView.getNode(Ext.get(element).parent('.performance-item').dom.id));
		Ext.Ajax.request({
			scope: this,
			url: '/ajax/performance/public/remove-itinerary/',
			params: { performanceId: record.data.performanceId },
			success: function(r){
				this.itineraryStore.load();
			}
		});
	}
	
	,dateSelected: function(){
		var date = this.dateMenu.getValue();
		var node = Ext.get(this.performanceView.getNode(this.performanceStore.find('date', date.format('n/d/Y'))));
		if(node != null){
			var top = Ext.get(node).dom.offsetTop;
			Ext.get(this.performancePanel.body).scrollTo('top', top, {
				duration:1
				,callback: function(){
					//animate
					node.animate(
					    { backgroundColor: { to: '#DFDFDF' } },
					    .5,
					    function(){
					    	node.animate(
					    		{ backgroundColor: { to: '#ffffff' } },
					    		.75,
					    		function(){
					    			node.dom.style.backgroundColor = '';
					    		},
					    		'easeOut',
					    		'color'
					    	);
					    },
					    'easeOut',
					    'color'  
					);
				}
			});
		}
	}
	
	,onLocationClick: function(event, element, object){
		if(!Ext.get(element).hasClass('map-location')){
			element = Ext.get(element).parent('.map-location');
		}
		//Set the correct store
		this.performanceView.bindStore(this.performanceStore);
		
		//Clear the window toolbar and hide it
		this.detailsWindow.getTopToolbar().removeAll(true);
		this.detailsWindow.getTopToolbar().hide();
		
		//Filter the performances
		var record = Ext.get(element).record;
		this.performanceStore.setBaseParam('locationId', record.data.locationId);
		this.performanceStore.load();
		
		//Set the window title
		this.detailsWindow.setTitle(record.data.title);
		
		//Flir
		FLIR.replace( '.details-window .x-plain-header-text' , new FLIRStyle({ cFont:'gunplay' }) );
		
		//Show the window
		this.detailsWindow.show(element);
		if(this.detailsWindow.collapsed){
			this.detailsWindow.expand();
		}
	}
	
	,onPerformanceOver: function(view, index, node, e){
		Ext.get(node).select('.performance-toolbar').each(function(el){
			el.show();
		});
	}
	,onPerformanceOut: function(view, index, node, e){
		Ext.get(node).select('.performance-toolbar').each(function(el){
			el.hide();
		});
	}
	
});
