// $Id: map-engine-yandex.js,v 0.7 2011/02/16 16:16:45 rogozhin Exp $
/**
 * (c) Atr. Lebedev Studio
 * Author - Lev Rogozhin (lev@design.ru | lev@reijii.ru)
 */
var alfamap = {
	startParams:{
		lat:undefined, 
		lon:undefined,
		zoom:undefined,
		zoomControl:false,
		enableScrollZoom:true
	},
	zoomControl:{
		level:16,
		maxLevel:17,
		maxSliderHeight:320
	},
	zoomObject:undefined,
	container:undefined,
	map:undefined,
	icon:undefined,
	icons:{},
	groups:{},
	hintStyles:{},
	zoomController:function(params){
		var map,
			observe = [],
			bound,
			container,
			knob,
			_knobDrag = false,
			_knobTop = false,
			_knobY = false,
			maxLevel = 17,
			maxSliderHeight = 320,
			zoomOut,
			zoomIn,
			zoomLimit = {min:1, max:17};
		if (typeof params.maxLevel != 'undefined') {this.maxLevel = params.maxLevel}
		if (typeof params.zoomLimit != 'undefined') {
			this.zoomLimit = params.zoomLimit
			alfamap.map.setMinZoom(this.zoomLimit.min);
			alfamap.map.setMaxZoom(this.zoomLimit.max);
		}
		
		if (typeof params.maxSliderHeight != 'undefined') {this.maxSliderHeight = params.maxSliderHeight}
		this.onAddToMap = function (map, position) {
			this.map = map;
			this.container = YMaps.jQuery('<div class="mappoint"></div>'),
			this.position = position || new YMaps.ControlPosition(YMaps.ControlPosition.TOP_LEFT, new YMaps.Size(7, 7));
			this.container.css({
				position:'absolute',
				zIndex: YMaps.ZIndex.CONTROL,
				marginTop:"7px"
			});
			
			this._generateSlider();
			this.position.apply(this.container);
			
			this.knob[0].onmousedown = alfamap.zoomObject._startDrag;
			//this.knob.mousedown(this._startDrag, this);
			this.knob[0].onmouseup = alfamap.zoomObject._stopDrag;
			
			document.onmousemove = alfamap.zoomObject._moveKnob;
			document.onmouseup = alfamap.zoomObject._stopDrag;
			
			YMaps.Events.observe(this.map, this.map.Events.MouseMove, function(m){this._moveKnob()}, this);
			YMaps.Events.observe(this.map, this.map.Events.MouseUp, function(m){this._stopDrag()}, this);
								
			YMaps.Events.observe(this.map, this.map.Events.ZoomRangeChange, this.setKnob, this);
			YMaps.Events.observe(this.map, this.map.Events.Update, this.setKnob, this);
			
			this.container.appendTo(map.getContainer().parentNode);
		}
		this._generateSlider = function () {
			var ie = YMaps.jQuery.browser.msie;
			var sliderBg = YMaps.jQuery('<div></div>');
			this.zoomOut = YMaps.jQuery('<img alt="" src="/f/1/global/i-zoomout.gif"/>');
			this.zoomIn = YMaps.jQuery('<img alt="" src="/f/1/global/i-zoomin.gif"/>');
			this.knob = YMaps.jQuery('<img src=""/>');
			this.zoomOut.css({zIndex: YMaps.ZIndex.CONTROL, cursor: "pointer", height: "9px", left: ie?"-29px":"-13px", position: "relative", width: "9px"});
			this.zoomOut.bind("click", function(){alfamap.map.zoomBy(-1)});
			this.zoomIn.css({zIndex: YMaps.ZIndex.CONTROL, cursor: "pointer", height: "9px", left: ie?"-29px":"-13px", position: "relative", width: "9px", marginBottom: "2px", marginTop: "-5px"});
			this.zoomIn.bind("click", function(){alfamap.map.zoomBy(1)});
			sliderBg.css({zIndex: YMaps.ZIndex.CONTROL, backgroundColor: "#8d8e90", height: (this.maxSliderHeight+14)+"px", left: ie?"-30px":"-14px", marginBottom: "2px", position: "relative", width: "11px"});
			this.knob.css({zIndex: YMaps.ZIndex.CONTROL, marginLeft: ie?"-30px":"-14px", marginTop: "6px", position: "absolute", height:'15px', width:'11px',background:'url(/f/1/global/i-knob.gif)'});
			this.container.append(this.zoomIn);
			this.container.append(sliderBg);
			this.container.append(this.knob);
			this.container.append(this.zoomOut);
			this.setKnob();
		}
		this.setKnob = function () {
			if (alfamap.zoomObject._knobDrug) {return}
			var zoomLevel = this.map.getZoom();
			//console.log("zoom: "+ zoomLevel);
			//var z = this.maxLevel - zoomLevel;
			var z = this.maxLevel - zoomLevel;
			//var top = Math.round((this.maxSliderHeight/this.maxLevel*z));
			var mzl = typeof this.zoomLimit != 'undefined' && typeof this.zoomLimit.min != 'undefined' ? this.zoomLimit.min : 0;
			var top = Math.round((this.maxSliderHeight/(this.maxLevel - (mzl))*z));
			//var z = 
			this.knob.css("top", top+"px");
		}
		this._startDrag = function (ev) {
			ev = ev || window.event; 
			var mousePos = alfamap.zoomObject._mouseCoords(ev);
			alfamap.zoomObject._knobDrug = true;
			alfamap.map.disableDragging();
			alfamap.zoomObject._knobTop = alfamap.zoomObject.knob.css("top").replace('px', '');
			alfamap.zoomObject._knobY = mousePos;
			return false;
		}
		this._stopDrag = function (){
			alfamap.zoomObject._knobDrug = false;
			alfamap.map.enableDragging();
			alfamap.zoomObject.setKnob();
		}
		this._moveKnob = function (ev) {
			if (alfamap.zoomObject._knobDrug) {
				ev = ev || window.event; 
				var mousePos = alfamap.zoomObject._mouseCoords(ev),
					newPos = alfamap.zoomObject._knobTop - (alfamap.zoomObject._knobY - mousePos);
				if (newPos < 0) {newPos = 0}
				if (newPos > alfamap.zoomObject.maxSliderHeight) {newPos = alfamap.zoomObject.maxSliderHeight}
				alfamap.zoomObject.knob.css("top", newPos + "px");
				alfamap.zoomObject._aplayKnob();
			}
		}
		this._mouseCoords = function (ev) {
			return ev.pageY ? ev.pageY : ev.clientY + document.body.scrollTop  - document.body.clientTop;
		}
		this._aplayKnob = function (ev) {
			var top = alfamap.zoomObject.knob.css("top").replace('px', '');
			alfamap.map.setZoom(alfamap.zoomObject.maxLevel - Math.round(top/(alfamap.zoomObject.maxSliderHeight/(alfamap.zoomObject.maxLevel - alfamap.zoomObject.zoomLimit.min))));
		}
	},
	init:function(){
		if (arguments.length) {
			var args = arguments[0];
			if (typeof args.container != 'undefined') {
				this.container = args.container;
			} else {return 0}
			if (typeof args.init != 'undefined') {
				for (var i in args.init) {this.startParams[i] = args.init[i]}
			}
			if (typeof this.startParams.maxZoomHeight != 'undefined') {this.zoomControl.maxSliderHeight = this.startParams.maxZoomHeight}
		} else {return 0}
		
		this._init_icons();
		this.load();
		return 1;
	},
	_init_icons:function(){
		var hintStyle = new YMaps.HintContentStyle(new YMaps.Template("<div>$[hintContent]</div>"));
		this.icon = new YMaps.Style();
		this.icon.iconStyle = new YMaps.IconStyle(new YMaps.LayoutTemplate(trafficLayout({src:'/i/maps/alfa_marker.png'})));
		
		this.icon.iconStyle.shadow = new YMaps.IconShadowStyle();
		this.icon.iconStyle.shadow.href = "/i/maps/alfa_shadow.png";
		this.icon.iconStyle.shadow.size = new YMaps.Point(37, 34);
		this.icon.iconStyle.shadow.offset = new YMaps.Point(-9, -33);

		this.icon.hintContentStyle = hintStyle;
		
		this.icons.normal = this.icon;

		this.icons.gray = new YMaps.Style(this.icons.normal);
		this.icons.gray.iconStyle = new YMaps.IconStyle(new YMaps.LayoutTemplate(trafficLayout({src:'/i/maps/alfa_marker_gray.png'})));

		this.icons.black = new YMaps.Style(this.icons.normal);
		this.icons.black.iconStyle = new YMaps.IconStyle(new YMaps.LayoutTemplate(trafficLayout({src:'/i/maps/alfa_marker_black.png'})));
		
		this.icons.dark = new YMaps.Style(this.icons.normal);
		this.icons.dark.iconStyle = new YMaps.IconStyle(new YMaps.LayoutTemplate(trafficLayout({src:'/i/maps/alfa_marker_dark.png'})));

		this.icons.h24 = new YMaps.Style(this.icons.normal);
		this.icons.h24.iconStyle = new YMaps.IconStyle(new YMaps.LayoutTemplate(trafficLayout({src:'/i/maps/alfa_marker_24.png'})));

		this.icons.white = new YMaps.Style(this.icons.normal);
		this.icons.white.iconStyle = new YMaps.IconStyle(new YMaps.LayoutTemplate(trafficLayout({src:'/i/maps/alfa_marker_white.png'})));

		this.icons.externalAtm = new YMaps.Style(this.icons.normal);
		this.icons.externalAtm.iconStyle = new YMaps.IconStyle(new YMaps.LayoutTemplate(trafficLayout({src:'/i/maps/alfa_marker_external_atm.png'})));

		this.icons.city = new YMaps.Style();
		this.icons.city.iconStyle = new YMaps.IconStyle();
		this.icons.city.iconStyle.href = "/i/maps/alfa-marker-city.png";
		this.icons.city.iconStyle.size = new YMaps.Point(20, 20);
		this.icons.city.iconStyle.offset = new YMaps.Point(-10, -10);

		this.icons.traffic = new YMaps.Style();
		this.icons.traffic.iconStyle = new YMaps.IconStyle(new YMaps.LayoutTemplate(trafficLayout({src:'/i/maps/alfa_marker_24.png'})));
		this.icons.traffic.iconStyle.href = "/i/maps/alfa_marker.png";
		this.icons.traffic.iconStyle.size = new YMaps.Point(20, 34);
		this.icons.traffic.iconStyle.offset = new YMaps.Point(-9, -33);
		
		this.icons.traffic.iconStyle.shadow = new YMaps.IconShadowStyle();
		this.icons.traffic.iconStyle.shadow.href = "/i/maps/alfa_shadow.png";
		this.icons.traffic.iconStyle.shadow.size = new YMaps.Point(37, 34);
		this.icons.traffic.iconStyle.shadow.offset = new YMaps.Point(-9, -33);
	},
	_init_hint_styles:function(){
	},
	load:function(){
		this.map = new YMaps.Map(this.container);
		if (!arguments.length || typeof arguments[0].noCenter == 'undefined') {
			this.setCenter({lon:this.startParams.lon, lat:this.startParams.lat, zoom:this.startParams.zoom});
		}
		if (this.startParams.zoomComtrol) {
			this.zoomObject = new this.zoomController(this.zoomControl);
			this.map.addControl(this.zoomObject, this.startParams.zoomPosition);
		}
		if (this.startParams.enableScrollZoom) {
			this.map.enableScrollZoom();
		}
		if (typeof this.startParams.onZoom == 'function') {
			YMaps.Events.observe(this.map, this.map.Events.ZoomRangeChange, this.startParams.onZoom);
		}
		if (typeof this.startParams.onUpdate == 'function') {
			YMaps.Events.observe(this.map, this.map.Events.Update, this.startParams.onUpdate);
		}
		if (typeof this.startParams.onBoundsChange == 'function') {
			YMaps.Events.observe(this.map, this.map.Events.BoundsChange, this.startParams.onBoundsChange);
		}
	},
	setCenter:function(){
		if (arguments.length) {
			var p = arguments[0];
			this.map.setCenter(new YMaps.GeoPoint(p.lon, p.lat), p.zoom);
			return 1;
		} else {return 0}
	},
	getBounds:function(){
		return this.map.getBounds();
	},
	addOverlay:function(){
		
		if (arguments.length) {
			var p = arguments[0],
				draggable = typeof p.draggable != 'undefined' && p.draggable ? true : false, 
				curPoint = new YMaps.GeoPoint(p.lon, p.lat),
				_icon = typeof p.icon != 'undefined' ? p.icon : 'normal',
				icon = this.icons.normal;
			switch (_icon) {
				case 'black':
					icon = this.icons.black;
					break;
				case 'gray':
					icon = this.icons.gray;
					break;
				case 'dark':
					icon = this.icons.dark;
					break;
				case 'city':
					icon = this.icons.city;
					break;
				case 'traffic':
					icon = this.icons.traffic;
					break;
				default:
					if (typeof this.icons[_icon] != 'undefined') {
						icon = this.icons[_icon];
					} else {
						icon = this.icons.normal;
					}
			}
			var options = {draggable: draggable, style: icon}
			if (typeof p.hasHint != 'undefined') options.hasHint = p.hasHint;
			if (typeof p.hintOptions != 'undefined') options.hintOptions = p.hintOptions;

			var	placemark = new YMaps.Placemark(curPoint, options);
			
			if (typeof p.name != 'undefined') {
				placemark.name = p.name;
			}
			if (typeof p.description != 'undefined') {
				placemark.description = p.description;
			}
			
			if (typeof p.onClick == 'function') {//console.log("!");
				YMaps.Events.observe(placemark, placemark.Events.Click, p.onClick);
			}
			
			if (draggable) {
				placemark.draggable = true;
				if (typeof p.dragStart == 'function') {
					YMaps.Events.observe(placemark, placemark.Events.DragStart, p.dragStart);
					//YMaps.Events.observe(placemark, placemark.Events.DragStart, function(){console.log("drag start")});
				}
				if (typeof p.drag == 'function') {
					YMaps.Events.observe(placemark, placemark.Events.Drag, p.drag);
				}
				if (typeof p.dragEnd == 'function') {
					YMaps.Events.observe(placemark, placemark.Events.DragEnd, p.dragEnd);
				}
			}
			if (typeof p.hintContent != 'undefined') {
				placemark.hintContent = p.hintContent;
			}
				
			if (typeof p.meta != 'undefined') {
				placemark.metaDataProperty = p.meta;
			}
			//if (typeof this.groups[_icon] == 'undefined') this.groups[_icon] = new YMaps.GeoObjectCollection();
			//this.groups[_icon].add(placemark);
			if (!(typeof p.onlyPlacemark != 'undefined' && p.onlyPlacemark)) this.map.addOverlay(placemark);
			///var _end = new Date();
			///_dbg_time += (_end.getMinutes()*60*1000  + _end.getSeconds()*1000 + _end.getMilliseconds() - (_start.getMinutes()*60*1000  + _start.getSeconds()*1000 + _start.getMilliseconds()));
			///_dbg_count++;
			return placemark;
		} else {return false}
	},
	hideOverlays:function(){
		alfamap.map.removeAllOverlays();
	},
	removeOverlay:function(placemark){
		alfamap.map.removeOverlay(placemark);
		//this.map.removeOverlay(placemark);
	},
	removeAllOverlays:function(){
		alfamap.map.removeAllOverlays();
	},
	showOverlay:function(placemark, bound){
		if (typeof bound == 'object') {
			if (bound.contains(placemark.getGeoPoint())) {
				alfamap.map.addOverlay(placemark);
			} else {
				alfamap._delayedOverlays[alfamap._delayedOverlays.length] = placemark;
			}
		} else {
			alfamap.map.addOverlay(placemark);
		}
	},
	_delayedOverlays:[],
	showOverlayDelayed:function(){
		if (!alfamap._delayedOverlays.length) {
			return;
		}
		alfamap.showOverlay(alfamap._delayedOverlays.shift());
		if (alfamap._delayedOverlays.length) {
			setTimeout(arguments.callee, 3);
		}
	},
	stopDelayedShow:function(){
		alfamap._delayedOverlays = [];
	},
	createObjectCollection:function(){
		return new YMaps.GeoObjectCollection();
	},
	appendObjectCollection:function(collection, item){
		collection.add(item);
	}
}


function trafficLayout (img) {
	var foo = function (context, map, owner) {
		img = img || {};
		img.src = img.src || '/i/maps/alfa_marker.png';
		img.size = img.size || new YMaps.Point(20, 34);
		img.offset = img.offset || new YMaps.Point(-5, -29);

		var meta = context.metaDataProperty,
			show_traffic = typeof meta.traffic != 'undefined' && meta.traffic.size != -1 ? 'block' : 'none',
			traffic_size = show_traffic == 'block' && typeof meta.traffic.size != 'undefined' && meta.traffic.size != -1 ? meta.traffic.size : 0;
		//this.element = YMaps.jQuery(alfamap.Templates.marker.sprintf(img.offset.x, img.offset.y, img.src, img.size.x, img.size.y, (img.size.x + 4), 0, show_traffic, trafficSize(traffic_size)));
		this.element = YMaps.jQuery(alfamap.Templates.marker.sprintf(img.offset.x, img.offset.y, img.src, img.size.x, img.size.y, show_traffic, (img.size.x-2), 4, trafficSize(traffic_size)));
		
	}
	foo.prototype = TrafficLayout.prototype;
	
	return foo;
}
function trafficSize_ (size) {
	switch (size) {
		case 1: 
			return '25%';
		case 2: 
			return '66%';
		case 3:
			return '100%';
	}
	return '';
}
function trafficSize (size) {
	switch (size) {
		case 1: 
			return '0px';
		case 2: 
			return '-12px';
		case 3:
			return '-24px';
	}
	return '';
}

function TrafficLayout () {}
TrafficLayout.prototype.onAddToParent = function (parentNode) {this.element.appendTo(parentNode);};
TrafficLayout.prototype.onRemoveFromParent = function () { this.element.remove() }
TrafficLayout.prototype.update = function () {}
TrafficLayout.prototype.getOffset = function () { return new YMaps.Point(-5, -5) }
TrafficLayout.prototype.getRootNodes = function () { return this.element }


if (String.prototype.sprintf == undefined) {
	String.prototype.sprintf = function () {
		if (arguments.length) {
			var _arguments = arguments,
				_i = -1;
			return this.replace(/%s/g, function(){
				_i++;
				return _arguments[_i] == undefined ? '' : _arguments[_i] ;
			});
		} else {
			return this.replace(/%s/g, '');
		}
	}
}

alfamap.Templates = {
	_marker: '<div style="position:relative;left:%spx;top:%spx">'
			+'<img src="%s" style="width: %spx; height: %spx; "/>'
			+'<div style="left:%spx;top:%spx;position:absolute;display:%s;background:url(/i/maps/traffic-marker-back.png) no-repeat 0 0;width:8px;height:22px;">'
				+'<div style="font-size:1px;position:absolute;bottom:0;height:%s;background:url(/i/maps/traffic-marker.png) no-repeat  0% 100%;width:8px;"></div>'
			+'</div>'
		+'</div>',
	marker: '<div style="position:relative;left:%spx;top:%spx">'
			+'<img src="%s" style="width: %spx; height: %spx; "/>'
//			+'<div class="alfa-traffic-flag-icon-%s hidden" style="left:%spx;top:%spx;position:absolute;display:%s;background:url(/i/maps/traffic-marker-2.png) no-repeat 100% %s;width:14px;height:12px;"></div>'
			+'<div class="alfa-traffic-flag-icon-%s alfa-traffic-flag-icon-hidden" style="font-size:1px;left:%spx;top:%spx;position:absolute;background:url(/i/maps/traffic-marker-2.png) no-repeat 100% %s;width:14px;height:12px;"></div>'
		+'</div>'
	
};
