/*
 * Google Maps Api を利用しやすくするためのライブラリ。
 * google maps と prototype.js の後に読み込む。
 *
 * Copyright (c) Spookies Co.,Ltd
 * http://www.spookies.co.jp
 */

var DEFAULT_MAP_OPTIONS = Object.extend({
  styleId:           'map',
  mapControl:        new GLargeMapControl(),
  hasSmallMap:       false,
  hasMapTypeControl: false,
  onMove:            Prototype.emptyFunction,
  onMoveEnd:         Prototype.emptyFunction,
  onAddOverlay:      Prototype.emptyFunction,
  onRemoveOverlay:   Prototype.emptyFunction,
  onClearOverlays:   Prototype.emptyFunction
}, {});

var DEFAULT_MARKER_OPTIONS = Object.extend({
  onClick:           Prototype.emptyFunction,
  onDblClick:     Prototype.emptyFunction
}, {});

/*
 * google maps api を利用して map をロードします。<br>
 * html を省略すると、onclick イベントは設定されません。
 * @param latitude 緯度
 * @param longitude 経度
 * @param zoom 倍率
 * @param onclick 時に表示する html
 * @param options
 * 
 */
function loadMap(latitude, longitude, zoom, html, options) {
  if (options) {
    options = $H(DEFAULT_MAP_OPTIONS).merge($H(options));
  }
  if (GBrowserIsCompatible()) {
    var newLatLng = convLatLng(latitude, longitude);
    var cLat = newLatLng.lat;
    var cLon = newLatLng.lng;
    var map = null;
    if (options) {
      map = new GMap2($(options.styleId));
      map.addControl(options.mapControl);
      if (options.hasMapTypeControl) {
        map.addControl(new GMapTypeControl());
      }
      if (options.hasSmallMap) {
        map.addControl(new GOverviewMapControl(new GSize(150,150)));
      }
    } else {
      map = new GMap2($("map"));
      map.addControl(new GSmallMapControl());
    }

    if (!zoom || zoom < 0 || zoom > 19) {
      zoom = 17;
    }
    map.setCenter(new GLatLng(cLat, cLon), zoom);

    if (html) {
      addMarker(map, latitude, longitude, null);
    }

    if (options) {
      GEvent.addListener(map, 'move', options.onMove.bindAsEventListener(this, map));
      GEvent.addListener(map, 'moveend', options.onMoveEnd.bindAsEventListener(this, map));
      // observe overlay events
      GEvent.addListener(map, "addoverlay", options.onAddOverlay.bindAsEventListener(this));
      GEvent.addListener(map, "removeoverlay", options.onRemoveOverlay.bindAsEventListener(this));
      GEvent.addListener(map, "clearoverlays", options.onClearOverlays.bindAsEventListener(this));
      GEvent.addListener ( map, 'zoomend', function ( oldZoomLevel, newZoomLevel ) {
        if ( newZoomLevel > 17 ) {
          map.setZoom ( 17 );
        }
      } );

    } else {
      GEvent.addListener(map, "moveend", function() {
        var center = map.getCenter();
        if ($("map_y")) {
          $("map_y").innerHTML = center.y;
        }
        if ($("map_x")) {
          $("map_x").innerHTML = center.x;
        }
        if ($("map_zoom")) {
          $("map_zoom").innerHTML = map.getZoom();
        }
      });
    }
    return map;
  }
}
/*
 * google map へマーカーを追加します。
 * html を省略すると、onclick イベントは設定されません。
 * @param map 地図
 * @param latitude 緯度
 * @param longitude 経度
 * @param onclick 時に表示する html
 * 
 */
function addMarker(map, latitude, longitude, html) {
  if (!map) {
    loadMap(latitude, longitude, null, html);
    return;
  }
  var newLatLng = convLatLng(latitude, longitude);
  var cLat = newLatLng.lat;
  var cLon = newLatLng.lng;

  var icon = new GIcon();
  icon.image = '/img/map/star.png';
  icon.printImage = '/img/map/star.gif';
  icon.iconSize = new GSize (15, 15);
  icon.iconAnchor = new GPoint (7, 7);
  icon.infoWindowAnchor = new GPoint (7, 7);

  var marker = new GMarker(new GLatLng(cLat, cLon), {icon:icon});
  map.addOverlay(marker);
  if (html) {
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowHtml(html);
    });
  }
}

function addShopMarker(map, shopJsonObj, options) {
  if (!map) {
    return;
  }
  if (options) {
    options = $H(DEFAULT_MARKER_OPTIONS).merge($H(options));
  }
  var shop = shopJsonObj.Shop;
  var newLatLng = convLatLng(shop.latitude, shop.longitude);
  var cLat = newLatLng.lat;
  var cLon = newLatLng.lng;
  var icon = new GIcon();
  icon.iconSize = new GSize (40, 52);
  icon.iconAnchor = new GPoint (21, 51);
  icon.infoWindowAnchor = new GPoint (30, 18);

  var image_url = IMAGE_URL + 'map/' + shop.area_file_genre_id;
  if (shop.rss_url) {
    if (shop.hasLatestBlogEntry) {
      image_url += 'l';
    } else {
      image_url += 'b';
    }
  }
  if (shop.hasCoupon) {
    image_url += 'c';
  }
  image_url += '.gif';

  icon.image = icon.printImage = image_url;

  var marker = new GMarker(new GLatLng(cLat, cLon), {icon:icon});
  marker.shopJson = shopJsonObj;
  map.addOverlay(marker);
  if (options) {
    GEvent.addListener(marker, 'click', options.onClick.bindAsEventListener(this, marker));
    GEvent.addListener(marker, 'dblclick', options.onDblClick.bindAsEventListener(this, marker));
  }
  return marker;
}

/*
 * 旧形式の緯度・経度を新しい形式の緯度・経度へコンバートします。<br>
 * @param 緯度（lat）・経度（lng）の連想配列
 * @return 新しい形式の連想配列
 */
function convLatLng(latitude, longitude) {
  var latArray = latitude.split(".");
  var lngArray = longitude.split(".");
  if (latArray.length < 3) {
    return {lat:latitude, lng:longitude};
  }
  latArray[2] = latArray[2] + "." + latArray[3];
  lngArray[2] = lngArray[2] + "." + lngArray[3];
  var lat = eval(latArray[0]) + eval(latArray[1]/60) + eval(latArray[2]/3600);
  var lng = eval(lngArray[0]) + eval(lngArray[1]/60) + eval(lngArray[2]/3600);
  lat = lat - lat * 0.00010695 + lng * 0.000017464 + 0.0046017;
  lng = lng - lat * 0.000046038 - lng * 0.000083043 + 0.010040;
  return {lat:lat, lng:lng};
}

/**
 * shop 画像の Url を取得します。
 * @param obj (json object|id)
 * @param type thumbnail_type
 */
function getShopImageUrl(obj, type) {
  var id = 0;
  // Shop property があるかどうかで json か判断
  if (obj != null && obj.Shop) {
    id = obj.Shop.shop_image1_id;
  } else {
    id = obj;
  }
  if (!id) {
    return IMAGE_URL + SHOP_DEFAULT_IMAGE_URL;
  } else {
    if (type) {
      return TOP_URL + "img/shops/" + id + "/" + type;
    } else {
      return TOP_URL + "img/shops/" + id;
    }
  }
}

var LeafMap = Class.create();
LeafMap.prototype = {
  initialize : function(gmap) {
    this.map = gmap;
    this.markers = [];
    this.selected_area_id = null;
  },
  getMap : function() {
    return this.map;
  },
  getMarkers : function() {
    return this.markers;
  },
  addMarker : function(marker) {
    if (marker.getPoint() == null) {
      return;
    }
    for (var i=0;i<this.markers.length;i++) {
      var point = this.markers[i].getPoint();
      if (point.lat() == marker.getPoint().lat() && point.lng() == marker.getPoint().lng()) {
        return;
      }
    }
    this.markers.push(marker);
  },
  removeMarker : function(marker) {
    if (marker.getPoint() == null) {
      return;
    }
    for (var i=0;i<this.markers.length;i++) {
      var point = this.markers.getPoint();
      if (point.lat() == marker.getPoint().lat() && point.lng() == marker.getPoint().lng()) {
        this.markers.splice(i, 1);
      }
    }
  },
  clearMarkers : function() {
    this.map.clearOverlays();
    this.markers = [];
  }
}

function setMapLoadingOffset(mapElem, loadElem) {
  var map = $(mapElem);
  var loading = $(loadElem);
  Rico.Corner.round(loading);
  var y = document.body.scrollTop || document.documentElement.scrollTop;
  var cOffset = Position.cumulativeOffset (map);
  var map_dimensions = Element.getDimensions(map);
  var load_dimensions = Element.getDimensions(loading);
  loading.style.left = cOffset[0] + map_dimensions.width/2 - load_dimensions.width/2 + 'px';
  loading.style.top = cOffset[1] + map_dimensions.height/2 - load_dimensions.height/2 + 'px';
}

