/**
 * Class handling the custom map navigation control
 */
function NavigationControll()
{
    this.directionHeight = 57;
    this.directionWidth = 57;

    this.indicatorsHeight = 13;

    this.scaleHeight = 100;
    this.scaleWidth = 45;
    this.scaleTopOffset = 34; // top zoom scale marker (offset from zoom scale image top)
    this.scaleBottomOffset = 35; // bottom zoom scale marker (offset/padding from bottom)

    this.zoomTop = this.directionHeight; // positioned right below the directions controll
    this.zoomLeft = (this.directionWidth - this.scaleWidth) / 2;

    this.sliderHeight = 15;
    this.sliderLeft = 2;

    this.scaleUsedHeight = this.scaleHeight - this.scaleTopOffset - this.scaleBottomOffset;
    this.maxZoom = 17;
    this.minZoom = 10;
    this.zoomLevels = 5;//this.maxZoom - this.minZoom + 1;
    this.zoomLevelHeight = this.scaleUsedHeight / (this.zoomLevels - 1);
    this.zoomValues = [17, 15, 13, 12, 10];
}

NavigationControll.prototype = new GControl();

/**
 * Returns the mouse click horiz. coordinate relative to the control layer
 */
NavigationControll.prototype.getEventRelativeX = function(event, element)
{
    var x = 0;
    
    if (document.all) {
      //MSIE
      x = event.offsetX;
    } else {
      x = event.layerX;
    }
    return x;
}

/**
 * Returns the mouse click vertical coordinate relative to the control layer
 */
NavigationControll.prototype.getEventRelativeY = function(event, element)
{
    var y = 0;
    if (document.all) {
      //MSIE
      y = event.offsetY;
    } else {
      y = event.layerY;
    }
    return y;
}

/**
 * Returns the zoom scale Y coordinate corresponding to the input zoom level (for positioning the slider)
 */
NavigationControll.prototype.zoomToScaleY = function(zoom)
{
    var result = this.scaleTopOffset + (this.zoomValues.indexOf(zoom) - this.zoomValues.indexOf(this.maxZoom)) * this.zoomLevelHeight;
    return result;
}

/**
 * Returns the zoom level corresponding to the input Y coordinate on the slider scale
 */
NavigationControll.prototype.scaleYToZoom = function(y)
{
    if (y < this.scaleTopOffset)
        return this.maxZoom; // top scale offset area - maps to max zoom

    if (y >= this.scaleHeight - this.scaleBottomOffset)
        return this.minZoom; // bottom scale offset area - maps to min zoom

    return this.zoomValues[parseInt((y - this.scaleTopOffset) / this.zoomLevelHeight)];
}

/**
 * Updates the slider's position with the current zoom level on map
 */
NavigationControll.prototype.updateSliderPosition = function(slider)
{
    var yPos = this.zoomToScaleY(this.map.getZoom()) - this.sliderHeight / 2;
    slider.style.top = yPos + 'px';
}

/**
 * Map movement/panning actions
 */
NavigationControll.prototype.moveUp = function()
{
    this.map.panDirection(0, +1);
}

NavigationControll.prototype.moveDown = function()
{
    this.map.panDirection(0, -1);
}

NavigationControll.prototype.moveLeft = function()
{
    this.map.panDirection(+1, 0);
}

NavigationControll.prototype.moveRight = function()
{
    this.map.panDirection(-1, 0);
}

NavigationControll.prototype.moveCenter = function()
{
}

/**
 * Control init founction -- lays out all elements and registers proper event callbacks
 */
NavigationControll.prototype.initialize = function(map)
{
    this.map = map;

    var container = document.createElement('div');

    // Contains the left, right, up, down, center arrows
    var directionDiv = document.createElement('div');
    directionDiv.style.position = 'absolute';
    directionDiv.style.left = '0px';
    directionDiv.style.top = '0px';

    var directionImg = document.createElement('img');
    this.directionImg = directionImg;
    directionImg.setAttribute('src', '/images/icons/navigator-direction.gif');
    directionImg.setAttribute('border', '0');
    directionImg.style.cursor = 'pointer';
    directionImg.style.position = 'absolute';
    directionImg.style.left = '0px';
    directionImg.style.top = '0px';

    directionDiv.appendChild(directionImg);
    
    // Contains the scale and the slider
    var zoomDiv = document.createElement('div');
    zoomDiv.style.position = 'absolute';
    zoomDiv.style.left = this.zoomLeft + 'px';
    zoomDiv.style.top = this.zoomTop + 'px';

    // Contains the zoom scale
    var scaleDiv = document.createElement('div');
    scaleDiv.style.position = 'absolute';
    scaleDiv.style.left = '0px';
    scaleDiv.style.top = '0px';
    scaleDiv.style.zIndex = '0'; // layered

    var scaleImg = document.createElement('img');
    this.scaleImg = scaleImg;
    scaleImg.setAttribute('src', '/images/icons/navigator-zoom.gif');
    scaleImg.style.cursor = 'pointer';
    scaleImg.style.position = 'absolute';
    scaleImg.style.left = '0px';
    scaleImg.style.top = '0px';

    scaleDiv.appendChild(scaleImg);
    zoomDiv.appendChild(scaleDiv);

    // Contains the slider indicating the curent zoom level
    var sliderDiv = document.createElement('div');
    sliderDiv.style.position = 'absolute';
    sliderDiv.style.left = '0px';
    sliderDiv.style.top = '0px';
    sliderDiv.style.zIndex = '1'; // layered

    var sliderImg = document.createElement('img');
    this.sliderImg = sliderImg;
    sliderImg.setAttribute('src', '/images/icons/navigator-pointer.gif');
    sliderImg.style.cursor = 'pointer';
    sliderImg.style.position = 'absolute';
    sliderImg.style.left = this.sliderLeft + 'px';
    this.updateSliderPosition(sliderImg);

    sliderDiv.appendChild(sliderImg);
    zoomDiv.appendChild(sliderDiv);

    // Add them to the controll div
    container.appendChild(directionDiv);
    container.appendChild(zoomDiv);
    //container.appendChild(indicatorsDiv);

    // Events
    var self = this;

    // listen to the map's zoom change event
    GEvent.addListener(map, "zoomend", function(prevZoom, currentZoom) {
      self.updateSliderPosition(sliderImg);
      //console.log("Zoom: from " + prevZoom + ' to ' + currentZoom);
    });
    
    // Direction buttons
    GEvent.addDomListener(directionImg, "click", function(event) {
        var x = self.getEventRelativeX(event, directionImg);
        var y = self.getEventRelativeY(event, directionImg);
        
        if (y > 18 && y < 39) // center line (left, right or center)
        {
            if (x < 18) // left
            {
                self.moveLeft();
            }
            else if (x > 40) // right
            {
                self.moveRight();
            }
            else // center
            {
                self.moveCenter();
            }
        }
        else if (x > 20 && x < 37) // center column (up or down)
        {
            if (y < 18) // up
            {
                self.moveUp();
            }
            if (y > 39)
            {
                self.moveDown();
            }
        }
    });

    // Scale click
    GEvent.addDomListener(scaleImg, "click", function(event) {
        var y = self.getEventRelativeY(event, scaleImg);
        if (y > 28 && y < 70) { // slider
            map.setZoom(self.scaleYToZoom(y));
            self.updateSliderPosition(sliderImg);
        }
        else
        {
            var x = self.getEventRelativeX(event, scaleImg);
            if (x > 14 && x < 32) {
                if (y > 7 && y < 25) {
                    if (map.getZoom() < self.maxZoom) {
                        map.setZoom(self.zoomValues[self.zoomValues.indexOf(map.getZoom()) - 1]); // replaced zoomIn by prev. zoom value in the allowed levels list
                        self.updateSliderPosition(sliderImg);
                    }
                }
                else if (y > 75 && y < 92) {
                    if (map.getZoom() > self.minZoom) {
                        map.setZoom(self.zoomValues[self.zoomValues.indexOf(map.getZoom()) + 1]); // replaced zoomOut by next zoom value in the allowed levels list
                        self.updateSliderPosition(sliderImg);
                    }
                }
            }
        }
  });

    // Slider dragging events
    GEvent.addDomListener(sliderImg, "mousedown", function() {
        return self.startDrag();
    });

    GEvent.addDomListener(sliderImg, "mouseup", function(event) {
        return self.endDrag(event)
    });

    GEvent.addDomListener(scaleImg, "mouseup", function(event) {
        return self.endDrag(event)
    });

    GEvent.addDomListener(scaleImg, "mouseout", function(event) {
        return self.endDrag(event);
    });

    GEvent.addDomListener(sliderImg, "mousemove", function(event) {
        return self.moveDrag(event);
    });

    GEvent.addDomListener(scaleImg, "mousemove", function(event) {
        return self.moveDrag(event);
    });

    GEvent.addDomListener(sliderImg, "dragover", function(event) {
        return self.moveDrag(event);
    });

    GEvent.addDomListener(scaleImg, "dragover", function(event) {
        return self.moveDrag(event);
    });

    map.getContainer().appendChild(container);
    return container;
}

/**
 * Event callback functions
 */
NavigationControll.prototype.startDrag = function()
{
    this.dragging = true;
}

NavigationControll.prototype.endDrag = function(event)
{
    if (!this.dragging){
        return;
    }
    this.dragging = false;

    var y = this.getEventRelativeY(event, this.scaleImg);
    this.map.setZoom(this.scaleYToZoom(y));
    this.updateSliderPosition(this.sliderImg);
}

NavigationControll.prototype.moveDrag = function(event)
{
    if (!this.dragging){
        return;
    }
    var y = this.getEventRelativeY(event, this.scaleImg);
    this.map.setZoom(this.scaleYToZoom(y));
    this.updateSliderPosition(this.sliderImg);
    return false;
}

NavigationControll.prototype.getDefaultPosition = function() {
    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(10, 10));
}

