var map;

var imagesConfig = {
	'staticSizeX' : 22,
	'staticSizeY' : 25,
	'dynamicSize' : 26
};

var bulavkaMap = [2, 2, 6, 1, 11, 2, 12, 7, 11, 12, 6, 13, 2, 12, 1, 7];

var staticImages = {
	'1' :  {
		'icon' : PATH_WEB_IMG + 'map/icon_small_dark.png',
		'imageMap' :  bulavkaMap
		},
	'2' :  {
		'icon' : PATH_WEB_IMG + 'map/icon_small_light.png',
		'imageMap' :  bulavkaMap
		},
	'3' :  {
		'icon' : PATH_WEB_IMG + 'map/icon_norm_dark.png',
		'imageMap' :  bulavkaMap
		},
	'4' :  {
		'icon' : PATH_WEB_IMG + 'map/icon_norm_light.png',
		'imageMap' :  bulavkaMap
		},
	'5' :  {
		'icon' : PATH_WEB_IMG + 'map/icon_big_dark.png',
		'imageMap' :  bulavkaMap
		},
	'6' :  {
		'icon' : PATH_WEB_IMG + 'map/icon_big_light.png',
		'imageMap' :  bulavkaMap
		}
};

var default_x = 55.752622;
var default_y = 37.623024;
var span_x = 0.175;
var span_y = 0.27;

var moscowBounds = {
	'maxx' : default_x + span_x,
	'maxy' : default_y + span_y,
	'minx' : default_x - span_x,
	'miny' : default_y - span_y
};

function nullBounds() {
	this.maxx = -1000;
	this.maxy = -1000;
	this.minx = 1000;
	this.miny = 1000;
};


function resizeBounds (baseBounds, maxBounds)
{
	if (baseBounds['minx'] < maxBounds['minx']) baseBounds['minx'] = maxBounds['minx'];
	if (baseBounds['miny'] < maxBounds['miny']) baseBounds['miny'] = maxBounds['miny'];
	if (baseBounds['maxx'] > maxBounds['maxx']) baseBounds['maxx'] = maxBounds['maxx'];
	if (baseBounds['maxy'] > maxBounds['maxy']) baseBounds['maxy'] = maxBounds['maxy'];

	if (baseBounds['maxx'] < maxBounds['minx']) baseBounds['maxx'] = maxBounds['minx'];
	if (baseBounds['maxy'] < maxBounds['miny']) baseBounds['maxy'] = maxBounds['miny'];
	if (baseBounds['minx'] > maxBounds['maxx']) baseBounds['minx'] = maxBounds['maxx'];
	if (baseBounds['miny'] > maxBounds['maxy']) baseBounds['miny'] = maxBounds['maxy'];

	if (
		(baseBounds['minx'] > baseBounds['maxx'])
		|| (baseBounds['miny'] > baseBounds['maxy'])
	) {
		baseBounds['maxx'] = moscowBounds['maxx'];
		baseBounds['maxy'] = moscowBounds['maxy'];
		baseBounds['minx'] = moscowBounds['minx'];
		baseBounds['miny'] = moscowBounds['miny'];
	}

	return baseBounds;
}

function enlargeBounds (baseBounds, x, y)
{
	if (
		( x < moscowBounds['minx'])
		|| ( y < moscowBounds['miny'])
		|| ( x > moscowBounds['maxx'])
		|| ( y > moscowBounds['maxy'])
	)
		return baseBounds;


	if ( x < baseBounds['minx']) baseBounds['minx'] = x;
	if ( y < baseBounds['miny']) baseBounds['miny'] = y;
	if ( x > baseBounds['maxx']) baseBounds['maxx'] = x;
	if ( y > baseBounds['maxy']) baseBounds['maxy'] = y;

	return baseBounds;
}

function getGMapBounds (mapBounds)
{
	difx = (mapBounds['maxx'] - mapBounds['minx'] + 0.1)/10.;
	dify = (mapBounds['maxy'] - mapBounds['miny'] + 0.1)/10.;
	var bounds =
		new GLatLngBounds(
			new GLatLng(
				mapBounds['minx'] - difx,
				mapBounds['miny'] - dify
			),
			new GLatLng(
				mapBounds['maxx'] + difx,
				mapBounds['maxy'] + dify
			)
		);

	return bounds;
}

function $A(iterable)
{
	if (!iterable)
		return [];

	if (iterable.toArray)
		return iterable.toArray();

	var length = iterable.length, results = new Array(length);

	while (length--)
		results[length] = iterable[length];

	return results;
}

Function.prototype.bindAsEventListener = function()
{
	var __method = this, args = $A(arguments), object = args.shift();
	return function(event) {return __method.apply(object, [(event || window.event)].concat(args).concat($A(arguments)));}
};

function addSmallestMapControl(map) {

	function SmallestMapControl() {
	}

	// To "subclass" the GControl, we set the prototype object to
	// an instance of the GControl object
	SmallestMapControl.prototype = new GControl();


	SmallestMapControl.prototype.initialize = function(map) {
		var container = document.createElement("div");

		var zoomInDiv = document.createElement("div");
		this.setButtonStyle_(zoomInDiv);
		container.appendChild(zoomInDiv);
		zoomInDiv.innerHTML = "<img src=\"" + PATH_WEB_IMG+ "/map/plus.png\" />";
		GEvent.addDomListener(zoomInDiv, "click", function() {
			map.zoomIn();
		});

		var zoomOutDiv = document.createElement("div");
		this.setButtonStyle_(zoomOutDiv);
		container.appendChild(zoomOutDiv);
		zoomOutDiv.innerHTML = "<img src=\"" + PATH_WEB_IMG+ "/map/minus.png\" />";
		GEvent.addDomListener(zoomOutDiv, "click", function() {
			map.zoomOut();
		});

		map.getContainer().appendChild(container);
		return container;
	}

	// By default, the control will appear in the top left corner of the
	// map with 7 pixels of padding.
	SmallestMapControl.prototype.getDefaultPosition = function() {
		return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7, 7));
	}

	// Sets the proper CSS for the given button element.
	SmallestMapControl.prototype.setButtonStyle_ = function(button) {
		button.style.border = "none";
		button.style.padding = "2px";
		button.style.marginBottom = "3px";
		button.style.textAlign = "center";
		button.style.width = "20px";
		button.style.height = "20px";
		button.style.cursor = "pointer";
	}

	map.addControl(new SmallestMapControl());
}

function getRandomLocation (markerOptions, url) {
	span = 0.06;
	var marker =  new GMarker(new GLatLng(55.752622 - span/2 + Math.random() * span, 37.623024 - span/2 + Math.random() * span), markerOptions);
	GEvent.addListener(
			marker,
			"click",
			function() {
				document.location.href = url;
			}
	);
	return marker;
};

function SkidkiMainMap(categories, mode) {
	this.markers = {
		"1" : [],
		"2" : [],
		"3" : [],
		"4" : [],
		"5" : [],
		"6" : []
	};
	if (!mode)
		mode = 'sales';

	this.showCategory = function ( category ) {
		this.map.closeExtInfoWindow();
		if (category == 'all') {
			for (currentCategory in this.categories) {
				for (currentLocation in this.categories[currentCategory]['locations']) {
					this.categories[currentCategory]['locations'][currentLocation].show();
				}
			}
		} else {
			for (currentCategory in this.categories) {
				if (currentCategory == category) {
					for (currentLocation in this.categories[currentCategory]['locations']) {
						this.categories[currentCategory]['locations'][currentLocation].show();
					}
				} else {
					for (currentLocation in this.categories[currentCategory]['locations']) {
						this.categories[currentCategory]['locations'][currentLocation].hide();
					}
				}
			}
		}
		this.getScale(category);
	};

	this.setZoom = function (object, category) {
		this.map.setZoom(this.zoom);
	};

	this.getScale = function ( category ) {
		var mapBounds = new nullBounds();

		if (this.categories[category] && this.categories[category]['locations']) {
			for (currentLocation in this.categories[category]['locations']) {
				point = this.categories[category]['locations'][currentLocation].getLatLng();
				mapBounds = enlargeBounds(mapBounds, point.lat(), point.lng());
			}
		} else {
			for (currentCategory in this.categories) {
				for (currentLocation in this.categories[currentCategory]['locations']) {
					point = this.categories[currentCategory]['locations'][currentLocation].getLatLng();
					mapBounds = enlargeBounds(mapBounds, point.lat(), point.lng());
				}
			}
		}

		mapBounds = resizeBounds(mapBounds, moscowBounds);
		var center = new GLatLng((mapBounds['minx']+ mapBounds['maxx'])/2., (mapBounds['miny']+ mapBounds['maxy'])/2.);
		this.zoom = this.map.getBoundsZoomLevel(getGMapBounds(mapBounds));

		this.map.panTo(center);

		window.setTimeout( this.setZoom.bindAsEventListener(this, category) , 500);
	};

	this.showAllPoints = function ( category ) {
		var mapBounds = new nullBounds();

		for (currentCategory in this.categories) {
			for (currentLocation in this.categories[currentCategory]['locations']) {
				point = this.categories[currentCategory]['locations'][currentLocation].getLatLng();
				mapBounds = enlargeBounds(mapBounds, point.lat(), point.lng(), moscowBounds);
			}
		}

		mapBounds = resizeBounds(mapBounds, moscowBounds);
		var center = new GLatLng((mapBounds['minx']+ mapBounds['maxx'])/2., (mapBounds['miny']+ mapBounds['maxy'])/2.);

		this.zoom = this.map.getBoundsZoomLevel(getGMapBounds(mapBounds));
		this.map.setCenter(center, this.zoom);
	};

	this.showAllStores = function ( category ) {
		var mapBounds = new nullBounds();

		for (currentLocation in this.categories) {
			point = this.categories[currentLocation]['location'].getLatLng();
			mapBounds = enlargeBounds(mapBounds, point.lat(), point.lng());
		}

		mapBounds = resizeBounds(mapBounds, moscowBounds);
		var center = new GLatLng((mapBounds['minx']+ mapBounds['maxx'])/2., (mapBounds['miny']+ mapBounds['maxy'])/2.);

		this.zoom = this.map.getBoundsZoomLevel(getGMapBounds(mapBounds));
		this.map.setCenter(center, this.zoom);
	};

	this.goToStore = function ( store ) {
		var point = null;

		for (currentCategory in this.categories) {
			for (currentLocation in this.categories[currentCategory]['locations']) {
				if (currentLocation = store) {
					point = this.categories[currentCategory]['locations'][currentLocation].getLatLng();
				}
			}
		}

		if (point)
			this.map.setCenter(point, 13);
	};

	this.posStoreMarker = function ( object, cat ) {
		this.categories[cat]['location'].openExtInfoWindow(this.map, "red_window", "<div>Загрузка...</div>", {ajaxUrl: this.categories[cat]['url'],  beakOffset: 3});
	};

	this.posSaleMarker = function ( object, cat, location) {
		this.categories[cat]['locations'][location].openExtInfoWindow(
			this.map,
			"red_window",
			"<div>Загрузка...</div>",
			{ajaxUrl: this.categories[cat]['urls'][location],  beakOffset: 3}
		);
	};

	this.initSales = function () {
		for (currentCategory in this.categories) {
			var letteredIcon;

			if (this.categories[currentCategory]['url']) {
				letteredIcon = new GIcon(baseIcon);
			} else {
				letteredIcon = new GIcon(baseNoShadowIcon);
			}

			letteredIcon.image = this.categories[currentCategory]['icon'];

			var markerOptions = { icon:letteredIcon };
			this.categories[currentCategory]['urls'] = new Array();					
			for (currentLocation in this.categories[currentCategory]['locations']) {
				var x = this.categories[currentCategory]['locations'][currentLocation]['x'];
				var y = this.categories[currentCategory]['locations'][currentLocation]['y'];

				this.categories[currentCategory]['urls'][currentLocation] = this.categories[currentCategory]['locations'][currentLocation]['url'];
				this.categories[currentCategory]['locations'][currentLocation] = new GMarker(new GLatLng(x, y), markerOptions);


				GEvent.addListener(
					this.categories[currentCategory]['locations'][currentLocation],
					"click",
					this.posSaleMarker.bindAsEventListener(
						this,
						currentCategory,
						currentLocation
					)
				);

				this.map.addOverlay(this.categories[currentCategory]['locations'][currentLocation]);
			}
		}

		this.showAllPoints();
	};

	this.showStoresMarkers = function (object, num) {
		if (num > 0) {
			try {
				for (i = 0; i < 20; i++ )
					this.map.addOverlay(this.markers[num].pop());
				window.setTimeout( this.showStoresMarkers.bindAsEventListener(this, num) , 0);
			} catch (e) {
				window.setTimeout( this.showStoresMarkers.bindAsEventListener(this, num - 1) , 0);
			}
		}
	};

	this.initStores = function () {
		this.mgr = new MarkerManager(this.map);
		for (currentCategory in this.categories) {
			var letteredIcon = new GIcon(baseNoShadowIcon);
			var imageInfo;
			if (!(imageInfo = staticImages[this.categories[currentCategory]['icon']]))
				throw new Exception("no proper image found for " + this.categories[currentCategory]['icon']);

			letteredIcon.image = imageInfo['icon'];
			letteredIcon.imageMap = imageInfo['imageMap'];

			var markerOptions = { icon:letteredIcon };

			var x = this.categories[currentCategory]['location']['x'];
			var y = this.categories[currentCategory]['location']['y'];

			this.categories[currentCategory]['location'] = new GMarker(new GLatLng(x, y), markerOptions);

			GEvent.addListener(
				this.categories[currentCategory]['location'],
				"click",
				this.posStoreMarker.bindAsEventListener(
					this,
					currentCategory
				)
			);

			this.markers[this.categories[currentCategory]['icon']].push(this.categories[currentCategory]['location']);
		}
		this.showAllStores();

		GEvent.addListener(
				this.map,
				"load",
				this.showStoresMarkers(this, 6)
			);
	};

	var baseIcon = new GIcon();
	baseIcon.shadow = PATH_WEB_IMG+ "/map/shadow.png";
	baseIcon.iconSize = new GSize(imagesConfig['dynamicSize'], imagesConfig['dynamicSize']);
	baseIcon.shadowSize = new GSize(imagesConfig['dynamicSize']+10, imagesConfig['dynamicSize']+1);
	baseIcon.iconAnchor = new GPoint(imagesConfig['dynamicSize'] / 2 , imagesConfig['dynamicSize'] / 2 );
	baseIcon.infoWindowAnchor = new GPoint(imagesConfig['dynamicSize'] / 2 - 4 , 6);

	var baseNoShadowIcon = new GIcon(G_DEFAULT_ICON);
	baseNoShadowIcon.iconSize = new GSize(imagesConfig['staticSizeX'], imagesConfig['staticSizeY']);
	baseNoShadowIcon.shadow = "";
	baseNoShadowIcon.iconAnchor = new GPoint(5, imagesConfig['staticSizeY']);
	baseNoShadowIcon.infoWindowAnchor = new GPoint(2, imagesConfig['staticSizeY'] + 8);

	this.categories = categories;
	this.stores = new Array();
	this.map = new GMap2(document.getElementById("map_canvas"));

	this.map.setCenter(new GLatLng(default_x, default_y), 13);
	addSmallestMapControl(this.map);
	this.map.enableScrollWheelZoom();

	if (mode == 'stores')
		this.initStores();
	else if (mode == 'sales')
		this.initSales();

}

$(window).unload( function () { GUnload(); } );






















