var map_precision_msg = {
   'exact': '',
   'number': 'Найден дом с тем же номером.',
   'near': 'Найден дом на расстоянии не далее 10 номеров от запрошенного',
   'street': 'Найдена улица',
   'other': 'Найдена только часть адреса',
   'suggestion': "Слабая уверенность, уровень предположений 'Может быть, искали'"};

var standartStyles = [
            "default#greenPoint",
            "default#redPoint", "default#yellowPoint",
            "default#darkbluePoint", "default#nightPoint",
            "default#greyPoint", "default#bluePoint",
            "default#orangePoint", "default#darkorangePoint",
            "default#pinkPoint", "default#violetPoint", "default#whitePoint"
        ];


function GkYandexMap(container)
{
 this.map = null;
 this.container = container;
 this.palcesCollections = [];
 this.currentPlacemarker = null;
 this.currentStyleIndex = 0;
 this.is_admin = false;
 this.cbShowPlaceEnd = null;
 this.cbShowAddressEnd = null;
 this.cbPrecisionMsg = null;
 this.cbNotFound = null;
}

GkYandexMap.prototype = 
{

 Init: function(is_set_center, callback)
 {
  if (this.map == null)
  {
   var that = this;
   var loadMap = function()
   {
    that.map = new YMaps.Map(document.getElementById(that.container));
    if (is_set_center) that.map.setCenter(new YMaps.GeoPoint(49.629305,58.603867), 12, YMaps.MapType.MAP);
    that.map.addControl(new YMaps.TypeControl());
    that.map.addControl(new YMaps.ToolBar());
    that.map.addControl(new YMaps.Zoom());
    that.map.addControl(new YMaps.MiniMap());
    that.map.addControl(new YMaps.ScaleLine());
    if (callback) callback();
   };
   YMaps.load(loadMap);
  }
 }

 ,ShowPlaces: function(plugin, params, style)
 {
  if (this.map == null) Init(false);
  var ci = plugin + params;
  if (this.currentPlacemarker) { this.map.removeOverlay(this.currentPlacemarker); this.currentPlacemarker = null; }
  if (!this.palcesCollections[ci])
  {
   var that = this;
   $j.ajax(
      {url: 'http://afisha.gorodkirov.ru/useful/yandex_map/get_places.json'
       ,data: {plugin:plugin, params:params}
       ,dataType: 'json'
       ,type: 'POST'
       ,success: function(res, textStatus)
        {
         if (!res)
         {
           alert('К сожалению указанный адрес не может быть отображён на карте');
           if (that.cbShowPlaceEnd) that.cbShowPlaceEnd();
           return false;
         }
         var collection = that.palcesCollections[ci] = new YMaps.GeoObjectCollection(style);
         that.addPlacesToCollection(collection, res, 0);
        }
       ,error: function(XMLHttpRequest, textStatus, errorThrown)
        {
           alert('Ajax Error');
           if (that.cbShowPlaceEnd) that.cbShowPlaceEnd();
        }
      });
  }
  else
  {
   this.showPlacemarker(this.palcesCollections[ci]);
   if (this.cbShowPlaceEnd) this.cbShowPlaceEnd();
  }
  return false;
 }


 ,ShowAddress: function(address)
 {
  if (this.map == null) Init(false);
  this.map.removeOverlay(this.currentPlacemarker);
  var geocoder = new YMaps.Geocoder(address, {results: 1, boundedBy: this.map.getBounds()});

  var that = this;
  YMaps.Events.observe(geocoder, geocoder.Events.Load, function () 
  {
   if (this.length())
   {
    that.showPlacemarker(this.get(0));
    if (that.cbPrecisionMsg)
    {
     var msg = map_precision_msg[that.currentPlacemarker.precision];
     that.cbPrecisionMsg(msg);
    }
   }
   else 
   {
    if (thar.cbNotFound) that.cbNotFound();
   }
   if (that.cbShowAddressEnd) that.cbShowAddressEnd();
  });
  return true;
 }

 ,GetNextStyle: function()
 {
   var s = standartStyles[this.currentStyleIndex++];
   if (this.currentStyleIndex >= standartStyles.lenght) this.currentStyleIndex = 0;
   return s;
 }


 // ----------- Private methods

 ,calcBounds: function(collection)
 {
   var geoBounds = new YMaps.GeoCollectionBounds();
   collection.forEach(function(x) { geoBounds.add(x.getGeoPoint()); });
   collection.setBounds(geoBounds);
 }

 ,setPlaceCoord: function(plugin, params, place_id, x, y, precision)
 {
  $j.get('http://afisha.gorodkirov.ru/useful/yandex_map/set_place_coord',
         data={plugin:plugin, params:params, place_id:place_id, x:x, y:y, precision:precision});
 }

 ,addPlacesToCollection: function(collection, places, i)
 {
  if (i>=places.places.length) return;
  var that = this;
  var place = places.places[i];
  if (place.x>=0)
  {
   var point = new YMaps.GeoPoint(place.x, place.y);
   this.addPlacemarkToCollection(places, place, collection, point);
   i++;
   if (i<places.places.length) this.addPlacesToCollection(collection, places, i);
   else
   {
     this.calcBounds(collection);
     this.showPlacemarker(collection);
     if (this.cbShowPlaceEnd) this.cbShowPlaceEnd();
   }
  }
  else
  {
   var geocoder = new YMaps.Geocoder(place.address, {results: 1, boundedBy: this.map.getBounds()});
   YMaps.Events.observe(geocoder, geocoder.Events.Load, 
    function () 
    {
     if (this.length())
     {
       var point = this.get(0);
       var precision = point.precision
       point = point.getGeoPoint();
       that.setPlaceCoord(places.plugin, places.params, place.place_id, point.getLng(), point.getLat(), precision);
       that.addPlacemarkToCollection(places, place, collection, point);
     }
     else 
     {
       if (that.is_admin) alert("К сожалению адрес '" + place.address + "' не найден");
     }
     i++;
     if (i<places.places.length) that.addPlacesToCollection(collection, places, i);
     else
     {
      that.calcBounds(collection);
      that.showPlacemarker(collection);
      if (that.cbShowPlaceEnd) that.cbShowPlaceEnd();
     }
    });
  }
 }

 ,addPlacemarkToCollection: function(places, place, collection, point)
 {
   var that = this;
   var placemark = new YMaps.Placemark(point);
   var div = $j('<div />');
   div.html(place.html);

   if (this.is_admin)
   {
    var adiv = $j('<div />');
    var a = $j('<a />');
    a.html('Переместить');
    a.attr('href', '#');
    a.click(function()
    {
      if (placemark.getOptions().draggable)
      {
        placemark.setOptions({draggable: false});
        placemark.setIconContent(null);
        var point = placemark.getGeoPoint();
        that.setPlaceCoord(places.plugin, places.params, place.place_id, point.getLng(), point.getLat(), 'manual');
        $j(this).html('Переместить');
      }
      else
      {
        placemark.setOptions({draggable: true});
        placemark.setIconContent("Поехали!");
        $j(this).html('Сохранить');
      }
      return false;
    });
    adiv.append(a)
    div.append(adiv);
    YMaps.Events.observe(placemark, placemark.Events.DragEnd, function (mEvent) {placemark.setIconContent(mEvent.getGeoPoint().toString()); });
   }
   placemark.setBalloonContent(div.get(0));
   collection.add(placemark);
 }

 ,showPlacemarker: function(place_mark)
 {
  if (place_mark && this.map)
  {
   this.currentPlacemarker = place_mark;
   this.map.addOverlay(place_mark);
   this.map.setBounds(place_mark.getBounds());
  }
 }

}












