var AMEXMapControls = Class.create({});

Object.extend(AMEXMapControls, {
    TYPES: {
        HYB_ID: 'mapTypeHybrid',
        MAP_ID: 'mapTypeMap',
        SAT_ID: 'mapTypeSatellite'
    },
    /*********************************************************************************
     *
     *      DO NOT EDIT BELOW THIS LINE
     *
     *********************************************************************************/
    TYPES_TPL: new Template('<div id="mapcontrols"><div id="#{SAT_ID}" class="sat"><p>#{satellite}</p></div><div id="#{HYB_ID}" class="hyb"><p>#{hybrid}</p></div><div id="#{MAP_ID}" class="map"><p>#{map}</p></div></div>'),
    CONTROLS_TPL: new Template('<div id="#{CONTAINER_ID}"><div id="pannorth" class="pan"></div><div id="paneast" class="pan"></div><div id="pansouth" class="pan"></div><div id="panwest" class="pan"></div><div id="zoomin"></div><div src="#{ZOOM_OUT}" id="zoomout"></div><div id="#{ZOOMMETER_ID}"></div><div id="#{ZOOMSLIDER_ID}"></div></div>'),
    CONTROLS: {
        ZOOMIN_ID: 'zoomin',
        ZOOMOUT_ID: 'zoomout',
        ZOOMSLIDER_ID: 'zoomslider',
        ZOOMMETER_ID: 'zoommeter',
        CONTAINER_ID: 'zoomcontrol',
        PAN_CLASS: 'pan'
    }
});

AMEXMapControls.addMethods({
    initialize: function(parent) {
        this.parent = parent;
        this.parentMap = this.parent.map;

        Object.extend(Lang.STRINGS, AMEXMapControls.TYPES);

        $(AMEXMap.MAP_ELEMENT_ID).insert(AMEXMapControls.TYPES_TPL.evaluate(Lang.STRINGS));
        $(AMEXMap.MAP_ELEMENT_ID).insert(AMEXMapControls.CONTROLS_TPL.evaluate(AMEXMapControls.CONTROLS));

        $(AMEXMapControls.TYPES.MAP_ID).down().observe('click', this.clickType.bindAsEventListener(this));
        $(AMEXMapControls.TYPES.HYB_ID).down().observe('click', this.clickType.bindAsEventListener(this));
        $(AMEXMapControls.TYPES.SAT_ID).down().observe('click', this.clickType.bindAsEventListener(this));

        this.dragSliderListener   = this.dragSlider.bindAsEventListener(this);
        this.placeSliderListener  = this.placeSlider.bindAsEventListener(this);


        this.slider = $(AMEXMapControls.CONTROLS.ZOOMSLIDER_ID);

        $(AMEXMapControls.CONTROLS.CONTAINER_ID).select('.'+AMEXMapControls.CONTROLS.PAN_CLASS).invoke('observe', 'click', this.pan.bindAsEventListener(this));

        $(AMEXMapControls.CONTROLS.ZOOMIN_ID).observe('click', this.zoomIn.bindAsEventListener(this));
        $(AMEXMapControls.CONTROLS.ZOOMOUT_ID).observe('click', this.zoomOut.bindAsEventListener(this));

        $(AMEXMapControls.CONTROLS.ZOOMSLIDER_ID).observe('mousedown', this.clickSlider.bindAsEventListener(this));
        MQEventManager.addListener(this.parentMap, 'zoomend', this.setSliderPosition.bindAsEventListener(this));

        this.setSliderPosition();
    },
    clickType: function(event) {
        this.setMapByType(event.target.up().className);
    },
    setMapByType: function(type) {
        this.parentMap.setMapType(type);
        document.fire('maptype:change');
    },
    setSliderPosition: function() {
      var moveTo = -Math.floor(this.parentMap.getZoomLevel()*4.875)+150;

      this.slider.setStyle({ top: moveTo+'px' });
      document.fire('zoom:change');
    },
    setZoomFromSlider: function() {
      var slidePos = parseInt(this.slider.getStyle('top'), 10);

      var zoomTo = -(Math.floor(slidePos/4.875)+14)+45;
      this.parentMap.setZoomLevel(zoomTo);

      if(this.parent) { this.parent.setModel('zoom', zoomTo); }
      document.fire('zoom:change');
    },
    clickSlider: function(event) {
      $('zoomslider').stopObserving('mousedown');

      document.observe('mousemove', this.dragSliderListener);
      document.observe('mouseup', this.placeSliderListener);
    },
    dragSlider: function(event) {
      var newPos = event.clientY-$('zoomcontrol').cumulativeOffset()[1]+$('zoomcontrol').cumulativeScrollOffset()[1];

      if(newPos >= parseInt($('zoommeter').getStyle('top'), 10) &&
        newPos <= ($('zoommeter').getHeight()+parseInt($('zoommeter').getStyle('top'), 10))
      ) {
        this.slider.setStyle({ top: newPos+'px' });
      }
    },
    placeSlider: function(event) {
      this.setZoomFromSlider();

      $('zoomslider').observe('mousedown', this.clickSlider.bindAsEventListener(this));

      document.stopObserving('mousemove', this.dragSliderListener);
      document.stopObserving('mouseup', this.placeSliderListener);
    } ,
    pan: function(event) {
      var direction = event.element().id;
      this.panByDirection(direction);
    },
    panByDirection: function(direction) {
      /*
        TODO Paul - fix panning over the "edge of the world" pacific ocean where we reset to 0
        TODO Paul - return case for going off the top and bottom poles
      */
      var lat = this.parentMap.getCenter().lat;
      var lng = this.parentMap.getCenter().lng;

      // calculate the pan distance as half the width/height of the current view
      var latPan = Math.abs(this.parentMap.getBounds().ul.lat - this.parentMap.getBounds().lr.lat)/2;
      var lngPan = Math.abs(this.parentMap.getBounds().ul.lng - this.parentMap.getBounds().lr.lng)/2;

      switch(direction) {
        case "pannorth" :
          lat = lat+latPan;
        break;
        case "paneast" :
          lng = lng+lngPan;
        break;
        case "pansouth" :
          lat = lat-latPan;
        break;
        case "panwest" :
          lng = lng-lngPan;
        break;
        default :
          lat = 0;
          lng = 0;
        break;
      }

      this.parentMap.panToLatLng(new MQLatLng(lat, lng));
    },
    zoomIn: function() {
      var currentZoomLevel = this.parentMap.getZoomLevel();

      // Check valid zoom level
      if(currentZoomLevel == 16) { return; }

      currentZoomLevel++;

      if(this.parent) { this.parent.setModel('zoom', currentZoomLevel); }
      this.parentMap.setZoomLevel(currentZoomLevel);
      if(Prototype.Browser.WebKit) {
          this.parentMap.getDeclutter().setDeclutterMode(0);
          this.parentMap.getDeclutter().setDeclutterMode(2);
      }
      this.setSliderPosition();
    },
    zoomOut: function() {
      var currentZoomLevel = this.parentMap.getZoomLevel();

      // Check valid zoom level
      if(currentZoomLevel == 1) { return; }

      currentZoomLevel--;

      if(this.parent) { this.parent.setModel('zoom', currentZoomLevel); }
      this.parentMap.setZoomLevel(currentZoomLevel);
      if(Prototype.Browser.WebKit) {
          this.parentMap.getDeclutter().setDeclutterMode(0);
          this.parentMap.getDeclutter().setDeclutterMode(2);
      }
      this.setSliderPosition();
    }
});

