YUI().use('node', 'io', 'overlay', 'json-parse', function(Y){
// CALENDAR CLASS
	var Calendar = (function (){
		
		return{
			init: function(options){
				this.options = options;
			//these are labels for the days of the week
				this.cal_days_labels = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
				
			// these are human-readable month name labels, in order
				this.cal_months_labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
				this.cal_months_short_labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
				
			// these are the # days for each month, in order
				this.cal_days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
			// this is the current date
				this.cal_current_date = new Date();
				this.todays_date = this.cal_current_date.getDate();
				
			// set the calendars month and year
				if (this.options){
					this.month = this.options.month;
					this.year = this.options.year; 
				}else{
					this.month = this.cal_current_date.getMonth();
					this.year = this.cal_current_date.getFullYear();
				}
				
			// get first day of month
				this.firstDay = new Date(this.year, this.month, 1);
				this.startingDay = this.firstDay.getDay();
				
			// find number of days in month
				this.monthLength = this.cal_days_in_month[this.month];
				
			// compensate for leap year
				if (this.month == 1) { // February only!
					if((this.year % 4 == 0 && this.year % 100 != 0) || this.year % 400 == 0)
					  this.monthLength = 29;
				}
				
				this.eventListDiv = Y.one('#eventlist');
				this.eventListDiv._node.innerHTML += '<p class="list">Calendar Initialized</p>';
				Y.one('#calendar').removeClass('loading');
				
				this.eventListArray = [];
				this.activated = false;
			},
			
			generate: function(month, year){
				var calendar = Y.one('#calendar_table');
				if ( calendar )
					calendar.remove();
					
			// make the header
				this.monthName = this.cal_months_labels[this.month];
				var calTable = Y.one(document.createElement('table'));
				calTable._node.id = 'calendar_table';
				var calHead = Y.Node.create('<thead></thead>');
				
				var calMonth = Y.Node.create('<tr class="calMonth"></tr>');
				var calMonthTh = Y.Node.create('<th colspan="7"></th>');
				var calMonthHeading = Y.Node.create('<h1 class="month">' +this.monthName +' '+ this.year +'</h1>');
				calMonthTh.append(calMonthHeading);
				
				var nextMonth = Y.Node.create('<a class="nextMonth" href="#">&gt;</a>');
				nextMonth.on('click', function(event){
									event.preventDefault();
									Y.Node.all('#eventlist .list').remove();
									var nextMonth = ( Calendar.month < 11 )? Calendar.month +1 : 0;
									var nextYear = ( Calendar.month < 11 )? Calendar.year : Calendar.year +1;
									Calendar.init({month: nextMonth, year: nextYear});
									Calendar.generate();
									Calendar.getEventList({month: Calendar.cal_months_labels[nextMonth], year: nextYear});
								});
				calMonthHeading.append(nextMonth);
				
				if ((this.year >= this.cal_current_date.getFullYear() && this.month > this.cal_current_date.getMonth()) || (this.year > this.cal_current_date.getFullYear() && this.month <= this.cal_current_date.getMonth())){
					var prevMonth = Y.Node.create('<a class="prevMonth" href="#">&lt;</a>');
					prevMonth.on('click', function(event){
										event.preventDefault();
										Y.Node.all('#eventlist .list').remove()
										var nextMonth = ( Calendar.month > 0 )? Calendar.month -1 : 11;
										var nextYear = ( Calendar.month > 0 )? Calendar.year : Calendar.year -1;
										Calendar.init({month: nextMonth, year: nextYear});
										Calendar.generate();
										Calendar.getEventList({month: Calendar.cal_months_labels[nextMonth], year: nextYear});
									});
					calMonthHeading.append(prevMonth);
				}
				
				calMonth.append(calMonthTh);
				calHead.append(calMonth);
				
				var calTr = new Array();
				
			// day of the week headings
				calTr[0]= Y.Node.create('<tr></tr>');
				for(var i = 0; i <= 6; i++ ){ 
					calTr[0].append(Y.Node.create('<th class="dotw">' +this.cal_days_labels[i]+ '</th>'));
				}
				calHead.append(calTr[0]);
				calTable.append(calHead);
				var calBody = Y.Node.create('<tbody></tbody>');
				
			// fill in the days
				var day = 0;
				var tempDay;
				var tempMonth;
				
			// this loop is for is weeks (rows)
				for (var i = 0; i < 6; i++) {
					calTr[i+1]= Y.Node.create('<tr></tr>');
					
				// this loop is for weekdays (cells)
					for (var j = 0; j <= 6; j++) { 
						if	(day <= this.monthLength && (i > 0 || j >= this.startingDay)){
							day++;
							(day < 10)? tempDay = '0' +day : tempDay = day +'';
							(this.month +1 < 10)? tempMonth = '0' +(this.month +1) : tempMonth = this.month +1;
						}
						if (j==0 || j ==6){
							(day == 0 || day == (this.monthLength+1))? calTr[i+1].append(Y.Node.create('<td id="d' +tempDay+ '" class="weekend invalid">' +day+ '</td>')) : calTr[i+1].append(Y.Node.create ('<td id="d' +tempDay+ '" class="weekend valid" rel="' +this.year+'-'+tempMonth+'-'+tempDay+ '"><span></span>' +day+ '</td>'));
						}
						else{					
							(day == 0 || day == (this.monthLength+1))? calTr[i+1].append(Y.Node.create('<td id="d' +tempDay+ '" class="weekday invalid">' +day+ '</td>')) : calTr[i+1].append(Y.Node.create ('<td id="d' +tempDay+ '" class="weekday valid" rel="' +this.year+'-'+tempMonth+'-'+tempDay+ '"><span></span>' +day+ '</td>'));
						}
					}
				// stop making rows if we've run out of days
					if (day > this.monthLength)
						break;
					else
						calBody.append(calTr[i+1]);
				}
				calBody.append(calTr[calTr.length-1]);
				
				calTable.append(calBody);
				this.Calendar = calTable;
				Y.one('#calendar').append(calTable);
			},
			
			getEventList: function(date){
				var month = date.month;
				var year = date.year;
				
				var callback = {
					timeout : 3000,
					on : {
						success : function (x,o) {
							//console.log("RAW JSON DATA: " + o.responseText);
							var eventList = [];
							var html = '';
							
							// Process the JSON data returned from the server
							try {
							 	eventList = Y.JSON.parse(o.responseText);
							 	Calendar.eventListDiv._node.innerHTML += '<p class="list">Events List Loaded</p>';
							}
							catch (e) {
								Calendar.eventListDiv._node.innerHTML += '<p class="list fail">JSON Parse failed!</p>';
								Calendar.eventListDiv._node.innerHTML += '<p class="list fail">' +e+ '</p>';
							}
							
							if ( eventList.length > 0 )
								Calendar.populateCalendar(eventList);
						},
						
						failure : function (x,o) {
							alert("Async call failed!");
						}
					
					}
				}
				// Make the call to the server for JSON data
				Y.io('/actions/getEvents.php?month=' +month+ '&year=' +year, callback);
			},
			
			populateCalendar: function(eventList){
				this.eventListArray = eventList;
				this.hotTicketsArray = Array();
				
				Y.all('#calendar_table td').removeClass('eventOn')
					.removeClass('featured')
					.removeClass('selected');
				
				var eventCount;
				var date;
				var day;
				
			// mark calendar days with an event
				for ( var i = 1, event; event = this.eventListArray[i++]; ){
					date = event.date;
					day = date.slice(8);
					
					cal_date = Y.one('#calendar_table #d' +day);
					cal_date.addClass('eventOn');
					if ( event.featured == '1' ){
						cal_date.addClass('featured');
						if ( this.hotTicketsArray.length <= 5 )
							this.hotTicketsArray.push(event);
					}
					
					eventCount = parseInt(cal_date.one('span').get('text'));
					eventCount = ( eventCount ) ? eventCount +1 : 1 ;
					cal_date.one('span').set('text', eventCount);
					
				}
				
				
				if ( this.todays_date < 10 )
					this.todays_date = '0' +this.todays_date;
				if ( this.month == new Date().getMonth() ) 
					Y.one('td#d' +this.todays_date).addClass('today');
				
				if ( this.hotTicketsHTML == undefined ){
					this.hotTicketsHTML = Y.Node.create('<div class="list hot clearfix"><h2>HOT TICKETS</h2></div>');
					for ( var i = 1, event; event = this.hotTicketsArray[i++]; ){
						this.hotTicketsHTML.append(Y.Node.create('<div class="event featured"><h3 class="venue">' +event.venue+ '</h3><p class="headliner">' +event.headliner+ '</p></div>')); 
					}
				}
				this.activate();
			},
			
			activate: function(){
			// calendar date clicked on
				var cal_dates = Y.all('#calendar td.eventOn');
				
				cal_dates.on('click', function(e){
					e.stopPropagation
					cal_dates.removeClass('selected');
					var events = Y.all('#eventlist .list');
					
					if ( e.currentTarget.hasClass('eventOn') ) {
					// set class of selected calander date to 'selected'
						e.currentTarget.addClass('selected');
					// set class of selected event list to 'selected'
						events.toggleClass('selected');
					}
					else
						Calendar.clearList();
				});
				
			// calendar date moused over
				cal_dates.on('mouseover', function(e){
					e.stopPropagation();
					var list;
					if ( list = Y.one('#eventlist .list') )
						list.addClass('hide');
					Calendar.createList(e.currentTarget.getAttribute('rel'));
				});
				
			// calendar date moused out
				cal_dates.on('mouseout', function(e){
					e.stopPropagation();
					var list = Y.one('#eventlist .list.hide');
					if ( list )
						list.removeClass('hide');
					Calendar.clearList();
				});
				
				if ( !this.activated ){
				// instructions
					var inst = Y.all('.events h1 a.inst');
					inst.on('mouseover', function(e){
						e.preventDefault();
						Calendar.clearList();
						
						var list;
						if ( list = Y.one('#eventlist .selected') )
							list.addClass('hide');
						var instructions = Y.Node.create('<div class="list instructions"><p><ol><li>Choose an event <strong>SOURCE</strong> from the list to the right.</li><li>Mouse-over a calendar day to see the events for that day appear in the right-hand pane.</li><li>Select a calendar day with a single click. Events for that day will now remain in the right pane.</li><li>Click on a different calendar day to change the selected day.</li><li>Click on an empty calendar day to clear the list of events.</li><li>Click on an event ticket to see more information about the event.</li><li>Click the "<strong>X</strong>" in the upper right corner of the event information to return to the calendar.</li></ol></p></div>');
						Y.one('#eventlist').insert(instructions, 2);
					});
					inst.on('mouseout', function(e){
						e.preventDefault();
						Calendar.clearList();
						
						var list;
						if ( list = Y.one('#eventlist .selected') )
							list.removeClass('hide');
					});
					inst.on('click', function(e){
						e.preventDefault();
						Y.one('#eventlist .list').addClass('selected');
					});
					
				// hot tickets
					var hot = Y.all('.events h1 a.hot'); 
					hot.on('mouseover', function(e){
						e.preventDefault();
						Calendar.clearList();
						
						var list;
						if ( list = Y.one('#eventlist .selected') )
							list.addClass('hide');
						var instructions = Calendar.hotTicketsHTML;
						
						Y.one('#eventlist').insert(instructions, 2);
					});
					hot.on('mouseout', function(e){
						e.preventDefault();
						Calendar.clearList();
						
						var list;
						if ( list = Y.one('#eventlist .selected') )
							list.removeClass('hide');
					});
					hot.on('click', function(e){
						e.preventDefault();
						Y.one('#eventlist .list').addClass('selected');
					});
					this.activated = true;
				}
				this.eventListDiv._node.innerHTML += '<p class="list">Calendar Activated</p>';
				this.clearList();
			},
			
		// add events coresponding to the event object date
			createList: function(date){
				var list = Y.Node.create('<div class="list clearfix" rel="' +date+ '"></div>');
				
				for ( var i = 1, event; event = this.eventListArray[i++]; ){
					if ( event.date == date ){
						var eventDiv = Y.Node.create('<div class="event" rel="' +event.id+ '"></div>');
						eventDiv.on('click', function(e){
							e.preventDefault();
							var eventId = e.currentTarget.getAttribute('rel');
							Calendar.getEventDetails(eventId);
						});
							
						eventDiv.append(Y.Node.create('<h3 class="venue">' +event.venue+ '</h3>'));
						eventDiv.append(Y.Node.create('<p class="headliner">' +event.headliner+ '</p>'));
						
						if ( event.featured == '1' ){
							list.insert(eventDiv, 0);
							eventDiv.addClass('featured');
						}else
							list.append(eventDiv, 'bottom');
					}
				}
				
				this.eventListDiv.append(list);
				
			},
			
			clearList: function (){
				var lists = Y.all('#eventlist .list');
				lists.each(function (list){
					if ( !list.hasClass('selected') )
						list.remove();
				});
			},
			
			readableDate: function(date, format){
			// convert date to readable format
				var tmp_day = date.substr(8,2).toInt();
				var tmp_month = date.substr(5,2).toInt();
				var tmp_year = date.substr(0,4).toInt();
				
				if (format == 0 || format == null)
					return this.cal_months_labels[tmp_month-1] +'-'+ tmp_day +'-'+ tmp_year;
				if (format == 1)
					return this.cal_months_short_labels[tmp_month-1] +'-'+ tmp_day +'-'+ tmp_year;
				else
					return this.cal_months_labels[tmp_month-1] +'-'+ tmp_day +'-'+ tmp_year;
			},
			
			getEventDetails: function(id){
				var callback = {
					timeout : 3000,
					on : {
						success : function (transId, response) {
							try {
							 	Calendar.showEventDetails(response);
							}
							catch (e) {
								alert('ERROR parsing AJAX request');
								console.log(e);
							}
						},
						
						failure : function (x,o) {
							alert("Async call failed!");
						}
					}
				}
				// Make the call to the server for JSON data
				Y.io('/actions/getEventDetails.php?id=' +id, callback);
			},
			
			showEventDetails: function(response){
				var html = Y.Node.create(response.responseText);
				//alert('Functionality Comming...');
				/*
				var header = html.one('.eventHeader');
			 	var body = html.one('.eventBody');
			 	var footer = html.one('.eventFooter');
			 	*/
				var overlay = new Y.Overlay({
					//headerContent: header, 
					bodyContent: html, 
					//footerContent: footer,
					centered: true,
					width: 800,
					height: 500,
					zIndex: 9999
			 	});
			 	
			 	Y.one('#container').on('click', function(){
			 		Y.one('.yui-overlay').remove();
			 		overlay.destroy();
			 		mask.detach('click')
			 	})
			 	
				overlay.render("body");
			}
			
		}
	})();
	Calendar.init();
	Calendar.generate();
	Calendar.getEventList({month: Calendar.cal_months_labels[Calendar.month], year: Calendar.year});
});
