$(document).ready(initGeo);
/* Default values seteadas desde la page que llama */
city_id_default = (typeof city_id_default == 'undefined') ? '' : city_id_default;
city_name_default = (typeof city_name_default == 'undefined') ? '' : city_name_default;
country_name_default = (typeof country_name_default == 'undefined') ? ''  : country_name_default;
iterative = (typeof iterative == 'undefined') ? false : iterative;
city_name_element = (typeof city_name_element == 'undefined') ? null : city_name_element;
country_name_element = (typeof country_name_element == 'undefined') ? null : country_name_element;

function initGeo() {
      vmap = new geoMap(mapType, iterative);
      vmap.mapInit();
}
function find_property_in_object(obj,pattern) {
    var mycity;
    for (var p in obj) {
      //console.log( "Poperty: " + p + ", Value: " + obj[p] ); 
      if (typeof obj[p]== "object") {
        if (mycity = find_property_in_object(obj[p],pattern)) 
          return mycity;
      }else{
        if ( p == pattern) 
          return obj[p];
      }
    }
    if (typeof mycity != 'undefined') 
      return mycity;
    else
      return false;
}
function bind(toObject, methodName){
    //return function(arg){toObject[methodName](arg)}
    var args = [];
    for (var n = 2; n < arguments.length; n++)
      args.push(arguments[n]);
    return function(){toObject[methodName](args)};
}
function bindargs(toObject, methodName){
    return function(arg){toObject[methodName](arg)}
}
function geoPoint(lat, lng) {
  this.lat = lat != 0 ? lat : -40.5;
  this.lng = lng != 0 ? lng : -63.5;
  this.city_id = '';
  this.city_name = '';
  this.country_name = '';
  this.address = '';
  this.setAsCurrentLocation = function() {
    $(lat_element).val(this.lat);
    $(long_element).val(this.lng);
    if (this.city_id)
      $(city_id_element).val(this.city_id);
    if ($(city_name_element))
      $(city_name_element).val(this.city_name);
    if ($(country_name_element))
      $(country_name_element).val(this.country_name);
  }
  this.getLatLng = function() {
    return new GLatLng(this.lat, this.lng);
  }
  this.log = function () {
    console.log (
      ' lat: ' + this.lat +
      ' lng: ' + this.lng +
      ' city_id: ' + this.city_id +
      ' city_name: ' + this.city_name +
      ' country_name: ' + this.country_name +
      ' address: ' + this.address 
    );
  }
}
function geoMap(type, iterative) { 
  this.iterative = iterative; 
  this.zoom = lat_default != 0 ? 11 : 5;
  this.map = new GMap2(document.getElementById("map"));
  this.geoCoder = new GClientGeocoder();
  this.bounds = new GLatLngBounds;
  this.type = type;
  this.markerEvents = new Array();
  this.currentLocation = new geoPoint(lat_default, long_default);
  this.currentLocation.city_id = city_id_default;
  this.currentLocation.city_name = city_name_default;
  this.currentLocation.country_name = country_name_default;
  var baseIcon = new GIcon(G_DEFAULT_ICON);
  baseIcon.image = "/images/icons/ajustar.gif";
  baseIcon.imageMap = [0,0,42,0,42,67,0,67];
  baseIcon.iconSize = new GSize(40,67);
  //baseIcon.iconSize = new GSize(30,40);
  //baseIcon.shadow = "/images/icons/sombra_categorias.png";
  //baseIcon.shadowSize = new GSize(61, 20);
  baseIcon.iconAnchor = new GPoint(19, 67);
  baseIcon.infoWindowAnchor = new GPoint(18, 2);
  this.markerUser = new GMarker(new GLatLng(),{draggable: true, icon: baseIcon});
  GEvent.addListener(this.markerUser, "click", bind(this, "clickMarkerUser"));
  this.key = 0;
  this.interval = 0;
 
  this.mapInit = function() {
    this.map.setMapType(G_NORMAL_MAP);
    this.map.setCenter(this.currentLocation.getLatLng());
    this.markerUser.setLatLng(this.map.getCenter());
    switch (this.type) {
    case "showBig": 
      this.markerUser.disableDragging();
      this.map.addControl(new GLargeMapControl());
      this.showEvents();
      this.bounds.extend(this.map.getCenter());
      this.zoom = this.map.getBoundsZoomLevel(this.bounds, this.map.getSize()); //- 1;
      this.map.setCenter(this.bounds.getCenter());
      if (this.iterative)
        this.interval = window.setInterval(bind(this, "highlightMarker"), 3000);
      break;
    case "showSmall": 
      this.markerUser.disableDragging();
      //this.map.addControl(new GSmallMapControl());
      this.showEvents();
      this.bounds.extend(this.map.getCenter());
      this.zoom = this.map.getBoundsZoomLevel(this.bounds, this.map.getSize()); //- 1;
      this.map.setCenter(this.bounds.getCenter());
      //this.zoom = this.map.getBoundsZoomLevel(this.bounds)<14 ? this.map.getBoundsZoomLevel(this.bounds) : 14;
      break;
    case "editBig": 
      this.currentLocation.setAsCurrentLocation();
      this.map.addControl(new GSmallMapControl());
      GEvent.addListener(this.markerUser, "dragend", bind(this, "dragEnd"));
      break;
    }
    this.map.setZoom(this.zoom);
    this.map.addOverlay(this.markerUser);
  }
  this.reCenter = function (){
    this.map.checkResize();
    this.map.setCenter(this.currentLocation.getLatLng());
  }
  this.highlightMarker = function () {
    //console.log("flashMessage key: " + this.key);
    $('#event_box_' + events[this.key].event.id).hide();
    this.key = (this.key+1)%this.markerEvents.length;
    $('#event_box_' + events[this.key].event.id).fadeIn(380);
    html = "<strong>" + events[this.key].event.name.substr(0,40) + "</strong>" ; 
    //console.log(html);
    this.markerEvents[this.key].openInfoWindow(html);
  }
  this.clickMarkerUser = function (){
    this.markerUser.openInfoWindow('Para ajustar tu posición haz click <a href="/users/adjust">aquí</a>');
  }
  this.showEvents = function (){
    for (var key in events) {
      var e = events[key].event;
      if (e.venue.lat != 0 && e.venue.long != 0) {
        this.bounds.extend(new GLatLng(e.venue.lat, e.venue.long));
        //console.log(e.name + e.venue.lat + e.venue.long + e.category.icon);
        var baseIcon = new GIcon(G_DEFAULT_ICON);
        baseIcon.image = "/images/icons/" + e.category.icon + ".png";
        baseIcon.imageMap = [0,0,42,0,42,42,0,42];
        baseIcon.shadow = "/images/icons/sombra_categorias.png";
        baseIcon.iconSize = new GSize(35,42);
        baseIcon.shadowSize = new GSize(35, 42);
        baseIcon.iconAnchor = new GPoint(0, 42);
        baseIcon.infoWindowAnchor = new GPoint(35, 0);
        this.markerEvents[key] = new GMarker(new GLatLng(e.venue.lat, e.venue.long), { icon: baseIcon, title: e.name }); 
        //this.markerEvents[key].bindInfoWindowHtml("<strong>" + e.name + "</strong> " + e.venue.address);
        GEvent.addListener(this.markerEvents[key], "click", bind(this, "clickEventIcon", e.id));
        this.map.addOverlay(this.markerEvents[key]);
        //console.log('#event_box_' + e.id);
        $('#event_box_' + e.id).mouseover(bind(this, "overEventDiv", key)); 
        $('#event_box_' + e.id).mouseout(bind(this, "outEventDiv", key)); 
      }
    }
  }
  this.clickEventIcon = function (id){
    $("div[id*=event_box_]").hide(); 
    $('#event_box_' + id).fadeIn(380);
  }
  this.overEventDiv = function (key){
    //console.log("key: " + key);
    this.bounds = new GLatLngBounds;
    this.bounds.extend(this.currentLocation.getLatLng());
    this.bounds.extend(this.markerEvents[key].getLatLng());
    this.zoom = this.map.getBoundsZoomLevel(this.bounds, this.map.getSize()); //- 1 ;
    this.map.setZoom(this.zoom);
    this.map.setCenter(this.bounds.getCenter());
    for (var i in this.markerEvents) {
      if (i != key )
        this.markerEvents[i].hide();
      else
        this.markerEvents[i].show();
    }
    if (this.iterative)
      window.clearInterval(this.interval);
  }
  this.outEventDiv = function (key){
    //console.log("key: " + key);
    this.bounds = new GLatLngBounds;
    this.bounds.extend(this.currentLocation.getLatLng());
    for (var i in this.markerEvents) {
        this.markerEvents[i].show();
        this.bounds.extend(this.markerEvents[i].getLatLng());
    }
    this.zoom = this.map.getBoundsZoomLevel(this.bounds, this.map.getSize()); // - 1 ;
    this.map.setZoom(this.zoom);
    this.map.setCenter(this.bounds.getCenter());
    if (this.iterative)
      this.interval = window.setInterval(bind(this, "highlightMarker"), 3000);
  }
  this.findAddress = function () {
    var l = $.trim($('#geoLocation').val());
    if(l.length > 0) {
      $('#spinner').show();
      this.geoCoder.getLocations(l, bindargs(this, "readResponse"));
    }
  }
  this.readResponse = function (response){
    //console.log("response: " + response.Status.code);
    if (response && response.Status.code == 200) {
      var firstPoint;
      $('#map_results').empty();
      for (var key in response.Placemark) {
        //console.log("key:" + key + ", value: " + response.Placemark[key]);
        var place = response.Placemark[key];
        var address = place.address;
        //console.log("address :" + address);
        var lat = place.Point.coordinates[1];
        var lng = place.Point.coordinates[0];
        /* Deprecated google geocoding, usamos el nuestro
         var country_code = find_property_in_object(place.AddressDetails,'CountryNameCode');
        var cityTmp = find_property_in_object(place.AddressDetails,'LocalityName');
        var city = cityTmp ? cityTmp : '' ;
        if (key == 0) {
          this.currentLocation = new geoPoint( lat, lng, city, country_code, address);
        }
        */
        $('<a id="result_' + key + '" ' +
          'onclick="vmap.moveToPoint(new geoPoint(' + lat + ',' + lng + '))" ' + 
          'class="linkgris" >' + address + '</a><br/>'
        ).appendTo('#map_results');
      }
    } else {
        $("<p> No se encontraron resultados </p>").appendTo('#map_results');
    }
		if (typeof this.onSearchCompleted == "function") {
			this.onSearchCompleted($('#map_results'));
		}
  }
	this.onSearchCompleted = function () {}
  this.reverseGeocoding = function (){
    $.get("/cities/closest", {lat: this.currentLocation.lat, long: this.currentLocation.lng},bindargs(this,"reverseGeocodingSetData"),"json");
    //console.log(this.currentLocation.log());
  }
  this.reverseGeocodingSetData = function (data) {
    this.currentLocation.city_id = data.city_id;
    this.currentLocation.city_name = data.city_name;
    this.currentLocation.country_name = data.country_name;
    this.currentLocation.setAsCurrentLocation();
    this.markerUser.setLatLng(this.currentLocation.getLatLng());
    this.flashMessage("Ahora est&aacute;s aqu&iacute;! <br/>" + this.currentLocation.city_name + ', ' + this.currentLocation.country_name, 3500 );
    $('#spinner').hide();
  }
  this.moveToPoint = function (gPoint){
    this.currentLocation = gPoint;
    //this.currentLocation.log();
    this.map.setCenter(this.currentLocation.getLatLng(), 11);
    this.currentLocation.setAsCurrentLocation();
    this.reverseGeocoding();
  }
  this.dragEnd = function() {
    $('#spinner').show();
    this.currentLocation.lat = this.markerUser.getPoint().lat();
    this.currentLocation.lng = this.markerUser.getPoint().lng();
    this.currentLocation.setAsCurrentLocation();
    //reverse geo coding
    //desactivo el de google y activo el nuestro para garantizar resultado
    //this.geoCoder.getLocations(this.markerUser.getPoint(), bindargs(this, "readResponseReverse"));
    this.reverseGeocoding();
  }
  this.flashMessage = function (message, time) {
    this.markerUser.openInfoWindow(message);
    window.setTimeout(bind(this, "closeInfoWindow"), time);
  }
  this.closeInfoWindow = function () {
    this.markerUser.closeInfoWindow();
  }
  /* Deprecated google reverse geocoding
  this.readResponseReverse = function (response){
    //console.log("response: " + response.Status.code);
    if (response && response.Status.code == 200) {
      var place = response.Placemark[0];
      var cityTmp = find_property_in_object(place.AddressDetails,'LocalityName');
      if (cityTmp) {
        this.currentLocation.city = cityTmp;
        this.currentLocation.country_code = find_property_in_object(place.AddressDetails,'CountryNameCode');
        this.currentLocation.setAsCurrentLocation();
      } else {
        $.get("/cities/closest", {lat: this.currentLocation.lat, long: this.currentLocation.lng},bindargs(this,"geoReverse"),"json");
      }
    } else {
      //TODO que hago si el reverse ni siquiera me responde???
      $.get("/cities/closest", {lat: this.currentLocation.lat, long: this.currentLocation.lng},bindargs(this,"geoReverse"),"json");
    }
    this.currentLocation.city = data.city;
    this.currentLocation.country_code = data.country_code;
    this.currentLocation.setAsCurrentLocation();
    //console.log(this.currentLocation.log());
  }*/
}

