/**
 * gmap.js
 * gmap class
 * @author okm
 */
  var path="/";

  // marker add zindex processes 
  function importanceOrder(marker,b) {
      return GOverlay.getZIndex(marker.getPoint().lat()) + marker.importance*10000;
  }
  function normalOrder(marker,b) {
      return 1;
  }
  function inverseOrder(marker,b) {
      return -GOverlay.getZIndex(marker.getPoint().lat());
  }

  // MillMap Class
  function MillMap(){
      var ref = this;
 
      /* private */
      this.map = null;         // GMap2
      this.geocoder = null;    // GClientCeocoder
      this._inputMarker = null;

      this._spotList = new Array();

      this._customInfoDIV = null;
      this._customInfoMsgDIV = null;
      this._customInfoWindow = null;

      /* public */
      this.zoom = null;
      this.selected_spot = null;
      this.inputMarker_draggable = true;

      /* public stmap events */
      this.onMove = null;
      this.onClick = null;
      this.onMoveStart = null;
      this.onMoveEnd = null;
      this.onZoomEnd = null;
      this.onMapTypeChanged = null;

      // spot marker event
      this.onSpotMarkerMouseOver = null;
      this.onSpotMarkerMouseOut = null;

      // ! this is string param
      this.onSpotMarkerWindowClickFunc = null;

      this.onSearch = null;
      this.onSearchFail = null;

      this.onInputMarkerClick = null;
      this.onInputMarkerSet = null;
      this.inputMarkerMouseOver = null;
      this.inputMarkerMouseOut = null;
      this.inputMarker_visible = false;

      this.viewIconList = new Array();

      /* insert icon */
      this.insertIcon = new GIcon();
      this.insertIcon.image = path+"common/map/add_flag.gif";
      this.insertIcon.shadow = path+"common/map/flag_shadow.png";
      this.insertIcon.iconSize = new GSize(35,35);
      this.insertIcon.iconAnchor = new GPoint(2,34);

      /* spot icon"s" */
      //this.spotIcon = new GIcon(G_DEFAULT_ICON);
      this.spotIcon_Studio = new GIcon();
      this.spotIcon_Studio.image = path+"common/map/spot_icon.png";
      this.spotIcon_Studio.shadow = path+"common/map/spot_shadow.png";
      this.spotIcon_Studio.iconSize = new GSize(35,35);
      this.spotIcon_Studio.iconAnchor = new GPoint(17,35);

      this.spotIcon_Hall = new GIcon();
      this.spotIcon_Hall.image = path+"common/map/spot_hall.png";
      this.spotIcon_Hall.shadow = path+"common/map/spot_shadow.png";
      this.spotIcon_Hall.iconSize = new GSize(35,35);
      this.spotIcon_Hall.iconAnchor = new GPoint(17,35);

      this.spotIcon_Street = new GIcon();
      this.spotIcon_Street.image = path+"common/map/spot_street.png";
      this.spotIcon_Street.shadow = path+"common/map/spot_shadow.png";
      this.spotIcon_Street.iconSize = new GSize(35,35);
      this.spotIcon_Street.iconAnchor = new GPoint(17,35);
      
      /** functions **/
      this.initMap = function(initObj) {
          if (GBrowserIsCompatible()) {
	      var defLat = 35.67431;
	      var defLng = 139.69082;
	      var defZoom = 13;
              this.zoom = defZoom;

              var map_id = "map";
              if(initObj.id != null) map_id = initObj.id;

              this.map = new GMap2(document.getElementById(map_id));

              this.geocoder = new GClientGeocoder();

              for(var item in initObj){
		  var value = initObj[item];
                  if(item == "mapTypeControl"){
		      if(value != false){
			  var ctrlObj = new GMapTypeControl();
			  var pos = new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(5, 15));
			  this.map.addControl(ctrlObj, pos);
		      }
		  }else if(item == "mapControl"){
		      if(value == "small"){
			  var ctrlObj = new GSmallMapControl();
			  this.map.addControl(ctrlObj);
		      }else if(value == "large"){
			  var ctrlObj = new GLargeMapControl();
			  this.map.addControl(ctrlObj);
		      }
		  }else if(item == "lng"){
		      if(!isNaN(value)) defLng = value;
		  }else if(item == "lat"){
		      if(!isNaN(value)) defLat = value;
		  }else if(item == "zoom"){
		      if(!isNaN(value) && value >= 0 && value < 20){
			  defZoom = value;
		      }
		  }
		  this[item] = initObj[item];
              }

	      /* add event to map */
	      //GEvent.addListener(this.map, "move",           this._onMoveHandler );
	      GEvent.addListener(this.map, "click",          this._onClickHandler );
	      //GEvent.addListener(this.map, "movestart",      this._onMoveStartHandler );
	      GEvent.addListener(this.map, "moveend",        this._onMoveEndHandler );
	      GEvent.addListener(this.map, "dragend",        this._onDragEndHandler );
	      GEvent.addListener(this.map, "zoomend",        this._onZoomEndHandler );
	      //GEvent.addListener(this.map, "maptypechanged", this._onMapTypeChangedHandler );
	      var markerInitObj = new Object;
	      markerInitObj.draggable = this.inputMarker_draggable;
	      markerInitObj.icon = this.insertIcon;
	      markerInitObj.zIndexProcess = importanceOrder;
	      this._inputMarker =  new GMarker(new GLatLng(defLat,defLng), markerInitObj);
	      this._inputMarker.importance = 1000;
              GEvent.addListener(this._inputMarker, 'click', this._onInputMarkerClickHandler);
              GEvent.addListener(this._inputMarker, 'mouseover', this._onInputMarkerMouseOverHandler);
              GEvent.addListener(this._inputMarker, 'mouseout', this._onInputMarkerMouseOutHandler);
              GEvent.addListener(this._inputMarker, 'dragstart', this._onInputMarkerDragStartHandler);
              GEvent.addListener(this._inputMarker, 'dragend', this._onInputMarkerDragEndHandler);
              this.map.setCenter(new GLatLng(defLat, defLng),Number(defZoom));
	  }
      }
      
      this.viewSpotMarkerCenter = function(){
          this.viewInputMarkerCenter();
/*
          var markerInitObj = new Object;
          markerInitObj.draggable = this.inputMarker_draggable;
          markerInitObj.icon = this.insertIcon;
          markerInitObj.zIndexProcess = importanceOrder;
          var marker =  new GMarker(this.map.getCenter(), markerInitObj);
          this.map.addOverlay(marker);
*/
      }

      this.targetIdMarkerCenter = function(spot_id){
          for(var i = 0; i < this.viewIconList.length; i++){
              if(this.viewIconList[i].spot_id == spot_id){
                  this.map.setCenter(this.viewIconList[i].getPoint());
                  break;
              }
          }
      }
      
      this.targetIdMarkerClick = function(spot_id){
          for(var i = 0; i < this.viewIconList.length; i++){
              if(this.viewIconList[i].spot_id == spot_id){
                  this.onSpotMarkerClickHandler(this.viewIconList[i]);
                  break;
              }
          }
      }

      this.setCustomInfoWindow = function( div, message_div){
          var map = this.map;
          this._customInfoDIV = div;
          this._customInfoMsgDIV = message_div;
          function customBox(){}
          customBox.prototype = new GOverlay();
          customBox.prototype.initialize = function(map){
              ref.map.getPane(G_MAP_MARKER_PANE).appendChild(ref._customInfoDIV);
              ref._customInfoDIV.style.zIndex = 36000000;
          }
          customBox.prototype.remove = function() {
                ref.map.getPane(G_MAP_MARKER_PANE).removeChild(ref._customInfoDIV);
          }
          customBox.prototype.copy = function() {
              return new customBox();
          }
          customBox.prototype.redraw = function(force){}
          this._customInfoWindow = new customBox();
          this.map.addOverlay(this._customInfoWindow);  
      }

      this.viewCustomInfoWindow = function(msg){
      }

      // get south west edge point of map.
      this.getSouthWest = function(){
	  var bounds = this.map.getBounds();
          return this.parseLatLng(bounds.getSouthWest());
      }

      // search from area and move map. and call onSearch or onSearchFail event.
      this.searchAndView = function(areaString){
	  if(this.geocoder){
	      this.geocoder.getLatLng(
		  areaString,
		  this._onSearchHandler
              )
	  }
      }

      // view marker
      this.viewInputMarkerCenter = function(){
          if(this.getZoom() < 16) this.setZoom(16);
	  if(this.inputMarker_visible == false){
	      this.map.addOverlay(this._inputMarker,{zIndexProcess:importanceOrder});
//	      this.map.addOverlay(this._inputMarker);
	      this.inputMarker_visible = true;
	  }
	  this._inputMarker.setPoint(this.map.getCenter());
      }
      this.closeInputMarker = function(){
          this.inputMarker_visible = false;
	  this.map.removeOverlay(this._inputMarker);
      }

      this.moveMapToInputMarkerCenter = function(){
	  if(this.inputMarker_visible){
	      this.map.setCenter(this._inputMarker.getPoint());
	  }
      }
      this.getInputMarkerPoint = function(){
	  if(this.inputMarker_visible){
	      return this.parseLatLng(this._inputMarker.getPoint());
	  }
	  return null;
      }

      this.clearSpots = function(){
          for(var i = 0; i < this.viewIconList.length; i++){
	      this.map.removeOverlay(this.viewIconList[i]);
	  }
      }

      // view spots
      this.viewSpots = function( spots ){
	  this.clearSpots();
	  this.viewIconList = new Array;
          var markers;
	  var i = 0;
          for( i = 0;  i < spots.length; i++){
              var spotMarker = null
              switch(spots[i].division){
                  case "ホール":
                     spotMarker = new GMarker(new GLatLng(spots[i].lat,spots[i].lng), { icon : this.spotIcon_Hall, draggable :false} );
                     break;
                  case "ストリート":
                     spotMarker = new GMarker(new GLatLng(spots[i].lat,spots[i].lng), { icon : this.spotIcon_Street, draggable :false} );
                     break;
                  case "スタジオ":
                  default:
                     spotMarker = new GMarker(new GLatLng(spots[i].lat,spots[i].lng), { icon : this.spotIcon_Studio, draggable :false} );
                     break;
              }
	      this.map.addOverlay(spotMarker);
	      this.viewIconList.push(spotMarker);
              var ref = this;
              spotMarker.name = spots[i].name;
              spotMarker.spot_id = spots[i].spot_id;
              spotMarker.type = spots[i].type;
              GEvent.addListener(spotMarker, "click", this._onSpotMarkerClickHandler);
//              GEvent.addListener(spotMarker, "mouseover", this._onSpotMarkerMouseOverHandler);
//              GEvent.addListener(spotMarker, "mouseout", this._onSpotMarkerMouseOutHandler);
          }
	  if(this.inputMarker_visible == true){
	      this.inputMarker_visible = true;
	  }
	  return;
      }

      this.parseLatLng = function(point){
          var retPoint = new Object;
          retPoint.lat = point.lat();
          retPoint.lng = point.lng();
          return retPoint;
      }

      this.openInputMarkerInfoWindowHTML = function(htmlText){
	  var opt = this.map.getInfoWindow();
	  opt.maxWidth = 200;
	  opt.maxHeight = 50;

	  this.map.openInfoWindowHtml(this._inputMarker.getPoint(), htmlText, { pixelOffset: new GSize(12, -30) });
      }

      this.openInputMarkerInfoWindow = function(text){
	  this.map.openInfoWindow(this._inputMarker.getPoint(), text, { pixelOffset: new GSize(12, -30) });
      }

      this.openInputMarkerBlowup = function(){
	  //this.map.openInfoWindow(this._inputMarker.getPoint(), text, { pixelOffset: new GSize(12, -30) });
	  this.map.showMapBlowup(this._inputMarker.getPoint(), { pixelOffset: new GSize(12, -30), mapType : G_NORMAL_MAP, zoomLevel : 18 });
      }

      this.closeInfoWindow = function(){
	  this.map.closeInfoWindow();
      }

      /////////////////////////////////////////////////////////////////////////////////////////

      /* Wrapper */

      // get center point of map.
      this.getCenter = function(){
	  return this.parseLatLng(this.map.getCenter());
      }

      this.setCenter = function(lat, lng, zoom, map_type){
          if(zoom == null) zoom = this.getZoom();
          if(map_type == null) map_type = G_NORMAL_MAP;
          this.map.setCenter(new GLatLng(lat,lng), Number(zoom), map_type);
      }

      // get zoom level
      this.getZoom = function(){
	  return this.map.getZoom();
      }

      this.setZoom = function(level){
          this.map.setZoom(level);
      }

      this.zoomIn = function(){
	  this.map.zoomIn();
      }

      this.zoomOut = function(){
          this.map.zoomOut();
      }

      this.getMaximumResolution = function(){
          return this.map.getCurrentMapType().getMaximumResolution();
      }

      this.getMinimumResolution = function(){
          return this.map.getCurrentMapType().getMinimumResolution();
      }

      // get north east edge point of map.
      this.getNorthEast = function(){
          var bounds = this.map.getBounds();
          return this.parseLatLng(bounds.getNorthEast());
      }

      this.enableDragging = function(){
          this.map.enableDragging();
      }

      this.disableDragging = function(){
          this.map.disableDragging();
      }

      /////////////////////////////////////////////////////////////////////////////////////////

      /* Events */
      
      /* change scope location */
      // map event
      this._onMoveHandler = function(){ref.onMoveHandler();}
      this._onClickHandler = function(){ref.onClickHandler();}
      this._onMoveStartHandler = function(){ref.onMoveStartHandler();}
      this._onMoveEndHandler = function(){ref.onMoveEndHandler();}
      this._onDragEndHandler = function(){ref.onDragEndHandler();}
      this._onZoomEndHandler = function(){ref.onZoomEndHandler();}
      this._onMapTypeChangedHandler = function(){ref.onMapTypeChangedHandler();}

      // geocoder event
      this._onSearchHandler = function(point){ref.onSearchHandler(point);}

      // marker event
      this._onInputMarkerClickHandler = function(){ref.onInputMarkerClickHandler();}
      this._onInputMarkerMouseOverHandler = function(){ref.onInputMarkerMouseOverHandler();}
      this._onInputMarkerMouseOutHandler = function(){ref.onInputMarkerMouseOutHandler();}
      this._onInputMarkerDragStartHandler = function(){ref.onInputMarkerDragStartHandler();}
      this._onInputMarkerDragEndHandler = function(){ref.onInputMarkerDragEndHandler();}

      this._onSpotMarkerClickHandler = function(){
	  var marker = this;
          ref.onSpotMarkerClickHandler(marker);
      }
      this._onSpotMarkerMouseOverHandler = function(){
          ref.onSpotMarkerMouseOverHandler(this);
      }
      this._onSpotMarkerMouseOutHandler = function(){
          ref.onSpotMarkerMouseOutHandler(this);
      }

      // map event
      this.onMoveHandler = function(){
          if(this.onMove)this.onMove();
      }
      this.onClickHandler = function(){
          if(this.onClick)this.onClick();
      }
      this.onMoveStartHandler = function(){
          if(this.onMoveStart)this.onMoveStart();
      }
      this.onMoveEndHandler = function(){
          now_zoom = this.map.getZoom();          
          if(this.zoom != now_zoom && this._customInfoWindow != null){
              this.map.removeOverlay(this._customInfoWindow);  
              if(this.selected_spot != null) this.onSpotMarkerClickHandler(this.selected_spot);
          }
          this.zoom = now_zoom;
          if(this.onMoveEnd)this.onMoveEnd();
      }
      this.onDragEndHandler = function(){
          if(this.onDragEnd)this.onDragEnd();
      }
      this.onZoomEndHandler = function(){
          if(this.onZoomEnd)this.onZoomEnd();
      }
      this.onMapTypeChangedHandler = function(){
          if(this.onMapTypeChanged)this.onMapTypeChanged();
      }

      // geocoder event
      this.onSearchHandler = function(point){
	  if(!point){
	      this.onSearchFailHandler();
	  }else{
	      this.map.setCenter(point,14);
	      if(this.onSearch) this.onSearch(point);
	  }
      }

      this.onSearchFailHandler = function(point){
	  if(this.onSearchFail) this.onSearchFail();
      }
 
      // marker event
      this.onInputMarkerClickHandler = function(){
          if(this.onInputMarkerClick) this.onInputMarkerClick();
      }
      this.onInputMarkerMouseOverHandler = function(){
	  if(this.onInputMarkerMouseOver) this.onInputMarkerMouseOver();
      }
      this.onInputMarkerMouseOutHandler = function(){
	  if(this.onInputMarkerMouseOut) this.onInputMarkerMouseOut();
      }
      this.onInputMarkerDragStartHandler = function(){
      }
      this.onInputMarkerDragEndHandler = function(){
	  if(this.onInputMarkerDragEnd) this.onInputMarkerDragEnd();
      }

      this.onSpotMarkerMouseOverHandler = function(marker){
	  if(this.onSpotMarkerMouseOver) this.onSpotMarkerMouseOver(marker);
      }
      this.onSpotMarkerMouseOutHandler = function(marker){
	  if(this.onSpotMarkerMouseOut) this.onSpotMarkerMouseOut(marker);
      }

      this.onSpotMarkerClickHandler = function(marker){
	  // for click tougle
          if(this.selected_spot == marker) return this.closeCustomInfoWindow();

          this.selected_spot = marker;
          var marker_pixls = this.map.fromLatLngToDivPixel(marker.getPoint());
          // for millon specified
          // var msg = marker.name +  marker.type;
          var msg = marker.type + "<br/>";
          if(this.onSpotMarkerWindowClickFunc == null){
              msg += '<A href="'+ path +'spot/'+ marker.spot_id + '" style="color:#000000"><b>' + marker.name + "</b></A>";
          }else{
              msg += '<A href="#" onClick="' + this.onSpotMarkerWindowClickFunc + '(' + marker.spot_id  + ')" style="color:#000000;text-decoration:underline" ><b>' + marker.name + "</b></A>";
          }
          var x = marker_pixls.x - 22;
          var y = marker_pixls.y - 90;
          this.openCustomInfoWindow(msg, x, y);
      }

      this.openInputMarkerWindow = function(msg){
          var marker_pixls = this.map.fromLatLngToDivPixel(this._inputMarker.getPoint());
          var x = marker_pixls.x -5;
          var y = marker_pixls.y -90;
          this.openCustomInfoWindow(msg, x, y);
      }

      this.openCustomInfoWindow = function(msg, x, y){
          this.map.removeOverlay(this._customInfoWindow);  
          this._customInfoDIV.style.display = "block";
          this._customInfoDIV.style.zIndex = 4000000;
          this._customInfoDIV.style.top = y + "px";
          this._customInfoDIV.style.left = x + "px";
          this._customInfoMsgDIV.innerHTML = msg;
          this.map.addOverlay(this._customInfoWindow);

      }

      this.closeCustomInfoWindow = function(){
          this.selected_spot = null;
          this.map.removeOverlay(this._customInfoWindow);  
      }

  }
  window.onunload = GUnload;
