/*===============================================================================================
	
	Mayomo
	map.lib.js		map definition and behaviour

	Modifications: 
	20090831		XXX		Initial implementation
																		
===============================================================================================*/

window.Map = {};
(function() {
	
	var o = OpenLayersMap = {
		
		/**
		 * map instance
		 *
		 * @access private
		 * @type OpenLayers.Map
		 * @default null
		 */
		_map : null, 
		
		/**
		 * _server
		 * 
		 * @private
		 * @type {String}
		 * @default {String} "http://www.mayomo.com:81/tilecache/tilecache.py?"
		 */
		_server : "http://mayomobg.homeip.net/tilecache/tilcache.py/1.0.0", // "http://www.mayomo.com:81/tilecache/tilecache.py?",
		
		/**
		 * _markers
		 * 
		 * @access private
		 * @type OpenLayers.Layer.Markers
		 * @default OpenLayers.Layer.Markers( "Markers" )
		 */
		_markers : new OpenLayers.Layer.Markers( "Markers" ),
		
		_labels : new OpenLayers.Layer.Markers("Labels"),
		
		/**
		 * _topLeftCorner
		 * 
		 * @access private
		 * @type {Array}
		 * @default {Array} Array()
		 */
		_topLeftCorner : new Array(),
		
		/**
		 * _bottomRightCorner
		 * 
		 * @access private
		 * @type {Array}
		 * @default {Array} Array()
		 */
		_bottomRightCorner : new Array(),
		
		/**
		 * _size
		 * 
		 * @access private
		 * @type OpenLayers.Size
		 * @default OpenLayers.Size(10, 10)
		 */
		_size : new OpenLayers.Size(20, 20),
		
		/**
		 * _offset
		 * 
		 * @access private
		 * @param OpenLayers.Pixel
		 * @default OpenLayers.Pizel(-(10/2), -(10/2))
		 */
		_offset : new OpenLayers.Pixel(-(10/2), -(9/2)),
		
		/**
		 * _vectorLayer
		 * 
		 * @private
		 * @type OpenLayers.Layer.Vector
		 * @default OpenLayers.Layer.Vector("Simple Geometry")
		 */
		_vectorLayer : null,
		
		/**
		 * _zoomLevel
		 * 
		 * @private
		 * @type {Integer}
		 * @default {Integer} 0
		 */
		_zoomLevel : 0,
		
		/**
		 * _pageOffset
		 * 
		 * @access private
		 * @type int
		 * @default 0
		 */
		_pageOffset : 0,
		
		/**
		 * _timeoutid
		 * 
		 * @access private
		 * @type {js timer timeout}
		 * @default {null}
		 */
		_timeoutid : null,
		
		/**
		 * _lon
		 * 
		 * @private
		 * @type {Int} 
		 * @default {Int} 0
		 */
		_lon : 0,
		
		/**
		 * _lat
		 * 
		 * @private
		 * @type {Int}
		 * @default {Int} 3
		 */
		_lat : 10,
		
		/**
		 * _zoom
		 * 
		 * @private
		 * @type {Int}
		 * @default {Int} 2
		 */
		_zoom : 2,
		
		/**
		 * _usingCache
		 * 
		 * @private
		 * @type {Boolean}
		 * @default {Boolean} false
		 */
		_usingCache : false,
		
		/**
		 * flags whether to save the coordinates of the center and the
		 * zoom level in a cookie. improving the back button compatibility.
		 * It is disabled by default.
		 * 
		 * @private
		 * @type {Boolean}
		 * @default false
		 */
		_saveLonLatZoom : false,
		//
		vectors : null,
		mask : null,
		//
		_clickToSaveCoordinates : false,
		//
		_uploadMarker : new OpenLayers.Layer.Markers( "Markers" ),
		//
		_vectorLayer : null,
		//
		_useCloudMade : 1,
		//
		_onlyCloudMade : false,
		//
		_newsOnDemand : false,
		//
		_transformation : [
			{ 'from' : new OpenLayers.Projection("EPSG:4326"), 'to' : new OpenLayers.Projection("EPSG:4326")},	
			{ 'from' : new OpenLayers.Projection("EPSG:4326"), 'to' : new OpenLayers.Projection("EPSG:900913")}
		],
		//
		_cloudmade : null,
		
		/**
		 * @private
		 * @var _thumbsCount
		 * @type {Int}
		 * @default 0
		 */
		_thumbsCount : 0,
		
		/**
		 * @private
		 * @var _ajaxRequest
		 * @type {xhr} request
		 * @default null
		 */
		_ajaxRequest : null,
		
		/**
		 * Disable popups flag
		 * 
		 * @var Boolean
		 */
		_popupsDisabled : false,
		
		/**
		 * init
		 * 
		 * initialize the map, loads the tiles, possitions them,
		 * register a moveend event listener and calles the load
		 * function which loads the thumbs and places them on the 
		 * right place
		 * 
		 * @access {public}
		 * @param {Void}
		 * @return void
		 */
		init : function( onlyCloudMade, oQueryString ) {
			
			// if there's no #map div don't load the map
			// this is because of the slow connection 
			// version of the site.
			if ($('#map').length == 0) 
				return;
				
			// listen when to reload the map
			$(document).bind('reload-map', function() {
				o.load(true, BaseController.getQueryString());
			});
			
			// use only from cloudmade or use entire world from geo Json
			if ( typeof onlyCloudMade != 'undefined' )
		    	o._onlyCloudMade = onlyCloudMade;

			// init the map, bind to #map div
		    o._map = new OpenLayers.Map('map');
			
		    o._cloudmade = new OpenLayers.Layer.CloudMade("CloudMade", {
			    key : 'c75669f443cd5ddf803d02b33fcb3a8b',
			    styleId : 7511
			});
            
			OpenLayers.Feature.Vector.style['default']['fillOpacity'] = 1;    
            o.vectors = new OpenLayers.Layer.GML("World Countries", 
            	'/map/virtu.geo.json.html', 
            	{
		            format: OpenLayers.Format.GeoJSON, 
		            styleMap: o._buildStyle(), 
		            projection: new OpenLayers.Projection("EPSG:4326")
		        }
			);
			var mask = new OpenLayers.Layer.GML("Mask", 
            	'/map/mask.geo.json.html', 
            	{
		            format: OpenLayers.Format.GeoJSON, 
		            styleMap: o._buildMaskStyle(), 
		            projection: new OpenLayers.Projection("EPSG:4326")
		        }
			);

			// TODO: uncomment to show virtu continent
			// o._map.addLayers([o._cloudmade, mask, o.vectors]);
			o._map.addLayers([o._cloudmade, mask]);

			var label = new OpenLayers.Marker.Label(new OpenLayers.LonLat(-40,45).transform(
				o._transformation[o._useCloudMade].from, 
				o._transformation[o._useCloudMade].to), null, 'Virtu');
            // TODO: uncomment to show VIRTU label
			// o._labels.addMarker(label);
			
			var virtu_path= 'path';
			if (navigator.appName == 'Microsoft Internet Explorer') {
				virtu_path = 'group';
			}
							
            var options = {
				hover: true,
				onSelect: function(feature) {
					// finally 
					$( virtu_path ).mousemove(function(e) {  
						$('#map').append('<div id="tooltip"></div>'); 
						$('#tooltip').addClass('country-tooltip').css({ 
							top : e.pageY + 10,
							left : e.pageX + 10,
							width : 'auto'						
						}).html('<div class="left sprite">&nbsp;</div><span class="sprite">' + feature.attributes.name + '</span>').show();
					});
				},
				onUnselect : function(feature) { 
               		$( virtu_path ).mouseout(function(e) {
						$('#tooltip').remove();		
               		});
				},
				callbacks : { 
					'click' : function(e) {
	               		o._map.setCenter(new OpenLayers.LonLat( 
		               			this.handlers.feature.feature.attributes.lon, 
		               			this.handlers.feature.feature.attributes.lat).transform(
									o._transformation[o._useCloudMade].from, 
									o._transformation[o._useCloudMade].to), 
	               			this.handlers.feature.feature.attributes.zoomLevel);
	               		//
	               		$('input[id="country"]').val(this.handlers.feature.feature.attributes.name);
	               		if (!o._clickToSaveCoordinates)
	               			o.load(true, BaseController.getQueryString());
	               	}
               	}
            };
            // 
            var select = new OpenLayers.Control.SelectFeature(o.vectors, options);
            o._map.addControl(select);
            select.activate();

			// stops the map mouse wheel behaviour initially
			o._disableWheel();

			// if there's a coordinate cookie
			var withCookie = $.cookie('zoomTo') && $.cookie('centerLon') && $.cookie('centerLat');
			//
		    if (withCookie) {
		    	// predefine lon, lat and zoom from cookie
		    	o._lon = $.cookie('centerLon');
		    	o._lat = $.cookie('centerLat');
		    	o._zoom = $.cookie('zoomTo');
		    } else {
		    	// disable dragging on initial view
		    	o._disableDragging();
		    }
		    
		    o._map.setCenter( new OpenLayers.LonLat( o._lon, o._lat ).transform(
							o._transformation[o._useCloudMade].from, 
							o._transformation[o._useCloudMade].to), o._zoom );
		    
		    // set possition and zoom for the map
		    o._zoomLevel = o._map.zoom;
		    o._topLeftCorner = o._map.getLonLatFromPixel(new OpenLayers.Pixel($('#map').offset().left, $('#map').offset().top)).transform(
				o._transformation[o._useCloudMade].to, 
				o._transformation[o._useCloudMade].from);
		    o._bottomRightCorner = o._map.getLonLatFromPixel(new OpenLayers.Pixel($('#map').offset().left + $('#map').width(),$('#map').offset().top + $('#map').height())).transform(
				o._transformation[o._useCloudMade].to, 
				o._transformation[o._useCloudMade].from);
				
			o._map.events.register('movestart', o._map, function() {
				o._stopPopups = true;
				$(o._markers.div).empty();
			});
			
			var firstLoad = true;
		    // when user zooms
		    o._map.events.register('moveend', o._map, function(e) {

		    	// don't zoom out more
		    	if (o._map.zoom < 2)
		    		o._map.zoomTo(2);
		    		
		    	if (o._timeoutid) 
		    		clearTimeout(o._timeoutid);

		    	o._refresh();
		    		
		    	firstLoad = false;
		    });
		    
		    var userClicked = false;
		    o._map.events.register('mousedown', o._map, function() {
		    	userClicked = true;
		    });
		    o._map.events.register('mousemove', o._map, function() {
	    		userClicked = false;
	    	});
	    	o._map.events.register('mouseup', o._map, function(e) {
	    		
		    	if ( userClicked ) {
		    		o._enableWheel();
		    		o._enableDraggig();
		    	}
		    	
		    	if ( o._clickToSaveCoordinates ) {
		    		var lon = o._map.getLonLatFromPixel(new OpenLayers.Pixel(e.pageX, e.pageY - 230)).transform(
									o._transformation[o._useCloudMade].to, 
									o._transformation[o._useCloudMade].from)['lon'];
					var lat = o._map.getLonLatFromPixel(new OpenLayers.Pixel(e.pageX, e.pageY - 230)).transform(
									o._transformation[o._useCloudMade].to, 
									o._transformation[o._useCloudMade].from)['lat'];
									
					o._putMarker(lon, lat);
				    o._saveCoordinates(lon, lat);
		    	}
	    	});
	    	o._map.addLayer( o._markers );
	    	o._map.addLayer( o._labels );
	    	o._map.addLayer( o._uploadMarker );
		},
		
		/**
		 * load
		 * 
		 * loads new thumbnails to the map
		 * 
		 * @access public
		 * @param {Boolean} reload
		 * @return {Boolean} success
		 */
		load : function(reload, oQueryString)
		{
			$('.map-tooltip').remove();
			// set default value
			if ( typeof reload == null)
				reload = false;
				
			// if it's news on demand
			if (oQueryString.category == 16 || oQueryString.category == 33)
				o._newsOnDemand = true;
			else 
				o._newsOnDemand = false;

			if ( !o._pageOffset ) 
				$('#preloader').show();
			
		    if (o._map.zoom < o._zoomLevel || reload) {
		    	o._thumbsCount = 0;
		    	o._markers.clearMarkers();
				$('a.mapthumb').unbind();
				$('div.thumb').unbind();
				$('a.mapthumb').remove();
				$('div.thumb').remove();
			}
			
			if (o._map.zoom > o._zoomLevel)
				o._enableWheel();
				
			o._zoomLevel = o._map.zoom;
			
			var lonlats = '/';

			// when the map not zoomed (initial case) we don't include 
			// the latitude and logitude bound box and the request
			// don't need to include its coordinates
			if (o._map.zoom > 2) 
				var lonlats = '/latmax/' 
				            + (o._topLeftCorner['lat']+5) 
				            + '/latmin/' 
				            + o._bottomRightCorner['lat'] 
				            + '/lonmax/' 
				            + o._bottomRightCorner['lon'] 
				            + '/lonmin/' 
				            + o._topLeftCorner['lon'] 
				            + '/';
			
			// construct the request to the server in case there is no
			// cache for it!
			if (typeof oQueryString != 'undefined') {
				var queryString = oQueryString;
				var requestUrl = '/information/list/category/' +
				    			queryString.category + '/state/' +
				    			queryString.state + '/FD/' +
				    			queryString.fd + '/TD/' +
				    			queryString.td + '/keywords/' + 
				    			queryString.keywords + 
				    			lonlats + 'offset/' + 
				    			o._pageOffset;
			}
		
			// check for the cache usage. if only the category is not null
			// or it's a integer than use the cache if not don't use it
			if (queryString.state + queryString.fd + queryString.td + queryString.keywords == '' 
			    && lonlats == '/'
            ) {
				if (+queryString.category)
					requestUrl = '/information/list/category/' + queryString.category;
				else 	
					requestUrl = '/information/list/category/9/';
			}
						
			o._usingCache = true;
			
		    o._ajaxRequest = $.ajax({ 
		    	url : requestUrl,
		    	dataType : 'json',
		    	success : function(data) {
		    		var data               = data.results,
		    			newsOnDemand       = o._newsOnDemand,
		    			mapZoomed          = (o._map.zoom > 3),
		    			newsOnDemandOffset = new OpenLayers.Pixel(-33, -25),
		    			tooltips           = [],
		    			j                  = 0,
		    			promotedIndex      = 0,
		    			dl                 = data.length,
		    			marks              = o._markers,
		    			markersStr         = '',
		    			ll;
		    			
		    		var mapContainerOffset = $('#map_OpenLayers_Container').offset();
		    			
		    		for (var i = dl; i--; ) {
	    				var item     = data[dl-i-1], 
	    				    lon      = item.o, 
	    				    lat      = item.a,
	    				    id       = item.i,
	    				    titlep   = item.tp,
	    				    path     = item.h,
	    				    http     = item.h,
	    				    tooltip  = item.tt,
	    				    type     = item.ty,
	    				    promoted = item.ip,
	    				    title    = item.t,
	    				    descr    = item.d;
		    			
		    			if (typeof item == 'undefined')
		    				continue;
		    			
						// for news demand
		    			if (newsOnDemand) {
		    				ll = o._map.getLayerPxFromLonLat(new OpenLayers.LonLat(lon,lat).transform(
								 o._transformation[o._useCloudMade].from, 
								 o._transformation[o._useCloudMade].to));
								
							markersStr += '<div id="OL_Icon_'+i+'" style="position:absolute;top:'+(ll.y-30)+'px;left:'+ll.x+'px"><a class="request icon" href="/' + titlep + '" id="matid-' + id + '"></a></div>';
		    			} else {
		    				ll = o._map.getLayerPxFromLonLat(new OpenLayers.LonLat(lon,lat).transform(
								 o._transformation[o._useCloudMade].from, 
								 o._transformation[o._useCloudMade].to));
							
							if (!mapZoomed) {
								markersStr += '<div id="OL_Icon_'
								            + i
								            + '" style="position:absolute;top:'
								            + (ll.y-4)
								            + 'px;left:'
								            + ll.x
								            + 'px"><a class="mapthumb icon dot" href="/' 
								            + titlep 
								            + '" thumb="' 
								            + http 
								            + '" tooltip="' 
								            + title
								            + '{{}}'
								            + tooltip 
								            + '{{}}' 
								            + descr 
								            + '"></a></div>';
							} else {
								if (type == 1) {
									markersStr += '<div id="OL_Icon_'+i+'" style="position:absolute;top:'+(ll.y-14)+'px;left:'+ll.x+'px"><a class="mapthumb icon photo" style="width:28px;height:28px;" href="/' + 
			        					titlep + '" thumb="' + 
			        					http + '" tooltip="' + 
			        					title+'{{}}'+tooltip+'{{}}'+descr + '"></a></div>';
								} else {
									markersStr += '<div id="OL_Icon_'+i+'" style="position:absolute;top:'+(ll.y-14)+'px;left:'+ll.x+'px"><a class="mapthumb icon video" style="width:28px;height:28px;" href="/' + 
			        					titlep + '" thumb="' + 
			        					http + '" tooltip="' + 
			        					title+'{{}}'+tooltip+'{{}}'+descr + '"></a></div>';
								}
							}
			    			
							if (ll.y + mapContainerOffset.top < $('#map').offset().top) continue;
							if (ll.y + mapContainerOffset.top > $('#map').offset().top + $('#map').height()) continue;
							if (ll.x + mapContainerOffset.left < $('#map').offset().left) continue;
							if (ll.x + mapContainerOffset.left > $('#map').offset().left + $('#map').width()) continue;
							
			    			if (1==promoted && promotedIndex < 30) {
		    					j++;
		    					tooltips[promotedIndex++] = [
		    							tooltip,
		    							http,
		    							{
		    							   top : ll.y + mapContainerOffset.top,
		    							   left: ll.x + mapContainerOffset.left + 3
		    							},
		    							titlep,
		    							title,
		    							descr];
		    				} else if (j < 30) {
			    				tooltips[j++] = [
			    						tooltip,
			    						http,
		    							{
		    							   top : ll.y + mapContainerOffset.top,
		    							   left: ll.x + mapContainerOffset.left + 3
		    							},
		    							titlep,
		    							title,
		    							descr];
			    			}
		    			}
		    		} // end of for
		    		$(marks.div).html(markersStr);			
		    		
		    		if (newsOnDemand) {
			    		$('.request').mouseover(o._showNewsOnDemandTooltip);
			    		$('.request').mouseout(function() {
			    			clearTimeout(o._timeoutid);
			    			o._timeoutid = setTimeout(function() {
			    				$('#news-on-demand-tooltip').hide();
			    			}, 1000);
			    		});
		    		} else {
		    			$('#map').delegate('.mapthumb', 'mousemove', o._showTooltip)
		    					 .delegate('.mapthumb', 'mouseout', o._hideTooltip);
		    		}
		    		
		    		$('#preloader').hide();
		    		
		    		// star the process of showing the tooltips
//		    		if (!o._popupsDisabled) {
//			    		o._stopPopups = false;
//			    		clearTimeout(o._tooltipTimeout);
//			    		o._startShowingPopups(tooltips, 0);
//		    		}
		    	} // end of success
		    }); // end of ajax call
		},
		
		/**
		 * Disable the popup tooltips
		 * 
		 * @public
		 */
		disablePopups : function()
		{
			o._popupsDisabled = true;
		},
		
		/**
		 * Enable the tooltip popups
		 * 
		 * @public
		 */
		enablePopups : function()
		{
			o._popupsDisabled = false;
		},
		
		/**
		 * Start the process of showing popups.
		 * 
		 * @private
		 * @param void
		 * @return void
		 */
		_stopPopups : false,
		_tooltipTimeout : null,
		_clientWidth : $(window).width(),
		_startShowingPopups : function(tooltips, index) 
		{
			if (o._stopPopups) {
				o._tooltipTimeout = setTimeout(function() {
					o._startShowingPopups(tooltips, index);
				}, 10000);
			} else if ( typeof tooltips[index] == 'undefined' ) {
				var i = index+1;
				o._startShowingPopups(tooltips, i);
			} else {
				var tt = tooltips[index][0];
				
				$('#map').append('<div class="map-tooltip" rel="' + index + '">' +
						'<div class="mtooltip-down">&nbsp;</div>' +
						'<div class="material-tooltip">' +
						'<div style="background: #ccc url(' +
						tooltips[index][1] +
						')" class="thumbtooltip" id="thumbtooltip>' + 
						'<a class="round" title="" href=""></a>' +
						'</div>' +
						'<h1>' +
						tooltips[index][4] + '</h1><br/>' +
						'<div class="tooltip-details">' +
						tt + '</div>' +
						'<div class="material-descr">' +
						tooltips[index][5] + '</div>' +
						'</div>' +
						'</div>');
				
				$('.map-tooltip[rel=' + index + ']').
					show().
					click(function() {
						location.href = '/' + tooltips[index][3];
					});
			    
				var top  = (tooltips[index][2].top - $('.map-tooltip[rel=' + index + '] > .material-tooltip')[0].clientHeight);
				var left = tooltips[index][2].left+2;
				
				var tooHigh = 0,tooLeft = 0;			
				if (top < 103)
					tooHigh = 1;
				if (left+252 > o._clientWidth)
					tooLeft = 2;
					
				switch (tooHigh+tooLeft) {
					case 0:
						break;
					case 1:
						top = tooltips[index][2].top + 15;
						var topcsstxt = $('.map-tooltip[rel=' + index + '] > .mtooltip-down').css('cssText') + 
							';background:transparent url(/images/material-tooltip-ul.png) no-repeat 0 0;height:12px;';
						$('.map-tooltip[rel=' + index + '] > .mtooltip-down').css('cssText', topcsstxt);
						var btmcsstxt = $('.map-tooltip[rel=' + index + '] > .material-tooltip').css('cssText') +
							';background:transparent url(/images/material-tooltip-down.png) no-repeat 0 bottom;';
						$('.map-tooltip[rel=' + index + '] > .material-tooltip').css('cssText', btmcsstxt);	
						break;
					case 2:
						left = tooltips[index][2].left - 255;
						var btmcsstxt = $('.map-tooltip[rel=' + index + '] > .material-tooltip').css('cssText') +
							';background:transparent url(/images/material-tooltip-down-dr.png) no-repeat 0 bottom;';
						$('.map-tooltip[rel=' + index + '] > .material-tooltip').css('cssText', btmcsstxt);
						break;
					case 3:
						top = tooltips[index][2].top + 5;
						left = tooltips[index][2].left - 252;
						break;
				}
				
				var csstxt = $('.map-tooltip[rel=' + index + ']').css('cssText') + ';top:'+ top +
								'px;left:' + left +
								'px;width:200px;';
				
				$('.map-tooltip[rel=' + index + ']').css('cssText', csstxt);
				//$('.map-tooltip[rel=' + index + '] > *').fadeTo(5000,1).fadeOut('fast');
				
				var i = index;
				if ( tooltips.length == i+1 )
					i = -1;
				o._tooltipTimeout = setTimeout(function() {
					$('.map-tooltip').remove();
					o._startShowingPopups( tooltips, i+1 );
				}, 3000);
			}
		},
		
		/**
		 * addMaterialThumb - ads one thumb on the map for a given materialId
		 * 
		 * @public
		 * @param {Int} materialId
		 * @return {Void}
		 */
		addMaterialThumb : function( materialId ) 
		{
			$.ajax({
				url : '/information/get/id/' + materialId,
				dataType : 'json',
				success : function(data) {
					var thumb = new OpenLayers.Thumb(data[0].http_path, o._size, o._offset, null, data[0].tooltip,data[0].title_processed,true);
					
					var marker = new OpenLayers.Marker(
						new OpenLayers.LonLat(+data[0].longitude,+data[0].latitude).transform(
									o._transformation[o._useCloudMade].from, 
									o._transformation[o._useCloudMade].to
								),
						thumb);	
					o._markers.addMarker(marker);
					
					if (data[0].type_id == 1)
						$(thumb.imageDiv).children().addClass('markedphoto').css({width:'28px',height:'28px',zIndex:30000});
					else if (data[0].type_id == 2)
						$(thumb.imageDiv).children().addClass('markedvideo').css({width:'28px',height:'28px',zIndex:30000});
					
					if ( o._newsOnDemand ) {
			    		$('.mapthumb').mouseover(o._showNewsOnDemandTooltip);
		    		} else {
		    			$('.mapthumb').mousemove(o._showTooltip);
			    		$('.mapthumb').mouseout(o._hideTooltip);
		    		}
				}
			});
		},
		
		/**
		 * setCenter - position the map on the given lon/lat and zoom level
		 * 
		 * @public
		 * @param {Number} lon
		 * @param {Number} lat
		 * @param {Int} zoom
		 * @return {Void}
		 */
		setCenter : function( lon, lat, zoom ) 
		{
			o._map.setCenter( new OpenLayers.LonLat( lon, lat ).transform(
							o._transformation[o._useCloudMade].from, 
							o._transformation[o._useCloudMade].to), zoom );
		},
		
		/**
		 * enables the map slide
		 */
		enableSlide : function() 
		{
			var mapHeight = $('#map').height();
			// change the cursor
			$('.map-slider').mouseover(function() {
				document.body.style.cursor = 'move';
			});
			$('.map-slider').mouseout(function() {
				document.body.style.cursor = 'auto';
			});
			//
			$('.map-slider').mousedown(function() {
				$(document).mousemove(function(e) {
					mapHeight = e.pageY - 105;
					$('#map').css('height', mapHeight);
					o._map.updateSize();
				});
				$(document).mouseup(function() {
					$('#map').css('height', mapHeight);
					$(document).unbind();
				});
			});
		},
		
		/**
		 * enables the save of coordinates
		 */
		enableCoordinatesSave : function() {
			o._clickToSaveCoordinates = true;
		},
		
		/**
		 * puts a marker on the clicked place
		 */
		_putMarker : function( lon, lat  ) {
			o._uploadMarker.clearMarkers();
			o._uploadMarker.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(lon, lat).transform(
									o._transformation[o._useCloudMade].from, 
									o._transformation[o._useCloudMade].to)));
		},

		/**
		 * set a form values for lon lat from mouse click over the map
		 */
		_saveCoordinates : function( lon, lat ) 
		{
//			console.log(lon, lat);
//			$('input[id="longitude"]').val(lon);
//			$('input[id="latitude"]').val(lat);
		},
		
		/**
		 * buildStyle
		 * 
		 * @private
		 * @param {Void}
		 * @return {Void}
		 */
		_buildStyle : function() {
            var theme = new OpenLayers.Style();
            var rule = new OpenLayers.Rule({filter: new OpenLayers.Filter.Comparison({
                type: OpenLayers.Filter.Comparison.LESS_THAN,
                property: "value",
                value: 10
                }),
                symbolizer: {"Polygon": {'fillColor': '#f2f2f2', 'strokeColor' : '#cfcfcf'}}
            });
            theme.addRules([rule]); // #f2f2f2, #cfcfcf , ruleMed1, ruleMed2, ruleHigh]);
            var stylemap = new OpenLayers.StyleMap({'default':theme, 'select': {'strokeColor': '#59bce6', 'fillColor': '#59bce6', 'strokeWidth': 1}});            

            return stylemap;
        },
        
        /**
         * 
         */
        _buildMaskStyle : function() 
        {
        	var theme = new OpenLayers.Style();
            var rule = new OpenLayers.Rule({filter: new OpenLayers.Filter.Comparison({
                type: OpenLayers.Filter.Comparison.LESS_THAN,
                property: "value",
                value: 10
                }),
                symbolizer: {"Polygon": {'fillColor': '#909090', 'strokeColor' : '#909090'}}
            });
            theme.addRules([rule]); 
            var stylemap = new OpenLayers.StyleMap({'default':theme, 'select': {'strokeColor': '#909090', 'fillColor': '#909090', 'strokeWidth': 0}});

            return stylemap;
        },
		
		/**
		 * destroyVectorLayer
		 * 
		 * @public
		 * @param {Void}
		 * @return {Void}
		 */
		destroyVectorLayer : function() {
			o._vectorLayer.destroy();
		},
		
		/**
		 * center
		 * 
		 * centers the map to lat and log with zero values
		 * and setup the zoom level to 2
		 * 
		 * @public
		 * @param {Void}
		 * @return {Void}
		 */
		center : function() {
			o._map.setCenter(new OpenLayers.LonLat(0, 3), 2)
		},
		
		/**
		 * _showTooltip
		 * 
		 * @access private 
		 * @param {MouseEvent} event
		 * @return void
		 */
		_showTooltip : function(event) 
		{
			if ($(event.target).is('a')) {
				
				o._stopPopups = true;
				$('.map-tooltip').hide();

				$(this).parent().addClass('popup-thumb');
				$(this).addClass('popup-thumb');
				//
				var offset = $(this).offset();
				//
				var tt = $(this).attr('tooltip').split('{{}}');
				
				$("#map-tooltip").html(
						'<div class="mtooltip-down">&nbsp;</div>' +
						'<div class="material-tooltip">' +
						'<div style="background: #ccc url(' +
						$(this).attr('thumb') +
						')" class="thumbtooltip" id="thumbtooltip>' + 
						'<a class="round"></a>' +
						'</div>' +
						'<h1>' +
						tt[0] + '</h1><br/>' +
						'<div class="tooltip-details">' +
						tt[1] + '</div>' +
						'<div class="material-descr">' +
						tt[2] + '</div>' +
						'</div>').show();
						
				// top and left
				var top = event.pageY - $('#map-tooltip > .material-tooltip')[0].clientHeight;
				var left = event.pageX;
				
				// css
				var csstxt = $('#map-tooltip').css('cssText') + ';top:' + top + 'px;left:' + left + 'px;width:200px;';
						
				$('#map-tooltip').css('cssText', csstxt);
				
			}
			//
			return false;
		},
		
		/**
		 * _showNewsOnDemandTooltip
		 * 
		 * @access private 
		 * @param {MouseEvent} event
		 * @return void
		 */
		_showNewsOnDemandTooltip : function(event) {
			if (event.target.nodeName == "A") {
				//
				clearTimeout(o._timeoutid);	
				$('#news-on-demand-tooltip').mouseenter(function() {
					clearTimeout(o._timeoutid);	
				});
				//
				$('#news-on-demand-tooltip').mouseleave(function() { 
					o._timeoutid = setTimeout(function() {
						$('#news-on-demand-tooltip').hide();
					}, 2000);
				});
				//
				var materialId = $(this).attr('id').substr(6);
				//
				var offset = $(this).offset();
				//
				$.ajax({
					dataType : 'json',
					url : '/information/get/id/' + materialId,
					success : function( data ) {
						
						$('#news-on-demand-title').html(data[0].title);
						$('#news-on-demand-dc').html(data[0].date_processed);
						$('#news-on-demand-username').html(data[0].user_name).attr('href', '/user/profile/name/' + data[0].user_name);
						$('#news-on-demand-description').html(data[0].description);
						$('#news-on-demand-answer').attr('href', '/video-reply/id/' + materialId);
						
						$("#news-on-demand-tooltip").css({
							top: offset.top + 30,
							left: (offset.left + $('#news-on-demand-tooltip').width() + 50 > $(window).width())? 
									offset.left - $('#news-on-demand-tooltip').width() - 20 : offset.left + 15,
							width : '200px'
						}).show();	
						
						// get video replies
						$.ajax({
							dataType : 'json',
							url : '/information/get-video-replies/id/' + materialId,
							success : function(data) {
								$('#news-on-demand-vrlist').empty();
								
								// if there are materials
								if ( +data.count > 0 ) {
									for (var i = 0; i < data.list.length; i++) {
										$('#news-on-demand-vrlist').append(
												'<div class="item">' +
												'<a class="thumb" href="/' +
												data.list[i].video_reply_id + '">' +
												'<img style="width: 70px;" src="' +
												data.list[i].http_path + '"/>' +
												'<img class="news-req-round-img" src="../images/round_white.gif"/></a>' +
												'<a title="Add To My Playlist" class="addItem atmp-' +
												data.list[i].video_reply_id + '" href="#"/>' +
												'<h1><a href="/' +
												data.list[i].video_reply_id + '">' +
												data.list[i].video_reply_title +'</a></h1>' +
												'<h2>by heyjoe<br/> 27 september 2009 </h2>' +
												'</div>');
									}
									$('#news-on-demand-reports-count').html( +data.count + ' reports');
								} else {
									$('#news-on-demand-reports-count').html('no reports');
								}
								
								$('#news-on-demand-reports-count').attr('href', '/' + materialId);
								$('#news-on-demand-see-all').attr('href', '/' + materialId)
							}
						});
					}
				});
				
			}
			//
			return false;
		},
		
		/**
		 * removeControls
		 */
		removeControls : function() {
			$('.olControlPanZoom').hide();
		},
		
		/**
		 * removeMarkers
		 */
		removeMarkers : function() { 
		    o._markers.clearMarkers();
			$(o._markers.div).hide(); 
		},
		
		/**
		 * _hideTooltip
		 * 
		 * @access private
		 * @param {} event
		 * @return void
		 */
		_hideTooltip : function(event) {
			$(this).parent().removeClass('popup-thumb');
			$(this).removeClass('popup-thumb');
			$("#map-tooltip").hide();
			if (o._map.zoom == 2)
				o._stopPopups = false;
		},
		
		/**
		 * _disableWheel
		 * 
		 * @access private
		 * @param void
		 * @return void
		 */
		_disableWheel : function() {
			controls = o._map.getControlsByClass('OpenLayers.Control.Navigation');
		
			for(var i = 0; i < controls.length; i++) {
				controls[i].disableZoomWheel();
			}
		},
		
		/**
		 * _enableWheel
		 * 
		 * @access private
		 * @param void
		 * @return void
		 */
		_enableWheel : function() {
			controls = o._map.getControlsByClass('OpenLayers.Control.Navigation');
		
			for(var i = 0; i < controls.length; i++) {
				controls[i].enableZoomWheel();
			}
		},
		
		/**
		 * _disableDragging
		 * 
		 * @private
		 * @param {Void}
		 * @return {Void}
		 */
		_disableDragging : function() {
			for (var i = 0; i< o._map.controls.length; i++) {
                if (o._map.controls[i].displayClass == "olControlNavigation") {
                    o._map.controls[i].deactivate();
                }
            }
		},
		
		/**
		 * _enableDraggig
		 * 
		 * @private
		 * @param {Void}
		 * @return {Void}
		 */
		_enableDraggig : function() {
			for (var i = 0; i< o._map.controls.length; i++) {
                if (o._map.controls[i].displayClass == "olControlNavigation") {
                    o._map.controls[i].activate();
                }
            }
		},
		
		/**
		 * _refresh
		 * 
		 * refresh happens when user 'moveend's. On finish dragging,
		 * zoom out/in. when user zoom in there should not be clear refresh
		 * and that is happening in 'load' function
		 * 
		 * @access private
		 * @param {Void}
		 * @return {Void}
		 */
		_refresh : function() {
			
			// set a cookie, and center point of the map
			// that's needed when user refresh the browser.
			// this cookie lasts for one session. When this cookie
			// is cleared the user will see initial map on refresh
			if (o._saveLonLatZoom) {
				$.cookie('zoomTo', o._map.zoom);
				$.cookie('centerLat', o._map.getCenter()['lat']);
				$.cookie('centerLon', o._map.getCenter()['lon']);
			}
			
			// get the topleft, and bottomright corners of the map. 
			// this is necessary when the user zooms the map, or drag it,
			// because the query to the database for the thumbs do not to be
			// for an area which is not seen in the current map view.
			o._topLeftCorner = o._map.getLonLatFromPixel(new OpenLayers.Pixel($('#map').offset().left, $('#map').offset().top)).transform(
				o._transformation[o._useCloudMade].to, 
				o._transformation[o._useCloudMade].from);
		    o._bottomRightCorner = o._map.getLonLatFromPixel(new OpenLayers.Pixel($('#map').offset().left + $('#map').width(),$('#map').offset().top + $('#map').height())).transform(
				o._transformation[o._useCloudMade].to, 
				o._transformation[o._useCloudMade].from);
		    
			// load the map with not refresh
			o.load(reload = true, BaseController.getQueryString());
			
		}, 
		
		/**
		 * enables the save in cookie of the browsed lon, lat and zoom of the map
		 * 
		 * @public
		 * @param {Void}
		 * @return {Void}
		 */
		enableLonLatZoomSave : function() {
			o._saveLonLatZoom = true;
		},
		
		//
		// callbacks
		//
		callbackReloadMap: function (){
			o.load(true, BaseController.getQueryString());
		}
		
	}; // ... map class
	
	// export public methods
	window.Map.init = OpenLayersMap.init;
	window.Map.load = OpenLayersMap.load;
	window.Map.destroyVectorLayer = OpenLayersMap.destroyVectorLayer;
	window.Map.center = OpenLayersMap.center;
	window.Map.setCenter = OpenLayersMap.setCenter;
	window.Map.enableSlide = OpenLayersMap.enableSlide;
	window.Map.rebuildVirtu = OpenLayersMap.rebuildVirtu;
	window.Map.hideVirtu = OpenLayersMap.hideVirtu;
	window.Map.callbackReloadMap = OpenLayersMap.callbackReloadMap;
	window.Map.enableCoordinatesSave = OpenLayersMap.enableCoordinatesSave;
	window.Map.addMaterialThumb = OpenLayersMap.addMaterialThumb;
	window.Map.removeControls = OpenLayersMap.removeControls;
	window.Map.removeMarkers = OpenLayersMap.removeMarkers;
	window.Map.enableLonLatZoomSave = OpenLayersMap.enableLonLatZoomSave;
	window.Map.disablePopups = OpenLayersMap.disablePopups;
	window.Map.enablePopups = OpenLayersMap.enablePopups;
	
	// make object private
	window.OpenLayersMap = null;
})();	
