//--------------------------- classes ----------------------------

// constructeur de la classe
function Store( params )
{
	//------------ params --------------
	for ( var i in params ) {
		this[i] = params[i];
	}
}
  
Store.prototype.getInfoWindowHtml = getInfoWindowHtml;
function getInfoWindowHtml() {
	return this.infowindowhtml;
}


Store.prototype.getDirectionsSummaryHtml = getDirectionsSummaryHtml;
function getDirectionsSummaryHtml() {
	return '<div class="summary">' + this.infowindowhtml + '</div>'
		 + '<div class="timetable">' + this.timetablehtml + '</div>'
		 + '<p class="showDirections"><a href="#">' + globals.messages.show_store_directions + '</a></p>'
		 + '<div class="cleaner"></div>'
		 + '<div class="directions">' + this.directions.htmlRoute + '</div>';
}


//--------------------------- globals ----------------------------
var map				= null;
var stores			= null;
var stores_length	= 0;
var max_results		= 3;



// init the application
function initialize() {
	var elementMap = document.getElementById('map');
	$(elementMap).css(globals.map.css);

	map = new MapOfthedead(elementMap, globals.map.defaults, getStores);

	initControls();
}

// get stores data from web service
function getStores() {
	jQuery.getJSON(globals.services.stores + '/getstores/locale/' + globals.locale, null, function ( json ) {
		if ( json != undefined ) {
			stores = new Array();
			var i;
			for ( i in json ) {
				stores.push(new Store(json[i]));
			}
			stores_length = stores.length;
		}
			
		initMarkers();
	});
}

// add the stores' markers on the map
function initMarkers() {
	var base = new google.maps.Icon(G_DEFAULT_ICON);
	base.iconSize = new google.maps.Size(40, 35);
	base.shadowSize = new google.maps.Size(40, 35);
	base.iconAnchor = new google.maps.Point(20, 35);
	base.infoWindowAnchor = new google.maps.Point(20, 35);
		
	var store, icon = null;
	var i = 0;
	for ( ; i < stores_length; i++ ) {
		icon	= new google.maps.Icon(base, globals.map.logo.url, null, globals.map.logo.url);
		store	= stores[i];

		map.addMarker(
			[store.gps[1], store.gps[0]],
			store.company,
			store.infowindowhtml,
			icon
		);
	}
}

// retrieve a store in the stores Array by the given id
function getStoreById( id ) {
	var i = 0;
	for ( ; i < stores_length; i++ ) {
		if ( stores[i].id == id ) {
			return stores[i];
		}
	}
	
	return false;
}

// @todo : no other place?
var fromAddress	= '';
var travelMode	= '';

// init form controls
function initControls() {
	jQuery('form#store_search').submit(search);
	unblockApplication();
}

function search( e ) {
	e.preventDefault();
	
	blockApplication();
	
	fromAddress = $('input#address', this).val() + ', Belgique';
	travelMode = $('select#travelmode', this).val();

	getStoreDirections();
}

var pointer	= 0;

function removeDirectionsMarkers(  ) {
	var numMarkers = this.getNumGeocodes();
	var i = 0;
	for ( ; i < numMarkers; i ++ ) {
		this.getMarker(i).hide();
	}
}

// first part of a recursive process to get directions of each store
function getStoreDirections() {
	var store = stores[pointer];
	
	var temp = document.getElementById('temp');
	
	if ( temp == undefined ) {
		var temp = document.createElement('div');
		temp.id = 'temp';
		temp.style.display = 'none';
		document.body.appendChild(temp);
	}
	
	var directions = new google.maps.Directions(map.map, temp);

	google.maps.Event.addListener(directions, 'load', getStoreDirectionsCallback);
	google.maps.Event.addListener(directions, 'addoverlay', removeDirectionsMarkers);
	google.maps.Event.addListener(directions, 'error', getStoreDirectionsErrorCallback);
	
	directions.load(
		'from: ' + fromAddress + ' to: ' + store.address,
		{
			'locale' : globals.locale,
			'preserveViewport' : true,
			'getPolyline' : true,
			'getSteps' : true,
			'travelMode' : eval(travelMode)
		}
	);
}

// second part of a recursive process to get directions of each store
function getStoreDirectionsCallback( data ) {
	var code = this.getStatus().code;
	
	if ( code == '200' ) {
		var store = stores[pointer];
	
		if ( store.directions != undefined ) {
			store.directions.clear();
		}
		
		store.directions = data;

		var polyline = data.getPolyline();
		polyline.setStrokeStyle({color:'#c5316f', opacity:'.7'});
		polyline.hide();

		setTimeout(function (e) {
			store.directions.htmlRoute = document.getElementById('temp').innerHTML;
			document.getElementById('temp').innerHTML = '';

			getStoreDirectionsIncrementation();
		}, 25);
	}
}

function getStoreDirectionsErrorCallback( data ) {
	stores[pointer].directions = null;
	//alert(stores[pointer].id);
	
	getStoreDirectionsIncrementation();
}

function getStoreDirectionsIncrementation() {
	if ( pointer < stores_length-1 ) {
		pointer++;
		getStoreDirections();
	} else {
		pointer = 0;
		getNearestStores();
	}
}

// used to sort the stores according to their distances
function compareDistance( a, b ) {
	if ( a.directions != null && b.directions != null ) {
		return a.directions.getDistance().meters - b.directions.getDistance().meters;
	} else if ( a.directions == null ) {
		return 1;
	} else {
		return -1;
	}
}

// get the n nearest stores and add the event listener
function getNearestStores() {
	stores.sort(compareDistance);
	
	var htmlList = '';
	var i = 0;
	try {
		for ( ; i < max_results; i++ ) {
			htmlList+= '<li id="store_' + stores[i].id + '">'
					+ stores[i].getDirectionsSummaryHtml()
					+ '</li>';
		}
	
		var storesElement = document.getElementById('stores');
		storesElement.innerHTML = htmlList;
		storesElement.style.display = 'block';
		
		jQuery('li p.showDirections a', storesElement).click(showStoreDirections);
		jQuery('li div.summary', storesElement).css({cursor : 'pointer'}).click(showStoreRoute).eq(0).click();
	} catch( e ) {
		alert(globals.messages.no_results_for_your_search);
	}
	
	var storesElementLinks = document.getElementById('displayall');
	storesElementLinks.style.display = 'none';
	
	unblockApplication();
}

function adjustViewport( bounds ) {
	var boundsCenter = bounds.getCenter();
	var zoom = map.map.getBoundsZoomLevel(bounds);
	
	google.maps.Event.addListener(map.map, 'moveend', function ( e ) {
		google.maps.Event.clearListeners(map.map, 'moveend');
		this.setZoom(zoom);
	});
	
	map.map.panTo(boundsCenter);
}

function showStorePolyline( id ) {
	var store, polyline;
	var i = 0;
	for ( ; i < stores_length; i++ ) {
		store = stores[i];

		if ( store.directions != null ) {
			polyline = store.directions.getPolyline();
		
			if ( store.id != id && !polyline.isHidden() ) {
				polyline.hide();
			} else if ( store.id == id && polyline.isHidden() ) {
				polyline.show();

				var polylineBounds = polyline.getBounds();
				adjustViewport(polylineBounds);
			}
		}
	}
}

function showStoreRoute( e ) {
	var id = this.parentNode.id.substring(6);
	showStorePolyline(id);
}

function showStoreDirections( e ) {
	e.preventDefault();
	
	var parent = this.parentNode.parentNode;
	
	var id = parent.id.substring(6);
	showStorePolyline(id);
	
	var div = $('div.directions', parent);
	
	if ( div.is(':visible') ) {
		this.innerHTML = globals.messages.show_store_directions;
		div.slideUp(700);
	} else {
		this.innerHTML = globals.messages.hide_store_directions;
		div.slideDown(700);
	}
}

