var com = com || {};
com.resmark = {

	/**
		regex for date formats:
	*/
	DATE_FORMAT: /(0[1-9]|1[0-2])\/(([0-2][0-9])|(3[0-1]))\/20[0-9]{2}/,
	startDateId: 'startDate',
	endDateId: 'endDate',
	minDate: null,
	maxDate: null,
	daysToSearch: 1,
	activityDateMap: 
	{
	/*
		'4':  {startDate:'05/15/2010', daysToSearch:3},
		'5':  {startDate:'06/15/2010', daysToSearch:2},
		'15': {startDate:'06/15/2010', daysToSearch:7},
		'16': {startDate:'06/15/2010', daysToSearch:7},
		'11': {startDate:'06/15/2010', daysToSearch:7},
		'12': {startDate:'06/01/2010', daysToSearch:7},
		'3':  {startDate:'05/15/2010', daysToSearch:4},
		'2':  {startDate:'05/15/2010', daysToSearch:7}
	*/
	},
	
	/**
		YAHOO.calendar createDateSelector(String inputId)
		Creates and returns a new YUI calendar object
	*/
	createDateSelector: function (inputId)
	{
		var config = {pages:2, title:'Please select a date:', mindate: new Date()};
		var dateSelector = new YAHOO.widget.CalendarGroup('_' + inputId, inputId + 'Container', config);
		dateSelector.selectEvent.subscribe(com.resmark.onDateSelected, dateSelector, true);
		this['mouseActive_' + inputId] = false;
		dateSelector.renderEvent.subscribe(function() {
			YAHOO.util.Event.addListener(inputId + 'Container', 'mouseover', com.resmark.mouseEntered, dateSelector, true);
			YAHOO.util.Event.addListener(inputId + 'Container', 'mouseout', com.resmark.mouseExited, dateSelector, true);
		}, dateSelector, true);
		
		dateSelector.render();
		return dateSelector;
	},
	
	mouseEntered: function()
	{
		com.resmark['mouseActive' + this.id] = true;
		//console.log("mouseActive" + this.id + ": " + com.resmark['mouseActive' + this.id]);
	},
	
	mouseExited: function ()
	{
		com.resmark['mouseActive' + this.id] = false;
		//this.mouseActive = false;
		//console.log("mouseActive" + this.id + ": " + com.resmark['mouseActive' + this.id]);
	},
	
	getStartDateInput: function ()
	{
		return document.getElementById(this.startDateId);
	},
	
	getEndDateInput: function ()
	{
		return document.getElementById(this.endDateId);
	},
	
	setStartDate: function(mmddyyyy)
	{
		var dateInput = this.getStartDateInput();
		dateInput.value = mmddyyyy;
	},
	
	getStartDate: function ()
	{
		var dateInput = this.getStartDateInput();
		return this.getDateValue(dateInput.value);
	},
	
	setEndDate: function(mmddyyyy)
	{
		var dateInput = this.getEndDateInput();
		dateInput.value = mmddyyyy;
	},
	
	getEndDate: function ()
	{
		var dateInput = this.getEndDateInput();
		return this.getDateValue(dateInput.value);
	},
	
	/**
		boolean isValidDate(String mmddyyyy)
		Returns true if the supplied argument matches the month pattern MM/dd/yyyy
	*/
	isValidDate: function (mmddyyyy)
	{
		mmddyyyy = mmddyyyy || '';
		if (mmddyyyy.match(this.DATE_FORMAT))
		{
			var isValid = false;
			var fields = mmddyyyy.split('/') || [];
			if (fields.length == 3)
			{
				var month = Number(fields[0]) - 1;
				var day   = Number(fields[1]);
				var year  = Number(fields[2]);
				
				var testDate = new Date(year, month, day);
				testDate.setFullYear(year);
				isValid = testDate.getFullYear() == year && testDate.getMonth() == month && testDate.getDate() == day;
			}
		}
		
		return isValid;
	},
	
	/**
		Date getDateValue(mmddyyyy)
		Returns a valid Date object with the proper full year set
		or null (if the supplied date is not valid.
	*/
	getDateValue: function (mmddyyyy)
	{
		var result = null;
		if (this.isValidDate(mmddyyyy))
		{
			var fields = mmddyyyy.split('/') || [];
			if (fields.length == 3)
			{
				var month = Number(fields[0]) - 1;
				var day   = Number(fields[1]);
				var year  = Number(fields[2]);
				
				result = new Date(year, month, day);
				result.setFullYear(year);
			}
		}
		
		return result;
	},
	
	/**
		String getMMDDYYYY(Date dateObject)
		Returns an MM/dd/yyyy formatted date string
		that reflects the value of the supplied dateObject.
	*/
	getMMDDYYYY: function (dateObject)
	{
		var result = null;
		if (dateObject)
		{
			var month = dateObject.getMonth() + 1;
			var day   = dateObject.getDate();
			var year  = dateObject.getFullYear();
			if (month < 10)
			{
				month = '0' + month;
			}
			if (day < 10)
			{
				day = '0' + day;
			}
			
			result = month + '/' + day + '/' + year;
		}
		
		return result;
	},
	
	/**
		void updateDateValue(String eventType, int[] dateFields, YUICalendarGroup calendarObject)
		Event listening function that executes when a yui.CalendarGroup
		object makes a selection.  The "this" context of this method
		is the instance of the yui.CalendarGroup this function was registered on.
	*/
	onDateSelected: function (eventType, dateFields, calendarObject)
	{
		var myId = calendarObject.id;
		var inputId = myId.substring(1, myId.length);
		var theDates = this.getSelectedDates();
		var selectedDate = theDates[0] || new Date();
		
		var myInput = document.getElementById(inputId);
		if (selectedDate)
		{
			myInput.value = com.resmark.getMMDDYYYY(selectedDate);
		}
		
		var myContainer = document.getElementById(calendarObject.containerId);
		myContainer.style.display = 'none';
		if (inputId == com.resmark.startDateId)
		{
			com.resmark.refreshEndDate();
		}
		else
		{
			com.resmark.refreshStartDate();
		}
	},
	
	/**
		void showCalendar(String inputId, YUICalendarGroup calendarObject)
	*/
	showCalendar: function (inputId, calendarObject)
	{
		var myInput = document.getElementById(inputId);
		var myContainer = document.getElementById(inputId + 'Container');
		var selectedDate = this.getDateValue(myInput.value) || new Date();
		
		calendarObject.cfg.setProperty('selected', myInput.value);
		calendarObject.setMonth(selectedDate.getMonth());
		calendarObject.setYear(selectedDate.getFullYear());
		calendarObject.render();
		//calendarObject.cfg.setProperty('pagedate', selectedDate.getMonth() + '/' + selectedDate.getFullYear());
		
		var xyArray = YAHOO.util.Dom.getXY(myInput);
		var myX = xyArray[0] - 200;
		var myY = xyArray[1] + 20;
		myContainer.style.display = 'block';
		YAHOO.util.Dom.setXY(myContainer, [myX, myY]);
	},
	
	/**
		void hideCalendar(String inputId)
	*/
	hideCalendar: function (inputId)
	{
		if (!this['mouseActive_' + inputId])
		{
			var myContainer = document.getElementById(inputId + 'Container');
			myContainer.style.display = 'none';
		}
	},
	
	refreshStartDate: function ()
	{
		var startInput = document.getElementById(this.startDateId);
		var endInput   = document.getElementById(this.endDateId);
		var startDate  = this.getDateValue(startInput.value) || new Date();
		var endDate    = this.getDateValue(endInput.value) || new Date();
		
		if (startDate > endDate)
		{
			startDate = endDate;
		}
		
		startInput.value = this.getMMDDYYYY(startDate);
	},
	
	refreshEndDate: function ()
	{
		var startInput = com.resmark.getStartDateInput();
		var endInput   = com.resmark.getEndDateInput();
		var startDate  = this.getDateValue(startInput.value) || new Date();
		var endDate    = this.getDateValue(endInput.value) || new Date();
		var minEndDate = com.resmark.getTargetEndDate(startDate);
		
		if (endDate < minEndDate)
		{
			endDate = minEndDate;
		}
		
		endInput.value = this.getMMDDYYYY(endDate);
	},
	
	
	/**
		void setSelectedActivities(String[] activityNameIds)
		sets the value of the hidden input with the id activityNameId or
		activityNameIds (depending on weather or not an array is passed in)
		if such an input can be found.
	*/
	setSelectedActivities: function (activityNameIds)
	{
		if (activityNameIds)
		{
			if (typeof activityNameIds == 'number' || typeof activityNameIds == 'string')
			{
				var dateConfig = com.resmark.activityDateMap[activityNameIds];
				if (dateConfig)
				{
					com.resmark.setMinDate(dateConfig.startDate, dateConfig.daysToSearch);
				}
				
				var myInput = document.getElementById('activityNameId');
				if (myInput)
				{
					myInput.value = activityNameIds;
				}
			}
			else if (activityNameIds.length && typeof activityNameIds.length == 'number' && activityNameIds.length > 0)
			{
				var minArrayDate = new Date(3000, 11, 31);
				var maxDaysToSearch = 1;
				for (var i = 0; i < activityNameIds.length; i++)
				{
					var id = activityNameIds[i];
					var dateConfig = com.resmark.activityDateMap[id];
					if (dateConfig)
					{
						var myDate = com.resmark.getDateValue(dateConfig.startDate);
						minArrayDate = minArrayDate > myDate ? myDate : minArrayDate;
						maxDaysToSearch = maxDaysToSearch < dateConfig.daysToSearch ? dateConfig.daysToSearch : maxDaysToSearch;
					}
				}
				
				com.resmark.setStartDate(minArrayDate, maxDaysToSearch);
				var myDiv = document.getElementById('rsmk-activityIdsContainer');
				if (myDiv)
				{
					myDiv.innerHTML = '';
					this.addHiddenInputs(myDiv, 'activityNameIds', activityNameIds);
				}
			}
		}
	},
	
	/**
		void setSelectedPromoCodes(String[] promoCodes)
		appends hidden inputs with the name 'promoCodes' to the element with id 'promoCodesContainer',
		if no such container can be found, this method has no effect.
	*/
	setSelectedPromoCodes: function (promoCodes)
	{
		var myDiv = document.getElementById('rsmk-promoCodesContainer');
		if (myDiv)
		{
			this.addHiddenInputs(myDiv, 'promoCodes', promoCodes);
		}
	},
	
	/**
		void addHiddenInputs(HTMLElement targetElement, String inputName, String[] ids)
		adds ids to targetElement in a series of hidden html input tags.
	*/
	addHiddenInputs: function (targetElement, paramName, ids)
	{
		if (ids && paramName)
		{
			for (var i = 0; i < ids.length; i++)
			{
				targetElement.innerHTML += '<input type="hidden" name="' + paramName + '" value="' + ids[i] + '" />';
			}
		}
	},
	
	setDatesIfMissing: function ()
	{
		var startDate = this.getStartDate();
		var endDate   = this.getEndDate();
		
		if (!startDate || !endDate)
		{
			startDate = (!startDate) ? com.resmark.minDate : this.getMMDDYYYY(startDate);
			this.setStartDate(startDate);
			this.refreshEndDate();
		}
	},
	
	/**
		void showSearchDialog(HTMLElement targetLink [, int[] activityIds [, String[] promoCodes]])
	*/
	showSearchDialog: function (targetLink, activityIds, promoCodes)
	{
		this.hideSearchDialog();
		this.setDatesIfMissing();
		
		var myContainer = document.getElementById('rsmk-searchContainer');
		
		if (myContainer.style.display == 'none')
		{
			var xyArray = YAHOO.util.Dom.getXY(targetLink);
			var myX = xyArray[0] -150;
			var myY = xyArray[1] + 20;
			
			var myTable = document.getElementById('rsmk-searchTypeTable');
			if (myTable)
			{
				myTable.style.display = activityIds ? 'none' : 'block';
			}
			
			this.setSelectedActivities(activityIds);
			this.setSelectedPromoCodes(promoCodes);
			
			myContainer.style.display = 'block';
			YAHOO.util.Dom.setXY(myContainer, [myX, myY]);
		}
	},
	
	hideSearchDialog: function ()
	{
		var myContainer = document.getElementById('rsmk-searchContainer');
		myContainer.style.display = 'none';
	},
	
	showSingleActivitySearchDialog: function (targetLink, activityNameIds)
	{
		this.showSearchDialog(targetLink, activityNameIds);
	},
	
	showParamSearchDialog: function (params)
	{
		this.showSearchDialog(params.targetLink, params.activityNameIds, params.promoCodes);
	},
	
	/**
		void setMinDate(String mmddyyyy [, int daysToSearch])
	*/
	setMinDate: function(mmddyyyy, daysToSearch)
	{
		daysToSearch = daysToSearch || 1;
		var targetDate = com.resmark.getDateValue(mmddyyyy) || new Date();
		if (targetDate < new Date())
		{
			// ensure the date is no earlier than today:
			targetDate = new Date();
		}
		
		com.resmark.minDate = com.resmark.getMMDDYYYY(targetDate);
		com.resmark.daysToSearch = daysToSearch;
		window.beginSelector.cfg.setProperty('mindate', com.resmark.minDate);
		window.endSelector.cfg.setProperty('mindate', com.resmark.minDate);
		com.resmark.getEndDateInput().value = null;
		com.resmark.getStartDateInput().value = com.resmark.minDate;
		com.resmark.refreshEndDate();
	},
	
	/**
		void setMaxDate(String mmddyyyy)
	*/
	setMaxDate: function(mmddyyyy)
	{
		window.beginSelector.cfg.setProperty('maxdate', mmddyyyy);
		window.endSelector.cfg.setProperty('maxdate', mmddyyyy);
		com.resmark.maxDate = mmddyyyy || '10/01/2010';
	},
	
	/**
		Date getTargetEndDate(Date startDate)
		Returns a new Date object that has a value of startDate + com.resmark.daysToSearch
	*/
	getTargetEndDate: function(startDate)
	{
		return startDate ? new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + com.resmark.daysToSearch) : null;
	},
	
	submitSearch: function()
	{
		var myForm = document.getElementById('rsmk-searchForm');
		if (myForm)
		{
			// check the date range bounds:
			var startDate = this.getStartDate();
			var endDate   = this.getEndDate();
			
			if (!startDate || !endDate)
			{
				alert("Start and end Dates are required for search.");
				this.getStartDateInput().focus();
				return;
			}
			if (startDate > endDate)
			{
				alert("Start date must be before end date.");
				this.getStartDateInput().focus();
				return;
			}
			
			var minDate   = this.getDateValue(this.minDate);
			var maxDate   = this.getDateValue(this.maxDate);
			if (minDate && startDate < minDate)
			{
				startDate = minDate;
				this.setStartDate(this.getMMDDYYYY(startDate));
			}
			
			var minEndDate = this.getTargetEndDate(startDate);
			if (maxDate && endDate > maxDate)
			{
				endDate = maxDate;
				this.setEndDate(this.getMMDDYYYY(endDate));
			}
			else if (minEndDate && endDate < minEndDate)
			{
				endDate = minEndDate;
				this.setEndDate(this.getMMDDYYYY(endDate));
			}
			
			myForm.submit();
		}
	},
	
	initializeDateSelectors: function ()
	{
		com.resmark.startDateId = 'startDate';
		com.resmark.endDateId   = 'endDate';
		
		var hardMinDate = com.resmark.getDateValue('05/01/2010');
		var hardMaxDate = com.resmark.getDateValue('10/01/2010');
		var today = new Date();
		
		com.resmark.minDate = com.resmark.getMMDDYYYY( today > hardMinDate ? today : hardMinDate );
		com.resmark.maxDate = com.resmark.getMMDDYYYY(hardMaxDate);
		
		window.beginSelector = com.resmark.createDateSelector('startDate');
		window.endSelector   = com.resmark.createDateSelector('endDate');
		com.resmark.setMinDate(com.resmark.minDate);
		com.resmark.setMaxDate(com.resmark.maxDate);
	}
};


YAHOO.util.Event.addListener(window, 'load', com.resmark.initializeDateSelectors);

	
	
