// include all the required library scripts
LibManager.require('frame.prototype.ajax');
LibManager.require('locations.LocationManager');

Object.extend(FastTrackController, {

	/**
	* holds the ajax request object
	* @var obj
	*/
	ajaxRequest: null,

	/**
	* holds the timeout for ajax requests
	* @var obj
	*/
	ajaxTimeout: null,

	/**
	* holds the total time for the current ajax request
	* @var int
	*/
	ajaxReqTime: null,

	/**
	* holds the maximum amount of time (in ms) that we'll allow for the ajax requests
	* @var int
	*/
	ajaxMaxReqTime: 10000,

	/**
	* holds the intervals (in ms) we'll check the status of the ajax request on
	* @var int
	*/
	ajaxCheckInterval: 500,

	/**
	* List of fast track form element names who use cookies to store / retrieve their value
	* @var array
	*/
	cookieFieldList: ['searchString'],

	/**
	* holds the base url for use with ajax requests
	* @var string
	*/
	ajaxBaseUrl: '',

	attach: function() {
		window.setTimeout('FastTrackController.load()', 1000)		
	},
	
	load: function() {
		this.ajaxBaseUrl = $j('#ajaxBaseUrl').val();
		Event.observe('topLoc', 'change', this.updateNoOfReviews.bindAsEventListener(this));
		Event.observe('secondLoc', 'change', this.updateNoOfReviews.bindAsEventListener(this));
		Event.observe('thirdLoc', 'change', this.updateNoOfReviews.bindAsEventListener(this));
	},


	/**
	* Shows the number of reviews in location box on the search form
	*
	* @return void
	*/
	showNoOfReviewsBox: function() {
		//Reveal the hidden review box
		$("noOfReviewsBox").style.display = "block";
	},

	/**
	* List of fast track form element names who use cookies to store / retrieve their value
	* @var array
	*/
	cookieFieldList: ['searchString'],

	/**
	* Checks to see if the ajaxRequest is currently processing a call (readyState 1,2 or 3)
	*
	* @return boolean
	*/
	callInProgress: function() {

		switch (this.ajaxRequest.transport.readyState) {
			case 1:
			case 2:
			case 3:
				return true;
				break;
			// Case 4 and 0                    
			default:
				return false;
				break;
		}
	},

	/**
	* Updates the number of reviews container for the location selected
	* 
	* @access public
	* @param locationCode String
	* @return void
	*/
	updateNoOfReviews: function(listBoxObject) {

		var listBoxOptions = Event.element(listBoxObject);
		var locationCode = listBoxOptions.options[listBoxOptions.options.selectedIndex].value;
		var errMsg = 'Error: no data received. Please try again.';
		var requestVars = {
			content: 'getNoOfReviewsInLocation',
			locationCode: locationCode
		};

		if (locationCode != "") {
			//this.createAjaxUpdater("noOfReviews",requestVars, errMsg);

			this.createMvcJsonRequest(
				{ LocationCode: locationCode },
				"/HolidayReview/ShowHolidayReviewCount",
				function(result) {
					$j("#noOfReviews").text(result);
					this.showNoOfReviewsBox();
				}
				);


		}
	},

	/**
	* Checks the current ajax request to see if it has a response if 
	* not and it's currently processing and has reached the timeout limit
	* then abort the request and notify the user
	*
	* @return void
	*/
	checkResponse: function() {
		var thisObj = this;

		this.ajaxReqTime += this.ajaxCheckInterval;
		if (this.callInProgress() && (this.ajaxReqTime >= this.ajaxMaxReqTime)) {
			this.ajaxRequest.transport.abort();
			if (this.ajaxRequest.options['onFailure']) {
				this.ajaxRequest.options['onFailure']();
			}
		} else {
			this.ajaxTimeout = window.setTimeout(
				function() {
					thisObj.checkResponse();
				},
				this.ajaxCheckInterval
			);
		}
	},

	createAjaxUpdater: function(container, reqVars, errorMsg) {

		var thisObj = this;
		this.ajaxReqTime = 0;
		this.ajaxTimeout = window.setTimeout(
			function() {
				thisObj.checkResponse();
			},
			thisObj.ajaxCheckInterval
		);
		this.ajaxRequest = new Ajax.Updater(
			container,
			thisObj.ajaxBaseUrl,
			{ method: 'get',
				parameters: $H(reqVars).toQueryString(),
				onComplete:

				 function(request) {
				 	window.clearTimeout(thisObj.ajaxTimeout);
				 	if (!request.responseText.length || request.status != 200) {
				 		alert(errorMsg);
				 	} else {
				 		thisObj.showNoOfReviewsBox();
				 	}
				 },


				onFailure: function(request) {

					window.clearTimeout(thisObj.ajaxTimeout);
					alert('Error: Cannot contact database. Please try again.');
				}
			}
		);
	},

	/**
	* Handles the onChange event for the location selects where their change controls the
	* value of it's descendents. E.g. the target is the parent & 1 or more descendents need
	* to change depending on the parent value.
	* 
	* @access public
	* @param obj Event
	* @return void
	*/
	changeChildLevel: function(e) {
		var targ = Event.element(e);

		// get the target level to populate (the next level up from the one the user just changed)
		var level = this.getLocLevel(targ) + 1;

		this.setLocCookie(level - 1, targ.options[targ.options.selectedIndex].value);

		// populate the target level & all those beyond that level (e.g. if a user changes level 1, we'll have to populate levels 2 & 3)
		do {
			this.populateSel(level);
			level++;
		} while (level < this.levelDetail.length);

		this.updateNoOfReviews(targ.options[targ.options.selectedIndex].value);
	},

	/**
	* Handles the on change on location fields that have no more descendents, basically just
	* sets the cookie for that select
	* 
	* @access public
	* @param obj Event
	* @return void
	*/
	onBotLocChange: function(e) {
		var targ = getTarg(e);

		this.setLocCookie(this.getLocLevel(targ), targ.options[targ.options.selectedIndex].value);

		this.updateNoOfReviews(targ.options[targ.options.selectedIndex].value);
	},

	/**
	* Creates a request to a JsonResult in an Asp.Net MVC site.
	* 
	* @param reqVars, json object to pass to mvc.
	* @param actionRoute, route to mvc json result.
	* @param successFn, function to call on success.
	* @param successArg, other argument to pass as well as result.
	* @return void
	*/
	createMvcJsonRequest: function(reqVars, actionRoute, successFn, successArg) {
		var thisObj = this;

		$j.ajax({
			type: "POST",
			url: actionRoute,
			dataType: "json",
			contentType: "application/json; charset=utf-8",
			data: reqVars != null ? $j.toJSON(reqVars) : null,
			success: function(result) {
				thisObj.successFn = successFn;
				eval(thisObj.successFn(result, successArg));
				thisObj.successFn = null;
			}
		});
	}
});