;
var MarkerGrouper = function(map, options) {
	this.map     = map;
	this.options = options;
	this.markers = Array();
	this.bounds  = new GLatLngBounds();
	this.history = {
		latlng: null,
		content: null
	};
}
MarkerGrouper.prototype.createMarker = function(latLng, opts) {
	var options = opts;
	if (!options)
		options = {};
	
	if (options.icon) {
		var image          = options.icon;
		options.icon       = new GIcon(G_DEFAULT_ICON);
		options.icon.image = image;
		
		if (options.iconSize) {
			options.icon.iconSize = options.iconSize;
			options.iconSize      = undefined;
		}
	} else if (this.options && this.options.icon) {
		var image          = this.options.icon;
		options.icon       = new GIcon(G_DEFAULT_ICON);
		options.icon.image = image;
		
		if (this.options.iconSize) {
			options.icon.iconSize = this.options.iconSize;
		}
	}

	var marker = new GMarker(latLng, options);
	
	var me = this;
	var mouseOnImage;
	if (options.mouseOverIcon) {
		mouseOnImage = options.mouseOverIcon;
	} else if(this.options && this.options.mouseOverIcon) {
		mouseOnImage = this.options.mouseOverIcon;
	}
	
	if (options.mouseOverIcon) {
		GEvent.addListener(marker, 'mouseover', function() {
			marker.setImage(options.mouseOverIcon);
		});
		GEvent.addListener(marker, 'mouseout', function() {
			marker.setImage(image);
		});
	} else if (this.options && this.options.mouseOverIcon) {
		GEvent.addListener(marker, 'mouseover', function() {
			marker.setImage(me.options.mouseOverIcon);
		});
		GEvent.addListener(marker, 'mouseout', function() {
			marker.setImage(image);
		});
	}
	
	if (options.overlay) {
		GEvent.addListener(marker, 'mouseover', function() {
			options.overlay.draw(marker);
		});
		GEvent.addListener(marker, 'mouseout', function() {
			options.overlay.remove();
		});
	}
	if (options.overlay && options.draggable) {
		GEvent.addListener(marker, 'dragstart', function() {
			me.history.latlng  = marker.getLatLng();
			me.history.content = options.overlay.getContent();
			options.overlay.remove();
			marker.setImage(mouseOnImage);
		});
		GEvent.addListener(marker, 'dragend', function() {
			var geocoder = new GClientGeocoder();
			geocoder.getLocations(marker.getLatLng(), function(response) {
				if (response && response.Status.code == 200)
					options.overlay.setContent(options.dragend(response, marker));
			});
		});
	}
	if (options.click) {
		GEvent.addListener(marker, 'click', function() {
			options.click();
		});
	}
	if (options.infoWindow) {
		var _isOpen = false;
		GEvent.addListener(marker, 'click', function() {
			if (_isOpen) {
				options.infoWindow.close();
				_isOpen = false;
			} else {
				options.infoWindow.toggle();
				_isOpen = true;
			}
		});
	}
	
	if (!this.bounds.containsLatLng(marker.getLatLng())) {
		this.bounds.extend(marker.getLatLng());
	}
	
	this.markers[this.markers.length] = marker;
	return marker;
}
MarkerGrouper.prototype.add = function(marker) {
	if (!this.bounds.containsLatLng(marker.getLatLng())) {
		this.bounds.extend(marker.getLatLng());
	}
	
	this.markers.push(marker);
}
MarkerGrouper.prototype.show = function() {
	if (this.options && this.options.fitBounds && this.markers.length > 0) {
		this.map.setCenter(this.bounds.getCenter());
		
		var zoomLevel = this.map.getBoundsZoomLevel(this.bounds) - 1;
		if (zoomLevel > 15)
			zoomLevel = 15;
		
		this.map.setZoom(zoomLevel);
	}

	for (var i = 0; i < this.markers.length; i++) {
		this.map.addOverlay(this.markers[i]);
	}
}
MarkerGrouper.prototype.hide = function() {
	for (var i = 0; i < this.markers.length; i++) {
		this.map.removeOverlay(this.markers[i]);
	}
}
MarkerGrouper.prototype.clear = function() {
	for (var i = this.markers.length - 1; i >= 0; i--) {
		this.map.removeOverlay(this.markers[i]);
		this.markers[i] = undefined;
	}
	this.markers = Array();
}
MarkerGrouper.prototype.getMarkers = function() {
	return this.markers;
}
MarkerGrouper.prototype.getBounds = function() {
	return this.bounds;
}
MarkerGrouper.prototype.size = function() {
	return this.markers.length;
}

var CustomControls = function(map, cssClass) {
	this._map       = map;
	this.MAX_HEIGHT = this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.style.height;
	this.MAX_WIDTH  = this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.style.width;
	
	this._div       = document.createElement('div');
	if (cssClass) {
		this._div.className = cssClass;
	}
}
CustomControls.prototype.set = function(cssProperty, cssValue) {
	eval('this._div.style.' + cssProperty + ' = "' + cssValue + '";');
}
CustomControls.prototype.hide   = function() {
	this._div.style.visibility = 'hidden';
}
CustomControls.prototype.show   = function() {
	this._div.style.visibility = 'visible';
}
CustomControls.prototype.inject = function() {
	this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.appendChild(this._div);
}
CustomControls.prototype.createControl = function(elementType, elementContent, cssClass) {
	var element = document.createElement(elementType);
	
	if (elementType == 'img')
		element.src       = elementContent;
	else
		element.innerHTML = elementContent;
	
	if (cssClass)
		element.className = cssClass;
	
	return element;
}
CustomControls.prototype.addZoomInControl = function(element) {
	var me = this;
	GEvent.addDomListener(element, 'click', function() {
		me._map.setZoom(me._map.getZoom() + 1);
	});
	
	this._div.appendChild(element);
}
CustomControls.prototype.addZoomOutControl = function(element) {
	var me = this;
	GEvent.addDomListener(element, 'click', function() {
		me._map.setZoom(me._map.getZoom() - 1);
	});
	this._div.appendChild(element);
}
CustomControls.prototype.addControl        = function(element) {
	this._div.appendChild(element);
}
CustomControls.prototype.addMapTypeControl = function(mapType, element) {
	var me = this;
	GEvent.addDomListener(element, 'click', function() {
		me._map.setMapType(mapType);
		$$('.maptype').setStyle('background-image', 'url(/Site/images/design/icons/clickWhiteBackInactive.png)');
		element.setStyle('background-image', 'url(/Site/images/design/icons/clickWhiteBackActive.png)');
	});
	this._div.appendChild(element);
}

var Overlay = function(map, infoContent, cssClass) {
	this._map         = map;
	this._infoContent = infoContent;
	this._cssClass    = cssClass;
	this._xAdjusted   = 0;
	this._yAdjusted   = 0;
}
Overlay.prototype.adjust = function(position) {
	this._xAdjusted = position.x;
	this._yAdjusted = position.y;
	
	return this;
}
Overlay.prototype.setContent = function(infoContent) {
	this._infoContent = infoContent;
}
Overlay.prototype.getContent = function() {
	return this._infoContent;
}
Overlay.prototype.draw = function(marker) {
	var position       = this._map.fromLatLngToDivPixel(marker.getLatLng());
	var div            = document.createElement('div');
	div.className      = this._cssClass;
	div.style.position = 'absolute';
	div.style.left     = (position.x + this._xAdjusted) + 'px';
	div.style.top      = (position.y + this._yAdjusted) + 'px';
	
	var l = document.createElement('div');
	l.className = 'left';
	l.innerHTML = '<p>' + this._infoContent + '</p>';
	div.appendChild(l);
	
	//div.innerHTML      = '<span>' + this._infoContent + '</span>';
	
	this._div          = div;
	this._map.getPane(G_MAP_MARKER_PANE).appendChild(this._div);
}
Overlay.prototype.remove = function() {
	this._map.getPane(G_MAP_MARKER_PANE).removeChild(this._div);
	this._div = undefined;
}

var OverlayPosition = function(x, y) {
	this.x = x;
	this.y = y;
}

var latest;
var InfoWindow = function(map, childElement, options) {
	this._map          = map;
	this._childElement = childElement;
	this._options      = options;
	this._isOpen       = false;
}
InfoWindow.prototype.toggle = function() {
	if (latest) {
		latest.close();
		latest._isOpen = false;
	}
	
	if (this._isOpen) {
		this.close();
		this._isOpen = false;
	}
	
	if (!this._isOpen) {
		var div = document.createElement('div');
		
		if (this._options && this._options.cssClass)
			div.className = this._options.cssClass;
		if (this._options && this._options.styles) {
			for (prop in this._options.styles)
				div.style[prop] = this._options.styles[prop];
		}
		if (this._options && this._options.panTo)
			this._map.panTo(this._options.panTo);
		
		div.appendChild(this._childElement);
		var btn = document.createElement('div');
		btn.style.position = 'absolute';
		btn.style.top      = '-15px';
		btn.style.right    = '-15px';
		btn.innerHTML = '<img src="/images/info-close.png" style="cursor: pointer;" />';
		div.appendChild(btn);
		
		var me = this;
		GEvent.addDomListener(btn, 'click', function() {
			me.close();
			me._isOpen = false;
			
			if (latest) {
				latest.close();
				latest._isOpen = false;
			}
		});
		
		this._div    = div;
		latest       = this;
		this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.appendChild(this._div);
		this._isOpen = true;
	}
}
InfoWindow.prototype.close = function() {
	if (this._div) {
		try {
			this._map.getPane(G_MAP_MAP_PANE).parentNode.parentNode.removeChild(this._div);
			this._isOpen = false;
		} catch(err) {}
	}
}
