/**
 * -------------------------------------
 * IFrame
 *
 * -------------------------------------
 */
$(document).ready(function() {

	// Declare variables
	var map			= new Map('map');
	var tab			= new Tab();
	var container	= new Container();

	// Set default search
	$("#postcode_input").val($('#current_search').html());

	// Bind event - click - Tab - map
	$('#map_tabs a.map').bind('click', function(){

		map.setType('map');
		tab.setActive('map');
		container.show('map');
	});

	// Bind event - click - Tab - sattelite
	$('#map_tabs a.satellite').bind('click', function(){

		map.setType('satellite');
		tab.setActive('satellite');
		container.show('map');

	});

	// Bind event - click - Tab - mixed
	$('#map_tabs a.mixed').bind('click', function(){

		map.setType('mixed');
		tab.setActive('mixed');
		container.show('map');

	});

	// Bind event - click - Tab - own
	$('#map_tabs a.own').bind('click', function(){
		tab.setActive('own');
		container.show('form');
		document.getElementById('form_frame').contentWindow.replaceH3();
	});

	// Bind event - click - Search
	$('form#search').bind('submit', function(){

		map.search();

		return false;

	});

	// Bind event - click - Search
	$('form#search input#postcode_input').bind('click', function(){

		if( 'Type your postcode' == $(this).val() )
		{
			$(this).val('');
		}

	});

	// Bind event - change - select_area
	$('form#search select#select_area').bind('change', function(){

		map.search();

	});

	// Init Map
	map.init();

	// Perform base search
	if( $("#postcode_input").val().length > 0 )
	{
		map.search();
	}
});


/**
 * -------------------------------------
 * Tab
 * Handles tab functionality
 * -------------------------------------
 */
var Tab = function()
{
	/**
	 * setActive()
	 *
	 * Set Active Tab
	 */
	this.setActive = function(name)
	{
		$('#map_tabs li a').each(function(){

			$(this).removeClass('active');
			$(this).parent().removeAttr('style');

		});

		// Set selected to active
		$('#map_tabs li a.' + name).addClass('active');

		// Shift next tab to hide dash
		$('#map_tabs li a.' + name).parent().next().attr('style', 'background-position: -1px;');
	}
}


/**
 * -------------------------------------
 * Map
 * Handles map functionality
 * -------------------------------------
 */
var Map = function(id)
{
	// Declare variables
	var _self				= this;
	var _id					= id;
	var _map				= null;

	var _iconExercise		= null;
	var _iconPhysio			= null;
	var _iconRemedial		= null;
	var _iconRunning		= null;
	var _iconSportsVenue	= null;
	var _iconDietitian		= null;
	var _iconSportsClub		= null;


	/**
	 * init()
	 *
	 * Initialize map
	 */
	this.init = function()
	{
		if( GBrowserIsCompatible() )
		{
			_map = new GMap2(document.getElementById(_id));

			// Set the map to center in Perth
			_map.setCenter(new GLatLng(-31.9554, 115.8586), 9);
			_map.addControl(new GSmallMapControl());

			_iconExercise		= this._buildIcon('/images/icons/map/pin_exercise.png');
			_iconPhysio			= this._buildIcon('/images/icons/map/pin_physio.png');
			_iconRemedial		= this._buildIcon('/images/icons/map/pin_remedial.png');
			_iconRunning		= this._buildIcon('/images/icons/map/pin_running.png');
			_iconSportsVenue	= this._buildIcon('/images/icons/map/pin_sports_venue.png');
			_iconDietitian		= this._buildIcon('/images/icons/map/pin_dietitian.png');
			_iconSportsClub		= this._buildIcon('/images/icons/map/pin_sports_club.png');
		}
	},

	/**
	 * -------------------------------------------------------------------------
	 * Private functions
	 * -------------------------------------------------------------------------
	 */

	/**
	 * _buildIcon()
	 *
	 * Create an icon given a filename for an icon image
	 *
	 * @param string filename
	 * @return GIcon
	 */
	this._buildIcon = function(filename)
	{
		// Declare variables
		var icon				= new GIcon();
		icon.image				= filename;
		icon.shadow				= '/images/maps/shade.png';
		icon.shadowSize			= new GSize(49, 60);
		icon.iconSize			= new GSize(28, 57);
		icon.iconAnchor			= new GPoint(14, 58);
		icon.infoWindowAnchor	= new GPoint(14, 10);

		return icon;
	},

	/**
	 * _clearMarkers()
	 *
	 * Clear all markers on the map
	 */
	this._clearMarkers = function()
	{
		_map.clearOverlays();
	},

	/**
	 * _addMarkers()
	 *
	 * Adds markers onto a map given a postcode using an ajax request
	 */
	this._addMarkers = function(postcode)
	{
		// Declare variables
		var _self = this;

		if( !postcode )
		{
			postcode = '';
		}

		GDownloadUrl('/ajax/get_markers/', function(data){

		_self._addMarkersComplete(data);

		}, 'postcode=' + escape(postcode));
	},

	/**
	 * _addMarkersComplete()
	 *
	 * Adds markers Complete callback
	 */
	this._addMarkersComplete = function(data)
	{
		// Declare variables
		var _self	= this;
		var xml		= GXml.parse(data);

		if( 'FALSE' == xml_get_field(xml, 'success') )
		{
			alert('Please enter a postcode or suburb.');
		}

		var items = xml.documentElement.getElementsByTagName("item");

		for(var i=0;i<items.length;i++)
		{
			var node = items[i]
			if( node.firstChild != null )
			{
				if( isMoz() )
				{
					var id			= node.getElementsByTagName("id")[0].textContent;
					var lat			= node.getElementsByTagName("lat")[0].textContent;
					var long		= node.getElementsByTagName("long")[0].textContent;
					var location	= node.getElementsByTagName("location")[0].textContent;
					var title		= node.getElementsByTagName("title")[0].textContent;
					var description = node.getElementsByTagName("description")[0].textContent;
					var postcode	= node.getElementsByTagName("postcode")[0].textContent;
					var type		= node.getElementsByTagName("type")[0].textContent;
					var website		= node.getElementsByTagName("website")[0].textContent;
					var phone		= node.getElementsByTagName("phone")[0].textContent;
					var email		= node.getElementsByTagName("email")[0].textContent;
					var int_encode	= node.getElementsByTagName("int")[0].textContent;
				}
				else
				{
					var id			= node.getElementsByTagName("id")[0].firstChild.nodeValue;
					var lat			= node.getElementsByTagName("lat")[0].firstChild.nodeValue;
					var long		= node.getElementsByTagName("long")[0].firstChild.nodeValue;
					var location	= node.getElementsByTagName("location")[0].firstChild.nodeValue;
					var title		= node.getElementsByTagName("title")[0].firstChild.nodeValue;
					var type		= node.getElementsByTagName("type")[0].firstChild.nodeValue;
					var int_encode	= node.getElementsByTagName("int")[0].firstChild.nodeValue;
					var postcode	= '';
					var description = '';
					var website		= '';
					var phone		= '';
					var email		= '';

					if( node.getElementsByTagName("postcode")[0].firstChild )
					{
						postcode = node.getElementsByTagName("postcode")[0].firstChild.nodeValue;
					}

					if( node.getElementsByTagName("description")[0].firstChild )
					{
						description = node.getElementsByTagName("description")[0].firstChild.nodeValue;
					}

					if( node.getElementsByTagName("website")[0].firstChild )
					{
						website = node.getElementsByTagName("website")[0].firstChild.nodeValue;
					}

					if( node.getElementsByTagName("phone")[0].firstChild )
					{
						phone = node.getElementsByTagName("phone")[0].firstChild.nodeValue;
					}

					if( node.getElementsByTagName("email")[0].firstChild )
					{
						email = node.getElementsByTagName("email")[0].firstChild.nodeValue;
					}
				}

				if( 0 == lat && 0 == long )
				{
					setTimeout(function(){
 
						// Declare variables
						var searchMap	= new GClientGeocoder();
						var search		= new Search();

						searchMap.getLatLng(search.completeSearch(unescape(location + " " + postcode)),  function(point){

							if( point)
							{
								// Update the marker
								var marker = new Marker(_map);
								
								marker.add(id, point.lat(), point.lng(), location, title, description, type, website, phone, email, _self._getIconByType(type));
								GDownloadUrl('/ajax/update_latlong/', function(){}, 'id=' + int_encode + '&lat=' + point.lat() + '&long=' + point.lng());
							}
							else
							{
								// Alert that the marker was not found
								GDownloadUrl('/ajax/incorrect_location/', function(){}, 'id=' + int_encode);
							}
						})
					}, 250);
				}
				else
				{
					var marker = new Marker(_map);
					marker.add(id, lat, long, location, title, description, type, website, phone, email, _self._getIconByType(type));
				}
			}
		}
		i++;
	},

	/**
	 * _getIconByType()
	 *
	 * Get an icon by type
	 */
	this._getIconByType = function(type)
	{
		// Declare variables
		var icon = null;

		switch(parseInt(type))
		{
			// The integer values matches those defined in constants.php for each marker (activity) type
			case 0:		// Dietitians
				icon = _iconDietitian;
				break;

			case 1:		// Clubs
				icon = _iconSportsClub;
				break;

			case 2:		// Venue
				icon = _iconSportsVenue;
				break;

			case 3:		// Exercise Physiologists
				icon = _iconExercise;
				break;

			case 4:		// Physiotherapists
				icon = _iconPhysio;
				break;

			case 5:		// Remedial Massage Therapists
				icon = _iconRemedial;
				break;

			case 6:		// Running Clubs
				icon = _iconRunning;
				break;

			default:	// Clubs
				icon = _iconSportsClub;
		}

		return icon;
	},


	/**
	 * -------------------------------------------------------------------------
	 * Public functions
	 * -------------------------------------------------------------------------
	 */

	/**
	 * setType()
	 *
	 * Set type of the map
	 */
	this.setType = function(type)
	{
		switch(type)
		{
			case 'mixed':
				_map.setMapType(G_HYBRID_MAP);
				break;

			case 'satellite':
				_map.setMapType(G_SATELLITE_MAP);
				break;

			default:
				_map.setMapType(G_NORMAL_MAP);
				break;
		}
	},

	/**
	 * search()
	 *
	 * Search
	 */
	this.search = function()
	{
		// Declare variables
		var _self		= this;
		var search		= new Search();
		var searchMap	= new GClientGeocoder();

		var postcode = $('#postcode_input').val();

		if( '' == postcode )
		{
			alert('Please enter a postcode or suburb.');
			return;
		}

		// Clear all markers
		this._clearMarkers();

		// Save a copy of the search string into the saved search div
		search.saveSearch(postcode);

		// Perform the search and then update the map to show the search result
		searchMap.getLatLng(search.completeSearch(postcode), function(latlng){
			if( latlng )
			{
				_map.setCenter(latlng, 13);
				_self._addMarkers(postcode);
			}
		});
	}
}


/**
 * -------------------------------------
 * Marker
 * Handles Marker functionality
 * -------------------------------------
 */
var Marker = function(map)
{
	// Declare variables
	var _map				= map;
	var _mapPageCityToSurf	= 'citytosurf_map_module';	// the filename of the page that utilises a customised version of this Google map (can be with or without .php extension)
	var _mapPageIframe		= 'iframe';	// the filename of the page that utilises a customised version of this Google map (can be with or without .php extension)


	/**
	 * -------------------------------------------------------------------------
	 * Private functions
	 * -------------------------------------------------------------------------
	 */

	/**
	 * Returns the filename component of the current URI
	 *
	 * @return string
	 */
	this._pageFilename = function()
	{
		// Declare variables
		var start	= null;
		var end		= null;
		var uri		= document.location.href;

		// Determine the end position of the filename in the URI
		if( uri.lastIndexOf("/")+1 == uri.indexOf("?") )
		{
			// File name component ends with "/?".
			// This means the filename has a trailing slash, so it actually starts after the second last slash and ends before the last slash.
			var uri_no_trail_slash	= uri.substring(0, uri.lastIndexOf("/"));
			start					= uri_no_trail_slash.lastIndexOf("/")+1;
			end						= uri_no_trail_slash.length;
		}
		else if( uri.indexOf("?") >= 1 )
		{
			// Filename component has a "?" after it in the URI
			start	= uri.lastIndexOf("/")+1;
			end		= uri.indexOf("?");
		}
		else
		{
			// Filename component is the last component of the URI
			start	= uri.lastIndexOf("/")+1;
			end		= uri.length;
		}

		return uri.substring(start, end);
	},


	/**
	 * -------------------------------------------------------------------------
	 * Public functions
	 * -------------------------------------------------------------------------
	 */

	/**
	 * add()
	 *
	 * Add a marker
	 */
	this.add = function(id, lat, long, location, title, description, type, website, phone, email, icon)
	{
		// Declare variables
		var search				= new Search();
		var currentSearch		= search.retrieveSavedSearch();
		var opts				= new Object();
		var extra_contact_html	= '';
		var email_html			= '';
		var html				= '';
		var selectedType		= $('#select_area').val();

		// Set opts
		opts.clickable			= true;

		// Get icon
		opts.icon = icon;

		// Set title
		opts.title = title;

		// Set Phone
		if( phone.substr(0,2) == "08" )
		{
			phone = "(" + phone.substr(0,2) + ") " +  phone.substr(2,4) + " " +  phone.substr(6,4)
		}
		else
		{
			phone = phone.substr(0,4) + " " +  phone.substr(4,3) + " " +  phone.substr(7,3)
		}
 
		// Set website
		if( trim(website) != 'http://')
		{
			extra_contact_html = '<a href="' + website + '" target="_blank">Website</a>';
		}
 
		// Set email
		if( email != '' )
		{
			if( website != '' )
			{
				extra_contact_html += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
			}

			extra_contact_html += '<a href="mailto:' + email + '">Email</a>';
		}

		// Set description
		description = description.substr(0, 60);

		// Get a copy of the current search string so it can be passed on the 'Update' url, stored in the update form and then retrieved again later
		html += '<div class="rightBorder map_info">';
		html += '<h1>' + title + '</h1>';
		html += '<p>' + description + '</p>';
		html += '</div>';
		html += '<div class="map_info">';
		html += '<p>' + location + '</p>';
		html += '<p>ph: ' + phone + '</p>';
		html += '<p>' + extra_contact_html + '</p>';
		html += '</div>';
		html += '<div class="map_info_footer">';
 
		switch(this._pageFilename())
		{
			case _mapPageCityToSurf:
			case _mapPageCityToSurf + '.php':
				// Also add a paramater to the query string to indicate the request comes from the City To Surf map module.
				html += '<a href="/aspirational/add_your_own/' + id + '/?search=' + currentSearch + '&citytosurf=1" style="margin-left: 110px;">Update</a><a style="margin-left: 20px;" href="/maps/fwd_to_friend/' + id + '/?search=' + currentSearch + '&citytosurf=1">Tell a friend</a>';
				break;

			case _mapPageIframe:
				// Also add a paramater to the query string to indicate the request comes from the City To Surf map module.
				html += '<a href="/aspirational/add_your_own/' + id + '/?search=' + currentSearch + '&iframe_module=1" style="margin-left: 110px;">Update</a><a style="margin-left: 20px;" href="/maps/fwd_to_friend/' + id + '/?search=' + currentSearch + '&iframe_module=1">Tell a friend</a>';
				break;

			default:
				// No. So make all links open in a hover.
				html += '<a href="javascript:hover(\'/aspirational/add_your_own/' + id + '/?search=' + currentSearch + '\', \'380px\')" style="margin-left: 110px;">Update</a><a style="margin-left: 20px;" href="javascript:hover(\'/maps/fwd_to_friend/' + id + '/\')">Tell a friend</a>';
		}
 
		html += '</div>';

		var marker = new GMarker(new GLatLng(lat, long), opts);
		//markerGroup[type].push(marker);

		// Add an event listener for the marker to open up the info window.
		GEvent.addListener(marker, 'click', function()
			{
				marker.openInfoWindowHtml(html);
				selectedMarker = marker;
			}
		);

		// Add marker to map
		_map.addOverlay(marker);

		// Determine if to show marker or not
		if( type == selectedType || selectedType == '' )
		{
			marker.show();
		}
		else
		{
			marker.hide();
		}

		return true;
	}
}


/**
 * -------------------------------------
 * Search
 * Handles Search functionality
 * -------------------------------------
 */
var Search = function()
{
	// Declare variables
	var _id = '#current_search';

	/**
	 * saveSearch
	 *
	 * Writes the content of search_string into the div_saved_search DOM object so it can be retrieved later
	 * by javascript during the same page instance.
	 *
	 * @param string searchString
	 */
	this.saveSearch = function(searchString)
	{
		if( $(_id) != undefined )
		{
			$(_id).html(searchString);
		}
	},

	/**
	 * retrieveSavedSearch()
	 *
	 * Retrieves the content of search string stored in the div_saved_search DOM object.
	 * If no content exists or the DOM object div_saved_search cannot be found, a blank string is returned.
	 *
	 * @return string
	 */
	this.retrieveSavedSearch = function()
	{
		// Declare variables
		var savedSearch = '';

		if( $(_id) != undefined )
		{
			savedSearch = $(_id).html();
		}

		return savedSearch;
	},

	/**
	 * completeSearch()
	 *
	 * @param String search
	 * @return string
	 */
	this.completeSearch = function(search)
	{
		if( search )
		{
			search = search.toString();
			if( search.toLowerCase().indexOf('western australia') < 0 )
			{
				search =  "western australia, " + search;
			}
		}
		return search;
	}
}

/**
 * -------------------------------------
 * Conatiner
 * Handles conatiner functionality
 * -------------------------------------
 */
var Container = function()
{
	/**
	 * show()
	 *
	 * shows the active container
	 */
	this.show = function(name)
	{
		// Hide all *_container divs
		$("div.[id*='_container']").hide();
		
		//Show the one we want to male active
		$("#" + name + "_container").show();
	}
}
