﻿/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true,
         bitwise: true, regexp: true, strict: true, newcap: true, immed: true,
         maxerr: 50, indent: 4
*/

/*global $, YAHOO, Event */

/*members CalendarGroup, Selector, addListener, cal, cfg, checked, clear, 
    d1, d2, data, deselectEvent, doDeSelect, doSelect, field1, field2, 
    filter, formatDate, getDate, getDay, getFullYear, getHours, getMinutes, 
    getMonth, getSeconds, init, init_calendar, init_locations, innerHTML, 
    label, length, multi_select, navigator, onDOMReady, query, render, 
    replace, selectEvent, setProperty, subscribe, substring, toString, util, 
    value, widget
*/



var EVCSEARCH = {

	data: {
		cal:    'EVCSEARCH_cal',
		label:  'EVCSEARCH_label',
		d1:     null,
		d2:     null,
		field1: 'EVCSEARCH_field_d1',
		field2: 'EVCSEARCH_field_d2'
	},

	init: function () {

		this.init_calendar();
		this.init_locations();

	},

	init_calendar: function () {

		this.data.cal = $(this.data.cal);
		this.data.label = $(this.data.label);
		this.data.field1 = $(this.data.field1);
		this.data.field2 = $(this.data.field2);

		if (!this.data.cal) {
			return;
		}

		this.data.field1.value = '';
		this.data.field2.value = '';

		this.data.cal = new YAHOO.widget.CalendarGroup(this.data.cal, {
			multi_select: true,
			navigator: true
		});

		this.data.cal.render();

		this.data.cal.selectEvent.subscribe(this.doSelect, this, true);
		this.data.cal.deselectEvent.subscribe(this.doDeSelect, this, true);

	},

	/** There is an "All Locations" option that is checked by default.
	  * When the user clicks some other location, this must uncheck.
	  * When the user clicks it back on, all other options must uncheck.
	  * When the user unchecks their last option, it must check itself.
	  */
	init_locations: function () {

		var checkboxes = YAHOO.util.Selector.query(".locationsList input[type='checkbox']"),
		allLocs = YAHOO.util.Selector.filter(checkboxes, "input[name='all_groups']")[0];

		function handleClick() {
			var x;

			// When the user clicks some other location, allLocs must uncheck.
			if (this !== allLocs && this.checked === true) {
				allLocs.checked = false;
				return;
			}

			// When the user clicks allLocs back on, all other options must
			// uncheck.
			if (this === allLocs && this.checked === true) {
				for (x = 0; x < checkboxes.length; x++) {
					if (checkboxes[x] !== this) {
						checkboxes[x].checked = false;
					}
				}
				return;
			}

			// When the user unchecks their last option, allLocs must recheck.
			for (x = 0; x < checkboxes.length; x++) {
				if (checkboxes[x].checked === true) {
					return;
				}
			}
			allLocs.checked = true;
		}

		if (checkboxes.length > 0) {
			Event.addListener(checkboxes, 'click', handleClick);
		}

	},

	/** Formats a date according to the supplied string.
	 *  String defaults to 'mmmm d, yyyy'
	 *  List of characters for the string:
	 *  <table>
	 *  <tr><td> m     </td><td> Months as 1-12             </td></tr>
	 *  <tr><td> mm    </td><td> Months as 01-12            </td></tr>
	 *  <tr><td> mmm   </td><td> Months as Jan-Dec          </td></tr>
	 *  <tr><td> mmmm  </td><td> Months as January-December </td></tr>
	 *  <tr><td> d     </td><td> Days as 1-31               </td></tr>
	 *  <tr><td> dd    </td><td> Days as 01-31              </td></tr>
	 *  <tr><td> ddd   </td><td> Days as Sun-Sat            </td></tr>
	 *  <tr><td> dddd  </td><td> Days as Sunday-Saturday    </td></tr>
	 *  <tr><td> y     </td><td> Years as 0-99              </td></tr>
	 *  <tr><td> yy    </td><td> Years as 00-99             </td></tr>
	 *  <tr><td> yyyy  </td><td> Years as 1900-9999         </td></tr>
	 *  <tr><td> h     </td><td> Hours as  1 - 12           </td></tr>
	 *  <tr><td> hh    </td><td> Hours as 01 - 12           </td></tr>
	 *  <tr><td> H     </td><td> Hours as  0 - 23           </td></tr>
	 *  <tr><td> HH    </td><td> Hours as 00 - 23           </td></tr>
	 *  <tr><td> nn    </td><td> Minutes as 0 - 59          </td></tr>
	 *  <tr><td> ss    </td><td> Seconds as 0 - 59          </td></tr>
	 *  <tr><td> t     </td><td> A/P                        </td></tr>
	 *  <tr><td> tt    </td><td> AM/PM                      </td></tr>
	 *  </table>
	 */
	formatDate: function (date, s) {
		s = (s) ? s : 'mmmm d, yyyy';
		if (isNaN(date) || date === null) {
			return '';
		}

		function pad(d) {
			var s = d.toString();
			return (d < 10) ? '0' + s : s;
		}

		var re = /\b(?:m{1,4}|d{1,4}|yyyy|yy?|hh?|nn?|ss?|tt?)\b/g,
		h = date.getHours(),
		mmm = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
		mmmm = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
		ddd = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
		dddd = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];

		h = (h === 0) ? 12 : (h <  13) ? h  : h - 12;

		return s.replace(re, function (match, pos, source) {
			switch (match) {
			case 'm':
				return date.getMonth() + 1;

			case 'mm':
				return pad(date.getMonth() + 1);

			case 'mmm':
				return mmm[date.getMonth()];

			case 'mmmm':
				return mmmm[date.getMonth()];

			case 'd':
				return date.getDate();

			case 'dd':
				return pad(date.getDate());

			case 'ddd':
				return ddd[date.getDay()];

			case 'dddd':
				return dddd[date.getDay()];

			case 'ddT':
				return pad(date.getDate()) + 'T';

			case 'y':
				return (date.getFullYear().toString().substring(2, 4) * 1).toString();

			case 'yy':
				return date.getFullYear().toString().substring(2, 4);

			case 'yyyy':
				return date.getFullYear().toString();

			case 'h':
				return h;

			case 'hh':
				return pad(h);

			case 'H':
				return date.getHours();

			case 'HH':
				return pad(date.getHours());

			case 'n':
				return date.getMinutes();

			case 'nn':
				return pad(date.getMinutes());

			case 's':
				return date.getSeconds();

			case 'ss':
				return pad(date.getSeconds());

			case 't':
				return (date.getHours() < 12) ? 'A' : 'P';

			case 'tt':
				return (date.getHours() < 12) ? 'AM' : 'PM';
			}
		});
	},




	doSelect: function (e, d) {
		var selDate = new Date(d[0][0][0], d[0][0][1] - 1, d[0][0][2]),
		label = '';

		// First click
		if (this.data.d1 === null) {
			this.data.d1 = selDate;
			label = 'On or after ' + this.formatDate(selDate, 'dddd, mmm d, yyyy');

		// Second click
		} else if (this.data.d2 === null) {
			this.data.d2 = selDate;

			if (this.data.d1 > this.data.d2) {
				selDate = this.data.d1;
				this.data.d1 = this.data.d2;
				this.data.d2 = selDate;
			}

			this.data.cal.cfg.setProperty('selected',
				this.formatDate(this.data.d1, 'm/d/yyyy') + '-' +
				this.formatDate(this.data.d2, 'm/d/yyyy'));
			this.data.cal.render();

			label = 'Between ' + this.formatDate(this.data.d1, 'dddd, mmm d, yyyy') +
			' and ' + this.formatDate(this.data.d2, 'dddd, mmm d, yyyy');

		// Third click clears.
		} else {

			this.data.d1 = null;
			this.data.d2 = null;
			this.data.cal.clear();
			label = 'Next 60 days';

		}

		this.data.label.innerHTML = label;
		this.data.field1.value = this.formatDate(this.data.d1, 'yyyy-mm-dd');
		this.data.field2.value = this.formatDate(this.data.d2, 'yyyy-mm-dd');

	},


	doDeSelect: function () {

		this.data.d1 = null;
		this.data.d2 = null;
		this.data.cal.clear();
		this.data.label.innerHTML = 'Next 60 days';
		this.data.field1.value = '';
		this.data.field2.value = '';

	}


};

Event.onDOMReady(EVCSEARCH.init, EVCSEARCH, true);

