if (! Clip ) var Clip = {};
Clip.Map = {};

Clip.Map = Class.create();
Clip.Map.prototype = {
  initialize : function(lat, lng, zoom) {
    this.lat  = parseFloat(lat);
    this.lng  = parseFloat(lng);
    this.zoom = parseInt(zoom);
    if (arguments.length != 0) {
      this.renderMap();
      this.addEvents();
    }
  },
  renderMap: function() {
    var gmap = new GoomapMapMainControl($("map"), parseInt($("map").style.width), parseInt($("map").style.height));
    gmap.setCenterMarkStyle(1);
    gmap.setDblClickScroll(false);
    if ($("gMAPzoom1")) {
      gmap.addController(new GoomapSliderMiniBar($("gMAPzoom1")));
    }  else if ($("gMAPzoom2")) {
      gmap.addController(new GoomapSliderMainBar($("gMAPzoom2")));
    }
    gmap.refreshView(new GoomapPoint(
      GoomapTransUnit.trans_deg2ms(this.lng),
      GoomapTransUnit.trans_deg2ms(this.lat)), this.zoom);
    this.gmap = gmap;
  },
  renderIcon : function(marker) {
    this.gmap.addOverlay(marker.createIcon());
  },
  setCenter : function(lat, lng) {
    lat = GoomapTransUnit.trans_deg2ms(lat);
    lng = GoomapTransUnit.trans_deg2ms(lng);
    this.gmap.setViewCenter(new GoomapPoint(lng, lat));
  },
  addEvents : function() {
    this.gmap.attachEventListener('click', function(state, point, param) {
      this.clickEvent(state, point, param);
    }.bind(this));
    this.gmap.attachEventListener('scrollstart', function() {
      this.moveEvent();
    }.bind(this));
    this.gmap.attachEventListener('scrollend', function() {
      this.moveendEvent();
    }.bind(this));
    this.gmap.attachEventListener('areazoom', function(old_zoom, new_zoom) {
      this.zoomEvent(old_zoom, new_zoom);
    }.bind(this));
  },
  // Events
  clickEvent : function(state, point, param) {
    // do nothing
  },
  moveEvent : function() {
    // do nothing
  },
  moveendEvent : function() {
    this.lat = GoomapTransUnit.trans_ms2deg(this.gmap.getViewCenter().x);
    this.lng = GoomapTransUnit.trans_ms2deg(this.gmap.getViewCenter().y);
  },
  zoomEvent : function(old_zoom, new_zoom) {
    this.zoom = new_zoom;
  }
}

// マーカークラス
Clip.Map.Marker = Class.create();
Clip.Map.Marker.prototype = {
  initialize : function(lat, lng, html) {
    this.image = "http://www.shonan-clip.jp/image/map/icn_white.png";
    this.point = new GoomapPoint(GoomapTransUnit.trans_deg2ms(parseFloat(lng)),
                      GoomapTransUnit.trans_deg2ms(parseFloat(lat)));
    this.html = html || undefined; 
  },
  setIcon : function(type) {
    var file;
    switch(type) {
      case "surfer"   : file  = "map_town_profile";  break;
      case "gourmet"  : file  = "map_town_gourmet";  break;
      case "hospital" : file  = "map_town_hospital"; break;
      case "event"    : file  = "map_town_event";    break;
      case "leisure"  : file  = "map_town_leisure";  break;
      case "lesson"   : file  = "map_town_lesson";   break;
      case "shop"     : file  = "map_town_shop";     break;
      case "school"   : file  = "map_town_school";   break;
      case "house"    : file  = "map_town_house";         break;
      case "town"     : file  = "icn_town";          break;
      case "photo"    : file  = "icn_special";       break;
      case "album"    : file  = "icn_album";         break;
      case "blog"     : file  = "icn_blog";          break;
      case "forum"    : file  = "icn_forum";         break;
      default         : file  = "icn_white";
    }
    this.image = "http://www.shonan-clip.jp/image/map/" + file + ".png";
  },
  createIcon : function() {
    this.gmarker = new GoomapMarker(this.point, this.image, 
      new GoomapMarkerStyle("http://www.shonan-clip.jp/image/map/icn_shadow.png", 1), 10, 39);
    if (this.html) {
      this.gmarker.attachEventListener("click", function() {
        this.tipsWindow();
      }.bind(this), null);
    }
    return this.gmarker;
  },
  setPoint : function(point) {
    this.point = point;
  },
  getPoint : function() {
    return this.point;
  },
  tipsWindow : function() {
    if (this.html) {
      var tips = new GoomapTipsParam("gmap", -127, -270);
      tips.attachHTMLText(this.html);
      this.gmarker.openTipsWindow(tips);
      $('gmap').style['height'] = "245px"; //XXX
    }
  }
}

// タウン情報表示 (検索結果)
Clip.Map.Render = Class.create();
Clip.Map.Render.prototype = Object.extend(new Clip.Map, {
  initialize : function() {
    Clip.Map.prototype.initialize.apply(this, arguments);
  }
});

// 近辺タウン情報表示 (登録なし)
Clip.Map.RenderNearMap = Class.create();
Clip.Map.RenderNearMap.prototype = Object.extend(new Clip.Map, {
  initialize : function() {
    Clip.Map.prototype.initialize.apply(this, arguments);
    this.markers = $H();
  },
  clearMarker : function() {
    if (this.pin) {
      this.gmap.removeOverlay(this.pin.gmarker);
      this.pin = undefined;
    }
  },
  moveendEvent : function() {
    this.renderNearIcons();
  },
  renderNearIcons : function() {
    var bounds = this.gmap.getViewBounds();

    // 表示範囲外のマーカーを削除
    var in_markers = $H();
    this.markers.each(function(e){
      var id = e[0];
      var marker = e[1];
      if (marker.point.x < bounds.westbc
           || marker.point.x > bounds.eastbc
           || marker.point.y < bounds.southbc
           || marker.point.y > bounds.northbc) {
        this.gmap.removeOverlay(marker.gmarker);
      } else {
        in_markers[id] = marker;
      }
    }.bind(this));
    this.markers = in_markers;

    // URL の構築
    var url = '/rest/map/location?';
    if (this.category)
      url = url + 'category=' + this.category + '&';
    if (this.admin_category)
      url = url + 'admin_category=' + this.admin_category + '&';
    if (this.rows) 
      url = url + 'rows=' + this.rows + '&';
    var q = $H({
      min_lat: GoomapTransUnit.trans_ms2deg(bounds.southbc),
      min_lng: GoomapTransUnit.trans_ms2deg(bounds.westbc),
      max_lat: GoomapTransUnit.trans_ms2deg(bounds.northbc),
      max_lng: GoomapTransUnit.trans_ms2deg(bounds.eastbc),
      zlevel: this.zoom || this.gmap.getZoomLevel(),
      format: 'json'
    });
    url = url + q.toQueryString();

    // 未描画のマーカーを描画
    new Ajax.Request(
      url, 
      { method: 'get', 
        onSuccess: function(request){
          if (request.responseText == '{}') return;
          var locations = eval( '(' + request.responseText + ')' );
          locations.markers.each(function(location) {
            if (this.markers[location.id] != undefined) throw $continue;
            var category = (location.category_name_roma || this.category);
            var tt =  category + '.tt';
            var html = '<div class="gMAPbot"><img src="/image/about/whiteblue_close.gif" alt="閉じる" name="gmap_bot" width="25" height="25" id="gmap_bot" onClick="map.gmap.closeTipsWindow();" onMouseOver="MM_swapImage(\'gmap_bot\',\'\',\'/image/about/whiteblue_close_f2.gif\',1);" onMouseOut="MM_swapImgRestore();"></div>\n';
            var html = html + Jemplate.process(tt, { mode: 1, individual: 1, search: 1, result: [location] });
            var marker = new Clip.Map.Marker(location.lat, location.lng, html); 
            if (this.pin && (marker.point.x == this.pin.point.x) && (marker.point.y == this.pin.point.y)) 
              throw $continue;
            marker.setIcon(category);
            this.renderIcon(marker);
            this.markers[location.id] = marker;
          }.bind(this));
        }.bind(this)
      }
    );
  }
});

// タウン情報登録
Clip.Map.Assign = Class.create();
Clip.Map.Assign.prototype = Object.extend(new Clip.Map.RenderNearMap, {
  initialize : function() {
    Clip.Map.RenderNearMap.prototype.initialize.apply(this, arguments);
  },
  clickEvent : function(state, point, param) {
    if (this.pin) {
      this.gmap.removeOverlay(this.pin.gmarker);
    }
    this.pin = new Clip.Map.Marker();
    this.pin.point = point;
    this.renderIcon(this.pin);
    assign();
  }
});

