// Initialization launched when the DOM tree is ready
$(document).ready(function(){
	// Disallow putting civil.se in frames.
	var no_frame_location = '/noframe';
	if (top.location != location) {
		  location.hash = no_frame_location;
	}
	
	// IE fails to change location.hash without reloading if the hash is not set dynamically
	// This is a workaround.
	// See e.g. http://www.michiknows.com/2007/06/06/ie-redirect-bug-with-dynamic-location-hash/
	if( $.browser.msie ) {
		location.hash = location.hash;
	}
	
	// Add Read It support
	$('body')
		.mouseup( getReaditText )
		.keyup( getReaditText );
	
	$('<form id="readitForm" method="post" action="javascript:readIT();"'
		+ ' enctype="text/urlencoded">'
		+ '<input type="HIDDEN" name="stext" value="">'
		+ '<input type="HIDDEN" name="lang" value="se">'
		+ '</form>').appendTo( 'body' );
	
	$('<li><a class="no-forward" href="javascript:submitReadIT();">Lyssna</a></li>').appendTo( '.access_menu ul' );	

	// Special menu for Tips & råd with images
	function setupTipsRadMenu() {
		$('.tips--rad_cats > li > h4 > img').click(function(){
			$(this).parent().parent().parent().find('li img[src$="_aktiv.gif"]').each(function(){
				$(this).attr('src', $(this).attr('src').replace(/_aktiv/, '') );
			});
			$(this).attr('src', $(this).attr('src').replace(/\.gif/, '_aktiv.gif') );
		});
	}
	
	// Function for fetching type_* class for body
	// It's used in transitions within the same family
	function getFamilyType( src ) {
		// Find old class with family
		var classes = src.attr('class').split(' ');
		var typeClass = false;

		for( i in classes ) {
			if( classes[i].indexOf('type_') == 0 ) {
				typeClass = classes[i];
				break;
			}
		}
		
		return typeClass;
	}
	
	// Initialize lightbox launch controller
	LaunchController.init({
		domains: ['civil.se'],
		rootUri: rootUri,
		//rootUri: '/',
		directFolders: ['composerutbildning', 'phpBB3'],
		transitions: {
			//Transitions from blank page
			family_blank: {
				// Transition from family_blank to family_start
				family_start: function( body ) {
					$('.map_dropdown .content').dropdownClose( function() {
						mapManager.show();
						$('.dialog').show();				
					} );
					$('body').attr('class', body.attr('class') );
					// Due to IE7- bug, disable transition if iframes available
					if( ($.browser.msie && $.browser.version < 8 && body.find('iframe').length) || ($.browser.msie && $.browser.version < 8 && body.find('embed').length) ) {
						$('#content_container').replaceWith( $('#content_container', body) );
					} else {					
						if(inPrevPages) {
							$('#content_container').backReplace( '#content_container', body );
						} else {
						$('#content_container').replace( '#content_container', body );
						}
					}
					$('#navigation_container').html( $('#navigation_container', body).html() );
					// Apply javascript in body
					$('> script', body).appendTo( $('body') );
				},
				
				// Transition from family_blank to family_tab
				family_tab: function( body ) {
					var menuClass = 'side_menu';
					if( getFamilyType( body ) == 'type_tips-rad' ) {
						menuClass = 'tips--rad_cats';
					}
										
					$('.dialog').hide();				
					mapManager.hide();
					
					$('body').attr('class', body.attr('class') );
					
					$('#content_container').replaceWith( $('#content_container', body) );
						
					$('#navigation_container').html( $('#navigation_container', body).html() );

					// Apply javascript in body
					$('> script', body).appendTo( $('body') );
					
					if( menuClass == 'tips--rad_cats' ) {
						$('.'+menuClass).slideMenu('h4',menuClass);
						setupTipsRadMenu();
					} else {
						$('.'+menuClass).slideMenu('h4 a',menuClass);
					}
				}								
			},
			//Transitions from start page
			family_start: {
				// Transtition from family_start to family_blank
				family_blank : function( body ) {
					$('.map_dropdown .content').dropdownClose();
					
					$('.dialog').hide();				
					mapManager.hide();

					$('body').attr('class', body.attr('class') );
					$('#content_container').replaceWith( $('#content_container', body) );
					$('#navigation_container').html( $('#navigation_container', body).html() );
				},
				// Transition between startpage and startpage, do nothing
				family_start : function() {
				},
				// Transition from family_start to family_tab
				family_tab: function( body ) {
					var menuClass = 'side_menu';
					if( getFamilyType( body ) == 'type_tips-rad' ) {
						menuClass = 'tips--rad_cats';
					}
					
					$('.map_dropdown .content').dropdownClose();
					
					$('.dialog').hide();				
					mapManager.hide();
					
					/*$('#content_container').animate({
						height: 605
					}, 'fast', null, function(){*/
						$('body').attr('class', body.attr('class') );
						// Due to IE7- bug, disable transition if iframes available
						//if( ($.browser.msie && $.browser.version < 8 && body.find('iframe').length) || ($.browser.msie && $.browser.version < 8 && body.find('embed').length) ) {
							$('#content_container').replaceWith( $('#content_container', body) );
						//} else {
						//	$('#content_container').replace( '#content_container', body );
						//}
						
						$('#navigation_container').html( $('#navigation_container', body).html() );
						// Apply javascript in body
						$('> script', body).appendTo( $('body') );
						
						if( menuClass == 'tips--rad_cats' ) {
							$('.'+menuClass).slideMenu('h4',menuClass);
							setupTipsRadMenu();
						} else {
							$('.'+menuClass).slideMenu('h4 a',menuClass);
						}
					//});
				}
			},
			// Transition from tab page
			family_tab: {
				// Transition from family_tab to family_blank
				family_blank : function( body ) {
					$('body').attr('class', body.attr('class') );
					$('#content_container').replaceWith( $('#content_container', body) );
					$('#navigation_container').html( $('#navigation_container', body).html() );
				},
				// Transition from family_tab to family_start
				family_start: function( body ) {
					$('.map_dropdown .content').dropdownClose( function() {
						mapManager.show();
						$('.dialog').show();				
					} );
					$('body').attr('class', body.attr('class') );
					// Due to IE7- bug, disable transition if iframes available
					if( ($.browser.msie && $.browser.version < 8 && body.find('iframe').length) || ($.browser.msie && $.browser.version < 8 && body.find('embed').length) ) {
						$('#content_container').replaceWith( $('#content_container', body) );
					} else {					
						if(inPrevPages) {
							$('#content_container').backReplace( '#content_container', body );
						} else {
						$('#content_container').replace( '#content_container', body );
						}
					}
					$('#navigation_container').html( $('#navigation_container', body).html() );
					// Apply javascript in body
					$('> script', body).appendTo( $('body') );
				},
				// Transition between family_tabs
				family_tab: function( body ) {
					var oldType = getFamilyType( $('body') );
					var newType = getFamilyType( body );
					var menuClass = 'side_menu';
					if( newType == 'type_tips-rad' ) {
						menuClass = 'tips--rad_cats';
					}
					$('body').attr('class', body.attr('class') );
					
					$('.map_dropdown .content').dropdownClose();
									
					// Due to IE7- bug, disable transition if iframes available
					if( ($.browser.msie && $.browser.version < 8 && body.find('iframe').length) || ($.browser.msie && $.browser.version < 8 && body.find('embed').length) ) {
						$('#content_container .tab_content_column').replaceWith( $('#content_container .tab_content_column', body) );
					} else {
						if(inPrevPages) {
							$('#content_container .tab_content_column').backReplace( '#content_container .tab_content_column', body );
						} else {
							$('#content_container .tab_content_column').replace( '#content_container .tab_content_column', body );
						}
					}
					
					if( oldType != newType ) {
						$('#content_container .tab_menu_column').html( $('#content_container .tab_menu_column', body).html() );
						$('#navigation_container').html( $('#navigation_container', body).html() );

						if( newType == 'type_tips-rad' ) {
							$('.'+menuClass).slideMenu('h4',menuClass);
							setupTipsRadMenu();
						} else {
							$('.'+menuClass).slideMenu('h4 a',menuClass);
						}
					}
					
					//highlight menu				
					$('.tab_menu_column .active').removeClass('.active');
					body.find('.active').each(function(a){
						$('.tab_menu_column').find('a[href="' + $(this).attr('href') + '"]').parent().addClass('active');
						//$('.tab_menu_column').find('a[href="' + $(this).attr('href') + '"]').html(  $(this).html() );						
					});
				}
			},
			// Transition from lightbox
			family_lightbox: {
				// Transition within a lightbox
				family_lightbox: function( target, html, bodyClasses ) {
					if( bodyClasses.newBody.indexOf('type_membership') != -1 ) {
						typeMembership = true;
						bodyClasses.newBody = bodyClasses.oldBody;
					} else {
						typeMembership = false;
					}
					
					if( bodyClasses.oldBody != bodyClasses.newBody || bodyClasses.newBody.indexOf('type_blank') != -1) {
						$('ul.edge_menu').remove();
						
						if( $.browser.msie ) {
							// jQuery & IE don't work with children.length
							target.find('.lightbox_content').replaceWith( $( '.lightbox_content', html ) );
							$('.scrollable').vertScroller();
						} else {
							if(inPrevPages) {
								target.find('.lightbox_content').backReplace( '.lightbox_content', html, function(){
									// Add scrollers
									$('.scrollable').vertScroller();
								});
							} else {
								target.find('.lightbox_content').replace( '.lightbox_content', html, function(){
									// Add scrollers
									$('.scrollable').vertScroller();
								});
							}
						}
					} else {
						if( $.browser.msie ) {
							// jQuery & IE don't work with children.length
							target.find('.lightbox_content .rightcol .contentarea').replaceWith( $( '.lightbox_content .rightcol .contentarea', html ) );
							$('.scrollable').vertScroller();						
						} else {
							if(inPrevPages) {
								target.find('.lightbox_content .rightcol .contentarea').backReplace( '.lightbox_content .rightcol .contentarea', html, function(){
									// Add scrollers
									$('.scrollable').vertScroller();
								});
							} else {
								target.find('.lightbox_content .rightcol .contentarea').replace( '.lightbox_content .rightcol .contentarea', html, function(){
									// Add scrollers
									$('.scrollable').vertScroller();
								});
							}
						}
					}
					
					if( typeMembership ) {
						$('body').attr('prev_lightbox_class' , bodyClasses.oldBody);
					}
				},
				family_start: function() {
				}
			},
			// Transition from system page
			family_system: {
				ALL: function() {
					location.reload();
				}
			}
		}
	})
	
	addAccessMenu('#toolbar .access_menu');	
	
	// Setup calendar view
	
	$('body').addClass('js-on');
	$('.calendar_container .categories input').checkBox();
	
	// Any hit on the calendar generates a request
	/*$(".calendar_container a:not(.change_month)").livequery('click', function(){
		mapManager.update();
	});*/
	
	// Category change
	$(".calendar_container .categories input").livequery('click', function(){
		mapManager.update();
	});
	
	// Month change in calendar
	$("#main_calendar .calendar thead a.change_month").livequery('click', function(e){
		mapManager.clear();
		showLoadIndicator();
		$("#main_calendar").load($(this).attr('href') + ' .calendar', function() {
			mapManager.update();
		} );
		
		e.preventDefault();
		return false;
	});
				
	// Setup dropdowns
	$('#map_districts').dropdown(function(){
		var districtId = $(this).attr('rel');
		
		$(this).parent().parent().parent().prev().text( $(this).text() );
		/*if( $(this).text() == 'Riks' ) {
			mapManager.switchToDistrict( 0 );
		} else*/ {
			mapManager.switchToDistrict( districtId );
		}
		
		$('#map_associations h4').text('Föreningar');
		$('#map_associations ul li[class!="template"]').remove();
		
		if( $(this).text() == 'Gotland' ) {
			associations[ districtId ] = [{
				name: 'Gotland',
				uri: LaunchController.rootUri + 'gotland/'
			}];
		}
		
		for( i in associations[ districtId ] ) {
			var newAssociation = $('#map_associations ul li[class="template"]')
				.clone(true)
				.removeAttr('class')
				.appendTo('#map_associations ul');
				
			newAssociation.find('a').attr('rel', i)
				.text(associations[ districtId ][i].name)
				.attr('href', associations[ districtId ][i].uri)
				.show();
		}
		
		if( mapManager.getDistrict() > 0 ) {
			mapManager.openDistrict();
		} else {
			$('#back_to_root').click();
		}
		mapManager.update();
	}, 'down', {height: 295} );
	
	$('#map_associations').dropdown(function(){
		var associationId = $(this).attr('rel');
		$(this).parent().parent().parent().prev().text( $(this).text() );
		
		mapManager.switchToAssociation( associationId );
		
		//mapManager.update();
	}, 'down', {height: 295} );
	
	
	var searchTimeout;
	$('#search_query').livequery('keyup', function() {
		clearTimeout(searchTimeout);
		//$(this).stop();
		/// Just the animate function as a dummy timer
		//$(this).animate({background: $(this).css('background')}, 500, null, function() {
		searchTimeout = setTimeout(
			function() {
				$.get(LaunchController.rootUri + 'sok/snabb', {'query': ( $('#search_query').val() + '*' ) }, function( data ){
					$('#search_results').html( data );
					if( $('.top_row', this).length == 0 ) {
						$('<div class="top_row"><div class="corner_container"><div class="corner corner_top_left"></div><div class="corner corner_top_right"></div><div style="clear: both; font-size: 0; height: 0;"></div></div></div>').prependTo( $('#search_results') );
						$('<div class="bottom_row"><div class="corner_container"><div class="corner corner_bottom_left"></div><div class="corner corner_bottom_right"></div><div style="clear: both; font-size: 0; height: 0;"></div></div></div>').appendTo( $('#search_results') );
					}				
				} );
				if( $('#search_query').val().length > 0 ) {
					$('#search_results').slideDown();
				} else {
					$('#search_results').slideUp();
				}
			}
			,
			500);
		//});
	});

	// Set a initial search-text in the seach-box.
	var search_text = $('<p></p>').html('S&ouml;k p&aring; civil').text(); // This is a workaround to get correct encoding on the text.
	
	$('#search_query').val(search_text);
	$('#search_query').livequery('focus', function(e){
		if($('#search_query').val() == search_text)
			$('#search_query').val('');
		
		$('#search_results').slideDown();
	});
	
	// Hide search results when clicking outside the search box area
	$(window).livequery('mousedown', function(e){
		if( $(e.target).parents('#search').length == 0 ) {
			if($('#search_query').val() == '')
				$('#search_query').val(search_text);
			
			$('#search_results').slideUp();
		}
	});
	
	$('.scrollable:not(.no-onload)').vertScroller();
	
	// Hide map menu when click outside the map
	$(document).click(function( e ){
		if( e.target.tagName.toLowerCase() != 'area' ) {
			$('#map_menu').fadeOut('fast');
		}
	});		
	
	// Setup map functionality
	var mapAreas = $('#map area').click( function( e, data ){
		
		$('#map_menu').get(0).coordinates = e;
		var el = $('#map_districts li a[uri="' + $(this).attr('uri') + '"]');
		$('#map_menu').get(0).el = $('#map_districts li a[uri="' + $(this).attr('uri') + '"]');
				
		$('#map_menu').fadeOut('fast', function(){
			//$('#map_menu .district_map').unbind('click');
			
			$('#map_menu li[class!="template"]').remove();
			
			var e = $(this).get(0).coordinates;
			var districtEl = $(this).get(0).el;
			if( districtEl.length != 1 ) {
				return;
			}					
			var districtId = $(districtEl).attr('rel');

			var menu = $('#map_menu')
				.css( 'left', ( e.pageX - 100 ) + 'px' )
				.css( 'top', e.pageY + 'px' )
				.appendTo( 'body' );
						
			mapManager.calculateDistrictEvents( districtId );
			
			var districtName = districtEl.text();
			if( $.inArray( districtEl.attr('uri'), ['/uppsala/', '/orebro/', '/kalmar/', '/blekinge/', '/malmohus/'] ) == -1 ) {
				districtName += 's';
			}
			
			districtName += ' distrikt';
			
			if ( districtEl.attr('uri') == '/gotland/' ) {
				districtName = 'Gotland';
				associations[ districtId ] = null;
			}
			
			$('h2 a.title', menu)
				.attr( 'href', LaunchController.rootUri + districtEl.attr('uri').substr( 1 ) )
				.text( districtName );

			// Browse through all associations
			if( typeof associations[ districtId ] != 'undefined' ) {
				for( i in associations[ districtId ] ) {
					var association = associations[ districtId ][ i ];
					
					var item = $('li.template', menu).clone()
						.removeClass( 'template' )
						.appendTo( $('ul', menu) );
					$('a', item).text( association.name )
						.attr('href', association.uri );
				}
			}
			
			/*$('#map_menu .district_map').click(function(){
				var districtId = $( $('#map_menu').get(0).el ).attr('rel');
				mapManager.switchToDistrict( districtId );
				mapManager.openDistrict();
			});*/
			menu.fadeIn( 'fast' );
		});
		e.preventDefault();
			
	}).removeAttr('title')
		// IE7- fixes
		.attr('real_alt', function( arr ) {
			return $(this).attr('alt');
		})
		.removeAttr('alt');
	
	// IE7- fix
	$('img#riks').removeAttr('alt');
	
	
	if( $.browser.msie ) {
		mapAreas.bind( 'mouseover', mapManager.districtMouseIn )
			.bind( 'mouseout', mapManager.districtMouseOut )
	} else {
		mapAreas.hover( mapManager.districtMouseIn, mapManager.districtMouseOut )
	}
		
	// Initialize map
	mapManager.update();
	
});

/**
 * Generic method for creating timestamps for dates (time omitted)
 * 
 * @param	int		Year
 * @param	int		Month
 * @param	int		Day
 * @return	Timestamp
 */
function timestamp( year, month, day ) {
	var d = new Date();
	d.setFullYear( year, month, day );
	return parseInt( d.setHours( 0, 0, 0, 0 ).toString().substring( 0, 10 ) );
}

/**
 * Map Manager object to handle all map functionality
 */
var mapManager = new function() {
	this.district = null;
	this.association = null;
	this.year = null;
	this.month = null;
	this.data = null;
	this.types = null;
	this.days = null;
	
	this.TYPE_ASSOCIATION = 0;
	this.TYPE_DISTRICT = 1;
	this.TYPE_COURSE = 2;
	this.TYPE_BLOG = 3;
	this.TYPE_INSTRUCTOR = 4;
	
	/**
	 * Switch to another district
	 * 
	 * @param	int		District id
	 */		
	this.switchToDistrict = function( id ) {
		this.district = id;
		this.association = null;
	}
	
	/**
	 * Switch to root district
	 */		
	this.switchToRoot = function() {
		this.district = null;
		this.association = null;
	}
	
	/**
	 * Switch to another association
	 * 
	 * @param	int		Association id
	 */	
	this.switchToAssociation = function( id ) {
		this.association = id;
	}
	
	/**
	 * Gets the assigned district
	 * 
	 * @return	District id
	 */	
	this.getDistrict = function() {
		return this.district == null ? '0' : this.district;
	}
	
	/**
	 * Gets the assigned association
	 * 
	 * @return	Association id
	 */
	this.getAssociation = function() {
		return this.association == null ? '0' : this.association;
	}
	
	/**
	 * Hides the map container
	 */	
	this.hide = function() {
		$('#map_container').slideUp('fast', function(){
			$('#map_container .content').hide();
			
			$('.map_dropdown').hide();
			$('.region_link').show();
			/*$('.map_dropdown').dropdown(function(){
				$(this).parent().parent().parent().prev().text( $(this).attr('rel') );
				mapManager.switchToDistrict( $(this).attr('rel') );
						
				//mapManager.update();
			}, 'up' );*/
		});
	}
	
	/**
	 * Displays the map container
	 */
	this.show = function() {
		$('#map_container').slideDown('fast', function(){
			$('#map_container .content').show();
			$('.region_link').hide();
			$('.map_dropdown').show();
			/*$('.map_dropdown').dropdown(function(){
				$(this).parent().parent().parent().prev().text( $(this).attr('rel') );
				mapManager.switchToDistrict( $(this).attr('rel') );
						
				mapManager.update();
			}, 'down' );*/
		});
	}
	 
	this.associationMouseIn = function(e) {
		var districtId = mapManager.getDistrict();
		var associationId = $(this).attr('rel');
		
		var events = [];
		if( mapManager.data != null && typeof mapManager.data[ districtId ] != 'undefined' ) {
			var associations = mapManager.data[ districtId ].associations;
			if( typeof associations[ associationId ] != 'undefined' ) {
				var association =  associations[ associationId ];
				var events = mapManager.filterEvents( association.elements, [] );		
			}
		}
		
		mapManager.popupMouseIn( e, $(this), districtId, associationId, events );
	}
	
	this.districtMouseIn = function(e) {
		var districtId = $('#map_districts a[uri="' + $(this).attr('uri') + '"]').attr('rel');
		
		var events = [];
		if( mapManager.data != null && typeof mapManager.data[ districtId ] != 'undefined' ) {
			events = mapManager.filterEvents( mapManager.data[ districtId ].elements, events );
			
			var associations = mapManager.data[ districtId ].associations;
			
			for( i in associations ) {
				var association = associations[i];
				events = mapManager.filterEvents( association.elements, events );
			}	
		}
		
		mapManager.popupMouseIn( e, $(this), districtId, null, events );
	}
	
	this.popupMouseIn = function( e, _this, districtId, associationId, events ) {
		
		var eventsByType = {};
		for( var i in events ) {
			var event = events[i];
			if( typeof eventsByType[ event.type ] == 'undefined' ) {
				eventsByType[ event.type ] = [];
			}
			eventsByType[ event.type ][ eventsByType[ event.type ].length++ ] = event;
		}
				
		if( associationId != null ) {
			var id = 'popup_' + associationId;
			_this.attr('ref', 'a:' + id).addClass('popup_parent').addClass('map_popup');
			var context = _this.parent();
		} else {
			var id = 'popup_' + _this.attr('uri').substr( 1, _this.attr('uri').length - 2 );
			_this.attr('ref', 'd:' + id).addClass('popup_parent').addClass('map_popup');
			var context = _this.parent().parent();
		}
		
		if( $('#' + id).length ) {
			var popup = $('#' + id);
		} else {		
			var popup = $('<div id="' + id + '"/>').css({
					'position': 'absolute',
					'background': '#fff',
					'border': 'solid 1px #000',
					'padding': '4px',
					'left': ( e.pageX - context.offset().left ) + 'px', 
					'top': ( e.pageY - context.offset().top ) + 'px', 
					'width': '100px', 
					'display': 'none'
				})
				.attr( 'ref', _this.attr('ref') )
				.addClass('map_popup')
				.hover(function(e){
				},function(e){
					var type = $(this).attr('ref').substr( 0, 1 );
					var parent = $('.popup_parent[ref="' + $(this).attr('ref') + '"]');
					if( parent.get(0) != e.relatedTarget ) {
						parent.triggerHandler('mouseleave');
					}					
				})
				.appendTo( context );
			
			var headline = $('<h4 />').appendTo( popup );
			
			if( _this.attr('real_alt') ) {
				headline.text( _this.attr('real_alt') );
			} else if( associationId != null && associationId != 0 ) {
				headline.text( mapManager.data[ districtId ].associations[ associationId ].name );
			} else {
				headline.text( mapManager.data[ districtId ].name );
			}
				
			for( var type in eventsByType ) {
				var eventCount = eventsByType[ type ].length;
				$('<div/>')
					.addClass( 'category_type_' + type )
					.addClass( 'category_type' )
					.appendTo( popup ).text( eventCount );
			}
		}
	
		popup.fadeIn('fast');
	}
	
	this.districtMouseOut = function(e) {
		if( $(e.relatedTarget).attr('ref') == $(this).attr('ref') ) {
			return;
		}
		var popup = $('div[ref="' + $(this).attr('ref') + '"]:not(.popup_parent)');
		popup.fadeOut('fast', function(){
			$(this).remove();
		});
	}
	
	this.clear = function() {
		mapManager.month = null;
		mapManager.year = null;
		mapManager.data = null;
	}
	
	/**
	 * Updates the map using the html parameters
	 */
	this.update = function() {
		mapManager.days = null;
		mapManager.types = null;		

		var currentMonth = parseInt( $('#main_month').val() );
		var currentYear = parseInt( $('#main_year').val() );

		if( mapManager.month != null && mapManager.year != null && currentMonth == mapManager.month && currentYear == mapManager.year ) {
			mapManager.displayEvents();
			return;
		}
		
		mapManager.year = currentYear;
		mapManager.month = currentMonth;			
				
		showLoadIndicator();

		$.getJSON( LaunchController.rootUri + 'kalender-karta?year=' + currentYear + '&month=' + currentMonth, function( data ) {			
			mapManager.data = data;
			mapManager.displayEvents();
						
			var districtId = mapManager.getDistrict();
			if( districtId > 0 ) {
				mapManager.openDistrict();
			}
			
			$('#map_loader').fadeOut();
		});
	}	
	
 	this.showDistrictLabel = function() {
		var districtEl = $('#map_districts a[rel="' + mapManager.getDistrict() + '"]');
		var districtName = districtEl.text();
		
		if( districtName[ districtName.length - 1 ] != 's' ) {
			districtName += 's';
		} 
		
		if( districtName == 'Riks' ) {
			return;
		}
 		
 		$('#district_label')
			.attr( 'href', LaunchController.rootUri + districtEl.attr('uri').substr(1) )
			.text( 'Klicka här för att gå till ' + districtName + ' sida' )
			.fadeIn( 'normal' ); 		
 	}
 
	this.openDistrict = function() {
		var events = mapManager.updateDistrict( mapManager.getDistrict() );
		$('a.map_popup').remove();
		$('#district_map').remove();		
		$('#map_menu').fadeOut( 'fast', function(){
			$('#riks').animate({
				opacity: .2
			});
					
			var districtLabel = $('#district_label')
			if( districtLabel.length == 0 ) {
				districtLabel = $('<a id="district_label" style="display: none;"/>')
				.css({
					position: 'absolute',
					top: '10px',
					left: '10px',
					textDecoration: 'none',
					color: '#000',
					zIndex: 100
				})
				.appendTo( '#map_container .map' );
								
				mapManager.showDistrictLabel();
				
			} else {
				districtLabel.fadeOut( 'normal', function() {
					mapManager.showDistrictLabel();
				} );				
			}
			
			$('#riks').removeAttr('usemap');
			if( $('#back_to_root').length == 0 ) {
				$('<a id="back_to_root" href="javascript:;" class="no-forward" />').appendTo( $('#map_container .map') );
			}
			$('#back_to_root').fadeIn('slow', function(){
				$('#map_container .map #back_to_root').unbind('click').click(function(){
					mapManager.updateDistrict( null );
					$('#district_map').parent().find('a.map_popup').remove();
					$('#district_map').fadeOut();
					$('#riks').attr('usemap', '#map');
					$('#riks').animate({
						opacity: 1
					});	
					$(this).fadeOut();
					$('#district_label').fadeOut( 'normal' );
				});
			});
			
			var name = $('#map_districts a[rel="' + mapManager.getDistrict() + '"]').attr('uri');
			name = name.substr( 1, name.length - 2 );			
			
			var districtMap = $('<img id="district_map" src="' + LaunchController.rootUri + '.composer/images/map/' + name + '.png" style="position: absolute; display: block;" />')
				.appendTo( '#map_container .map' );
						
			districtMap
				.css({
					left: 250,
					top: 200,
					width: 0,
					height: 0
				})			
				.animate({
					left: 0,
					top: 0,
					width: '400px',
					height: '300px'
				}, 'fast', function(){
					if( typeof mapManager.data[ mapManager.getDistrict() ] == 'undefined' ) {
						return;
					}
					var associations = mapManager.data[ mapManager.getDistrict() ].associations;
					
					var mouseIn = mapManager.associationMouseIn;
					
					// Custom solution for Gotland with no associations
					if( associations.length == 0 ) {
						var districtName = $('#map_districts a[rel="' + mapManager.getDistrict() + '"]').attr('uri');
						if( districtName == '/gotland/' ) {
							
							associations = [ {
								'top': 140,
								'left': 240,
								'id': 0,
								'uri': LaunchController.rootUri + 'gotland/'
							} ];
						}
						
						mouseIn = mapManager.districtMouseIn;
					}
					
					for( var i in associations ) {
						var association = associations[i];
						
						var a = $('<a/>').css({
							'top': ( parseInt( association.top ) ) + 'px',
							'left': ( parseInt( association.left ) ) + 'px'
						}).attr('rel', association.id)
							.attr( 'href', association.uri + 'handelser/' )
							.addClass('map_popup')
							.addClass('map_association_pointer')
							.appendTo( districtMap.parent() )
							.hover( mouseIn, mapManager.districtMouseOut );
						
						if( association.id == 0 ) {
							a.attr( 'uri', '/gotland/' );
						}
					}
				});
		});		
	}
	
	/**
	 * Returns events by district
	 * 
	 * @param	int		District id
	 * @return	array of events
	 */
	this.getEvents = function( districtId ) {
		var events = [];
		
		if( typeof mapManager.data[ districtId ] != 'undefined' || districtId == 0 ) {
			
			if( mapManager.days == null ) {
			
				// Get selected days...
				this.days = [];
				var currentMonth = parseInt( $('#main_month').val() );
				var currentYear = parseInt( $('#main_year').val() );		
				var maxDay = 0;
				$('#main_calendar .calendar tbody').find('td').each(function (i, v) {
					var day = parseInt( $.trim( $(v).find('a').length ? $(v).find('a').html() : $(v).html() ) );
					var year = currentYear;
					if( $(v).hasClass('outside_month') ) {
						var month = day > maxDay ? currentMonth - 1 : currentMonth + 1;
						if( currentMonth == 0 )	{
							year = year - 1;
							month = 12;
						} else if( currentMonth == 13 )	{
							year = year + 1;
							month = 1;
						}
					} else {
						var month = currentMonth;
						if( day > maxDay )
							maxDay = day;
					}
					
					mapManager.days[ mapManager.days.length ] = {
						year: year,
						month: month - 1,
						day: day
					}
				});
				
			}
			
			if( mapManager.types == null ) {
			
				// Get selected types...
				this.types = [];
				$('.calendar_container .categories').find('input:checked').each(function (i,v) {
					mapManager.types[ mapManager.types.length ] = parseInt( $(v).attr('id').substr( 5 ) );
				});
				
			}
					
			// Browse through all associations in district
			if( districtId == 0 ) {
				
				if( typeof mapManager.data[ districtId ] != 'undefined' ) {
					events = this.filterEvents( mapManager.data[ districtId ].elements, [] )
					events = this._addAuthor( events, mapManager.data[ districtId ].name );
				}
				
				for( districtId in mapManager.data ) {
					if( districtId == 0 ) {
						continue;
					}
					
					var newEvents = this.filterEvents( mapManager.data[ districtId ].elements, [] );
					newEvents = this._addAuthor( newEvents, mapManager.data[ districtId ].name );
					events = $.merge( events, newEvents );						
					
					var associations = mapManager.data[ districtId ].associations;
					for( i in associations ) {
						var association = associations[i];
						var newEvents = this.filterEvents( association.elements, [] );
						newEvents = this._addAuthor( newEvents, association.name );
						events = $.merge( events, newEvents );
					}
				}
				
			} else {
				events = this.filterEvents( mapManager.data[ districtId ].elements, [] );
				events = this._addAuthor( events, mapManager.data[ districtId ].name );
				
				var associations = mapManager.data[ districtId ].associations;
				
				for( i in associations ) {
					var association = associations[i];
					var newEvents = this.filterEvents( association.elements, [] )
					newEvents = this._addAuthor( newEvents, association.name );
					events = $.merge( events, newEvents );					
				}
			}
		}
		
		return events;
	}	

	/**
	 * Adds author data to events
	 */
	this._addAuthor = function( events, author )
	{
		for( i in events ) {
			events[i].author = author;
		}
		
		return events;
	}
	 
	/**
	 * Event sorter by start time
	 */
	this.sortEvents = function( a, b ) {
		return a.start <= b.start ? -1 : 1;
	}
	
	/**
	 * Display events in the info box
	 */
	this.displayEvents = function() {

		var events = this.getEvents( this.getDistrict() );
		events.sort( mapManager.sortEvents );
				
		var days = {};
		
		// Update info box
		var oldContainer = $('#main_events:visible').length ? '#main_events' : '#main_events_empty';
		$( oldContainer ).fadeOut('fast', function(){

			$('#main_events ul li[class!="template"]').remove();
			
			if( events.length == 0 ) {
				$('#main_events').hide();				
				$('#main_events_empty').fadeIn('fast');
			} else {
				$('#main_events_empty').hide();
				
				for( i in events ) {
					var event = events[i];
					
					var item = $('#main_events ul li.template').clone();
					
					$( 'h4 a', item ).attr( 'href', event.uri );
					$( 'h4 a', item ).text( event.title );
					$( '.time', item ).text( event.start_str );
					if( typeof event.author != 'undefined' ) {
						$( '.author', item ).text( '/' + event.author );
					}
					item.removeClass('template')
						.appendTo( '#main_events ul' );	
				}
				
				$('#main_events').fadeIn('fast', function() {
					$('.dialog .scrollable').vertScroller();	
				});			
			}
			
			mapManager.displayCalendarSpots( events );
		});
		
		return events;
	}
	
	/**
	 * Displays events in calendar 
	 */
	this.displayCalendarSpots = function( events )
	{
		var currentMonth = parseInt( $('#main_month').val() );
		var currentYear = parseInt( $('#main_year').val() );				
		
		$('#main_calendar td.selected').each(function(){
			$(this).removeClass('selected');
		});		
		
		var calDays = {};		
		
		for( i in events ) {
			var event = events[i];

			// Filter out events outside the selected dates
			for( var j = 1; j <= 31; j++ ) {
				var stamp = timestamp( currentYear, currentMonth - 1, j );
				
				// 86400 = day
				if( stamp >= event.start && stamp < parseInt( parseInt( event.stop ) + 86400 ) ) {
					if( typeof calDays[ j ] === 'undefined' ) {
						calDays[ j ] = '';
					}
					
					calDays[ j ] += ( calDays[ j ].length > 0 ? ', ' : '' ) + event.title;
				}
			}	
		}		
		
		for( i in calDays ) {
			$('#main_calendar td:not(.outside_month)').each(function(){
				var d = $(this).text();
				if( typeof calDays[d] != 'undefined' ) {
					$(this)
						.attr('title', calDays[d])
						.addClass('selected');
				}
			});
		}
	}
	 
	/**
	 * Filters out events using the category type and date filters
	 * 
	 * @param	object		Source object
	 * @param	array		Event list to append to
	 */
	this.filterEvents = function( src, ret ) {
		
		for( typeId in src ) {
			// Filter out non-selected category types
			if( $.inArray( parseInt( typeId ), this.types ) == -1 ) {
				continue;
			}
			
			var events = src[ typeId ].elements;
			
			for( eventId in events ) {
				
				var goodDay = false;
				
				// Filter out events outside the selected dates
				for( day in this.days ) {
					
					var d = this.days[day];
					var stamp = timestamp( d.year, d.month, d.day );
					// 86400 = day
					if( stamp >= events[ eventId ].start && stamp < parseInt( parseInt( events[ eventId ].stop ) + 86400 ) ) {
						goodDay = true;
						break;
					}
				}	
				
				if( goodDay == false ) {
					continue;
				}
				
				events[ eventId ].type = typeId;
				ret[ ret.length ] = events[ eventId ];
			}
		}

		return ret;
	}	
	
	/**
	 * Calculate amount of events per types
	 * 
	 * @param	int		District id
	 * @return	Set of event counts
	 */
	this.calculateDistrictEvents = function( districtId ) {
		var events = this.getEvents( districtId );
		
		typeCount = { 0: 0, 1: 0, 2: 0, 3: 0, 4: 0 };
		for( i in events ) {
			var event = events[i];
			typeCount[ parseInt( event.type ) ]++;
		}
		
		return typeCount;
	}
	 		
	/**
	 * Update dropdowns by district
	 * 
	 * @param	int		District id
	 */
	this.updateDistrict = function( districtId ) {
		// Clear association dropdown
		$('#map_associations h4').text('Föreningar');
		$('#map_associations li').remove('li[class!="template"]');	
		
		if( districtId === null ) {
			$('#map_districts h4').text('Distrikt');
			mapManager.switchToRoot();
		} else {
			$('#map_districts h4').text( $('#map_districts a[rel="' + districtId + '"]').text() );
			mapManager.switchToDistrict( districtId );

			for( i in associations[ districtId ] ) {
				var newAssociation = $('#map_associations ul li[class="template"]')
					.clone(true)
					.removeAttr('class')
					.appendTo('#map_associations ul');
				
				newAssociation.find('a').attr('rel', i)
					.text(associations[ districtId ][i].name)
					.attr('href', associations[ districtId ][i].uri)
					.show();	
			}
		}
		
		return this.displayEvents();
	}
}


function showLoadIndicator()
{
	var loader = $('#map_loader');
	if( loader.length == 0 ) {
		loader = $('<div id="map_loader" style="display: none;"/>')
			.css({
				position: 'absolute',
				left: '100px',
				top: '100px',
				padding: '0 0 0 36px',				
				zIndex: '100',
				border: 'solid 4px #000',
				background: '#000 url(' + LaunchController.rootUri + '.composer/images/loader.gif) no-repeat left center',
				color: '#fff',
				lineHeight: '32px',
				height: '32px'
			})
			.text( 'Laddar...' )
			.appendTo( $('#map_container .map') );
	}
	loader.fadeIn();
}
 
/**
 * Function for display modal lightbox content animation
 * 
 * @param	array		Element container
 * @param	array		Lightbox settings
 * @param	function	Callback after this function
 */
function showContent( elts, settings, callback ) {	
	elts.contentWrapper
		.css({ // Reset the CSS at the start position
			marginTop: (-100/2 + settings.marginScrollTop)+'px',
			marginLeft: (-100/2 + settings.marginScrollLeft)+'px',
			height: '100px',
			width: '100px',
			opacity: 0
		})
		.show()
		.animate({ // Set the width
			width: settings.width+'px',
			marginLeft: (settings.marginLeft)+'px',
			opacity: 0.5
		}, {duration: 200})
		.animate({ // Set the height
			height: settings.height+'px',
			marginTop: (settings.marginTop)+'px',
			opacity: 1
		}, {complete: callback, duration: 200});
		
		$('<div class="top_row"><div class="corner_container"><div class="corner corner_top_left"></div><div class="corner corner_top_right"></div><div style="clear: both; font-size: 0; height: 0;"></div></div></div>').prependTo( elts.contentWrapper );
		$('<div class="bottom_row"><div class="corner_container"><div class="corner corner_bottom_left"></div><div class="corner corner_bottom_right"></div><div style="clear: both; font-size: 0; height: 0;"></div></div></div>').appendTo( elts.contentWrapper );
}
	
/**
 * Function for display modal lightbox transition animation
 * Actually this function only skips the nyroModal built-in transition system
 * hideTransition() does the actual job.
 * 
 * @param	array		Element container
 * @param	array		Lightbox settings
 * @param	function	Callback after this function
 */
function showTransition( elts, settings, callback ) {	
	elts.loadBackup = elts.loading.html();
	elts.loading.html( elts.contentWrapper.html() );
	elts.loading
		.css({
			marginTop: elts.contentWrapper.css('marginTop'),
			marginLeft: elts.contentWrapper.css('marginLeft'),
			height: elts.contentWrapper.css('height'),
			width: elts.contentWrapper.css('width'),
			opacity: 1
		})	
		.show();
		callback();
}	

/**
 * Function for hide modal lightbox transition animation
 * 
 * @param	array		Element container
 * @param	array		Lightbox settings
 * @param	function	Callback after this function
 */
function hideTransition( elts, settings, callback ) {	

	elts.contentWrapper
		.css({
			width: settings.width+'px',
			marginLeft: (settings.marginLeft)+'px',
			height: settings.height+'px',
			marginTop: (settings.marginTop)+'px',
			opacity: 1
		});
		$('<div class="top_row"><div class="corner_container"><div class="corner corner_top_left"></div><div class="corner corner_top_right"></div><div style="clear: both; font-size: 0; height: 0;"></div></div></div>').prependTo( elts.contentWrapper );
		$('<div class="bottom_row"><div class="corner_container"><div class="corner corner_bottom_left"></div><div class="corner corner_bottom_right"></div><div style="clear: both; font-size: 0; height: 0;"></div></div></div>').appendTo( elts.contentWrapper );			

	elts.loading.hide();
	var newContents = elts.contentWrapper.clone(true);
	elts.contentWrapper.html( elts.loading.html() ).show();
	
	if(  typeof LaunchController.settings.transitions['family_lightbox'] !== 'undefined' && typeof LaunchController.settings.transitions['family_lightbox']['family_lightbox'] !== 'undefined' ) {
		// Try custom function
		LaunchController.settings.transitions['family_lightbox']['family_lightbox']( elts.contentWrapper, newContents, settings.bodyClasses );
	} else {
		if(inPrevPages) {
			elts.contentWrapper.find('.lightbox_content').replace( '.lightbox_content', newContents );
		} else {
			elts.contentWrapper.find('.lightbox_content').replace( '.lightbox_content', newContents );
		}
	}
		
	elts.content.css('overflow', 'hidden');
	elts.loading.html( elts.loadBackup );
	callback();
}	

/**
 * Function to be executed after lightbox content loading
 * 
 * @param	array		Element container
 * @param	array		Lightbox settings
 */
function endShowContent( elts, settings ){	

	elts.content.css('overflow', 'hidden');
	elts.content.css('height', 'auto');
		
	// Add close button
	$('#nyroModalWrapper #lightbox_close').remove();
	$('<button id="lightbox_close"/>').appendTo( $('#nyroModalWrapper') ).click(function(){
		LaunchController.closeLightbox();
	});
	
	var toolbar = $('#toolbar').clone();
	toolbar
		.addClass('LBtoolbar')
		.appendTo( $('#nyroModalWrapper') );
	
	addAccessMenu('#nyroModalWrapper .access_menu', ['#nyroModalWrapper .access_menu', '#nyroModalWrapper .access']);
	
	// Add scrollers
	$('.scrollable').vertScroller();
	
	// Add menu effects
	$('.side_menu').slideMenu();

	var menu = $('ul.edge_menu');
	if( menu.length == 1 ) {

		menu.css({
			top: '50px',
			display: 'block',
			position: 'absolute'
		}).appendTo('#nyroModalWrapper');
			
		$('li', menu).mouseover(function(e){
			$(this).stop();
			var progress = Math.abs(parseInt($(this).css('marginLeft')));
	
			$(this).animate({ 
		     		marginLeft: '-100px'
		      	}, 6 * (100 - progress)	);
		});

		$('li', menu).mouseout(function(e){
			var progress = Math.abs(parseInt($(this).css('marginLeft')));
			$(this).stop();
	
			$(this).animate({ 
				marginLeft: '0px'
			}, 6 * progress	);
		});	  
	
	}
};

//Boolean for whether in history or not
	if(! (inPrevPages instanceof Boolean) ) {
		var inPrevPages=false;	
	}
	// Array to store history in
	//if(! (prevPages instanceof Array) ) {
		var prevPages = new Array();
		prevPages.unshift(location.href);
	//}
	
	
	//Function to add current page to history
	 jQuery.prevPagesAdd = function( pageUrl ) {
	 	var maxLength = 10;
		//Store the current page in page history
		if(prevPages[0] != pageUrl) {
			prevPages.unshift(pageUrl);
		}
		if(prevPages.length == maxLength) {
			prevPages.pop();
		}
		//Show array for debugging
		//prevPages.forEach(function(element, index, array) {console.log("Element "+index+" = "+element); });
	
	}	
	
//Is the current page in the history
jQuery.prevPagesCheck = function( pageUrl ) {
	inPrevPages=false;
	var prevPagesIndex=-1;
	for(var i=0; i<prevPages.length; i++) {
		if(prevPages[i]==pageUrl) {
			prevPagesIndex=i;
			break;
		}
	}
		if(prevPagesIndex>=0) {
			//Remove pages from history as needed
			for(var i=0; i<=prevPagesIndex; i++) {
				prevPages.shift();
				inPrevPages=true;
				$('body').addClass('inHistory');
			}
		}
}

//Setup accessibility menu
function addAccessMenu( dest, els )
{
	if( typeof els == 'undefined' || els == null ) {
		els = [ '#toolbar .access', '#toolbar .access_menu' ]
	}
	
	new vertMouseoverSlider( dest, els );	
	$('.enlarge_text', $(dest)).bind('click', function(){
		if( $('body').hasClass('largest') ) {
			return;
		} else if( $('body').hasClass('large') ) {
			$('body').removeClass('large');
			$('body').addClass('largest');
		} else {
			$('body').addClass('large');
		}
	});
	
	$('.shrink_text', $(dest)).bind('click', function(){
		if( $('body').hasClass('largest') ) {
			$('body').removeClass('largest');
			$('body').addClass('large');
		} else {
			$('body').removeClass('large');
		}
	});
}