var i18n = i18n || {};

// language strings
jQuery.i18n.addDictionary({
	'POINTVIEW_SEARCHTOVIEW': "Search on the right to view point data"
});

;(function($) {

	/**
	 */
	$.fn.DemandMap_DemandPointList = function(_options, demandControlSelector) { 
		
		// ######## static private properties #########
		
		// config
		var defaults = {
			'pageSize': 25,
			'mimetypeToExtension': {
				'application/vnd.google-earth.kml+xml': 'kml',
				'text/xml': 'xml',
				'text/csv': 'csv'
			}
		};
		
		return this.each(function(){
			// ######## private instance properties #########
			var options = $.extend({}, defaults, _options);
			
			// Reference to this control
			var $this = $(this);
			var container = this;
			
			// objects
			var demandControl = $(demandControlSelector);
			
			// state
			var _currentPage = 0;
			// avoid more than one request running at any given moment
			var ajaxManager = $.manageAjax({manageType: 'abortOld', maxReq: 0});
		
			// clear javascript notice
			$this.html('<p class="message">' + $.i18n._t('POINTVIEW_SEARCHTOVIEW') + '</p>');
		
			// only load data if tab is selected
			$('.dataViews ul').bind('tabsselect', function(event, ui) {
				switch(ui.panel.id) {
					case 'Tab-Map':
						break;
					case 'Tab-DemandPointList':
						$this.fn('refresh', [true]);
						break;
				}
			});
			
			// event listeners for changes to data filtering
			$(document).bind('DemandSearchBar:searchend', function(e) {
				// TODO This currently gets called twice on initial load with a predefined
				// location parameter in the URL
				$this.fn('refresh');
			});
			$('#DemandCategoryControl').bind('DemandCategoryControl:loadcategories', function(e) {
				$this.fn('refresh');
			});
			// searching for location is implicitly reacted to by listening to map moves
			$('#Map').one('DemandMap:move', function(e) {
				$this.fn('refresh');
			});
			
			$('.pagination a', container).livequery('click', function(e) {
				$this.fn('refresh', true, e.target.href);
				return false;
			});
			
			// url config
			if($.jget['hideaccessiblelist']) $this.hide();
			
			// update links, hide if no parameters are given
			updateDownloadLinks();

			// ######## public methods #########
			$this.fn({
				'refresh' : function(force, url) {
					if(!$this.is(':visible') && !force) return false;
					
					if(!url) {
						// don't set this above the cluster threshold,
						// or the clustering will kick in
						url = demandControl.fn('getDataURL');						
						url += '&limit=' + options.pageSize + "&start=" + 0;
					}
					
					var startResults = url.match(/start=([\d]*)/);
					if(startResults) _currentPage = startResults[1];

					ajaxManager.add({
						url: url,
						success: buildTable.bind(this),
						dataType: 'json'
					});
				}
			});
			
			// ######## private methods #########
			function buildTable(markers) {
				var html = '<table summary="This table consists of three visible and one hidden column, the hidden column contains: Region, Telephone and Mobile Telephone numbers. Information in this table utilises micro formats in the form of the vCard and GEO specifications\">';
				
				// header definition
				html += 
				   	'<caption class="hidden">Accessible Point View</caption>'
					+'<thead>'
					+'	<tr>'
					+'		<th>Organisation</th>'
					+'		<th>Address</th>'
					+'		<th>Category</th>'
					+'		<th class="hidden">Hidden Column - Telephone, Mobile and Region</th>'
					+'	</tr>'
					+'</thead>'
				;
				
				// body definition
				html += '<tbody>';
				for(var i=0; i<markers.items.length; i++) {
					var m = markers.items[i];
					html += 
						'<tr class="vcard">'
						+ '	<td class="org">' + _val(m.OrganisationTitle) + '</td>'
						+ '	<td class="adr">'
						+ '		<span class="street-address">' + _val(m.StreetNumber) + ' ' + _val(m.Street) + '</span>'
						+ '		<span class="region hidden">' + _val(m.Region) + '</span>'
						+ '	</td>'
						+ '	<td>' + _val(demandCategories[m.CategoryID].Title) + '</td>'
						+ '	<td class="hidden">'
						+ '		<span class="tel"><span class="type">Main</span>' + _val(m.Phone) + '</span>'
						+ '		<span class="tel"><span class="type">Mobile</span>' + _val(m.Mobile) + '</span>'
						+ '		<span class="geo">GEO:'
						+ '			<span class="latitude">' + _val(m.Point.lat) + '</span>,'
						+ '			<span class="longitude">' + _val(m.Point.lng) + '</span>'
						+ '		</span>'
						+ '		<span class="postal-code">' + _val(m.PostalCode) + '</span>'
						+ '	</td>'
						+ '</tr>'
					;
				}
				html += '</tbody>';
				html += '</table>';
				
				html += paginationSummary(markers);
				// pagination
				html += '<div class="pagination">';
				html += pagination(markers);
				html += '</div>';
				
				// insert html
				$this.html(html);
				
				// accessibility
				$('.pagination a:first', this).focus();
				
				// point download links 
				updateDownloadLinks();
			}
			
			function pagination(markers) {
				var html = '';
				
				var url = demandControl.fn('getDataURL');

				var totalPages = Math.ceil(markers.totalSize / options.pageSize);
				var maxPages = 20;
				var startPage = (_currentPage - Math.floor(maxPages / 2)) - 1;
				var endPage = _currentPage + Math.floor(maxPages / 2);

				if(startPage < 0) {
					startPage = 0;
					endPage = maxPages;
				}
				if(endPage > totalPages) {
					endPage = totalPages;
					startPage = Math.max(0, endPage - maxPages);
				}
				
				html += '<ul>';
				for(var i=0; i<endPage; i++) {
					var pagedURL = url + '&limit=' + options.pageSize + '&start=' + i*options.pageSize;
					html += '<li>';
					html += '<a href="' + pagedURL + '">';
					html += (i==Math.floor(_currentPage/options.pageSize)) ? '<strong>' + (i+1) + '</strong>' : (i+1);
					html += '</a>';
					html += '</li>';
				}
				html += '</ul>';
				
				return html;
			}
		
			function paginationSummary(markers) {
				var html = '';
				
				var totalSize = markers.totalSize;
				
				if (totalSize == 0) return '';
				
				var fromItem = parseInt(_currentPage) + 1;
				var toItem = (fromItem - 1) + parseInt(options.pageSize);
				
				if (toItem > totalSize) toItem = totalSize;
				
				html += '<div id="PaginationSummary">';
				html += '<span>Showing</span> ' + fromItem + '<span>-</span>' + toItem + ' <span>of</span> ' + totalSize;
				html += '</div>';
				
				return html; 
				
			}
			
			function updateDownloadLinks() {
				$links = $('.demandPointsDownloadLinks a');
				$holder = $('#PointDownloadLinksHolder');
				
				// if no categories select, return 
				if ($('input.category:checked, input.subcategory:checked').length == 0) {
					$holder.hide();
					return false;
				}
				
				$holder.show();
				
				var url = demandControl.fn('getDataURL');
				$links.each(function() {
					var ext = options.mimetypeToExtension[$(this).attr('type')]
					$(this).attr('href', url.replace('.json', '.' + ext) + '&export=1');
				});
				
				$holder.removeClass('loading');
			}
						
			/**
			 * Helper function to avoid faulty data.
			 * @todo Fix root cause on serverside CSV data import
			 */
			function _val(val) {
				return (val == 'NULL' || val == 'null' || val == null) ? '' : val;
			}
			
		});
	}
})(jQuery);