/**
 * @author Tyler Gaw <tylerg@arc90.com>
 *
 * Javascript document for University Page specifics.
 *
 * TODO BEFORE RELEASE: Change the urls at 
 *                      GradeGuru.university.courses.baseUrl
 *                      GradeGuru.university.courseSearch.baseUrl
 *
 */

GradeGuru.university = {
	
	// The ID of this university, pulled from the URL
	// @member INT
	id: null,
	
	// US or UK
	// @member STRING 'us' or 'uk'
	locale: null,
	
	// The correct name 'courses' or 'modules'
	// @see setLocale()
	// @member STRING
	localName: null,
	
	// Method that is called on page load to start things up
	init: function ()
	{
		this.setId();
		this.setLocale();
		this.cleanDisplay();
		this.subjects.init();
		this.courseSearch.init();
		this.welcomeBanner();
	},

	// Grab the University ID from the URL and store it for later use
	setId: function ()
	{
		var idQuery = 'university_id=';
		
		// We're using parseInt here as a fail safe. Just in case there are
		// other query parameters, we'll parse out anything after the uni id
		this.id = parseInt(window.location.search.split(idQuery)[1], 10);
	},
	
	// There are a number of differences between US and UK implementations
	// glean the country from the header and store it for later
	setLocale: function ()
	{
		var locationText = $('#university-header h2 em').text().toLowerCase(),
			usTest = 'united states of america';
		
		if(locationText.indexOf(usTest) !== -1)
		{
			this.locale = 'us';
			
			// For now we only have one word that needs to be different
			// set it manually here
			this.localName = 'courses';
		}
		else
		{
			this.locale = 'uk';
			this.localName = 'modules';
		}
	},
	
	// Build options for use with the jquery.pager plugin
	pagerOptions: function (page, pagecount, callback)
	{
		return {
			pagenumber: page, 
			pagecount: pagecount,
			buttonClickCallback: callback,
			emptyClass: 'disabled', 
			currentClass: 'active', 
			specialClass: 'arrow',
			prevLabel: '&lt;', 
			nextLabel: '&gt;',
			displayFirstLast: false
		};
	},
	
	// Fix some weird all-caps on the uni city name and
	// Some special consideration for the University name and optional logo
	cleanDisplay: function ()
	{		
		var length = 0,
			cityCorrectCaps = GradeGuru.core.utils.ucwords($('#university-header h2 em').text().toLowerCase());
			
		$('#university-header h2 em').text(cityCorrectCaps);
		
		if ($('#uni-crest').length === 0) 
		{
			$('#university-header h2').css({'max-width': '48%', 'min-width': '48%'})
			length = 40;
		}
		else
		{
			length = 35;
		}
		
		$('#university-header h2 span').truncate({max_length: length});
	},
	
	// Display a banner explaining GradeGuru with a sign up link
	// @dependency gradeguru.registration.js
	welcomeBanner: function ()
	{
		// First we'll check for a cookie to see if the user
		// has already seen and closed the banner, if so remove it
		
		//Changes by Sanjeev
		
		//if (GradeGuru.core.cookie.get('university.dismissBanner') !== null)
		//{
			//$('#welcome-banner').remove();
		//}
		
		if (GradeGuru.core.cookie.get('university.dismissBanner') == null)
		{
			$('#welcome-banner').show("slow");
		}
		
		$('#banner-signup').colorbox({href: GradeGuru.registration.urls.signUp});
		
		$('#banner-close').click(
			function ()
			{
				// Set a cookie so we don't show the banner to this user again
				GradeGuru.core.cookie.set('university.dismissBanner', true, 30);
				
				// Fade out then slide up the banner
				$(this).closest('div').animate({opacity: 0}, 200).slideUp(200, 
					function ()
					{
						$(this).remove();
					}
				);
			}
		);
	},
	
	// The list of available subjects
	subjects: {
		
		// Run a couple of initial cleanups on data, correct caps and truncating then
		// bind the subject clickhandler and load the first subject's courses
		init: function ()
		{
			this.displayCleanup();
			$('#subjects-list li').click(this.clickHandler);
			this.loadFirstSubject();
		},
		
		// First check for a hash in the url of a subject to load
		// if there is not a hash we'll find the first subject in 
		// the list and load its courses
		loadFirstSubject: function ()
		{
			var hash = window.location.hash,
				
				// jQuery li object
				selectedSubject = null,
				
				// Decoded hash of the subject sent through the hash
				subjectName = '',
				
				// The jQuery collection of subjects
				subjects = $('#subjects-list li'),
				subjectPerPage = this.paging.displayMax;
			
			if (hash)
			{
				
				// Load the subject from the hash
				subjectName = decodeURIComponent(hash.replace('#', ''));
				
				// Store the selected subject li jQuery object
				selectedSubject = subjects.find("strong:contains('" + subjectName + "')").parent().parent();
				
				// We need to advance to the right 'page' of subjects
				// so we have to find which page the selected subject is on
				// by using the position of the selected (index) 
				// and the number we display per page
				this.paging.init(Math.ceil((subjects.index(selectedSubject) + 1) / subjectPerPage));
				
				// Load the subject
				selectedSubject.click();
			}
			else
			{
				$('#subjects-list li:first').click();
				this.paging.init(1);
			}
		},
		
		// Update the subject-meta information
		// Then build the courses query string
		// and pass it off to the course loading
		clickHandler: function ()
		{	
			// Deactivate the previously selected item, activate the current
			$(this).addClass('active').siblings().removeClass('active');
			
			// Pass courses the selected subject so we can extract
			// some information from it
			GradeGuru.university.courses.init($(this));
			
			return false;
		},
		
		// Truncate long names and properly capitalize
		displayCleanup: function ()
		{
			$('#subjects-list li a strong').each(
				function ()
				{
					var correctCaps = GradeGuru.core.utils.ucwords($(this).text().toLowerCase());
					$(this).text(correctCaps);
					$(this).truncate({max_length: 32 });
				}
			);
		},
		
		paging: {
			
			displayMax: 10,
			
			init: function (page)
			{
				var $this = GradeGuru.university.subjects.paging,
					displayMax = $this.displayMax,
					startPoint = (page - 1) * displayMax,
					endPoint = startPoint + displayMax,
					numItems = $('#subjects-list li').length,
					displayEnd = (endPoint > numItems) ? numItems : endPoint,
					pageCount = Math.ceil(numItems / displayMax);
				
				// Set pages/current display text
				$('#subjects-paging dt').html((startPoint + 1) + "&ndash;" + displayEnd + " of " + numItems + " Subjects");
				
				$('#subjects-paging dd').pager(GradeGuru.university.pagerOptions(page, pageCount, $this.init));
				
				// Show/Hide the correct set of subjects
				$('#subjects-list li').each(
					function (i)
					{
						if(i < startPoint || i > endPoint - 1)
						{
							$(this).hide();
						}
						else
						{
							$(this).show();
						}
					}
				);
			}
		}
	},
	
	courses: {
		
		// Prod
		baseUrl: 'moduleListViewActionnlu.do?SearchModule=false',
		
		// Dev
		//baseUrl: '../api/courses/courses.json',
		
		// Store the subject ID to use when making paging requests
		subjectId: null,
		
		// The total number of courses. We use this for paging
		total: 0,
		
		// @param OBJ subject - a jQuery object of the selected subject
		init: function (subjectObj)
		{
			var $this = GradeGuru.university.courses,
				idPrefix = 'subject-',
				url = '',
				aCopy,
				subjectName = '';
				
			// Store the subject ID
			$this.subjectId = subjectObj.attr('id').replace(idPrefix, '');
			
			// Set the subject name
			subjectName = subjectObj.find('strong:first').text().replace('...', '');
			$('#subject-name').html(subjectName);
			
			// Set the window hash to this subject
			window.location.hash = subjectName;
			
			// We need to extract the total from the <a> tag
			// but the text is not in an element, so we have to clone
			// the <a> remove the extra <strong> and then grab the trimmed text
			aCopy = subjectObj.find('a:first').clone();
			aCopy.find('strong').remove();
			$this.total = aCopy.text().trim();

			// If this subject has no courses, we need to display the empty state
			if ($this.total > 0)
			{
				$this.paging.init(1);
			}
			else
			{
				$this.emptyState();
			}
		},
		
		// Create a URL for the course resourse
		// @param INT disciplineId - AKA Subject ID
		// @param INT startIndex - zero based index of the course to start from
		// @return STRING url - The location of the courses set we want
		buildUrl: function (disciplineId, startIndex)
		{
			var url = this.baseUrl;
			url += '?SearchModule=false';
			url += '&disciplineId=' + disciplineId;
			url += '&startIndex=' + startIndex;
			
			return url;
		},
		
		// Load a page of courses in the selected subject
		// @param STRING url - The URL of the courses
		load: function (url)
		{
			var $this = GradeGuru.university.courses;
			
			$('#courses-list').html('<p id="course-loading">Loading...</p>');
			
			$.ajax(
				{
					dataType: 'json',
					url: url,
					success: function (data)
					{ 
						GradeGuru.university.courses.parse(data.courses);
					}
				}
			);
		},
		
		// Create the list of courses
		// @param OBJ courses
		parse: function (courses)
		{
			var html       = '<ul>', 
				displayMax = 36, 
				breakPoint = 12, 
				count      = 0;
			
			$.each(courses, 
				function (i, item)
				{
					var hasNotes = '';
					
					count++;
					
					if (i < displayMax)
					{
						// We want courses that have notes to be called out,
						// so we'll put an extra class on those that do
						if (item.notes > 0)
						{
							hasNotes = ' class="has-notes" ';
						}
						
						html += '<li' + hasNotes + '><a href="' + item.url + '">' + item.name + '</a></li>';
                		
						// If we have the max number we want in a column,
						// start a new one
						if (count === breakPoint)
						{
							html += '</ul><ul>';
							count = 0;
						}
					}
					else
					{
						return false;
					}
				}
			);

			$('#courses-list').html(html);
			$('#courses-list ul:last').addClass('last-item');
			$('#courses-list li a').truncate({max_length: 25});
		},
		
		// If there are no courses, display a message saying so and give calls to action
		emptyState: function ()
		{			
			var $this = GradeGuru.university.courses,
				shareUrl = 'notesUploadViewAction.do',
				inviteUrl = 'invitationViewActionnlu.do?universityId=' + GradeGuru.university.id + '&amp;selectedDisciplineId=' + $this.subjectId,
				emptyHtml = '';
			
			emptyHtml += '<div id="subject-empty-state">';
			emptyHtml += '<p><strong>Be the first to start sharing notes in this subject area.</strong> Create a course, share your notes and invite your classmates.</p>';
			emptyHtml += '<ul>';
			emptyHtml += '<li><a href="' + shareUrl +'" class="button made-large share-notes-icon"><span>Share Notes</span></a></li>';
			emptyHtml += '<li><a href="' + inviteUrl + '" class="button made-large invite-classmates-icon"><span>Invite Classmates</span></a></li>';
			emptyHtml += '</ul>';
			emptyHtml += '</div>';
			
			$('#courses-list').html(emptyHtml);
			
			// Clear paging html
			$('#courses-paging dt, #courses-paging dd').html('');
		},
		
		paging: {			
			init: function (page)
			{
				var $this = GradeGuru.university.courses,
					displayMax = 36,
					startPoint = (page - 1) * displayMax,
					endPoint = startPoint + displayMax,
					numItems = $this.total,
					displayEnd = (endPoint > numItems) ? numItems : endPoint,
					pageCount = Math.ceil(numItems / displayMax),
					correctNoun = GradeGuru.core.utils.ucwords(GradeGuru.university.localName);

				// Set pages/current display text
				$('#courses-paging dt').html((startPoint + 1) + '&ndash;' + displayEnd + ' of ' + numItems + ' ' + correctNoun);
				
				$('#courses-paging dd').pager(GradeGuru.university.pagerOptions(page, pageCount, $this.paging.init));
				
				// Load the selected page of courses
				$this.load($this.buildUrl($this.subjectId, (endPoint - displayMax)));
			}
		}
	},
	
	// Course suggestion search
	courseSearch: {
		
		// Prod
		url: 'moduleListViewActionnlu.do?SearchModule=true',
		
		// Dev
		//url: '../api/courses/courses.json?SearchModule=true',
		
		// Bind the search input to the filterlist() plugin
		init: function ()
		{
			var $this = this;
			
			$('#course-search-input').smartinput()
				.attr({'autocomplete':'off', 'maxlength':'65'})
				.filterlist(
					{
						data: function (e)
						{
							return 'q=' + e.val();
						},
						url: $this.url,
						dataType: 'json',
						minChars: 3,
						before: $this.prepare,
						error: function ()
						{
							var errorMsg = {
								'debug': 'File: gradeguru.university.js \nLoc: GradeGuru.university.courseSearch \nMethod: Ajax error()',
								'friendly': 'We seem to be having some technical difficulties, please try again'
							};
							GradeGuru.core.utils.debug.alert(errorMsg);
						},
						success: function (data) 
						{ 
							$this.parse(data.courses);
						}
					}
				);
		},
		
		// Create or update the markup to display the search results
		prepare: function ()
		{
			// If the status message is not displayed, display it
			// if it is, just modify it
			if($('#course-search-status').length === 0)
			{
				$('#course-search-form fieldset').append('<span id="course-search-status" class="searching">Searching...</span>');
			}
			else
			{
				$('#course-search-status').attr('class', 'searching').html('Searching...');
			}

			// Append the results container to the DOM if it doesn't exist
			if($('#course-search-results').length === 0)
			{
				$('#course-search-container').append('<div id="course-search-results" style="display:none;"></div>');
			}

			if($('a.btn-clear').length === 0)
			{
				$('#course-search-container').append('<a class="btn-clear"></a>');
				$('a.btn-clear').click(GradeGuru.university.courseSearch.clear);
			}
		},
		
		// Create the markup from the courses json object
		parse: function (results)
		{
			var totalResults = results.length, 
				searchQuery, 
				html = '<ul>', 
				count = 0,
				
				// Math to create smart, multiple columns
				minRowCount = 80, 
				midPoint    = Math.ceil(totalResults * 0.5),
				breakPoint  = (midPoint < minRowCount) ? minRowCount : midPoint;
				
			if (totalResults > 0)
			{
				searchQuery = $('#course-search-input').val();

				$.each(results, 
					function (i, item)
					{
						var matched = GradeGuru.core.utils.searchMatch(item.name, searchQuery);
						
						// We want to treat courses with notes differently
						hasNotes    = (item.notes > 0) ? "class='has-notes'" : "";					
						
						// This is for demo purposes only, results shouldn't return if not searched for
						if (matched)
						{
							html += "<li " + hasNotes + "><a href='" + item.url + "'>" + matched + "</a></li>";
							
							// If we've reached the max amount we want in a column, start a new one
							count += 1;
							if (count === breakPoint)
							{
								html += '</ul><ul>';
							}
						}
					}
				);
				
				$('#course-search-results').html(html).slideDown();
				
				// This is probably not really necessary, but I didn't want to 
				// declare yet another variable to hold the 'results' string.
				(function (count)
				{
					var t;
					
					if (count > 1)
					{
						t = ' results';
					}
					else
					{
						t = ' result';
					}
					
					$('#course-search-status').attr('class', 'has-results').html('Your search returned ' + count + t);
				})(count);
			}
			else
			{
				$('#course-search-status').attr('class', 'no-results').html('Your search returned 0 results');
			}
		},
		
		// Remove the search results and clear the input
		clear: function ()
		{
			$(this).remove();
			$('#course-search-status').remove();
			$('#course-search-input').val('').blur();
			$('#course-search-results').slideUp(200, 
				function()
				{
					$(this).remove();
				}
			);
		}
	}
};

$(document).ready(function () {
	
	// We don't want this just running everywhere,
	// so check for the correct id.
	if ($('#university').length !== 0)
	{
		GradeGuru.university.init();
	}
});