/**
 * @author The Roundhouse [Paul]
 */

var Calendar = new Class({
	
	_now: 			new Date(),
	_objRaceInfo:	null,
	_iMonth:		0,
	_iYear: 		0,
	_strTimestamp: 	null,
	_divTarget: 	null,
	_aPrev: 		null,
	_aNext: 		null,
	_bShowForecast: false,
	_arrMonths: 	[31, // January
					 28, // February
					 31, // March
					 30, // April
					 31, // May
					 30, // June
					 31, // July
					 31, // August
					 30, // September
					 31, // October
					 30, // November
					 31],// December
					 
	_arrMonthNames: ["January",
					 "February",
					 "March",
					 "April",
					 "May",
					 "June",
					 "July",
					 "August",
					 "September",
					 "October",
					 "November",
					 "December"],
					 
	_arrDayNames: 	["Monday",
					 "Tuesday",
					 "Wednesday",
					 "Thursday",
					 "Friday",
					 "Saturday",
					 "Sunday"],
					 
	setDate: function(iMonth, iYear)
	{
		this._iMonth 	= iMonth;
		this._iYear 	= iYear;
	},

	setRaceInfo: function(objRaceInfo)
	{
		this._objRaceInfo = objRaceInfo;
	},
	
	createTable: function()
	{
		var tblFixtureCalendar 	= new Element('table');
		tblFixtureCalendar.setAttribute('summary', 'Fixtures Calendar');
		tblFixtureCalendar.setAttribute('id', 'fixturecalendartable');
		
		var capCalendar 		= new Element('caption');
		var spanCaption 		= new Element('span');
		spanCaption.addClass('centre');
		
		var aPrev 				= new Element('a');
		aPrev.setAttribute('id', 'pre');
		aPrev.setAttribute('href', 'javascript:void(0)');
		
		var aNext 				= new Element('a');
		aNext.setAttribute('id', 'nxt');
		aNext.setAttribute('href', 'javascript:void(0)');
		
		var spanMonthName 		= new Element('span');
		spanMonthName.setAttribute('id', 'fixmonthname');
		spanMonthName.addClass('floatleft');
		spanMonthName.setHTML('Month');
		
		spanCaption.adopt(aPrev);
		spanCaption.adopt(spanMonthName);
		spanCaption.adopt(aNext);
		capCalendar.adopt(spanCaption);
		tblFixtureCalendar.adopt(capCalendar);
		
		var thCalendar 			= new Element('thead');
		var tbCalendar 			= new Element('tbody');
		
		tbCalendar.setAttribute('id', 'fixcaltable');
		
		var trDayHeader			= new Element('tr');
		for(var i = 0; i < 7; i++)
		{
			var th 				= new Element('th');
			var spanFullName 	= new Element('span')
			
			th.setAttribute('scope', 'col');
			th.setHTML(this._arrDayNames[i].substring(0,1));
			spanFullName.addClass('hidden');
			spanFullName.setHTML(" - "+this._arrDayNames[i]);
			th.adopt(spanFullName);
			
			trDayHeader.adopt(th);
		}
		
		thCalendar.adopt(trDayHeader);
		tblFixtureCalendar.adopt(capCalendar);
		tblFixtureCalendar.adopt(thCalendar);
		tblFixtureCalendar.adopt(tbCalendar);
		
		var divTableHolder = $('fixturecalender');
		if(divTableHolder)
		{
			divTableHolder.adopt(tblFixtureCalendar);
			
			this._divTarget = tbCalendar;
			this._aNext = aNext;
			this._aPrev = aPrev;
		}
	},
	
	write: function(bIgnoreNext)
	{
		if(bIgnoreNext == undefined)
			bIgnoreNext = false
		
		// find out when the first of the month is
		var dtSelected  = new Date(this._iYear, this._iMonth, 1);
		var firstDay 	= dtSelected.getDay();
		var monthLength	= this._arrMonths[this._iMonth];
		
		// check if showing current month
		var bThisMonth 	= (this._now.getFullYear() == this._iYear &&
						   this._now.getMonth() == this._iMonth);
		
		// check for a leap year
		if(this._iMonth == 1 && !(this._iYear%4))
			monthLength = 29;
			
		// since sunday is 0 but we want it to appear as 6
		// we need to add 6 to the first day number then
		// mod 7 it to bring it in range
		firstDay		= (firstDay + 6) % 7;
				
		// remove the table
		$('fixturecalendartable').remove();
		
		// now recreate it
		this.createTable();
		
		// set the month name
		$('fixmonthname').setHTML(this._arrMonthNames[this._iMonth] + ", "+this._iYear);
		
		 
		// start the day count at 0
		var iDayCount 	= 0;
		var bInMonth	= false;
		
		// each row
		for(var r = 0; r < 6; r++)
		{
			// create the row
			var trNewRow = new Element('tr');
			
			// each column
			for(var c = 0; c < 7; c++)
			{
				// check if we are in the month
				if(!bInMonth)
					bInMonth = (r==0 && c>=firstDay);
				else
					bInMonth = ((r*7 + c) < (firstDay + monthLength));
					
				// create the column
				var tdNewCol 	= new Element('td');
				
				// if we're in the month
				if(bInMonth)
				{
					// increment the day count
					iDayCount++;
					
					// if we are showing this month set the today class on today's date
					if(bThisMonth && iDayCount == this._now.getDate())
						tdNewCol.addClass('today');
					
					
					// set the id so we can refer to it later
					tdNewCol.setAttribute('id', 'fixcaldate'+iDayCount);
					
					// create a new span
					var spanNewCol 	= new Element('span');
					spanNewCol.setHTML(iDayCount);
					tdNewCol.adopt(spanNewCol);
				}
				else
				{
					tdNewCol.setHTML("&nbsp;");
				}
			
				// have the row adopt the column
				trNewRow.adopt(tdNewCol);
			}
			
			// now have the table adopt the new row
			this._divTarget.adopt(trNewRow);
		}
		
		// remove any events on the click buttons
		this._aNext.removeEvents();
		this._aPrev.removeEvents();
		
		// now do the onclick events for prev / next
		this._aNext.addEvent('click', this.nextMonth.bind(this));
		this._aPrev.addEvent('click', this.prevMonth.bind(this));
		
		// request race info for this month
		this._strTimestamp = (new Date()).getTime().toString();
		this._objRaceInfo.getDates(this._iMonth, this._iYear, this._strTimestamp, bIgnoreNext, this.showDates.bind(this));
		
	},
	
	showDates: function(arrDates, strTimestamp)
	{
		// check the timestamp matches
		if(strTimestamp == this._strTimestamp)
		{
			// store the date info for later
			this._arrDates = arrDates;
			
			// now go through each one and populate the calendar
			for(var i = 0; i < arrDates.length; i++)
			{
				var objDate 	= arrDates[i];
				
				if(objDate.bNext)
				{
					this.showDateDetails(i, false, true);
				}
				else
				{
					var tdTarget 	= $('fixcaldate'+objDate.iDate);
					
					if(tdTarget && objDate.iDate && objDate.iMonth == this._iMonth && objDate.iYear == this._iYear)
					{
						var aTarget 			= new Element('a');
						var divRaceDetails 		= $('racemeta');
						if(!divRaceDetails)
						{
							var strOffset = "";
							if(deconcept.util.getRequestParameter && deconcept.util.getRequestParameter("offset") != "")
								strOffset = deconcept.util.getRequestParameter("offset");
							//alert(deconcept.util.getRequestParameter +":"+ deconcept.util.getRequestParamter("offset"));
							strOffset 	= (strOffset!="" ? "&offset="+strOffset : "");
							
							if(objDate.bResults)
							{
								aTarget.setAttribute("href", "../results&racereports/result_details.php?id="+objDate.bResults+strOffset);
							}
							else
							{
								aTarget.setAttribute("href", "../fixtures/fixture_details.php?id="+objDate.ID+strOffset);
							}
						}
						else
						{
							aTarget.setAttribute("href", "javascript:void(0)");
							aTarget.ID 			= i;
							aTarget.objCalendar	= this;
							aTarget.addEvent("click", function()
												  {
												  	  this.objCalendar.showDateDetails(this.ID, this.getAttribute('rel'));
												  });
						}
						aTarget.adopt(tdTarget.firstChild);
						tdTarget.adopt(aTarget);
						
						if(objDate.bResults)
						{
							tdTarget.addClass('results');
							aTarget.setAttribute("rel", true);
						}
						
						tdTarget.addClass('meet');
					}
				}
			}
			
			if(arrDates.length == 0)
			{
				var divRaceDetails 		= $('racemeta');
				if(divRaceDetails)
				{
					divRaceDetails.innerHTML = "Fixture details will be updated soon.";
				}
			}
		}
	},
	
	showDateDetails: function(iDateID, bResults, bNext)
	{
		// prevent previous forecast requests
		this._bShowForecast 	= false;
		
		// grab the details of the date object
		var objDateDetails 		= this._arrDates[iDateID];
		var objTrackDetails 	= this._objRaceInfo.getTrack(objDateDetails.iTrack);
		
		// get the RSS link
		this._strRSSLink 		= objTrackDetails.strForecastRSS;
		
		// now we need to populate the 'view'
		var divRaceDetails 		= $('racemeta');
		
		// clear the weather forecast
		var divForecast 		= $('forecast');
		
		// link to the stuff
		var aViewDetails 		= $('viewracedetails');
		
		// check the div exists
		if(divRaceDetails)
		{
			// start by emptying it out
			divRaceDetails.empty();
			
			// create the title, etc
			var strRaceTitle 	=  objTrackDetails.strTitle + ", " + objDateDetails.strTitle;
			
			// get the track outline
			var imgTrack = new Element('img');
			imgTrack.setAttribute('alt', objTrackDetails.strTitle);
			imgTrack.setAttribute('src', objTrackDetails.strImgPath);
			imgTrack.addClass('floatright');
			
			// get the race date
			var strRaceDate		= this._arrMonthNames[objDateDetails.iMonth] + " " + objDateDetails.iDate + this.dateSuffix(objDateDetails.iDate);
				
			// get the title of the track
			var h4Title = new Element('h4');
			if(bNext)
				h4Title.setHTML("Next Event - "+strRaceDate);
			else
				h4Title.setHTML(strRaceDate);
			
			// the date and title of the meet
			var pRaceTitle 	= new Element('p');
			pRaceTitle.addClass('strong');
			pRaceTitle.setHTML(strRaceTitle);
			
			var pRaceDetails = new Element('p');
			pRaceDetails.setHTML(objDateDetails.strShortDescription);
			
			divRaceDetails.adopt(imgTrack);
			divRaceDetails.adopt(h4Title);
			divRaceDetails.adopt(pRaceTitle);
			divRaceDetails.adopt(pRaceDetails);
			
		}
		
		// set the details link
		if(aViewDetails)
		{
			if(objDateDetails.bResults)
			{
				aViewDetails.setAttribute('href', '../results&racereports/result_details.php?id='+objDateDetails.bResults);
				aViewDetails.setHTML('View Result Details');
			}
			else
			{
				aViewDetails.setAttribute('href', '../fixtures/fixture_details.php?id='+objDateDetails.ID);
				aViewDetails.setHTML('View Fixture Details');
			}
			
			aViewDetails.removeClass('hidden');
		}
		
		// get the weather forecast		
		if(divForecast && this.iTrackChoice != objDateDetails.iTrack)
		{
			// keep the track choice so we don't
			// need to pull out the same info repeatedly
			this.iTrackChoice 		= objDateDetails.iTrack;
			
			// empty out the forecast
			divForecast.empty();
			
			// declare that we're showing the forecast
			this._bShowForecast = true;
				
			// get the forecast
			divForecast.setHTML("Retrieving 3-day forecast for " + objTrackDetails.strTitle +". Please wait...");
				
			// dispatch the AJAX request
			this._objRaceInfo.getForecast(objDateDetails.iTrack, this.writeForecast.bind(this));
			
		}
		
	},
	
	writeForecast: function(arrForecast)
	{
		var pTitle		= new Element('p');
		pTitle.addClass('floatleft');
		pTitle.addClass('strong');
		pTitle.setHTML('3-day Forecast')
		
		var aSubscribe 	= new Element('a');
		aSubscribe.setAttribute('href', this._strRSSLink);
		aSubscribe.setAttribute('id', 'subscribelink');
		aSubscribe.addClass('feed');
		aSubscribe.addClass('floatright');
		aSubscribe.setHTML('subscribe');
		
		var divClear 	= new Element('div');
		divClear.addClass('clear');
		
		var olTemps 	= new Element('ol');
		for(var i = 0; i < arrForecast.length; i++)
		{
			var liTemp 		= new Element('li');
			var brTemp 		= new Element('br');
			var spanTemp 	= new Element('span');
			
			// set the maximum temp string
			spanTemp.setHTML(arrForecast[i].strMaxTemp);
			
			// create all the markup
			liTemp.addClass(arrForecast[i].strCondition);
			liTemp.setHTML(arrForecast[i].strDay);
			liTemp.adopt(brTemp);
			liTemp.adopt(spanTemp);
			
			// write it into the forecast list
			olTemps.adopt(liTemp);
		}
		
		var divForecast 		= $('forecast');
		if(divForecast && this._bShowForecast)
		{
			divForecast.empty();
			
			divForecast.adopt(pTitle);
			divForecast.adopt(aSubscribe);
			divForecast.adopt(divClear);
			divForecast.adopt(olTemps);
			
			
		}
		
	},
	
	dateSuffix: function(iDate)
	{
		// create the suffix, default 'th'
		var strSuffix = "th";
		
		// now do the others
		switch(iDate)
		{
			case 1: 
			case 21:	strSuffix = "st";
						break;
			case 2: 
			case 22:	strSuffix = "nd";
						break;
			case 3: 
			case 23:	strSuffix = "rd";
						break;
		}
		
		// return the suffix
		return strSuffix;
	},
	
	nextMonth: function()
	{
		// increment the month
		this._iMonth++;
		
		// if we've gone past the end
		// of the year
		if(this._iMonth >= 12)
		{
			// reset the month to Jan
			// and increment the year
			this._iMonth = 0;
			this._iYear++;
		}
		
		// update the calendar
		this.write(true);
	},
	
	prevMonth: function()
	{
		// increment the month
		this._iMonth--;
		
		// if we've gone past the start
		// of the year
		if(this._iMonth < 0)
		{
			// reset the month to Dec
			// and decrement the year
			this._iMonth = 11;
			this._iYear--;
		}
		
		// update the calendar
		this.write(true);
	}
})

var raceInfo = new RaceInfo();
var calendar = new Calendar();
window.addEvent('domready', function()
{
	if(!document.FIN)
	{
		var dtNow 	= new Date();
		var iMonth 	= dtNow.getMonth();
		var iYear 	= dtNow.getFullYear();
		
		calendar.setDate(iMonth, iYear);
		calendar.setRaceInfo(raceInfo);
		
		calendar.write();
	}
})
