(function($) {

	var defaults = { width: 960, height: 600};
	var opened = false;

	$.fn.mSearch = function(options) {
	
		var options = $.extend({}, defaults, options);
		options.prefix = getPrefix(0000,9999);
		
		var mSearchMap;
		var mSearchCursorPosition;
		var mSearchMarker0;
		var mSearchMarker1;
		var mSearchRect;
		var isActive = false;
		var isOnStart = false;
		
		mSearchGetParams();
		
		init(this);
		
		function init(e) {
			return e.each(function(){
				$(this).click(function(){
					open_map($(this));
					return false;
				});
			});
		}	
		
		function open_map(element) {
			if (!opened) {
				
				opened = true;
				var pos = $(document).scrollTop() + 100;
				var popupW = options.width;
				var mapDiv = options.prefix + "_msearchdiv";
				
				var html = "<h5 class='metroheader'>Выбор области поиска объектов</h5>";
				html += "<div id='" + mapDiv + "' class='msearchdiv'></div>";
				html += "<div class='msearch_buttons' id='" + options.prefix + "_buttons'>";
				html += "<div id='" + options.prefix + "_area' ></div>";
				html += "<div id='" + options.prefix + "_help' ></div>";
				html += "<a href='#' id='" + options.prefix + "_startdraw' class='prettybutton'><span>Начать выбор области</span></a><br>";		
				html += "<a href='#' id='" + options.prefix + "_canceldraw' class='prettybutton'><span>Отмена</span></a>";			
				html += "<a href='#' id='" + options.prefix + "_reset' class='prettybutton hidden'><span><b>Сбросить</b></span></a>";
				html += "<a href='#' id='" + options.prefix + "_search' class='prettybutton hidden'><span><b>Выбрать эту область</b></span></a>";
				html += "<a href='#' id='" + options.prefix + "_resetclose' class='prettybutton'><span><b>Сбросить и закрыть</b></span></a>";	
				html += "</div>";
				html += "<div class='clear'></div>";
				
				popupbox = new popupBox({width: popupW, top: pos.top, prefix: options.prefix});
				popupbox.openBox(html);
				
				$('#' + mapDiv).width(popupW - 300).height(options.height - 50);
				loadMap(mapDiv);
				
				if (isOnStart) {
					$("#" + options.prefix + "_reset").removeClass('hidden');
					$("#" + options.prefix + "_search").removeClass('hidden');
					$("#" + options.prefix + "_startdraw").addClass('hidden');
				}
				
				$('#' + options.prefix + '_popupframe').height($('#' + options.prefix + '_popupMetro').height());
				
				listen();
			}
			
		}
		
		function listen() {
			$('#' + options.prefix + '_close_metro').click(function(){ close_map(); return false;});
			$("#" + options.prefix + "_startdraw").click(function() { 	mSearchStartDraw(); return false;});
			$("#" + options.prefix + "_canceldraw").click(function() { 	mSearchCancelDraw(); close_map(); return false;});
			$("#" + options.prefix + "_reset").click(function() { mSearchResetDraw(); return false; });
			$("#" + options.prefix + "_search").click(function() { mSearchGetParams();close_map(); return false; });
			$("#" + options.prefix + "_resetclose").click(function() { mSearchCloseEmpty();close_map(); return false; });
			$("#" + options.prefix + "_close").click(function() { close_map(); return false; });
		}
		
		function close_map() {
			isActive = false;
			opened = false;
			popupbox.closePopup();
		}

		function loadMap(id) {
			
			mSearchMapId = id;
			
			var mapOptions = {
				zoom: 11,
				center: new google.maps.LatLng(55.755768, 37.617671),
				mapTypeId: google.maps.MapTypeId.ROADMAP
			};

			mSearchMap = new google.maps.Map(document.getElementById(mSearchMapId), mapOptions);

			google.maps.event.addListener(mSearchMap, "mousemove", function(event) { 
				mSearchCursorPosition = event.latLng;
			});

			mSearchRect = new google.maps.Rectangle();
			
			var values = $(options.input).val();
			
			if(values){

				isOnStart = true;
				var rBounds = mSearchGetRectBounds();
				var point1 = rBounds.getSouthWest();
				var point2 = rBounds.getNorthEast();
			
				var rectOptions = {
					strokeColor: "#FF0000",
					strokeOpacity: 0.8,
					strokeWeight: 2,
					fillColor: "#FF0000",
					fillOpacity: 0.35,
					map: mSearchMap,
					bounds: rBounds
				};
				mSearchRect.setOptions(rectOptions);
				
				var MapCenter = rBounds.getCenter();
				mSearchMap.setCenter(MapCenter);
				mSearchMap.fitBounds(rBounds);
				mSearchMarker0 = new google.maps.Marker({
					position: point1,
					map: mSearchMap,
					title: "Вы можете передвинуть этот маркер для изменения выбранной области",
					draggable: true,
					cursor: 'move'
				});
				
				mSearchMarker1 = new google.maps.Marker({
					position: point2,
					map: mSearchMap,
					title: "Вы можете передвинуть этот маркер для изменения выбранной области",
					draggable: true,
					cursor: 'move'
				});
				
				mSearchListenMarkers();
				mSearchShowArea();
			}else{
				$("#" + options.prefix + "_area").html('Область поиска не выбрана');
			}
			
		}
		
		function mSearchGetRectBounds() {	
			var values = $(options.input).val();
			
			if(values){
				var coords = values.split(';');
				var lat1 = coords[0];
				var lat2 = coords[1];
				var lon1 = coords[2];
				var lon2 = coords[3];
				
				var point1 = new google.maps.LatLng(lat1,lon1);
				var point2 = new google.maps.LatLng(lat2,lon2);
				
				return new google.maps.LatLngBounds(point1, point2);
			}else{
				return false;
			}
		}

		function mSearchStartDraw() {
			$("#" + options.prefix + "_startdraw").addClass('hidden');
			$("#" + options.prefix + "_help").html("1. Нажмите левой кнопкой мыши на карте и потяните в сторону, растягивая область поиска. <br> 2. Опустите левую кнопку. <br>3. Если необходимо, передвиньте метки. <br>4. Нажмите кнопку <b>Выбрать эту область</b>").addClass('help');

			if(!isActive) {
				
				isActive = true;
				
				mSearchMap.setOptions({draggable: false});
				$("#" + mSearchMapId).css("cursor", "crosshair");
				
				var md = google.maps.event.addDomListener(document.getElementById(mSearchMapId), 'mousedown', function() {

					mSearchMarker0 = new google.maps.Marker({
						position: mSearchCursorPosition,
						map: mSearchMap,
						title: "Вы можете передвинуть этот маркер для изменения выбранной области",
						cursor: 'move'
					});
					
					mSearchMarker1 = new google.maps.Marker({
						position: mSearchCursorPosition,
						map: mSearchMap,
						title: "Вы можете передвинуть этот маркер для изменения выбранной области",
						cursor: 'move'
					});
					
					mSearchListenMarkers();
					
					var me = google.maps.event.addListener(mSearchMap, 'mousemove', function(event) {
						mSearchMarker1.setPosition(event.latLng);
						mSearchRedraw();
					});
					
					var mu = google.maps.event.addDomListener(document.getElementById(mSearchMapId), 'mouseup', function(event) {
						google.maps.event.removeListener(me);
						google.maps.event.removeListener(md);
						google.maps.event.removeListener(mu);
						mSearchRedraw();

						mSearchMarker0.setOptions({draggable: true});
						mSearchMarker1.setOptions({draggable: true});
						mSearchMap.setOptions({draggable: true});
												
						$("#" + options.prefix + "_search").removeClass('hidden');
						mSearchShowArea();
						isActive = false;
						$("#" + mSearchMapId).css("cursor", "default");
					});
					
				});	
			}
		}
		
		function mSearchListenMarkers() {
			dr1 = google.maps.event.addListener(mSearchMarker0, 'drag', mSearchRedraw); 
			dr2 = google.maps.event.addListener(mSearchMarker1, 'drag', mSearchRedraw);
			
			dr3 = google.maps.event.addListener(mSearchMarker0, 'dragend', 	mSearchShowArea);
			dr4 = google.maps.event.addListener(mSearchMarker1, 'dragend', 	mSearchShowArea);
		}	

		function mSearchResetDraw() {
			isOnStart = false;
			mSearchCancelDraw();
			mSearchStartDraw();
			$("#" + options.prefix + "_reset").addClass('hidden');
			$("#" + options.prefix + "_search").addClass('hidden');
			$("#" + options.prefix + "_startdraw").addClass('hidden');
			$("#" + options.prefix + "_help").html('');
			$("#" + options.prefix + "_area").html('Область поиска не выбрана');
		}
		
		function mSearchCloseEmpty(){
			mSearchCancelDraw();
			isOnStart = false;
			$(options.input).val('');
			$(options.area).html('Область поиска не выбрана');
		}

		function mSearchCancelDraw() {
			if (mSearchMarker0) {
				mSearchMarker0.setMap(null);
				mSearchMarker1.setMap(null);
				mSearchRect.setMap(null);
				$("#" + options.prefix + "_area").html('Область поиска не выбрана');
				$(options.input).val('');
				$(options.area).html('Область поиска не выбрана');
			}
		}
		
		function mSearchGetPosition() {
			var p0 = mSearchMarker0.getPosition();
			var p1 = mSearchMarker1.getPosition();

			if (p1.lng() < p0.lng()) {
				var p2 = p1;
				var p3 = p0;
			} else {
				var p2 = p0;
				var p3 = p1;
			}

			var latLngBounds = new google.maps.LatLngBounds(
				p2,
				p3
			);
			
			return latLngBounds;
		}


		function mSearchRedraw() {
			
			var rectOptions = {
				strokeColor: "#FF0000",
				strokeOpacity: 0.8,
				strokeWeight: 2,
				fillColor: "#FF0000",
				fillOpacity: 0.35,
				map: mSearchMap,
				bounds: mSearchGetPosition()
			};
			mSearchRect.setOptions(rectOptions);
		}
		
		function mSearchGetArea(){
			var rectBounds = (mSearchRect)?  mSearchRect.getBounds() : mSearchGetRectBounds();
			
			if(rectBounds)
			{
				var lat1 = rectBounds.getSouthWest().lat();
				var lon1 = rectBounds.getSouthWest().lng();
				var lat2 = rectBounds.getNorthEast().lat();
				var lon2 = rectBounds.getNorthEast().lng();

				$(options.input).val('');
				$(options.input).val(lat1 + ';' + lat2 + ';' + lon1 + ';' + lon2);
				
				var area = google.maps.geometry.spherical.computeArea(
					new Array(
						new google.maps.LatLng(lat1,lon2),
						rectBounds.getSouthWest(),
						new google.maps.LatLng(lat2,lon1),
						rectBounds.getNorthEast()
					)
				);
				
				area = area/1000000;
				
				if(area < 1){
					area = area.toFixed(3)
				}else{
					area = Math.round(area);
				}
				
				return area;
			}else{
				return false;
			}
		}

		function mSearchGetParams() {
			var area = mSearchGetArea();
			var message = (area)? 'Выбрана область ' + area + ' кв.км.' : 'Область поиска не выбрана';
			$(options.area).html(message);
		}
		
		function getPrefix(min, max) {
			return Math.floor(Math.random() * (max - min + 1)) + min;
		}
		
		function get_posistion(element) {
			var offset = element.offset();
			return {left: offset.left , top: offset.top}
		}
		
		function mSearchShowArea(){
			$('#' + options.prefix + '_area').html('Выбрана область ' + mSearchGetArea() + ' кв.км.');
		}

	}
	
})(jQuery);
