// Slider

Function.prototype.bind = function(obj)
{
    var _method = this;
    return function()
    {
        return _method.apply(obj, arguments);
    };    
} 

function slider()
{
    this.version = '1.0';
    this.isLOWER = 1;
    this.isUPPER = 2;
    this.movedArrow = this.isUPPER;
    this.style = {
        backgroundColour: '#828282',
        height: '4px',
        width: '300px',
        borderBottom: '#555 1px solid',
        borderRight: '#555 1px solid',
        colourBar: true,
        img: null
    };
    this.pointer = {
        top: '0px',
        width: '12px',
        height: '12px',
        backgroundColour: '#000000',
        backgroundColourLower: '#008C00',
        backgroundColourUpper: '#008C00',
        double: true,
        lowerImg: null,
        upperImg: null
    };
    this.values = {
        min: 0,
        upper: 50,
        lower: 50,
        max: 100,
        step: 1,
        minGap: 0,
        units: null,
        preUnits: false,
        fontSize: '14px',
        displayId: null,
        showCurrent: true,
        showLimits: true
    };
};

slider.prototype = {
    init: function(settings)
    {
        for (var i in settings) {
            if (typeof(this[i]) == 'undefined') {
                this[i] = settings[i];
            } else {
                for (var j in settings[i]) {
                    this[i][j] = settings[i][j];
                }
            }
        }
        if (this.pointer.upperImg && !this.pointer.lowerImg) {
            this.pointer.lowerImg = this.pointer.upperImg;
        }
        if (this.values.min == this.values.max) {
            var sliderEl = document.getElementById("priceRange");
            if (sliderEl) {
                sliderEl.innerHTML = '$' + this.values.min + ' - $' + this.values.max;
            }
            return false;
        }
        this.createSlider();
        this._event_docMouseMove = this._docMouseMove.bind(this);
        this._event_docMouseUp = this._docMouseUp.bind(this);
        if (this.pointer.double) {
            this.lowerArrow.onmousedown = this._mouseDownLower.bind(this);
        }
        this.upperArrow.onmousedown = this._mouseDownUpper.bind(this);
        this.slider_bar.onclick = this._sliderClick.bind(this);
    },
    
    createSlider: function()
    {
        var el = document.getElementById(this.id)
        if (!el) {
            alert('Element ' + this.id + ' not found!');
            return;
        }
        el.appendChild(this.createValuesDiv());
        this.slider_bar = this.createSliderBar();
        if (this.style.colourBar) {
            this.colourBar =  this.createColourBar();
            this.slider_bar.appendChild(this.colourBar);
        }
        if (this.pointer.double) {
            this.lowerArrow = this.createArrow(this.isLOWER);
            this.slider_bar.appendChild(this.lowerArrow);
        }
        this.upperArrow = this.createArrow(this.isUPPER);
        this.slider_bar.appendChild(this.upperArrow);
        var div = document.createElement('div');
        div.style.clear = 'both';
        el.appendChild(div);
        el.appendChild(this.slider_bar);
    },

    createValuesDiv: function()
    {
        // Do we have min/max fields?
        var container = document.getElementById(this.id + '-inner');
        if (container) {
            this.minFld = document.getElementById(this.id + '-min');
            this.maxFld = document.getElementById(this.id + '-max');
            this.minFld.value = this.values.lower;
            this.maxFld.value = this.values.upper;
            container.style.display = 'none';
        }
        var div = document.createElement('div');
        div.style.width = this.style.width;
        div.style.position = 'relative';
        div.style.textAlign = 'center';
        if (parseInt(this.pointer.top) != 0) {
            var padding = parseInt(this.pointer.top) * -1;
            div.style.paddingBottom = padding + 'px';
        }
        div.style.fontSize =  this.values.fontSize;
        this.min = document.createElement('span');
        this.min.style.left = 0;
        this.min.style.position = 'absolute';    
        if (this.values.showCurrent) {
            if (this.values.displayId) {
                this.display = document.getElementById(this.values.displayId);
            } else {
                this.display = document.createElement('span');
            }
        }
        this.max = document.createElement('span');
        this.max.style.right = 0;
        this.max.style.position = 'absolute';
        if (!this.values.units) {
            this.values.units = '';
        }
        if (this.values.showCurrent) {
            if (!this.pointer.double || this.values.lower == this.values.upper) {
                this.display.innerHTML = this.formatValues(this.values.upper);
            } else {
                this.display.innerHTML = this.formatValues(this.values.lower) + ' to ' + this.formatValues(this.values.upper);
            }
        }
        if (this.values.showLimits) {
            this.max.innerHTML = '<b>' + this.formatValues(this.values.max) + '</b>';
            this.min.innerHTML = '<b>' + this.formatValues(this.values.min) + '</b>';
        }
        div.appendChild(this.min);
        if (!this.values.displayId && this.values.showCurrent) {
            div.appendChild(this.display);
        }
        div.appendChild(this.max);
        return div;
    },
    
    createSliderBar: function()
    {
        var div = document.createElement('div');
        div.style.position = 'relative';
        if (this.style.img) {
            div.style.background = 'url(' + this.style.img + ')';
            div.style.borderLeft = this.style.borderBottom;
        } else {
            div.style.backgroundColor = this.style.backgroundColour;
            div.style.borderBottom = this.style.borderBottom;
        }
        div.style.borderRight = this.style.borderRight;
        div.style.height = this.style.height;
        div.style.width = this.style.width;
        return div;
    },

    createArrow: function(num)
    {
        var w = parseInt(this.pointer.width);
        var h = parseInt(this.pointer.height);
        var par = this.setArrow(num);
        par.style.backgroundColor = 'transparent';
        par.setAttribute(!/*@cc_on!@*/false ? 'tabIndex' : 'tabindex', '0');
        // Using iamges
        if (this.pointer.upperImg) {
            return par;
        }
        par.style.top = parseInt(this.style.height) + 'px';
        t0 = this.createDivNode();
        if (num == this.isLOWER) {
            t0.style.backgroundColor = this.pointer.backgroundColourLower;
        } else {
            t0.style.backgroundColor = this.pointer.backgroundColourUpper;
        }
        par.appendChild(t0);
        for (var i = 1; i < h; i++) {
            t = t0.cloneNode(false);
            if (num == this.isLOWER) {
                t.style.backgroundColor = this.pointer.backgroundColourLower;
            } else {
                t.style.backgroundColor = this.pointer.backgroundColourUpper;
            }
            t.style.marginLeft = 1 / 2 * w / h * i + 'px';
            t.style.marginRight = 1 / 2 * w / h * i + 'px';
            par.appendChild(t);
        }
        return this.reverseNodes(par);
        //return par;
    },

    setArrow: function(num)
    {
        var div = document.createElement('div');
        div.style.width = this.pointer.width;
        if (num == this.isLOWER) {
            if (this.pointer.lowerImg) {
                div.style.background = 'url(' + this.pointer.lowerImg + ')';
            } else {
                div.style.backgroundColor = this.pointer.backgroundColourLower;
            }
        } else {
            if (this.pointer.upperImg) {
                div.style.background = 'url(' + this.pointer.upperImg + ')';
            } else {
                div.style.backgroundColor = this.pointer.backgroundColourUpper;
            }
        }
        div.style.height = this.pointer.height;
        div.style.overflow = 'hidden';
        div.style.position = 'absolute';
        div.style.top = this.pointer.top;
        if (num == this.isUPPER) {
            div.style.left = parseInt((this.values.upper - this.values.min) / (this.values.max - this.values.min) * parseInt(this.style.width)) - parseInt(this.pointer.width) / 2  + 'px';
        } else {
            div.style.left = parseInt((this.values.lower - this.values.min) / (this.values.max - this.values.min) * parseInt(this.style.width)) - parseInt(this.pointer.width) / 2  + 'px';
        }
        return div;
    },
 
    createDivNode: function()
    {
        var o = document.createElement('div');
        o.style.height = '1px';
        o.style.overflow = 'hidden';
        return o;
    },

    reverseNodes: function(n)
    {
        var kids = n.childNodes;
        var rekids = n.cloneNode(false);
        var numkids = kids.length;
        for (var i = numkids-1; i >= 0; i--) {
            rekids.appendChild(kids[i]);
        }
        return rekids;
    },

    createColourBar: function()
    {
        var div = document.createElement('div');
        div.style.position = 'relative';
        if (!this.pointer.double) {
            div.style.left = 0;
            div.style.width = parseInt((this.values.upper - this.values.min) / (this.values.max - this.values.min) * parseInt(this.style.width)) + 'px';
        } else {
            div.style.left = (parseInt(this.values.lower) - this.values.min) / (this.values.max - this.values.min) * parseInt(this.style.width) + 'px';
            div.style.width = parseInt(((this.values.upper) - this.values.lower) / (this.values.max - this.values.min) * parseInt(this.style.width)) + 'px';
        }
        div.style.backgroundColor = this.pointer.backgroundColour;
        div.style.height = this.style.height;
        div.style.overflow = 'hidden';
        return div;
    },

    updateValues: function(e)
    { 
        var x = e.clientX + document.documentElement.scrollLeft;
        var offsetX = this.getPosition(this.slider_bar)[0];
        var x_x = x - offsetX;
        this.setPosition(x_x);
    },

    setPointer: function(upper, lower)
    {
        if (upper == lower) {
            return false;
        }
        var newUpper = (parseInt(upper) - this.values.min) / (this.values.max - this.values.min) * parseInt(this.style.width);
        this.movedArrow = this.isUPPER;
        this.setPosition(newUpper);
        if (lower) {
            var newLower = (parseInt(lower) - this.values.min) / (this.values.max - this.values.min) * parseInt(this.style.width);
            this.movedArrow = this.isLOWER;
            this.setPosition(newLower);
        }
    },
    
    setPosition: function(x)
    {
        if (this.movedArrow == this.isUPPER) {
            if (x > parseInt(this.style.width)) {
                x = parseInt(this.style.width);
            } else if (x < 0) {
                x = 0;
                this.upperArrow.style.left = x + 'px';
            }
            if (this.pointer.double) {
                if (x - parseInt(this.values.minGap) < parseInt(this.lowerArrow.style.left) + parseInt(this.pointer.width) / 2) {
                    x = parseInt(this.lowerArrow.style.left) + parseInt(this.pointer.width) / 2;
                    if (this.values.minGap) {
                        x = x + parseInt(this.values.minGap) + 1;
                    }
                }
            }
            this.upperArrow.style.left = x - parseInt(this.pointer.width) / 2 + 'px';
            if (this.style.colourBar) {
                if (!this.pointer.double) {
                    this.colourBar.style.left = 0;
                    if (parseInt(this.upperArrow.style.left) > 0) {
                        this.colourBar.style.width = parseInt(this.upperArrow.style.left) + 'px';
                    } else {
                        this.colourBar.style.width = '0px';
                    }
                } else {
                    this.colourBar.style.left = parseInt(this.lowerArrow.style.left) + parseInt(this.pointer.width) / 2 + 'px';
                    this.colourBar.style.width = parseInt(this.upperArrow.style.left) - parseInt(this.lowerArrow.style.left) + 'px'; 
                }
            } 
            this.values.upper = parseInt(x / parseInt(this.style.width) * (this.values.max - this.values.min) + this.values.min);
        } else {
            if (x > parseInt(this.style.width)) {
                x = parseInt(this.style.width); 
            } else if (x < 0) {
                x = 0;
                this.lowerArrow.style.left = x + 'px';
            }
            if (x + parseInt(this.values.minGap) > parseInt(this.upperArrow.style.left) + parseInt(this.pointer.width) / 2) {
                x = parseInt(this.upperArrow.style.left) + parseInt(this.pointer.width) / 2;
                if (this.values.minGap) {
                    x = x - parseInt(this.values.minGap) + 1;
                }
            }
            this.lowerArrow.style.left = x - parseInt(this.pointer.width) / 2 + 'px';
            if (this.style.colourBar) {
                this.colourBar.style.left = parseInt(this.lowerArrow.style.left) + parseInt(this.pointer.width) / 2 + 'px';
                this.colourBar.style.width =  parseInt(this.upperArrow.style.left) - parseInt(this.lowerArrow.style.left) + 'px'; 
            }
            this.values.lower = parseInt(x / parseInt(this.style.width) * (this.values.max - this.values.min) + this.values.min);
        }
        if (this.values.showCurrent) {
            if (!this.pointer.double || this.values.lower == this.values.upper) {
                this.display.innerHTML = this.formatValues(this.values.upper);
            } else {
                this.display.innerHTML = this.formatValues(this.values.lower) + ' to ' + this.formatValues(this.values.upper);
            }
        }
        if (this.minFld) {
            this.minFld.value = this.values.lower;
        }
        if (this.maxFld) {
            this.maxFld.value = this.values.upper;
        }
    },
    
    getPosition: function(el)
    {
        var curLeft = 0;
        var curTop = 0;
        var s = this.getScrolls(el);
        if (el.offsetParent) {
            do {
                curLeft += el.offsetLeft;
                curTop += el.offsetTop;
            } while (el = el.offsetParent);
            return [(curLeft - s[0]), (curTop - s[1])];
        }
    },
 
    getScrolls: function(el)
    {
        var curX = 0;
        var curY = 0;
        do {
            curX += el.scrollLeft;
            curY += el.scrollTop;
            if (el.nodeName == 'BODY') {
                break;
            }
        } while (el = el.parentNode);
        return [curX, curY];
    },
    
    formatValues: function(value)
    {
        if (this.values.preUnits) {
            return this.values.units + value;
        } else {
            return value + this.values.units;
        }
    },

    getTargetElement: function(evt)
    {
        return (evt.target) ? ((evt.target.nodeType == 3) ? evt.target.parentNode : evt.target) : evt.srcElement;
    },

    // Only use if one Arrow
    _sliderClick: function(e)
    {
        e = (e) ? e : ((window.event) ? window.event : '');
        var o = this.getTargetElement(e);
        if (!this.pointer.double) {
            if (o != this.upperArrow) {
                this.movedArrow = this.isUPPER;
                this.updateValues(e);
                if (this.afterChange) {
                    this.addEvent(this.slider_bar, 'click', this.afterChange);
                }
            }
        } else {
            if (o != this.upperArrow && o != this.lowerArrow) {
                var x = e.clientX + document.documentElement.scrollLeft;
                var offsetX = this.getPosition(this.slider_bar)[0];
                var x_x = x - offsetX;
                if (x_x < parseInt(this.lowerArrow.style.left)) {
                    this.movedArrow = this.isLOWER;
                    this.setPosition(x_x);
                }
                if (x_x > parseInt(this.upperArrow.style.left)) {
                    this.movedArrow = this.isUPPER;
                    this.setPosition(x_x);
                }
                if (this.afterChange) {
                    this.addEvent(this.slider_bar, 'click', this.afterChange);
                }
            }
        }
        this.noBubbleDefault(e);
    },

    _mouseDownLower: function(e)
    {
        this.movedArrow = this.isLOWER;
        this.addEvent(document, 'mousemove', this._event_docMouseMove);
        if (this.afterChange) {
            this.addEvent(document, 'mouseup', this.afterChange);
        }
        this.addEvent(document, 'mouseup', this._event_docMouseUp);
        this.noBubbleDefault(e);
    },

    _mouseDownUpper: function(e)
    {
        this.movedArrow = this.isUPPER;
        this.addEvent(document, 'mousemove', this._event_docMouseMove);
        if (this.afterChange) {
            this.addEvent(document, 'mouseup', this.afterChange);
        }
        this.addEvent(document, 'mouseup', this._event_docMouseUp);
        this.noBubbleDefault(e);
    },

     _docMouseMove: function(e)
     {
        this.updateValues(e)
        this.noBubbleDefault(e);
     },

    _docMouseUp: function(e)
    {
        this.removeEvent(document, 'mouseup', this._event_docMouseUp);
        this.removeEvent(document, 'mousemove', this._event_docMouseMove);
        if (this.afterChange) {
            this.removeEvent(document, 'mouseup', this.afterChange);
        }
        this.noBubbleDefault(e);
    },

    noBubbleDefault: function(e)
    {
        if (e && e.stopPropagation) {
            e.stopPropagation();
            e.preventDefault();
        } else {
            window.event.cancelBubble = true;
            window.event.returnValue = false; // IE fix
            }
    },

    addEvent: function(obj, type, fn)
    {
        if (obj.attachEvent) {
            obj['e' + type + fn] = fn;
            obj[type + fn] = function() { obj['e' + type + fn](window.event); }
            obj.attachEvent('on' + type, obj[type + fn]);
        } else {
            obj.addEventListener(type, fn, false);
        }
    },
    
    removeEvent: function(obj, type, fn)
    {
        if (obj.detachEvent) {
            obj.detachEvent('on' + type, obj[type + fn]);
            obj[type + fn] = null;
      } else {
            obj.removeEventListener(type, fn, false);
      }
    }

}


