/**
 * @author Tyler Gaw <tylerg@arc90.com>
 *         Alex Gutierrez <alexg@arc90.com>
 *
 * Javascript document for the user dashboard
 * a user's "home base." Organization and maintenance of their activity,
 * classes, notes, saved, rewards, and rating notifications
 *
 */

GradeGuru.dashboard = {
	
	// Empty sections object so we can store each tab of the dashboard
	// in its own object. (i.e. dashboard.sections.classes)
	sections: {},
	
	// The URL pattern for each section '$' is replaced with the filename
	// @config - This might need to change?
	sectionURLPattern: 'sections/$.html',
	
	// Start up the dashboard.
	// Check for a #section hash in the url. If there is
	// one navigate to that section of the dashboard
	init: function ()
	{
		// First thing, I'm checking that we're on Dashboard
		// so we can run a hash check for back/forward navigation
		if ($('#dashboard-navigation').length !== 0)
		{
			// Check for a #section sent through the URL
			var section = window.location.href.split('#')[1];
			this.loadSection(section);
			
			GradeGuru.core.utils.hashCheck.init(
				function (hash)
				{
					var section = hash.split('#')[1];
					GradeGuru.dashboard.loadSection(section);
				}
			);			
		}
		
		this.activationEmailResend();
		this.getSemesters();
		this.getClasses();
	},
	
	// Allow the user to request their activation email be sent again
	activationEmailResend: function ()
	{
		$('#activation-email-resend').live('click',
			function ()
			{
				var linkContainer = $(this).parent();
				
				$.ajax(
					{
						// @config - URL for email activation
						url: GradeGuru.config.sendActivationEmail,
						
						success: function ()
						{
							// Store the old message
							var prevMsg = linkContainer.html();
							
							// Overwrite the old message with a success message
							linkContainer.html("We've sent the email again, it should be in your inbox shortly.").effect('highlight', {'color': '#FFFF00'}, 1000);
							
							// Wait a sec, then revert to the old message
							setTimeout(
								function ()
								{
									linkContainer.html(prevMsg);
								}, 5000
							);
						},
						
						error: function ()
						{
							alert("We're having some technical difficulties, please try again.");
						}
					}
					
				);
				return false;
			}
		);
	},
	
	// Change to a different dashboard section
	// @param STRING section - Optional, the section of the tab to load
	// @param BOOL ignore404 - Optional for links on the dashboard with #hashes 
	//                         that are not dashboard links
	loadSection: function (section, ignore404)
	{
		var $this = GradeGuru.dashboard,
			url;
		
		// If there is no section (hash) sent,
		// set the section to the first tab
		if (!section)
		{
			section = $('#dashboard-navigation a:first').attr('href').split('#')[1];
		}
		
		url = $this.sectionURLPattern.replace('$', section);
		
		$this.setActiveSection(section);
		$this.loader.show($('#dashboard-section-container').innerHeight());
		
		$.ajax({
			type: 'GET',
			dataType: 'html',
			url: url,
			error: function (xhr, textStatus, errorThrown)
			{
				// Some links will call the Ajax request and get a 404,
				// if they are not supposed to open a section of the dashboard,
				// but open a different URL, then do not warn about the 404
				//
				if (!ignore404)
				{
					alert(GradeGuru.core.utils.requestError(xhr));
				}
			},
			success: function (data)
			{				
				$this.loader.hide();
				$('#dashboard-section-container').html(data);
				GradeGuru.dashboard.sections[section].init();
			}
		});
	},
	
	// Set the active tabs class active, remove active from any other tabs
	// @param STRING section - A string containing a dashboard section
	setActiveSection: function (section)
	{
		var tab = $("#dashboard-navigation li a[href='#" + section + "']");
		tab.addClass('active');
		tab.parent().siblings().find('a').removeClass('active');
	},
	
	// Loader visual to display while waiting for each section
	loader: {
		show: function (containerHeight)
		{
			var loader = $('<div/>', {
				'id': 'dashboard-loading',
				html: '<span>Loading...</span>',
				css: {
					height: containerHeight
				}
			});
			
			loader.insertBefore($('#dashboard-section-container'));
		},
		
		hide: function ()
		{
			$('#dashboard-loading').remove();
		}
	},
	
	// The current semester from the user's university
	// or the semester they last selected
	// @member - OBJ - e.g. {'id':'3', 'title':'Spring 2010'}
	currentSemester: null,
	
	// Check to see if the user has set a current semester
	// by checking for the existence of the current semester cookie
	getCurrentSemester: function ()
	{
		if (GradeGuru.core.cookie.get('dashboard.currentSemester') !== null)
		{
			GradeGuru.dashboard.currentSemester = JSON.parse(GradeGuru.core.cookie.get('dashboard.currentSemester'));
		}
		else
		{
			// If we don't have a current semester, from a cookie,
			// we need to find the current one in the data
			$.each(GradeGuru.dashboard.semesters,
				function (i, semester)
				{						
					if (semester.current)
					{
						GradeGuru.dashboard.currentSemester = semester;
						GradeGuru.core.cookie.set('dashboard.currentSemester', JSON.stringify(semester), 30);
						return false;
					}
				}
			);
		}
	},
	
	// Since we need to build the list of semesters for the
	// user in a couple different places. We'll make one call
	// and store the response here
	semesters: null,
	
	// Get the semesters for this user's university
	// by making a server call to retrieve them
	getSemesters: function ()
	{
		// @config - URL location
		var url = GradeGuru.config.universities.university01.semesters;

		$.ajax(
			{
				type: 'GET',
				dataType: 'json',
				url: url,
				success: function (data)
				{
					GradeGuru.dashboard.semesters = data.semesters;
					GradeGuru.dashboard.getCurrentSemester();
				}
			}
		);
	},
	
	// Storage for the user's classes. We use this so we only need to make
	// one call to the server and can use the classes in multiple places
	classes: null,
	
	// Retrieve the user's classes from the server or from the 
	// dashboard.classes cookie if it has been set
	getClasses: function ()
	{
		// @config - URL location
		var url = GradeGuru.config.users.user01.classes;
		
		$.ajax(
			{
				type: 'GET',
				dataType: 'json',
				url: url,
				success: function (data)
				{
					GradeGuru.dashboard.classes = data.classes;
				}
			}
		);
	}
};


/**
 * Dashboard Section: Classes
 * Classes that the user has added to his schedule.
 * The user can add new classes to their schedule or remove classes
 *
 * @dependencies - gradeguru.classes.js
 *
 */
GradeGuru.dashboard.sections.classes = {
	
	init: function ()
	{
		// First we need to check for any cookies
		// Right now we are storing the user's university semesters
		if (GradeGuru.core.cookie.get('dashboard.semesters') !== null)
		{
			GradeGuru.dashboard.semesters = JSON.parse(GradeGuru.core.cookie.get('dashboard.semesters'));
		}
		
		this.semesterSelect.build();
		this.add.init();		
	},
	
	semesterSelect: {
		
		// Build the list of semesters that the user can choose
		// from. Semesters are stored in GradeGuru.dashboard.semesters
		build: function ()
		{
			var classes = GradeGuru.dashboard.sections.classes,
				options = '',
				activeOption,
				listOptions,
				checkInterval = 0;
			
			// Create the standard elements
			activeOption = $('<li/>', 
			{
				'class': 'drop-menu-title',
				'id': 'semester-active'
			});
			
			listOptions = $('<li/>',
			{
				'class': 'drop-menu-items'
			});
			
			$('#semester-select').append(activeOption).append(listOptions);
			activeOption.append('<a rel=""></a>');			
			listOptions.append($('<ul/>'));
			
			// We need to put the actual iteration over the semesters object
			// in a function here so we can call it later when we've made
			// certain that the semesters have been retrieved
			function parseOptions ()
			{
				$.each(GradeGuru.dashboard.semesters,
					function (i, semester)
					{						
						options += '\n<li><a rel="' + semester.id + '">' + semester.title + '</a></li>';
					}
				);
				
				listOptions.find('ul').append(options);
				classes.semesterSelect.setActive();
				classes.list.init();
			}
			
			// Check check to see if the semesters have been retrieved from the server
			// when they have finish building the list
			checkInterval = setInterval(
				function ()
				{
					if (GradeGuru.dashboard.currentSemester !== null)
					{
						parseOptions();
						clearInterval(checkInterval);
					}
				}, 100);
		},
		
		// Set the visual display of the active semester
		// in the drop down list
		// @param OBJ [optional] semester - An object containing at least 'id' and 'title' members
		setActive: function (semester)
		{
			var s = semester || GradeGuru.dashboard.currentSemester,
				userData = GradeGuru.core.user.getData();

			// Set the attributes for the drop down title
			$('#semester-active a:first').attr('rel', s.id).text(s.title);
			
			// Set the semester active in the drop down
			$("li.drop-menu-items a[rel='" + s.id + "']").parent().addClass('active')
				.siblings().removeClass('active');
				
			// If the semester param is passed, we need to update
			// the semester storage object and cookie
			if (semester)
			{
				GradeGuru.dashboard.currentSemester = semester;
				GradeGuru.core.cookie.set('dashboard.currentSemester', JSON.stringify(semester), 30);
				
				// We also need to make a call to store the user's
				// semester choice server side.
				$.ajax(
					{
						type: 'POST',
						
						// @config - url
						url: GradeGuru.config.users.updateSemester,
						
						data: {
							'semester': semester.id
						},
						contentType: 'application/json'
					}
				);
			}
			
		}
	},
	
	// Manage the list of classes.
	list: {
		
		init: function ()
		{								
			this.updateDisplay();
			this.bindEvents();
		},
		
		// Update display of classes
		updateDisplay: function ()
		{
			var $this = GradeGuru.dashboard.sections.classes,
				classes = GradeGuru.dashboard.classes,
				classHtml = '';
			
			$('#class-list').html('<div id="semester-loading"></div>');
			
			if (classes.length === 0)
			{
				// Handle if the user has no classes in any semester
			}
			else
			{
				// Build the <li> element for each class from the dashboard.classes object
				$.each(classes, 
					function (i, classObj)
					{						
						if (classObj.semester.id === GradeGuru.dashboard.currentSemester.id)
						{
							classHtml += $this.generateClassHtml(classObj);
						}
					}
				);
				
				// We need one more check to see if this semester has classes
				if (classHtml === '')
				{
					$('#class-list').html('<p class="empty-message">Looks like you haven\'t added any classes to your <strong>' + GradeGuru.dashboard.currentSemester.title + '</strong> semester.</p>');
				}
				else
				{
					// Append the <li>s to the <ul>
					$('#class-list').html(classHtml);
				}
			}
		},
				
		// We have quite a few events to event that need to be live for the classes
		bindEvents: function ()
		{
			var $this = GradeGuru.dashboard.sections.classes,
				controls = $('p.class-controls a');
			
			// Bind a click event to our semester drop down items
			//
			$('#content-main').delegate('#semester-select li.drop-menu-items li a', 'click',
				function ()
				{
					var semester = {
						'id': $(this).attr('rel'),
						'title': $(this).text()
					};
					
					$this.semesterSelect.setActive(semester);
					
					// Update the list and clear the menu
					$this.list.updateDisplay();
					$('body').trigger('clearDropMenus');
			
					return false;
				}
			);
			
			$('#class-list > li').live('click', 
				function ()
				{
					window.location = $(this).find('h3:first a:first').attr('href');
				}
			);
			
			$('#class-list').delegate('li', 'hover', 
				function ()
				{
					$(this).toggleClass('hover');
				}
			);

			// Class controls hover
			controls.live('mouseover',
				function ()
				{
					GradeGuru.core.utils.infotip.create($(this), $(this).text(), 'class-actions-tip');
				}
			).live('mouseout',
				function ()
				{
					GradeGuru.core.utils.infotip.close();
				}
			);
			
			// Class remove link
			$('li.class-remove-link').live('click',
				function ()
				{
					var confirm = GradeGuru.core.utils.confirm('Are you sure you want to remove this class from your schedule');

					if (confirm)
					{
						$this.remove();
					}
					return false;
				}
			);
		}
	},
	
	// Add a class to the user's schedule
	add: {
		
		init: function ()
		{
			var $this = GradeGuru.dashboard.sections.classes,
				create = GradeGuru.classes.create;
			
			// Setting isFirst removes the back button from the 
			// first 'name' section of the Create Class modal
			create.isFirst = true;
			
			// We need to explicitly set the semester to null here
			// just in case it has been set from another entry point
			// such as complete note details.
			create.semester = null;
			
			// When we're done with the Create class workflow
			// kick off add to schedule and close the modal
			create.referrerReturn = function (obj)
			{
				$this.add.classToSchedule(obj);
				$.fn.colorbox.close();
			};
			
			$('#dashboard-add-class-btn').live('click',
				function ()
				{
					create.call();
				}
			);
		},

		// Add the class to the user's schedule
		// @param JSON data - A Class JSON object
		classToSchedule: function (classObj)
		{	
			var $this = GradeGuru.dashboard.sections.classes;
			
			// POST the class to the user's classes
			//
			// TODO: Since we'll need to make this request from the Class page (and possibly others)
			//      we should abstract this so we can send custom error and success events
			//
			$.ajax(
				{
					type: 'POST',
					
					// @config
					url: GradeGuru.config.users.user01.classes,
					dataType: 'json',
					contentType: 'application/json',
					data: 'class=' + JSON.stringify(classObj),
					success: function ()
					{
						// Once we've successfully made the request, we add the new class
						var classHtml = $this.generateClassHtml(classObj);
						
						// We need to check if the class that was created is in the
						// user selected semester, if not, change the selected 
						// semester to the one this class is in
						if (classObj.semester.id !== GradeGuru.dashboard.currentSemester.id)
						{
							$this.semesterSelect.setActive(classObj.semester);
							$this.list.updateDisplay();
						}
						
						// Check for the "no classes" message and remove if there
						if ($('#class-list .empty-message').length !== 0)
						{
							$('#class-list .empty-message').remove();
						}
						
						$('#class-list').prepend(classHtml);
						GradeGuru.core.utils.alertBanner('<strong>' + classObj.name + '</strong> has been added to your schedule.', 'confirmation', 5000);
						
						$('#class-' + classObj.id).effect('highlight', 2000);
					},
					error: function ()
					{
						alert('We seem to be having some technical difficulties, please try again.');
					}
				}
			);						
		}
	},
	
	// Allow a user to remove a class from their schedule
	remove: function ()
	{
		// Send an authenticated request to the server
		// then on success remove the class from the dom 
		// with some sweet fade/slide action
	},
	
	// Generate the HTML for a class on the user dashboard
	// @param OBJ classObj - A JSON object of a class
	// @return STRING html - The full HTML string of a class
	generateClassHtml: function (classObj)
	{
		var html = '',
			classCode;
			
		html += '<li id="class-' + classObj.id + '"><h3><a href="../class?class=' + classObj.id + '">' + classObj.name + '</a></h3>';
		
		if (classObj.code === null)
		{
			classCode = '&nbsp;';
		}
		else
		{
			classCode = classObj.code;
		}
		
		html += '<h4>' + classCode + '</h4>';
		html += '<p class="class-controls">';
		html += '<a class="class-control-share" href="' + classObj.id + '">Share Notes</a>';
		html += '<a class="class-control-invite" href="' + classObj.id + '">Invite Classmates</a></p>';
		html += '<ul class="class-meta">';
		html += '<li class="meta-prof">Prof. ' + classObj.professor.name + '</li>';
		html += '<li class="meta-section">' + classObj.firstSession.day + ' at ' + classObj.firstSession.time + '</li>';
		html += '<li class="meta-notes">' + classObj.noteCount + ' Notes</li>';
		html += '<li class="meta-mates">' + classObj.mateCount + ' Classmates</li>';
		html += '<li class="class-remove-link"><a href="' + classObj.id + '">I\'m not in this class</a></li>';
		html += '</ul></li>';
		return html;
	}
};

/**
 * Dashboard Section: Notes
 * - This user's notes. Both notes that they have shared,
 * - and notes that they have uploaded but not completed details
 *
 */
GradeGuru.dashboard.sections.notes = {
	
	// Storage for all queued notes
	// @member ARRAY of note OBJECTS
	queuedNotes: [],
	
	// Storage for all published notes
	// @member ARRAY of note OBJECTS
	publishedNotes: [],
	
	// Initialize the section
	init: function ()
	{
		this.fetchNotes();
	},
	
	// Retrieve the user's notes from the server
	fetchNotes: function ()
	{
		var $this = this;
		
		$.ajax(
			{
				type: 'GET',
				dataType: 'json',
				
				// @config
				url: GradeGuru.config.users.user01.notes,
				
				success: function (data)
				{
					// If we have notes, hide the zero-state msg
					if (data.notes.length > 0)
					{
						$('#notes-zero-state-msg').remove();
					}
					else
					{
						$('#notes-zero-state-msg').show();
					}
					
						
					// Store each note into either the queuedNotes[] or publishedNotes[] arrays
					$.each(data.notes,
						function (i, note)
						{
							if (note.status === 'published')
							{
								$this.publishedNotes.push(note);
							}
							else
							{
								$this.queuedNotes.push(note);
							}
						}
					);
					
					// Check for published notes, if there are any
					// initialize the shared notes container
					if ($this.publishedNotes.length > 0)
					{
						$this.sharedContainer.init();
					}
					
					// Check for unpublished notes, if there are any
					// initialize the share queue
					if ($this.queuedNotes.length > 0)
					{
						$this.shareQueue.init();
					}
				},
				
				error: function ()
				{
					alert("We seem to be having some technical difficulties, please try again.");
				}
			}
		);
	},
	
	// All published notes go in the shared container
	// the user can filter the notes by type and rating
	// as well as sort by any of the table columns
	sharedContainer: {
		
		// Populate and display the notes container
		init: function ()
		{
			var $this = this,
				notesHtml = '';
			
			// Generate a table row for each note
			$.each(GradeGuru.dashboard.sections.notes.publishedNotes,
				function (i, note)
				{
					notesHtml += $this.generateNoteHtml(note);
				}
			);
			
			// Set the number of published notes
			$('#notes-shared-container h4 span').text(GradeGuru.dashboard.sections.notes.publishedNotes.length);
			
			// Append the generated html to the note table
			$('#shared-notes-table tbody').html(notesHtml);
			
			// Sort/Filter table with dataTables
			$this.sortTable();
			
			// Finally show the container
			$('#notes-shared-container').show();
		},
		
		// Enabled table sorting and filtering
		// Uses jquery.dataTables
		sortTable: function ()
		{
			var table = $('#shared-notes-table').dataTable(
				{
					'bAutoWidth': false,
					'bFilter': true,
					'bInfo': false,
					'bLengthChange': false,
					'bPaginate': false,
					'aoColumns': [
						null,
						null,
						null,
						null,
						null,
						null,
						{'sSortDataType': 'num-html-asc', 'sType': 'html'}
					]
				}
			);

			// Check to make sure the table exists
			if (table[0])
			{
				table.fnSort([[3, 'desc']]);

				// Removing the search input that dataTable adds
				$('#shared-notes-table_filter').remove();

				// Enable filtering for the note table
				GradeGuru.noteFilters.init(0, table, {columns: {'type': 2, 'rating': 6}});
			}
		},
		
		// Generate the HTML for a note in a notes table
		// @param OBJ noteObj - A JSON object representation of a note
		// @return STRING html - The full HTML string of a class
		// Example HTML:
		//	<tr id="note-34">
		//		<td class="name-col"><a href="../note">Table of Important things</a></td>
		//		<td>Econ 101</td>
		//		<td>Calculations/Spreadsheet related</td>
		//		<td>12/10/2009</td>
		//		<td>
		//			<ul class="drop-menu">
		//				<li class="drop-menu-title"><a><span>&nbsp;</span></a></li>
		//				<li class="drop-menu-items">
		//					<ul>
		//						<li class="note-share-facebook"><a>Facebook</a></li>
		//						<li class="note-share-twitter"><a>Twitter</a></li>
		//						<li class="note-share-email"><a>Email</a></li>
		//						<li class="note-share-url">
		//							<span><input type="text" class="select-text-onclick" value="http://notes.gg/v87cp2" /></span>
		//						</li>
		//					</ul>
		//				</li>
		//			</ul>
		//		</td>
		//		<td>15</td>
		//		<td class="rating stars-four"><span>4</span></td>
		//	</tr>
		generateNoteHtml: function (noteObj)
		{
			var $this = this,
				average = noteObj.details.rating.average,
				html = '',
				d = new Date(),
				published = $.format.date(d.setISO8601(noteObj.details.published), 'MM/dd/yyyy');
			
			if (average.toLowerCase() === 'new')
			{
				html += '<tr class="note-new" id="note-' + noteObj.id + '">';
			}
			else
			{
				html += '<tr id="note-' + noteObj.id + '">';
			}

			html += '<td class="name-col">';
			html += '<a href="' + noteObj.url + '">' + noteObj.title + '</a>';
			html += '</td>';

			// @config - href to Class
			html += '<td><a href="../class?id=' + noteObj['class'].id + '">' + noteObj['class'].name + '</a></td>';
			html += '<td>' + noteObj.details.type.name + '</td>';
			html += '<td>' + published + '</td>';
			html += '<td>';
			html += '<ul class="drop-menu">';
			html += '<li class="drop-menu-title"><a><span>&nbsp;</span></a></li>';
			html += '<li class="drop-menu-items"><ul>';
			html += '<li class="note-share-facebook"><a>Facebook</a></li>';
			html += '<li class="note-share-twitter"><a>Twitter</a></li>';
			html += '<li class="note-share-email"><a>Email</a></li>';
			html += '<li class="note-share-url">';
			html += '<span><input type="text" class="select-text-onclick" value="' + noteObj.url + '" /></span>';
			html += '</li></ul></li></ul>';
			html += '</td>';
			html += '<td>' + noteObj.details.points + '</td>';

			if (average.toLowerCase() === 'new')
			{
				html += '<td>New</td>';
			}
			else
			{
				html += '<td class="rating stars-' + $this.ratingNumToText(average) + '">';
				html += '<span>' + average + '</span></td>';
			}

			html += '</tr>';
			return html;
		},

		// Convert a number rating to it's text
		// equivalent. Ex 3.5 to three-half
		// @param INT rating
		// @return STRING - The rating text
		// NOTE: This will probably be abstracted since we may need it in a few places
		ratingNumToText: function (rating)
		{		
			var ratings = {
				"0": "zero",
				"0.5": "half",
				"1": "one",
				"1.5": "one-half",
				"2": "two",
				"2.5": "two-half",
				"3": "three",
				"3.5": "three-half",
				"4": "four",
				"4.5": "four-half",
				"5": "five"
			}

			return ratings[rating];
		}
	},
	
	// All unpublished notes go in the share queue
	// The user can download the original note file,
	// finish the note details, delete an uploaded note
	// and see messages about the status of their notes-in-progress
	shareQueue: {		
		
		// Populate and display the share queue
		init: function ()
		{
			var $this = this,
				notesHtml = '';
			
			// Generate a markup for each note
			$.each(GradeGuru.dashboard.sections.notes.queuedNotes,
				function (i, note)
				{
					notesHtml += $this.generateNoteHtml(note);
				}
			);
			
			/*
			// Append the generated html to the note table
			$('#shared-notes-table tbody').html(notesHtml);
			
			// Finally show the container
			$('#notes-shared-container').show();
			*/
		},
		
		// Bind the click events for each type of action that can be taken
		// on notes that are unpublished.
		bindEvents: function ()
		{
			var $this = GradeGuru.dashboard.sections.notes.shareQueue;
			
			// Bind each item link in the queue to a click event
			$('#queue-list li span a').live('click',
				function (e)
				{	
					var parent = $(this).closest('li');
					
					$('body').trigger('infotip.close');
					
					switch ($(this).attr('class'))
					{
						
					case 'complete':
					
						// Set the details referrer
						// we do this so we can remove the correct element
						// from the DOM when the note details are completed
						$this.noteDetails.referrer = parent;

						// Setting the filename for the details window here
						// if we try to set it in the init method of details,
						// we'll have trouble holding on to it when leaving to
						// add a class
						$this.noteDetails.userInput.fileName = parent.find('strong:first').text();
						$this.noteDetails.userInput.filePath = parent.find('strong:first a').attr('href');

						$.fn.colorbox($this.noteDetails.colorBoxOpts());
						break;
					
					case 'delete':
						$this.dismissNote(parent);
						break;
					
					case '':
						
						if (parent.attr('class') === 'note-pending')
						{
							GradeGuru.core.utils.infotip.create($(this), 'Your note is almost ready to be shared with the community, we just need to complete a few more things on our end first. We should be finished in a few minutes.', 'message-tip');
						}
						else
						{
							GradeGuru.core.utils.infotip.create($(this), 'There was an error sharing your note. <br /> You can either <a id="note-error-delete">Delete this note</a> and try to upload it again <span class="note-error-divider">or</span> <a href="../contact">Contact us</a> to try and fix the problem.', 'message-tip');
							$('#note-error-delete').click(
								function ()
								{
									$this.dismissNote(parent);
								}
							);
						}
					}
					
					return false;
				}
			);
		},
		
		// Complete a note's details. Colorbox modal
		noteDetails: {
			
			// The row in the queue for this note
			referrer: null,
			
			// @config
			url: GradeGuru.config.modals.noteDetails,
			
			// Storage object for any fields that the user has completed
			// We do this so the user can leave to add a class then come
			// back to details without losing anything
			userInput: {
				fileName: '',
				filePath: '',
				title: '',
				noteSemester: null,
				noteClass: '',
				type: '',
				tags: ''
			},
			
			defaults: {
				noteClass: '',
				noteType: ''
			},
			
			// Initialize the complete note details modal
			init: function ()
			{
				var $this = GradeGuru.dashboard.sections.notes.shareQueue.noteDetails,
					create = GradeGuru.classes.create;
				
				// Lets first fill out any values that the user may
				// of provided this is for users that add a class 
				// during the note details workflow
				$('#note-filename').text($this.userInput.fileName)
				.attr('href', $this.userInput.filePath);
				
				$('#note-title').val($this.userInput.title);
				$('#note-type').val($this.userInput.type);
				$('#note-tags').val($this.userInput.tags);
				
				$('#note-title').click(
					function ()
					{
						$(this).removeClass('error');
					}
				);

				// If we leave to create a class, we need to send
				// the create object information on what needs to happen
				// when we come back to note details.
				// There are three different ways to get back:
				// 		1. User hits the back button on the first modal of create
				// 		2. User selects a class from the available classes
				// 		3. User creates a new class
				//
				// @param Object obj - Create class will pass back a JSON obj
				//						of the created class
				//
				create.referrerReturn = function (obj)
				{
					$.fn.colorbox($this.colorBoxOpts());

					// If we get back a class object, we need to POST it to
					// the user's classes
					//
					if (obj)
					{
						GradeGuru.dashboard.sections.classes.add.classToSchedule(obj);
						
						// The user adding a new class, let's store the name of the
						// added class so we can select it below 
						$this.userInput.noteClass = obj.name;
					}
				};
				create.isFirst = false;
				
				// Create the semester selector from the user's semesters
				$this.createSemesterSelector();
				
				// Bind the add class click event.
				// when the user goes to add a class, we store any data they've entered
				// and then take them to the Add Class workflow
				$('#note-details-add-class').click(
					function ()
					{
						$this.userInput.fileName = $('#note-filename').text();
						$this.userInput.title = $('#note-title').val();
						
						// Since we remove the note-class selected, we check
						// if it is not defined to control the value. Or
						// just store the selected value
						if ($('#note-class').val() === undefined)
						{
							$this.userInput.noteClass = '';
						}
						else
						{
							$this.userInput.noteClass = $('#note-class').val();
						}
						
						$this.userInput.type = $('#note-type :selected').val();
						$this.userInput.tags = $('#note-tags').val();
						
						// Open the create class workflow
						create.semester = {
							'id': $('#note-semester').val(),
							'title': $('#note-semester :selected').text()
						};
						
						create.call();

						return false;
					}
				);

				$('#share-note-details form').submit($this.submit);
			},
			
			// Create a select element for the user's semesters
			// data comes from GradeGuru.dashboard.semesters
			createSemesterSelector: function ()
			{
				var $this = GradeGuru.dashboard.sections.notes.shareQueue.noteDetails,
					semesters = GradeGuru.dashboard.semesters,
					selectedSemester = '',
					select = $('<select/>',
						{
							'id': 'note-semester',
							'name': 'note-semester'
						}
					),
					selectOptions = '';
				
				$('#note-details-class .select-container').prepend(select);
				
				$.each(semesters, 
					function (i, item)
					{							
						selectOptions += '<option value="' + item.id + '">' + item.title + '</option>';
					}
				);
				
				select.append(selectOptions);
				
				// Select the current semester
				if ($this.userInput.noteSemester !== null)
				{
					selectedSemester = $this.userInput.noteSemester.id;
				}
				else
				{
					selectedSemester = GradeGuru.dashboard.currentSemester.id;
				}
				$("#note-semester option[value='" + selectedSemester + "']").attr('selected', 'selected');
				
				// Create the class selector based on the selected semester
				$this.createClassSelector(selectedSemester);
				
				// When the a different semester is selected, updated the class selector
				$('#note-semester').change(
					function ()
					{
						$this.userInput.noteSemester = {
							'id': $(this).val(),
							'title': $(this).find(':selected').text()
						};
						
						$this.createClassSelector($(this).val());
					}
				);
			},
			
			// Create select elements classes of the selected semester
			// data comes from GradeGuru.dashboard.classes
			// @param INT semesterId
			createClassSelector: function (semesterId)
			{
				var $this = GradeGuru.dashboard.sections.notes.shareQueue.noteDetails,
					create = GradeGuru.classes.create,
					classes = GradeGuru.dashboard.classes,
					options = '',
					select,
					selectedAttr;
				
				// We need to retrieve the list of classes for this user
				// and populate the note-class select with them
				// if they have no classes, just show the Add Class link
				// If the user has classes, build the select
				$.each(classes, 
					function (i, item)
					{	
						if (item.semester.id === semesterId)
						{
							// If a new class has been added, check to see if it matches the current 
							// class. If so set it to selected and then change the userInput.noteClass
							// to the id instead of the name so we can set the val() afterwards
							if (item.name.toLowerCase() === $this.userInput.noteClass.toLowerCase())
							{
								selectedAttr = " selected='selected' ";
								$this.userInput.noteClass = item.id;
							}
							else
							{
								selectedAttr = '';
							}

							options += '<option value="' + item.id + '"' + selectedAttr + '>' + item.name + '</option>';
						}
					}
				);
				
				if (options === '')
				{
					$('#note-class').remove();
				}
				else
				{
					$('#note-class').remove();
					select = $('<select/>',
						{
							'id': 'note-class',
							'name': 'note-class'
						}
					);
					
					$('#note-details-class #note-semester').after(select);
					select.append('<option value="0">Select from your classes</option>');
					select.append(options);
					
					// Set the selected value
					$('#note-class').val($this.userInput.noteClass);
				}
			},
			
			// Create a JSON representation of the note to send to the server
			// @return OBJ
			buildNotePayload: function ()
			{
				// NOTE: The type, class values are set up to insert the text value
				//       instead of an ID. This will probably change to just sending
				//       the ID, but it looks fishy for the demo
				//       Also, the date format will probably be different
				//
				return {
					"note": {
						"id": "29",
						"owner": "62",
						"points": "0",
						"title": $('#note-title').val(),
						"type": $('#note-type option[value=' + $('#note-type').val() + ']').text(),
						"url": "../note?note=29",
						"university": "12",
						"class": $('#note-class option[value=' + $('#note-class').val() + ']').text(),
						"details": {
							"shared": "03/30/2010",
							"grade": "A",
							"tags": "money, christmas, easter, chocolate",
							"rating": {
								"average": "New",
								"totalScore": "0",
								"numberOfRatings": "0"
							}
						}
					}
				};
			},
			
			// On sumbit, do form validation. If valid build the note
			// payload and then send the note to the server
			submit: function ()
			{
				var $this = GradeGuru.dashboard.sections.notes.shareQueue,
					details = $this.noteDetails
					notePayload = {};
				
				// If we are error free, continue
				if (details.formIsValid())
				{
					notePayload = details.buildNotePayload();
					
					$.ajax(
						{
							type: 'POST',
							dataType: 'json',
							contentType: 'application/json',
							
							// @config
							url: GradeGuru.config.users.user01.notes,
							
							data: 'payload=' + JSON.stringify(notePayload),
							success: function (data)
							{
								$.fn.colorbox.close();
								$this.noteToPending(notePayload.note, details.referrer);
								GradeGuru.core.utils.alertBanner('Thanks for providing details for <strong>' + notePayload.note.title + '</strong>. We need to complete a few things on our end and then your note will be published.', 'confirmation', 6000);
							}
						}
					);
				}
				else
				{
					$('p.form-status:first').addClass('error').text('Please fix the errors below and try again');
					$.fn.colorbox.resize();
				}
				
				return false;
			},
			
			// Validate the form
			// @return BOOL isValid
			formIsValid: function ()
			{
				var isValid = true;
					
				if ($('#note-title').val() === '')
				{
					$('#note-title').addClass('error');
					isValid = false;
				}
				
				if ($('#note-class').length === 0 || $('#note-class').val() === '0')
				{
					$('#note-semester').parent().addClass('error');
					isValid = false;
					
					$('#note-semester, #note-class').change(
						function ()
						{
							$(this).parent().removeClass('error');
						}
					);
				}
				
				if ($('#note-type').val() === '0')
				{
					$('#note-type').parent().addClass('error');
					isValid = false;
					
					$('#note-type').change(
						function ()
						{
							$(this).parent().removeClass('error');
						}
					);
				}
				
				return isValid;
			},
			
			// Options to send to colorbox when it is called
			colorBoxOpts: function ()
			{
				var $this = GradeGuru.dashboard.sections.notes.shareQueue.noteDetails;

				return {
					href: $this.url,
					onComplete: $this.init
				};
			}
		},
		
		// Set the note to 'pending' while it is being indexed
		// @param OBJ referrer - jQuery object of the selected note
		noteToPending: function (note, referrer)
		{	
			// The pending class on the <li>
			referrer.addClass('note-pending')
			
			// Change the filename to the Title
			referrer.find('a:first').text(note.title);
			
			// Replace the complete/delete controls with the pending link
			referrer.find('span:first').html('<a>Pending</a>');
			
			// Give a little hightlight indicator
			referrer.effect('highlight', 2000);
		},
		
		// If no notes are in the queue, remove the container
		rowCheck: function ()
		{
			var queue = $('#notes-share-queue'),
				rows = $('#queue-list dd li:visible').length;

			if (!rows)
			{
				queue.animate({opacity: 0}, 200);
				queue.slideUp();
			}
		},
		
		// Remove a note from the user's queue
		dismissNote: function (note)
		{
			var msg = 'Are you sure you want to remove this note from your queue? \n\n This cannot be undone.';
			
			if (GradeGuru.core.utils.confirm(msg))
			{
				// TODO: We're going to need to make a DELETE call here
				note.fadeOut('fast', 
					function ()
					{
						GradeGuru.dashboard.sections.notes.shareQueue.rowCheck();
					}
				);
			}
			return false;
		}
	}
};


/**
 * Dashboard Section: Activity
 * - The activity stream for a user.
 * - Contains events about rewards, notes, university, etc.
 *
 */
GradeGuru.dashboard.sections.activity = {
	
	// Storage for this section's containing div jQuery obj
	sectionObj: {},
	
	// The default number of days to show
	daysToDisplay: 4,
	
	// Number of days to show on 'show more'
	dayIncrement: 4,
	
	init: function ()
	{
		var $this = GradeGuru.dashboard.sections.activity;
		$this.sectionObj = $('#dashboard-activity');
		$this.activityDisplay.init();
		$('#more-activity-link').click($this.activityDisplay.showMore);
	},

	// Display the correct number of days in the activity feed
	activityDisplay: {
		
		// Wrap each <dt><dd> set in a container so we can manipulate them as a set
		init: function ()
		{
			var $this = GradeGuru.dashboard.sections.activity;
			
			// Wrapping all the <dt><dd> pairs so we have a solid elem to measure height
			$this.sectionObj.find('dt').each(
				function (i)
				{
					var title = $(this),
						items = $(this).find('+ dd'),
						wrapper = $('<span />', {
							'id': 'day-' + i,
							'class': 'day-container'
						});
					
					title.parent().append(wrapper);
					wrapper.append(title).append(items);
				}
			);
			
			this.updateDisplay(false);
		},
		
		// Resize the activity stream to show more
		updateDisplay: function (animate)
		{
			var $this = GradeGuru.dashboard.sections.activity,
				displayHeight = 0,
				days = $('span.day-container');
			
			// If we've displayed all days, disable the more button
			if (days.length === $this.daysToDisplay)
			{
				$('#more-activity-link').unbind('click').addClass('disabled');
			}
			
			// Go through each valid day and add it's height to the display height
			days.each(
				function (i)
				{
					if (i < $this.daysToDisplay)
					{
						displayHeight = displayHeight + $(this).innerHeight();
					}
				}
			);
			
			// We don't always want to animate the height
			if (animate)
			{
				$this.sectionObj.find('dl').animate({height: displayHeight});
			}
			else
			{
				$this.sectionObj.find('dl').height(displayHeight);
			}
			
		},
		
		// Display more of the activity stream
		showMore: function ()
		{
			var $this = GradeGuru.dashboard.sections.activity;
			$this.daysToDisplay = $this.daysToDisplay + $this.dayIncrement;
			$this.activityDisplay.updateDisplay(true);
		}
	}
};

/**
 * Dashboard Section: Saved
 * These are notes that the user has saved for later use
 */
GradeGuru.dashboard.sections.saved = {
	init: function ()
	{
		var table = $('#saved-table').dataTable(
			{
				'bAutoWidth': false,
				'bFilter': true,
				'bInfo': false,
				'bLengthChange': false,
				'bPaginate': false,
				'aoColumns': [
					null,
					null,
					null,
					null,
					null,
					{'sSortDataType': 'num-html-asc', 'sType': 'html'}
				]
			}
		);
		
		// Check to make sure the table exists
		if (table[0])
		{
			table.fnSort([[5, 'desc']]);
			
			// Removing the search input that dataTable adds
			$('#saved-table_filter').remove();
			
			// Enable filtering for the note table
			GradeGuru.noteFilters.init(0, table, {columns: {'type': 2, 'rating': 5}});
		}
	}
};


/**
 * Dashboard Section: Rewards
 *
 */
GradeGuru.dashboard.sections.rewards = {
	init: function (){}
};


/**
 * Dashboard Section: Ratings
 * - Contains notes that the user has interacted with 
 * - and need to provide a rating.
 *
 */
GradeGuru.dashboard.sections.ratings = {
	
	// Storage for our dataTables object
	table: {},
	
	init: function ()
	{
		var $this = GradeGuru.dashboard.sections.ratings;
		this.table = $('#notes-to-rate-table');
		
		$('.rating-select').selectToRating({
			itemClick: function (e)
			{
				// Call the update rating display of the rating list - this doesn't work
				e.data.elem.trigger('selectToRating.setRating', $(this).attr('href'));
				$this.rated($(this));
				return false;
			}
		});
		
		$('#notes-to-rate-table .dismiss-col a').click(this.dismissRating);
		$('#btn-ratings-dismiss-all').click(this.dismissAll);
	},
	
	rated: function (elem)
	{
		var $this = this;
		elem.closest('td').prepend('<strong class="rating-confirmation">Thanks!</strong>');
		elem.closest('tr').fadeTo('fast', 0.6).delay(300).fadeOut('fast', 
			function () 
			{
				$this.rowCheck();
			}
		);
	},
	
	rowCheck: function ()
	{
		var rows = this.table.find('tbody tr:visible').length;
		
		if (!rows)
		{
			this.table.hide();
			this.table.parent().css({'border-top': '1px solid #e7e7e7'})
				.append('<p class="content-msg">Thanks for doing your part to keep strong notes in your GradeGuru community.</p>');
			
			$('#dashboard-ratings .module-info').hide();
			$('#btn-ratings-dismiss-all').hide();
		}
	},
	
	dismissRating: function ()
	{
		$(this).parent().parent().remove();
		GradeGuru.dashboard.sections.ratings.rowCheck();
		return false;
	},
	
	dismissAll: function ()
	{
		var dismiss = GradeGuru.core.utils.confirm("Ahh, come on. Are you sure you don't want to rate at least 1 note?");
		
		if (dismiss)
		{
			GradeGuru.dashboard.sections.ratings.table.find('tbody tr').remove();
			GradeGuru.dashboard.sections.ratings.rowCheck();
		}
		
		return false;
	}
};

$(document).ready(function () 
{
	// We don't need to run any scripts if we're not on the dashboard
	if ($('#dashboard').length !== 0)
	{
		GradeGuru.dashboard.init();
	}
});