var currentMapSwitcher = 1;
var propertyStreetViewLoaded = false;
var propertyLatitude;
var propertyLongitude;
var myPano;
var gmap;

function save_listing (link, id) {

	link.firstChild.nodeValue = 'Adding...';

	jQuery.post (
		'/account/save-listing',
		{ listing_id: id },
		function (resp) {
			link.firstChild.nodeValue = 'Added to My Property! Click to view.';
			link.href = '/account/my-property';
			link.onclick = null;
			link.className += link.className ? ' added' : 'added';
		}
	);

	return false;

}

function save_open_home (link, id) {

	link.firstChild.nodeValue = 'Adding...';

	jQuery.post (
		'/account/save-open-home',
		{ open_home_id: id },
		function (resp) {
			link.firstChild.nodeValue = 'Added to My Open Homes List! Click to view.';
			link.href = '/account/my-property';
			link.onclick = null;
			link.className += link.className ? ' added' : 'added';
		}
	);

	return false;

}

function redirect (url) {

	location.href = url;

	return false;

}

function confirm_redirect (url, message) {

	if (confirm (message))
		redirect (url);

	return false;

}

function image_switcher ()
{
	jQuery("div.thumbDisplay p a").click( function () {
		jQuery('#preview').attr({src: jQuery(this).attr('href'), alt: jQuery(this).attr('alt')});
		return false;
	});
}

function propertyMarker (listing_id, name, price, thumbnail, listing_sub_type) {

	var point = new GLatLng (glat, glng); // now uses global variables

	var icon = new GIcon ();
	icon.image = '/img/gmap/house.png';
	icon.shadow = '/img/gmap/shadow.png';
	icon.iconSize = new GSize (38, 23);
	icon.shadowSize = new GSize (38, 23);
	icon.iconAnchor = new GPoint (9, 23);
	icon.infoWindowAnchor = new GPoint (10, 23);
	icon.infoShadowAnchor = new GPoint (10, 23);

	var marker = new GMarker (point, icon);

	var mapProperty = jQuery.DIV ({ className: 'mapProperty' });

		var thumbnail = jQuery.DIV (
			{ className: 'thumbnail' },
			jQuery.A (
				{ href: '/' +listing_id },
				jQuery.IMG ({ src: thumbnail, width: 80, height: 60, alt: '' })
			)
		);
		
		mapProperty.appendChild (thumbnail);

		var details = jQuery.DIV ({ className: 'details' });

			details.appendChild (jQuery.A (
				{ href: '/' +listing_id },
				name
			));
			
			details.appendChild (jQuery.BR ());
				
			if(listing_sub_type) {
				details.appendChild (jQuery.SPAN ({ className: 'listing_sub_type' }, listing_sub_type));
				details.appendChild (jQuery.BR ());
			}
			
			details.appendChild (jQuery.SPAN ({ className: 'price' }, price));

		mapProperty.appendChild (details);

	GEvent.addListener (marker, 'click', function () {
		marker.openInfoWindowHtml (mapProperty)
	});

	return marker;

}

function officeMarker (latitude, longitude, office_id, rewrite, name, street_address, city) {

	var point = new GLatLng (latitude, longitude);

	var icon = new GIcon ();
	icon.image = '/img/gmap/house.png';
	icon.shadow = '/img/gmap/shadow.png';
	icon.iconSize = new GSize (38, 23);
	icon.shadowSize = new GSize (38, 23);
	icon.iconAnchor = new GPoint (9, 23);
	icon.infoWindowAnchor = new GPoint (10, 23);
	icon.infoShadowAnchor = new GPoint (10, 23);

	var marker = new GMarker (point, icon);

	var mapOffice = jQuery.DIV ({ className: 'mapOffice' });

		/*var thumbnail = jQuery.DIV (
			{ className: 'thumbnail' },
			jQuery.A (
				{ href: '/' +listing_id },
				jQuery.IMG ({ src: thumbnail, width: 80, height: 60, alt: '' })
			)
		);

		mapProperty.appendChild (thumbnail);*/

		var details = jQuery.DIV ({ className: 'details' });

			details.appendChild (jQuery.A (
				{ href: '/offices/' +rewrite },
				name
			));

			details.appendChild (jQuery.BR ());

			details.appendChild (jQuery.SPAN ({ }, street_address));

			details.appendChild (jQuery.BR ());

			details.appendChild (jQuery.SPAN ({ }, city));

		mapOffice.appendChild (details);

	GEvent.addListener (marker, 'click', function () {
		marker.openInfoWindowHtml (mapOffice)
	});

	return marker;

}

// These have to be global now due to getLatLng callback
var map;
var gmap;
// These are here for the call to propertyMarker()
var glat;
var glng;

function googleMap (element_id, address, zoom, large) {

	if (GBrowserIsCompatible ()) {

		map = document.getElementById (element_id);

		gmap = new GMap2 (map);
		geocoder = new GClientGeocoder();
		geocoder.getLatLng(address, function(point) {
			if(!point) {
				return;
			}
			gmap.addMapType(G_PHYSICAL_MAP);

			gmap.setCenter(point, zoom);

			if (large) {

				gmap.addControl (new GMapTypeControl ());
				gmap.addControl (new GLargeMapControl ());

			} else {

				gmap.addControl (new GSmallMapControl ());

			}

			//gmap.addControl (new GOverviewMapControl ());

			var maptypes = gmap.getMapTypes ();
			
			//street view
			init_control_tab();
			
			gmap.setMapType (maptypes[0]);
			
			//street view
			glat = point.lat();
			glng = point.lng();
			set_property_point(glat, glng);
			InitializeStreetView();
			
			// Set up the property marker
			gmap_mark_listing();
		});

	} else {

		map.innerHTML = "Maps are not compatible with your browser.";

		return false;

	}

}

// This is used on the offices page, it's too much work to redo everything to support multiple maps with the
// new API (we need the new API for address-based lookup, but we can get by with lat/lng for offices).
function googleMapLegacy (element_id, latitude, longitude, zoom, large) {

	if (GBrowserIsCompatible ()) {

		var map = document.getElementById (element_id);

		gmap = new GMap2 (map);
		gmap.addMapType(G_PHYSICAL_MAP);
		gmap.setCenter(
			new GLatLng (latitude, longitude),
			zoom
		);

		if (large) {

			gmap.addControl (new GMapTypeControl ());
			gmap.addControl (new GLargeMapControl ());

		} else {

			gmap.addControl (new GSmallMapControl ());

		}

		//gmap.addControl (new GOverviewMapControl ());

		var maptypes = gmap.getMapTypes ();
		
		//street view
		init_control_tab();
		
		gmap.setMapType (maptypes[0]);
		
		//street view
		set_property_point(latitude, longitude);
		InitializeStreetView();
		
		return gmap;

	} else {

		map.innerHTML = "Maps are not compatible with your browser.";

		return false;

	}

}

function loadListings(gmap, params, open_homes) 
{
	gmap.clearOverlays();

	function listingParser(data) 
	{
		var json 		= eval("(" + data + ")");
		var bounds 		= new GLatLngBounds;
		var listings 	= json['listings'];

		for(var i=0; i < listings.length; i++) {
	
			var listing 	= listings[i];
			var marker 		= propertyMarker(listing.latitude, listing.longitude, listing.id, listing.name, listing.price, listing.thumbnail, listing.listing_sub_type);
	
			gmap.addOverlay(marker);
			bounds.extend(marker.getPoint());
	
		}

		gmap.setCenter(
			bounds.getCenter(),
			gmap.getBoundsZoomLevel(bounds)
		);
	}
	
	// If we want to load open homes
	if(open_homes) {
		jQuery.post(
			'/ajax/open-homes',
			params,
			listingParser
		);
	}
	// Load listings
	else {
		jQuery.post(
			'/ajax/listings',
			params,
			listingParser
		);
	}
	
	jQuery('div#loading').hide();
}


/**
 * We're now usng select boxes for filters
 * so we need to format the filter string then
 * redirect (mainly because of min/max price
 * being in one select box)
 *
 */
function submit_filters() {

	var arr_elements = new Array();

	jQuery('#filters select').each(function() {

		var value 	= jQuery(this).attr('value');
		var name 	= jQuery(this).attr('name');

		if(value == '') {
			return;
		}

		// This is to account for min/max price select box
		if(name == 'price') {
			var arr_price = value.split('|');
			if(arr_price[0] != '') arr_elements.push('min_price='+arr_price[0]);
			if(arr_price[1] != '') arr_elements.push('max_price='+arr_price[1]);
		}
		else {
			arr_elements.push(name+'='+value);
		}

	});

	var location		= jQuery(document).attr('location').toString(); // For some reason this wasn't returning a string
	var request_uri 	= location.split('?');

	// Redirect with filters attached to url
	redirect(request_uri[0]+'?'+arr_elements.join('&'));
}

jQuery(document).ready(function () {
	jQuery("#email-agents").hide();
	jQuery("#email-agents-toggle").click(function (){
		jQuery("#email-agents").toggle();
		return false;
	});
});

function Node (id, label) {

	this.id = id;
	this.label = label;
	this.children = new Array ();

}

function createElement (type, name, checked) {

	var element = null;

	try {
		element = document.createElement('<input type="'+type+'" name="'+name+'"'+(checked ? ' checked="checked"' : '')+'>');
	} catch (e) {}

	if (!element || element.nodeName != 'INPUT') {
		element = document.createElement('input');
		element.type = type;
		element.name = name;
		element.checked = checked;
	}

	return element;

}

function addLoadEvent (func) {

	var oldonload = window.onload;

	if (typeof window.onload != 'function') {

		window.onload = func;

	} else {

		window.onload = function() {

			if (oldonload)
				oldonload ();

			func ();

		}

	}

}

function nodeSelectBox (nodes, element_id, selected_id, all_text, disabled) {

	var element = document.getElementById(element_id);
	var select = jQuery.SELECT({id: element_id, name: element_id});
	var child_nodes = new Array ();

	select.appendChild (jQuery.OPTION({
		text: all_text,
		innerText: all_text,
		value: '',
		selected: !selected_id
	}));

	for (var i = 0; i < nodes.length; i++) {

		var selected = (selected_id && nodes[i].id == selected_id);

		if (selected)
			child_nodes = nodes[i].children;

		select.appendChild (jQuery.OPTION({
			text: nodes[i].label,
			innerText: nodes[i].label,
			value: nodes[i].id,
			selected: selected
		}));

	}

	if (disabled)
		select.disabled = true;

	element.parentNode.replaceChild (select, element);

	return child_nodes;

}

function changeRegion () {

	var districts = new Array ();
	var region_id = this.options[this.selectedIndex].value;

	for (var i = 0; i < regions.length; i++) {

		if (regions[i].id == region_id)
			districts = regions[i].children;

	}

	nodeSelectBox (districts, 'district_id', false, 'All districts', !region_id);

	if (is_property) {

		document.getElementById('district_id').onchange = changeDistrict;

		nodeSelectBox (new Array (), 'suburb_id', false, 'All suburbs', true);

	}

}

function changeDistrict () {

	var suburbs = new Array ();
	var district_id = this.options[this.selectedIndex].value;
	var region = document.getElementById('region_id');
	var region_id = region.options[region.selectedIndex].value;

	for (var i = 0; i < regions.length; i++) {

		if (regions[i].id == region_id) {

			for (var j = 0; j < regions[i].children.length; j++) {

				if (regions[i].children[j].id == district_id)
					suburbs = regions[i].children[j].children;

			}

		}

	}

	nodeSelectBox (suburbs, 'suburb_id', false, 'All suburbs', !district_id);

}

function search_options (listing_sub_type_id, region_id, district_id, suburb_id) {

	is_property = (listing_type_id != 4);
	is_lifestyle = (listing_sub_type_id == 5);

	var districts = nodeSelectBox (regions, 'region_id', region_id, 'All regions', false);
	document.getElementById('region_id').onchange = changeRegion;

	var suburbs = nodeSelectBox (districts, 'district_id', district_id, 'All districts', !region_id);
	document.getElementById('district_id').onchange = changeDistrict;

	if (is_property) {

		nodeSelectBox (suburbs, 'suburb_id', suburb_id, 'All suburbs', (!region_id || !district_id));

	}


	var listing_sub_types = new Array ();
	for (var i = 0; i < listing_types.length; i++) {

		if (listing_types[i].id == listing_type_id)
			listing_sub_types = listing_types[i].children;

	}

	if (is_property) {

		nodeSelectBox (listing_sub_types, 'listing_sub_type_id', listing_sub_type_id, 'Any property type', false);

	} else {

		nodeSelectBox (listing_sub_types, 'listing_sub_type_id', listing_sub_type_id, 'Any business type', false);

	}

}

//street view 
function switchNormalMap(){
	$("#listingStreetviewMap").hide();
	$("#listingMap").show();
}

function handleNoFlash(errorCode) {
  if (errorCode == FLASH_UNAVAILABLE) {
    alert("Error: Flash doesn't appear to be supported by your browser");
    return;
  }
}

function propertyStreetViewInit(response){
 // can not find user position on streetview
 if (response.code != 200){
 	//handle the exception here
 	$("#showStreetViewTab").remove();
 }
 else{
 	var latlng = new GLatLng(response.Location.lat, response.Location.lng);
 	myPano = new GStreetviewPanorama(document.getElementById("listingStreetviewMap"));
	myPano.setLocationAndPOV(latlng);
	propertyStreetViewLoaded = true;
	currentMapSwitcher = 2;
	GEvent.addListener(myPano, "error", handleNoFlash);
 }
}

function set_property_point(latitude, longitude){
	propertyLatitude = latitude;
	propertyLongitude = longitude;
}

function InitializeStreetView(){
	client = new GStreetviewClient();
	var propertylatlong = new GLatLng(propertyLatitude,propertyLongitude);
	if(propertylatlong){
		client.getNearestPanorama(propertylatlong, propertyStreetViewInit);
	}
}

function switchStreetviewMap(){
	$("#listingMap").hide();
	$("#listingStreetviewMap").show();
	if(!propertyStreetViewLoaded){
		InitializeStreetView();
	}
}

function init_control_tab(){
	if($("#listingMap") && $("#showMapTab")){
	    $("#showMapTab").click(function(){if(currentMapSwitcher > 1){switchNormalMap();} gmap.setMapType(G_NORMAL_MAP);});
	}
	if($("#listingMap") && $("#showStreetViewTab")){
	    $("#showStreetViewTab").click(switchStreetviewMap);
	}
}

// Google Maps API v3 code is below.  Replaces all of the other map stuff above.

// The latitude and longitude will only be supplied if they have entered it into the admin area.
// We trust this as a precise location but if they are unavailable we ask Google to geocode the address.
function set_map_location(container, input_address, info_window_content, latitude, longitude) {
	map_container = document.getElementById(container);

	map = new google.maps.Map(map_container);
	geo = new google.maps.Geocoder();

	if(input_address.length == 0) {
		alert('empty address');
		return false;
	}

	// Looks like it needs to be on by default: if I hide it then reveal the map doesn't display well.
	map_container.style.display = "block";

	var georeq = {
		bounds: map_search_bounds,
		address: input_address
	};
	
	if(latitude && longitude) {
		map_position = new google.maps.LatLng(latitude, longitude);
		position_map(map_position, info_window_content);
	}
	else {
		geo.geocode(georeq, function(results, status) {
			if(status == google.maps.GeocoderStatus.OK) {
				map_position = results[0].geometry.location;
				position_map(map_position, info_window_content);
			}
			else {
				map_container.style.display = 'none';
				document.getElementById('map_disclaimer').style.display = 'none';
				document.getElementById('listingMapFail').style.display = 'block';
			}
		});
	}

	return false;
}

// Abstracted out so we can use it regardless of geocoding or lat/long supply.
function position_map(map_position, info_window_content) {
	map.setOptions({
		zoom: 16,
		center: map_position,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	});

	var icon = marker_image('/img/gmap/house.png');
	var shadow = marker_image('/img/gmap/shadow.png');
	marker = new google.maps.Marker({
		map: map,
		icon: icon,
		shadow: shadow,
		position: map_position,
		visible: true
	});
	google.maps.event.addListener(marker, 'click', toggle_map_info_window);
	info_window = new google.maps.InfoWindow({
		content: info_window_content
	});
	google.maps.event.addListener(info_window, 'closeclick', close_map_info_window);
	info_window_visible = false;

}

// f--k it, I may as well abstract this since all but one of the parameters is identical.
function marker_image(url) {
	return new google.maps.MarkerImage(
		url,							// url
		new google.maps.Size(38, 23),	// size
		new google.maps.Point(0, 0),	// origin
		new google.maps.Point(10, 23),	// anchor - the bit I am trying to change.
		new google.maps.Point(38, 23)	// scaled size
	);
}

function office_map(element_id, latitude, longitude, zoom) {
	var container = document.getElementById(element_id);

	var map = new google.maps.Map(container);
	
	var map_position = new google.maps.LatLng(latitude, longitude);
	map.setOptions({
		zoom: zoom,
		center: map_position,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		mapTypeControl: false,
		streetViewControl: false
	});
	var icon = new google.maps.MarkerImage(
		'/img/gmap/house.png',			// url
		new google.maps.Size(38, 23),	// size
		new google.maps.Point(0, 0),	// origin
		new google.maps.Point(10, 23),	// anchor - the bit I am trying to change.
		new google.maps.Point(38, 23)	// scaled size
	);
	var shadow = new google.maps.MarkerImage(
		'/img/gmap/shadow.png',			// url
		new google.maps.Size(38, 23),	// size
		new google.maps.Point(0, 0),	// origin
		new google.maps.Point(10, 23),	// anchor - the bit I am trying to change.
		new google.maps.Point(38, 23)	// scaled size
	);
	marker = new google.maps.Marker({
		map: map,
		icon: icon,
		shadow: shadow,
		position: map_position,
		visible: true
	});
}

function toggle_map_info_window() {
	if(info_window_visible) {
		close_map_info_window();
	}
	else {
		open_map_info_window();
	}
}

function open_map_info_window() {
	info_window.open(map, marker);
	info_window_visible = true;
}
function close_map_info_window() {
	info_window.close();
	info_window_visible = false;
}

