// frontend interface for ISPM

var ISPM_Frontend = ISPM.extend({
    groups: null,
    networks: null,
    reminders: null,
    
    providers: [],
    
    markersManager: null,
    
    loadedNetworks: [],
    updateNetworks: true,
    
    cityInput: 'ispm-city-input',
    streetInput: 'ispm-street-input',
    
    addrNotFoundEl: 'ispm-addr-not-found',
    addrFoundManyEl: 'ispm-addr-found-many',
    
    request: null,
    
    zoomMarkers: 11,
    zoomGroups: 11,
    zoomNetworks: 14,
    zoomAreas: 18,
    
    providersFoundWidget: 'frontend/providers_found',
    providersNotFoundWidget: 'frontend/providers_not_found',
    
    enableMarkers: function() {
	// create group marker icons (big, medium, small)
	var groupIcon = {};
	
	[['big', 64, 64], ['medium', 48, 48], ['small', 32, 32]].each(function(item) {
	    groupIcon[item[0]] = new GIcon(G_DEFAULT_ICON, this.base_url + 'img/ispm/group_marker.gif');
	    groupIcon[item[0]].iconSize = new GSize(item[1], item[2]);
	    groupIcon[item[0]].iconAnchor = new GPoint(item[1]/2, item[2]/2);
	    groupIcon[item[0]].shadow = "";
	}, this);
	
	// create network marker icon
	var networkIcon = new GIcon(G_DEFAULT_ICON, this.base_url + 'img/ispm/network_marker.gif');
	
	networkIcon.iconSize = new GSize(28, 34);
	networkIcon.iconAnchor = new GPoint(14, 28);
	networkIcon.shadow = "";
	
	var areaIcon = new GIcon(G_DEFAULT_ICON, this.base_url + 'img/ispm/area_marker.gif');
	
	areaIcon.iconSize = new GSize(40, 40);
	areaIcon.iconAnchor = new GPoint(20, 20);
	areaIcon.shadow = "";
	
	this.showLoader();
	
	for(var i in this.groups) {
		var networks = 0;
		
		for(var i2 in this.groups[i][2]) {
		    this.markersManager.addMarker(new GMarker(new GLatLng(this.groups[i][2][i2][0], this.groups[i][2][i2][1]), {
			    icon: networkIcon,
			    clickable: false,
			    draggable: false,
			    zIndexProcess: function() {return -1}
		    }), this.zoomMarkers, this.zoomNetworks-1);
		    
		    for(var i3 in this.groups[i][2][i2][2]) {
			this.markersManager.addMarker(new GMarker(new GLatLng(this.groups[i][2][i2][2][i3][0], this.groups[i][2][i2][2][i3][1]), {
				icon: areaIcon,
				clickable: false,
				draggable: false,
				zIndexProcess: function() {return -1}
			}), this.zoomNetworks, this.zoomAreas-1);
		    }
		    
		    networks++;
		}
		
		this.markersManager.addMarker(new GMarker(new GLatLng(this.groups[i][0], this.groups[i][1]), {
			icon: networks < 5 ? groupIcon.small : (networks < 10 ? groupIcon.medium : groupIcon.big),
			clickable: false,
			draggable: false,
			zIndexProcess: function() {return -1}
		}), 0, this.zoomGroups-1);
	}
	
	this.hideLoader();
	
	this.markersManager.refresh();
    },
    
    enableAutoLoad: function() {
	var that = this;
	
	GEvent.addListener(this.map, 'move', function() {
		that.loadAreas();
	});
	
	GEvent.addListener(this.map, 'zoomend', function(oldLevel, newLevel) {
		if(newLevel < that.zoomNetworks) {
			for(var i in that.loadedNetworks) {
				for(var i2 in that.loadedNetworks[i].areas) {
					if(that.loadedNetworks[i].areas[i2].poly) {
						that.loadedNetworks[i].areas[i2].poly.hide();
					}
				}
			}
			
			that.loadWidget('frontend/zoom');
			that.hidePointers();
		}
		else {
			that.loadAreas();
			
			for(var i in that.loadedNetworks) {
				for(var i2 in that.loadedNetworks[i].areas) {
					if(that.loadedNetworks[i].areas[i2].poly) {
						that.loadedNetworks[i].areas[i2].poly.show();
					}
				}
			}
			
			that.loadWidget('frontend/info');
		}
	});
    },
    
    enablePointers: function() {
	this.addPointer('blue', 'mappoint-blue.png', new GSize(80, 75), new GPoint(32, 70));
	this.addPointer('red', 'mappoint-red.png', new GSize(80, 75), new GPoint(32, 70));
	this.addPointer('violet', 'mappoint-violet.png', new GSize(80, 75), new GPoint(32, 70));
    },
    
    enableRequests: function() {
	var that = this;
	
	this.request = new ISPM_Request({ispm: this});
	
	GEvent.addListener(this.map, 'click', function(overlay, point, overlay_point) {
		point = overlay ? overlay_point : point;
		
		// if zoom level < 14 zoom in to 14 and center map on given point
		if(that.map.getZoom() < this.zoomNetworks) {
			that.map.setZoom(this.zoomNetworks);
			that.map.setCenter(point);
		}
		
		// hide all pointers
		that.hidePointers();
		
		// show blue pointer
		that.pointers.blue.setLatLng(point);
		
		// hide red pointer
		that.pointers.red.setLatLng(point);
		
		// get providers in given point
		that.getProvidersInPoint(point);
	});
    },
    
    enableReminders: function() {
	var that = this;
	
	if(this.reminders) {
		var reminderIcon = new GIcon(G_DEFAULT_ICON, this.base_url + 'img/ispm/reminder_marker.gif');
		
		reminderIcon.iconSize = new GSize(16, 35);
		reminderIcon.iconAnchor = new GPoint(8, 35);
		reminderIcon.shadow = "";
		
		var reminder = this.reminders.each(function(item, i) {
			var reminderMarker = new GMarker(new GLatLng(item[1], item[2]), {
				icon: reminderIcon,
				clickable: true,
				draggable: false,
				zIndexProcess: function() {return -1}
			});
			
			reminderMarker.reminderID = item[0];
			
			GEvent.addListener(reminderMarker, "click", function() {
				new mint.Request({
					url: $php.base_url + 'ispm_remote/get_reminder_info',
					method: 'POST',
					
					params: {
						id: this.reminderID
					},
					
					events: {
						done: function(response) {
							var info = mint.createElement("div", {
								className: "reminder-info-window",
								innerHTML: response
							});
							
							this.openInfoWindow(info);
						}.bind(this)
					}
				});
			});
			
			this.markersManager.addMarker(reminderMarker, 0, 17);
		}, this);
		
		this.markersManager.refresh();
	}
    },
    
    loadAreas: function() {
	var that = this;
	
	if(this.map.getZoom() >= this.zoomNetworks && this.updateNetworks) {
		for(var i in this.networks) {
			// if network center point is in view bounds
			if(this.map.getBounds().containsLatLng(new GLatLng(this.networks[i][0], this.networks[i][1]))) {
				if(this.loadedNetworks[i] === undefined) {
					this.loadedNetworks[i] = new ISPM_Network({
						id: i,
						ispm: this
					});
					
					this.loadedNetworks[i].load();
				}
			}
		}
		
		// update interval = 200ms
		this.updateNetworks = false;
		setTimeout(function() {that.updateNetworks = true}, 200);
	}
    },
    
    getProvidersInPoint: function(point) {
	var that = this;
	
	if(this.request) {
	    this.request.lat = point.lat();
	    this.request.lng = point.lng();
	}
	
	new mint.Request({
		url: $php.base_url + 'ispm_remote/get_providers_in_point',
		method: 'POST',
		
		params: {
			lat: point.lat(),
			lng: point.lng()
		},
		
		events: {
			done: function() {
				// check if any providers found and load specific widget
				if(this.response) {
					that.providers = eval('('+this.response+')');
					
					that.pointers.red.hide();
					
					that.pointers.blue.setLatLng(point);
					that.pointers.blue.show();
					
					that.loadWidget(that.providersFoundWidget, {
						providers: mint.encodeJSON(that.providers)
					});
				}
				else {
					// hide blue pointer and show red one
					that.pointers.blue.hide();
					
					that.pointers.red.setLatLng(point);
					that.pointers.red.show();
					
					that.loadWidget(providersNotFoundWidget, {
						lat: that.pointers.red.getLatLng().lat(),
						lng: that.pointers.red.getLatLng().lng()
					});
				}
			}
		}
	});
    },
    
    getSimilarCity: function(city) {
	var prefix = city.substr(0, 1), similar = '', ls = -1;
	var levenshtein = function(b, c) {
	    var s, l = (s = b.split("")).length, t = (c = c.split("")).length, i, j, m, n;
	    if(!(l || t)) return Math.max(l, t);
	    for(var a = [], i = l + 1; i; a[--i] = [i]);
	    for(i = t + 1; a[0][--i] = i;);
	    for(i = -1, m = s.length; ++i < m;)
		for(j = -1, n = c.length; ++j < n;)
		    a[(i *= 1) + 1][(j *= 1) + 1] = Math.min(a[i][j + 1] + 1, a[i + 1][j] + 1, a[i][j] + (s[i] != c[j]));
	    return a[l][t];
	};
	
	for(var i = 0; i < this.cities[prefix].length; i++) {
		var tmp = levenshtein(city, this.cities[prefix][i]);
		
		if(ls == -1 || tmp < ls) {
			similar = this.cities[prefix][i];
			ls = tmp;
		}
	}
	
	return similar;
    },
    
    findCityStreet: function(city, street) {
	$(this.addrNotFoundEl).hide();
	$(this.addrFoundManyEl).hide();
	
	var that = this, city = city || $(this.cityInput).value, street = street || $(this.streetInput).value;
	
	setCookie('city', city, 60, '/');
	setCookie('street', street, 60, '/');
	
	this.hidePointers();
	this.loadWidget('frontend/info');
	//this.loadWidget(this.map.getZoom() < 14 ? 'frontend/info' : 'frontend/info');
	
	if(!city || city.toLowerCase() == 'poland' || city.toLowerCase() == 'polska') {
		this.findAddr.call(this, 'Poland', function() {
			that.map.setZoom(6);
		});
	}
	else {
		this.getAddrPoint(street ? city + ' ' + street : city, function(status, point, addr, result) {
		    if(status == ISPM_POINT_FOUND) {
			that.map.setCenter(point);
			that.map.setZoom(street ? 16 : 14)
			
			if(street && city) {
				that.hidePointers();
				that.pointers.blue.setLatLng(point);
				that.getProvidersInPoint(point);
			}
		    }
		    else if(status == ISPM_POINT_FOUND_MANY) {
			$('ispm-addr-found-many-name').innerHTML = addr;
			$('ispm-addr-found-many-name-list').innerHTML = addr;
			
			$('ispm-addr-found-many-list').innerHTML = "";
			
			for(var i = 0, ln = result.Placemark.length; i < ln; ++i) {
			    if(result.Placemark[i].AddressDetails.Country && result.Placemark[i].AddressDetails.Country.AdministrativeArea) {
				var li = document.createElement("li"), a = document.createElement("a");
				
				a.innerHTML = result.Placemark[i].AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
				a.href = "#";
				a.__addr = result.Placemark[i].address;
				
				a.onclick = function() {
				    $ispm.findAddr(this.__addr, function(result) {
					if(result == ISPM_ADDRESS_FOUND) {
					    $ispm.map.setZoom(14);
					}
					else if(result == ISPM_ADDRESS_NOT_FOUND) {
					    $($ispm.addrNotFoundEl).show();
					}
				    });
				    
				    $($ispm.addrFoundManyEl).hide();
				    return false;
				}
				
				li.appendChild(a);
				li.appendChild(document.createTextNode(" (" + result.Placemark[i].address + ")"));
				
				$('ispm-addr-found-many-list').appendChild(li);
			    }
			}
			
			$(that.addrFoundManyEl).show();
		    }
		    else if(status == ISPM_POINT_NOT_FOUND) {
			$(that.addrNotFoundEl).show();
		    }
		});
	}
    }
});