/**
 * Constructor method for the model.  The model is a stateless component used to retrieve
 * rider course information.
 * @constructor
 * @extends HD.util.Observable
 */
HD.REO.Model = function() {
	this.observers = [];
	this.useDummyData = false;
	
	this.courseCache = {};
};

HD.REO.Model.prototype = {
	/**
	* Get course listing.
	* 
	* @param {Object} coursesRequest Course listing request has the following format:<br/>
	* 	{<br/>
	* 		&nbsp;&nbsp;zip : 53208,<br/>
	* 		&nbsp;&nbsp;city : "Milwaukee",<br/>
	* 		&nbsp;&nbsp;state : "WI",<br/>
	* 		&nbsp;&nbsp;radius : 100, // in miles<br/>
	* 		&nbsp;&nbsp;numOfDays : 90, // date range<br/>
	* 		&nbsp;&nbsp;nearbyStates : true, // include nearby states<br/>
	* 		&nbsp;&nbsp;fullClasses : true, // include classes that are full<br/>
	* 		&nbsp;&nbsp;pageNumber : 1, // page number<br/>
	* 		&nbsp;&nbsp;pageSize : 15, // page size<br/>
	* 		&nbsp;&nbsp;sortType : "startDate", // sort parameter, the other option is "distance"<br/>
	* 		// optional dealer object used to search for dealer classes<br/>
	* 		&nbsp;&nbsp;dealer : {<br/>
	* 			&nbsp;&nbsp;&nbsp;&nbsp;id : 123 // dealer id<br/>
	* 		&nbsp;&nbsp;}<br/>
	* 	}
	* @returns A color string for this shape
	*/
	getCourseList : function(coursesRequest) {
		this.notifyObservers("model_GetCourseList_Start");
		
		this.pageIndex = coursesRequest.pageNumber;
		
		var cb = this;
		
		var callback = function(coursesResponse) {
			var eventName = coursesResponse.success ? "model_GetCourseList_Finish" : "model_GetCourseList_Error";
			var courses = coursesResponse.courses;
			var numOfCourses = 0;
			if(courses != null) {
				numOfCourses = courses.length;
				for(var i = 0, len = courses.length; i < len; i++) {
					var course = courses[i];
					if(course.startDate != null) {
						course.startDate = cb.setTime(course.startDate);
					}
					if(course.endDate != null) {
						course.endDate = cb.setTime(course.endDate);
					}
					course.schedule = cb.setClassTime.call(cb, course.schedule);
					cb.courseCache[course.dealer.id + "!" + course.id] = course;
				}
				coursesResponse.courses = courses;
			}
			
			var searchLocation = "";
			var common = HD.util.Common;
			if(common.hasValue(coursesRequest.city) && common.hasValue(coursesRequest.state)) {
				searchLocation = coursesRequest.city + '+' + coursesRequest.state;
			} else if(common.hasValue(coursesRequest.zip)) {
				searchLocation = coursesRequest.zip;
			}
			if(coursesResponse.totalItems > 0 && !coursesResponse.showMsf) {
				HD.util.Analytics.track(HD.REO.analytics.getSearchResultsPage(HD.REO.experienceLevel, searchLocation, coursesResponse.totalItems));
			} else {
				HD.util.Analytics.track(HD.REO.analytics.getNoResultsPage(HD.REO.experienceLevel, searchLocation));
			}
			cb.notifyObservers.call(cb, eventName, coursesResponse);
		};
		
		coursesRequest.useDummyData = this.useDummyData;
		
		REOService.getCourseList(coursesRequest, callback);
	},
	
	setClassTime : function(schedule) {
		if(schedule != null) {
			if(schedule.classes != null) {
				for(var i = 0, len = schedule.classes.length; i < len; i++) {
					schedule.classes[i].startTime = this.setTime(schedule.classes[i].startTime);
					schedule.classes[i].endTime = this.setTime(schedule.classes[i].endTime);
				}
				return schedule;
			}
		}
	},
	
	setTime : function(date) {
		var time = date.getTime();
		var diffFromUtc = date.getTimezoneOffset() * 60000;
		var diffFromCentral = diffFromUtc + HD.util.Date.getCentralTimeOffset(date);
		var adjustedTime = time + diffFromCentral;
		date.setTime(adjustedTime);
		return date;
	},
	
	/**
	 * Get course details.
	 * 
	 * @param {Object} courseRequest Course detail object has the following format:
	 * 	{<br/>
	 * 		&nbsp;&nbsp;courseId: 12345,<br/>
	 * 		&nbsp;&nbsp;dealer: dealerObj<br/>
	 *	}<br/>
	 */
	getCourseDetails : function(courseRequest) {
		this.notifyObservers("model_GetCourseDetails_Start", courseRequest);
		
		var course = this.courseCache[courseRequest.dealer.id + "!" + courseRequest.courseId];
		
		var cb = this;
		var callback = function(courseResponse) {
			var eventName = courseResponse.success ? "model_GetCourseDetails_Finish" : "model_GetCourseDetails_Error";
			var courses = courseResponse.courses;
			if(courses != null && courses.length > 0) {
				var tempCourse = courses[0];
				course.fee = tempCourse.fee;
				course.disclaimer = tempCourse.disclaimer;
				course.moreClasses = tempCourse.moreClasses;
			}
			cb.notifyObservers.call(cb, eventName, course);
		};
		
		courseRequest.useDummyData = this.useDummyData;
		
		REOService.getCourseDetails(courseRequest, callback);
	},
	
	/**
	 * Set selected course in session.
	 * 
	 * @param {Object} course The selected course
	 */
	setSelectedCourse : function(course) {
		this.notifyObservers("model_SetSelectedCourse_Start", course);
		
		var cb = this;
		
		var callback = function(success) {
			var eventName = success ? "model_SetSelectedCourse_Finish" : "model_SetSelectedCourse_Error";
			cb.notifyObservers.call(cb, eventName, course);
		};
		
		REOService.setSelectedCourse(course, callback);
	},
	
	/**
	 * Get selected course from session.
	 * 
	 * @return The selected course
	 */
	getSelectedCourse : function() {
		this.notifyObservers("model_GetSelectedCourse_Start");
		
		var cb = this;
		
		var callback = function(course) {
			var eventName = course != null ? "model_GetSelectedCourse_Finish" : "model_GetSelectedCourse_Error";
			if(course.startDate != null) {
				course.startDate = cb.setTime(course.startDate);
			}
			if(course.endDate != null) {
				course.endDate = cb.setTime(course.endDate);
			}
			course.schedule = cb.setClassTime.call(cb, course.schedule);
			cb.notifyObservers.call(cb, eventName, course);
		};
		
		REOService.getSelectedCourse(callback);
	}
};

HD.util.Common.extend(HD.REO.Model, [HD.util.Observable]);
