/*
 * $Id: DSUtils.js 64408 2009-02-26 18:16:26Z kbauman $
 * $URL: https://build/subversion/DestinationSearch/ds-core-web/tags/ds-core-web-2.0.115/src/main/webapp/js/DSUtils.js $
 */
/*
 *
 */
function DSControls(){}
LMI.Lang.importFunctions( DSControls, LMI.Event );

/* DSControls.DSSlider */
/**
 * Creates a vertical slider control for the zoom bar
 *
 * @param map The map this slider is for
 * @param slider The image element for the slider
 * @param thumb The thumb image element
 * @constructor
 */
DSControls.DSSlider = function( slider, thumb ) {
    this.slider = slider;
    this.thumb = thumb;

    this.initEvents( 'startSlide', 'slide', 'endSlide' );

    LMI.BrowserEvent.preventEvent( this.slider, 'dblclick' );
    LMI.BrowserEvent.preventEvent( this.thumb, 'dblclick' );

    var o = {lockX:true};

    this.thumbDragger = new DSInteraction.Drag( this.thumb, o );
    this.thumbDragger.bindEvent( 'startDrag', this, this.startSlide );
    this.thumbDragger.bindEvent( 'endDrag', this, this.endSlide );
    this.thumbDragger.bindEvent( 'drag', this, this.slide );

    LMI.BrowserEvent.bind( this.slider, 'mousedown', this, this.sliderClick );
};
LMI.Lang.extend( DSControls.DSSlider, DSControls );
DSControls.DSSlider.prototype.initHeights = function() {
    if( ! this.usableHeight ) {
        this.usableHeight = this.slider.height - this.thumb.height;
        this.top = parseInt( this.slider.style.top );
        this.thumbDragger.options.minY = this.top;
        this.thumbDragger.options.maxY = this.top + this.usableHeight;
    }
};
DSControls.DSSlider.prototype.getPosition = function() {
    this.initHeights();
    var p = ( parseInt( this.thumb.style.top ) - this.top ) / this.usableHeight;
    return p;
};
DSControls.DSSlider.prototype.setPosition = function( p ) {
    this.initHeights();
    this.thumb.style.top = this.top + Math.round( p * this.usableHeight ) + 'px';
    return p;
};
DSControls.DSSlider.prototype.startSlide = function() {
    this.triggerEvent( 'startSlide', { position: this.getPosition() }, this );
};
DSControls.DSSlider.prototype.endSlide = function() {
    this.triggerEvent( 'endSlide', { position: this.getPosition() }, this );
};
DSControls.DSSlider.prototype.slide = function() {
    this.triggerEvent( 'slide', { position: this.getPosition() }, this );
};
DSControls.DSSlider.prototype.sliderClick = function( e ) {
    if( e.getMouseButton() === 0 ) {
        if( ! this.offsetTop ) {
            this.offsetTop = LMI.Element.getOffsets( this.slider.parentNode ).y;
        }
        var y = e.getPageY();
        this.thumb.style.top = ( y - this.offsetTop - ( this.thumb.height / 2 ) ) + 'px';
        this.thumbDragger.startDrag( e );
    }
};

/*
 *
 */
function DSCollection() {
    this.init();
}
DSCollection.prototype.init = function() {
    this.collection = [];
};
DSCollection.prototype.getLength = function() {
    return this.collection.length;
};
DSCollection.prototype.getByIndex = function( i ) {
    return this.collection[i];
};
DSCollection.prototype.push = function() {
    for( var i = 0; i < arguments.length; ++i ) {
        this.collection.push( arguments[i] );
    }
};
DSCollection.prototype.remove = function( index ) {
    this.collection.splice( index, 1 );
};
/*
 *
 */
function DSIterator( collection ) {
    this.pos = 0;
    this.collection = collection;
}
DSIterator.prototype.hasNext = function() {
    return this.pos < this.collection.getLength();
};
DSIterator.prototype.next = function() {
    if( this.hasNext() ) {
        return this.collection.getByIndex( this.pos++ );
    }
    var undef;
    return undef;
};

/*
 *
 */
function DSInteraction() { }
DSInteraction.Drag = function( el, options ) {
    this.init( el, options );
};
LMI.Lang.importFunctions( DSInteraction.Drag, LMI.Event );
DSInteraction.Drag.prototype.init = function( el, options ) {
    this.element = el;
    this.options = options || {};

    if ( LMI.Browser.browser == 'Explorer' ) {
        // disable IE's builtin drag functionality
        document.body.ondrag = function () { return false; };
    }
    this.handle = this.options.handle || this.element;

    this.initEvents( 'startDrag', 'drag', 'endDrag' );

    this.elStartLeft = this.elStartTop = null;

    this.startX = 0;
    this.startY = 0;
    if( ! this.options.disable ) {
        this.enable();
    }
};
DSInteraction.Drag.prototype.enable = function() {
    if( ! this.mousedown ) {
        this.mousedown = LMI.BrowserEvent.bind( this.handle, 'mousedown', this, this.startDrag );
    }
};
DSInteraction.Drag.prototype.disable = function() {
    if( this.mousedown ) {
        LMI.BrowserEvent.remove( this.mousedown );
        this.mousedown = null;
    }
};
DSInteraction.Drag.prototype.getEventObject = function() {
    return { clickStartPosition: { x: this.startX, y: this.startY },
             elementCurrentPosition: { x: this.getElementLeft(), y: this.getElementTop() },
             elementStartPosition: { x: this.elStartLeft, y: this.elStartTop }
           };
};
DSInteraction.Drag.prototype.getElementLeft = function() {
    return parseInt( LMI.StyleSheet.getStyle( this.element, 'left' ) );
};
DSInteraction.Drag.prototype.getElementTop = function() {
    return parseInt( LMI.StyleSheet.getStyle( this.element, 'top' ) );
};
DSInteraction.Drag.prototype.startDrag = function( e ) {
    if( e.getMouseButton() == 0 ) {
        this.startX = e.getPageX();
        this.startY = e.getPageY();

        this.originalPos = LMI.StyleSheet.getStyle( this.element, 'position' );
        if( this.originalPos != 'absolute' ) {
            var offsets = LMI.Element.getOffsets( this.element );
            this.element.style.position = 'absolute';
            this.element.style.top = offsets.y + 'px';
            this.element.style.left = offsets.x + 'px';
        }

        this.elStartLeft = this.getElementLeft();
        this.elStartTop = this.getElementTop();

        if( this.mousemove ) {
            LMI.BrowserEvent.remove( this.mousemove );
        }
        if( this.mouseup ) {
            LMI.BrowserEvent.remove( this.mouseup );
        }
        this.mousemove = LMI.BrowserEvent.bind( document, 'mousemove', this, this.drag );
        this.mouseup = LMI.BrowserEvent.bind( document, 'mouseup', this, this.endDrag );
        this.windowout = LMI.BrowserEvent.bind( window, 'mouseout', this, this.endDrag );

        this.triggerEvent( 'startDrag', this.getEventObject(), this );

        e.preventDefault();
        e.stopPropagation();
    }
};

DSInteraction.Drag.prototype.endDrag = function( e ) {
    if( e.getType() != 'mouseout' || ! e.getRelatedTarget() ) {
        LMI.BrowserEvent.remove( this.mousemove );
        LMI.BrowserEvent.remove( this.mouseup );
        LMI.BrowserEvent.remove( this.windowout );
        var o = this.getEventObject();
        o.clickEndPosition = { x: e.getPageX(), y: e.getPageY() };
        o.elementEndPosition = { x: this.getElementLeft(), y: this.getElementTop() };
        this.startX = 0;
        this.startY = 0;
        this.mousemove = this.mouseup = null;

        if( this.originalPos != 'absolute' ) {
            this.element.style.position = this.originalPos;
        }
        this.triggerEvent( 'endDrag', o, this );
    }
};
DSInteraction.Drag.prototype.drag = function( e ) {
    if( ! this.options.lockX ) {
        var x = e.getPageX();
        var newx = this.elStartLeft - ( this.startX - x );
        if( this.options.maxX && newx > this.options.maxX ) {
            newx = this.options.maxX;
        } else if( this.options.minX && newx < this.options.minX ) {
            newx = this.options.minX;
        }
        this.element.style.left = newx + 'px';
    }
    if( ! this.options.lockY ) {
        var y = e.getPageY();
        var newy = this.elStartTop - ( this.startY - y );
        if( this.options.maxY && newy > this.options.maxY ) {
            newy = this.options.maxY;
        } else if( this.options.minY && newy < this.options.minY ) {
            newy = this.options.minY;
        }
        this.element.style.top = newy + 'px';
    }
    this.triggerEvent( 'drag', this.getEventObject(), this );

    e.stopPropagation();
    e.preventDefault();
};
