/**
 * The list widget for rendering an array of courses and/or dealers.
 * @extends HD.Widget
 * 
 * @param {Object} config configuration object containing configurable properties 
 * @param {HD.REO.Model} model the model object, signals model events
 * @param {HD.REO.View} view the view object, facilitates the communication of events between widgets 
 */
HD.REO.View.List = function(config, model, view) {
	this.observers = [];
	this.config = config || {};
    
	if(model != null) {
		this.model = model;
		this.model.addObserver(this);
	}
	
	if(view != null) {
		this.view = view; 
	    this.view.addObserver(this);
	}
    
    this.viewAll = false;
    this.sortType = HD.REO.template.sortByDate;
};

/**
 * Template object containing overrideable methods and properties.
 * @static
 */
HD.REO.View.List.template = {
	showingNumbers : 'Showing _START-_END out of _TOTAL',
	viewSomeViewAll :	'<span class="hdViewSome _SOME_CLASS">View <em>15</em> per page</span> | <span class="hdViewAll _ALL_CLASS">View All</span>',
	fullClassTooltip : '<div><h4>Sorry, this class is full</h4>All open and waiting list seats are filled for this class.</div>',
	openClassTooltip : '<div><h4>_OPEN of _TOTAL seats are open for this class</h4>You can reserve a seat for this class.</div>',
	waitlistClassTooltip : '<div><h4>_OPEN of _TOTAL seats are open on the waiting list</h4>All open seats are filled. You can add yourself to the waiting list for this class.</div>',
	
	courseSubTypesInfos : [
	    null,        
		"<div>Women's course description goes here.</div>",
		"<div>Spanish language course description goes here.</div>"
	],
	
	getShowingNumbers : function(start, end, total) {
		var message = HD.REO.View.List.template.showingNumbers;
		message = message.replace(/_START/, start);
		message = message.replace(/_END/, end);
		message = message.replace(/_TOTAL/, total);
		return message;
	},
	
	getViewSomeViewAll : function(pageSize, totalItems, isViewAll) {
		if(pageSize >= totalItems && !isViewAll) {
			return "&nbsp;";
		}
		var message = HD.REO.View.List.template.viewSomeViewAll;
		message = message.replace(/_SOME_CLASS/, isViewAll ? "hdLink" : "");
		message = message.replace(/_ALL_CLASS/, isViewAll ? "" : "hdLink");
		return message;
	},
	
	getFullClassTooltip : function() {
		return HD.REO.View.List.template.fullClassTooltip;
	},
	
	getOpenClassTooltip : function(open, total) {
		var message = HD.REO.View.List.template.openClassTooltip;
		message = message.replace(/_OPEN/, open);
		message = message.replace(/_TOTAL/, total);
		return message;
	},
	
	getWaitlistClassTooltip : function(open, total) {
		var message = HD.REO.View.List.template.waitlistClassTooltip;
		message = message.replace(/_OPEN/, open);
		message = message.replace(/_TOTAL/, total);
		return message;
	},
	
	getCourseSubTypeInfo : function(courseType) {
		var info = HD.REO.View.List.template.courseSubTypesInfos[courseType];
		if(info == null) {
			info = "";
		}
		return info;
	},
	
	getDealerContact : function(dealer) {
		var address = dealer.address;
		var phone = dealer.phone;
		
		return [
			'<ul class="hdContactAddress">',
				'<li class="shopName">', dealer.name, '</li>',
				'<li class="shopAdd">', address.street1, '</li>',
				'<li class="shopCity">', address.city, ', ', address.state, ' ', address.zip, '</li>',
				'<li class="shopPh">(', phone.npa, ') ', phone.nxx, '-', phone.station, '</li>',
			'</ul>',
			'<ul class="hdContactInfo">',
				'<li class="maps"><a href="javascript:void(0)" onclick="', HD.REO.getDealerHref(dealer) ,'" class="hdMapDirectionsHours">Map, Directions & Hours</a></li>',
				'<li class="REcontact">Rider\'s Edge Contact</li>',
				'<li class="RECntctName">',
					'<a class="hdLink" href="mailto:', dealer.contactEmail, '">', dealer.contactName, '</a> (', dealer.contactEmail, ')',
				'</li>',
				( dealer.url != null ? '<li class="hdContactUrl">Website<br/><a class="hdLink" href="' + dealer.url + '">' + dealer.url + '</a></li>' : ''),
			'</ul>'
		].join('');
	}
};

HD.REO.View.List.prototype = {
	/**
	 * @see HD.Widget#update 
	 */
	update : function(eventName, eventData) {
		if(eventName == "model_GetCourseList_Start") {
			this.loading(true);
		} else if(eventName == "model_GetCourseList_Finish") {
			this.loading(false);
			this.render(eventData);
		} else if(eventName == "model_SetSelectedCourse_Finish") {
			this.view.notifyObservers("listView_CourseEnroll_Click", eventData.id);
		} else if(eventName == "searchView_Invalid_Parameters" || eventName == "searchView_New_Search" || eventName == "searchView_Validation_Error") {
			this.clearResults();
		}
	},
	
	/**
	 * @see HD.Widget#loading 
	 */
	loading : function(isLoading) {
		this.clearResults();
	},
	
	/**
	 * Clears search results.
	 */
	clearResults : function() {
		this.getParent().innerHTML = "";
	},
	
	/**
	 * @see HD.Widget#setListeners 
	 */
	setListeners : function(data) {
    	var courses = data.courses;
    	
    	if(courses == null || courses.length < 1) {
    		return;
    	}
		
		var parentEl = this.getParent();
		var dom = HD.util.Dom;
		
		var courseEls = dom.getByClass("hdItem", "div", parentEl);
		var pagingEls = dom.getByClass("hdPaging", "div", parentEl);
		var numOfItemsEl = dom.getByClass("hdNumOfItems", "div", parentEl)[0];
		var viewAllEls = dom.getByClass("hdViewAll", "span", numOfItemsEl);
		var viewSomeEls = dom.getByClass("hdViewSome", "span", numOfItemsEl);
		var toTopEl = dom.getByClass("hdToTop", "div", parentEl)[0];
		var sortEl = dom.get("hdSort");
		
		var cb = this;
		var viewCb = this.view;
		var modelCb = this.model;
		for(var i = 0, len = courseEls.length; i < len; i++) {
			this.setItemListener(courseEls[i], courses[i]);
		}
		
		this.paging = new HD.util.Paging({
			startingPage : 1,
			containers : pagingEls
		}, this.view);
		
		this.paging.render(data);
		
		if(viewAllEls.length > 0 && viewSomeEls.length > 0) {
			viewAllEls[0].onclick = function() {
				cb.viewAll = true;
				dom.addClass(viewSomeEls[0], "hdLink");
				dom.removeClass(viewAllEls[0], "hdLink");
				viewCb.notifyObservers.call(viewCb, "listView_ViewAll_Click");
			};
			
			viewSomeEls[0].onclick = function() {
				cb.viewAll = false;
				dom.addClass(viewAllEls[0], "hdLink");
				dom.removeClass(viewSomeEls[0], "hdLink");
				viewCb.notifyObservers.call(viewCb, "listView_ViewSome_Click");
			};
		}
		
		sortEl.onchange = function() {
			var selectedValue = this.options[this.selectedIndex].value;
			cb.sortType = selectedValue;
			viewCb.notifyObservers.call(viewCb, "listView_Sort_Change", selectedValue);
		};
		
		toTopEl.onclick = function() {
			dom.scrollToTop();
		};
	},
	
	/**
	 * Sets event listeners for an individual item.
	 * 
	 * @param {String|HTMLElement} courseEl the course UI element
	 * @param {Object} courseData the course data
	 */
	setItemListener : function(courseEl, courseData) {
		var dom = HD.util.Dom;
		var cb = this;
		var viewCb = this.view;
		var dealer = courseData.dealer;
		var courseId = courseData.id;
		var dealerId = dealer.id;
		
		
		var summaryEl = dom.getByClass("hdSummary", "div", courseEl)[0];
		var detailsEl = dom.getByClass("hdDetails", "div", courseEl)[0];
		var scheduleEl = dom.getByClass("hdSchedule", "div", courseEl)[0];
		var enrollEl = dom.getByClass("hdEnroll", "div", courseEl)[0];
		var openingsEl = dom.getByClass("hdCourseOpenings", "div", courseEl)[0];
		var tooltipEls = dom.getByClass("hdTooltip", "div", courseEl);
		var typeEl = dom.getByClass("hdType", "div", courseEl)[0];
		var typeLinkEls =  dom.getByClass("hdLink", "span", typeEl);
		
		var modelCb = this.model;
		var expand = function() {
			modelCb.getCourseDetails.call(modelCb, {courseId:courseId, dealer:dealer});
			
			var myAnim = new YAHOO.util.Anim(courseEl, {
			   height: { from: 32, to: 170}
			});
			
			myAnim.duration = 0.3;
			myAnim.animate();
			
			myAnim.onComplete.subscribe(function() {
				dom.removeClass(courseEl, "hdCollapsed");
				dom.addClass(courseEl, "hdExpanded");
			});
		};
		
		var collapse = function() {
			var myAnim = new YAHOO.util.Anim(courseEl, {
			   height: { from: 170, to: 32}
			});
			
			dom.removeClass(courseEl, "hdExpanded");
			dom.addClass(courseEl, "hdCollapsed");
			
			myAnim.duration = 0.3;
			myAnim.animate();
		};
		
		var isExpanded = false;
		summaryEl.onclick = function() {
			isExpanded = !isExpanded;
			if(isExpanded) {
				expand();
			} else {
				collapse();
			}
		};
		
		var scheduleView = new HD.REO.View.Schedule({
			parent : scheduleEl,
			courseId : courseId,
			dealerId : dealerId
		}, this.model, this.view);
		
		scheduleView.addObserver({
			update : function(eventName, eventData) {
				if(eventName == "detailView_Close_Click") {
					collapse();
				}
			}
		});

		var enrollView = new HD.REO.View.Enroll({
			parent : enrollEl,
			courseId : courseId,
			dealerId : dealerId
		}, this.model, this.view);
		
		openingsEl.onmouseover = function() {
			dom.show(tooltipEls[0]);
		};
		
		openingsEl.onmouseout = function() {
			dom.hide(tooltipEls[0]);
		};
		
		if(typeLinkEls.length > 0) {
			typeLinkEls[0].onmouseover = function() {
				dom.show(tooltipEls[1]);
			};
			
			typeLinkEls[0].onmouseout = function() {
				dom.hide(tooltipEls[1]);
			};
		}
	},
	
	/**
	 * @see HD.Widget#getHtml 
	 */
	getHtml : function(data) {
    	var classes = HD.CSS_CLASSES;
    	var reoClasses = HD.REO.View.CSS_CLASSES;
    	var template = HD.REO.View.List.template;
    	
    	var courses = data.courses;
    	
    	if(courses == null || courses.length < 1) {
    		return "";
    	}
    	
    	var firstIndex = 1 + ((data.pageNumber - 1) * data.pageSize);
    	var lastIndex = firstIndex - 1 + data.pageSize;
    	
    	if(lastIndex > data.totalItems) {
    		lastIndex = data.totalItems;
    	}
    	
    	var html = ['<div class="', classes.WIDGET, ' ', reoClasses.LIST ,'">',
    	            	'<div class="hdControlHeader">',
					    	'<div class="showing">', template.getShowingNumbers(firstIndex, lastIndex, data.totalItems), '</div>',
					    	'<div class="hdListSort">',
					    		'<span>',
						    		'<select id="hdSort" name="hdSort" class="hdSort">',
						    			'<option value="', HD.REO.template.sortByDate, '" ', (this.sortType == HD.REO.template.sortByDate ? ' selected' : ''), '>Sort By Date</option>',
						    			'<option value="', HD.REO.template.sortByDistance, '" ', (this.sortType == HD.REO.template.sortByDistance ? ' selected' : ''), '>Sort By Distance</option>',
						    		'</select> ',
						    	'</span>',
						    	'<div>&nbsp;</div>',
					    	'</div>',
					    	'<div class="hdNumOfItems">', template.getViewSomeViewAll(data.pageSize, data.totalItems, this.viewAll), '</div>',
					    	'<div class="hdPaging">&nbsp;</div>',
    	            	'</div>'];

    	for ( var i = 0, len = courses.length; i < len; i++) {
			var course = courses[i];
			var dealer = course.dealer;
			var address = dealer.address;
			var phone = dealer.phone;
			var schedule = course.schedule;
			var classDays = [];
			
			if(schedule != null && schedule.classes != null) {
				for(var j = 0, len1 = schedule.classes.length; j < len1; j++) {
					classDays.push(schedule.classes[j].startTime);
				}
			}
			
			var openingClass = reoClasses.FULL;
			var openingText = "Full";
			var openTooltip = template.getFullClassTooltip();
			if(course.openSeats > 0) {
				openingClass = reoClasses.OPEN;
				openingText = "Open";
				openTooltip = template.getOpenClassTooltip(course.openSeats, course.totalSeats);
			} else if(course.waitlistSeats > 0) {
				openingClass = reoClasses.WAITLIST;
				openingText = "Waitlist";
				openTooltip = template.getWaitlistClassTooltip(course.waitlistSeats, course.totalWaitlistSeats);
			}
			
			var typeTooltip = template.getCourseSubTypeInfo(course.subType);
			
			html.push([
				'<div class="hdItem hdCollapsed">',
					'<div class="hdTooltip hdEnrollTooltip hdHidden">',
						openTooltip,
					'</div>',
					'<div class="hdTooltip hdTypeTooltip hdHidden">',
						typeTooltip,
					'</div>',
					'<div class="hdSummary">',
						'<div class="expnd">',
							'<div class="hdExpand">&nbsp;</div>',
							'<div class="hdCollapse">&nbsp;</div>',
						'</div>',
						'<div class="rsltDate">',
							'<span class="clssDates">', HD.util.Date.formatSpan(course.startDate, course.endDate) ,'</span>',
							'<span class="clssDays">', HD.util.Date.formatDaySpan(classDays, 'ddd', ', ') ,'</span>',
						'</div>',
						'<div class="rsltLoc">',
							'<span class="locName">', dealer.name, '</span>',
							'<span class="locCity">', address.city, ', ', address.state, '</span>',
						'</div>',
						'<div class="hdDistance"><span>', Math.round(course.distance), ' mi.</span><div>&nbsp;</div></div>',
						'<div class="hdType">',
							, (HD.util.Common.hasValue(course.subTypeName) ? course.subTypeName + ' <span class="hdLink">(?)</span>': '&nbsp;') , 
						'</div>',
						'<div class="hdCourseOpenings">',
							'<span class="hdOpenings ', openingClass ,'">&nbsp;</span><span class="statWrd">', openingText, '</span>',
						'</div>',
					'</div>',
					'<div class="hdDetails">',
						'<div class="hdSchedule">...</div>',
						'<div class="hdContact"><h4>Address & contact Info</h4>',
							template.getDealerContact(dealer), 
							'<span class="hdDistance"><span>', Math.round(course.distance), ' mi.</span><div>&nbsp;</div></span>',
						'</div>',
						'<div class="hdEnroll">...</div>',
					'</div>',
				'</div>'].join(''));
		}
    	
    	html.push(	['<div class="hdControlFooter">',
				    	'<div class="hdToTop">Back to Top</div>',
				    	'<div class="hdPaging">&nbsp;</div>',
				    '</div>'].join(''));
    	
    	html.push('</div>');
    	
    	return html.join('');
	}
};

HD.util.Common.extend(HD.REO.View.List, [HD.Widget]);
