/*
	http://www.frequency-decoder.com/demo/slider-revisited/

        Unobtrusive Slider Control by frequency decoder v1.4 (http://www.frequency-decoder.com/)

        Released under a creative commons Attribution-ShareAlike 2.5 license (http://creativecommons.org/licenses/by-sa/2.5/)

        You are free:

        * to copy, distribute, display, and perform the work
        * to make derivative works
        * to make commercial use of the work

        Under the following conditions:

                by Attribution.
                --------------
                You must attribute the work in the manner specified by the author or licensor.

                sa
                --
                Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.

        * For any reuse or distribution, you must make clear to others the license terms of this work.
        * Any of these conditions can be waived if you get permission from the copyright holder.
*/

var fdSliderController;

(function() {

        function fdSlider(inp,range,callback,classname,hide,tween,vertical) {
                this._inp       = inp;
                this._hideInput = hide;
                this._min       = range[0]||0;
                this._max       = range[1]||0;
                this._range     = this._max - this._min;
                this._tween     = tween;
                this._mouseX    = 0;
                this._timer     = null;
                this._classname = classname;
                this._drag      = false;
                this._kbEnabled = true;
                this._callback  = callback;
                this._vertical  = vertical;
                this._steps     = inp.tagName.toLowerCase() == "input" ? 10 : inp.options.length - 1;
                this._resizeVal = 0;
                
                // ARIA namespaces
                this.NS_XHTML = "http://www.w3.org/1999/xhtml";
                this.NS_STATE = "http://www.w3.org/2005/07/aaa";
                
                this.events = {
                        stopevent: function(e) {
                                if(e == null) e = document.parentWindow.event;
                                if(e.stopPropagation) {
                                        e.stopPropagation();
                                        e.preventDefault();
                                }
                                /*@cc_on@*/
                                /*@if(@_win32)
                                e.cancelBubble = true;
                                e.returnValue = false;
                                /*@end@*/
                                return false;
                        },
                        redrawEvent:function(e) {
                                // Get around IE's window.resize bug by testing if the actual size of the wrapper has changed...
                                if((self._vertical && self.outerWrapper.offsetHeight != self._resizeVal) || (!self._vertical && self.outerWrapper.offsetWidth != self._resizeVal)) {
                                        self.events.redraw();
                                };
                        },
                        redraw: function() {
                                self.locate();

                                // Internet Explorer requires the try catch
                                try {
                                        var sW = self.outerWrapper.offsetWidth;
                                        var sH = self.outerWrapper.offsetHeight;
                                        var hW = self.handle.offsetWidth;
                                        var hH = self.handle.offsetHeight;
                                        var bH = self.bar.offsetHeight;
                                        var bW = self.bar.offsetWidth;
                                        var sI = self._steps;

                                        if(self._vertical) {
                                                self.bar.style.height = Math.round(sH - hH) + "px";
                                                self.bar.style.left   = Math.floor((sW - bW) / 2) + "px";
                                                self.bar.style.top    = Math.round(hH / 2) + "px";
                                                self._incPx    = (sH - hH) / sI < 1 ? 1 : (sH - hH) / sI;
                                        } else {
                                                self.bar.style.width  = Math.round(sW - hW) + "px";
                                                self.bar.style.left   = Math.round(hW / 2) + "px";
                                                self.bar.style.top    = Math.floor((sH - bH) / 2) + "px";
                                                self._incPx    = (sW - hW) / sI < 1 ? 1 : (sW - hW) / sI;
                                        };
                                        self.resetHandlePosition();
                                        self._resizeVal = (self._vertical) ? sH : sW;
                                } catch(err) { };
                        },
                        onfocus: function(e) {
                                self.outerWrapper.className = self.outerWrapper.className.replace('focused','') + ' focused';

                                fdSliderController.addEvent(window, 'DOMMouseScroll', self.events.trackmousewheel);
                                fdSliderController.addEvent(document, 'mousewheel', self.events.trackmousewheel);
                                if(!window.opera) fdSliderController.addEvent(window,   'mousewheel', self.events.trackmousewheel);

                                self.doCallback();
                        },
                        onblur: function(e) {
                                self.outerWrapper.className = self.outerWrapper.className.replace(/focused|fd-fc-slider-hover|fd-slider-hover/g,'');

                                fdSliderController.removeEvent(document, 'mousewheel', self.events.trackmousewheel);
                                fdSliderController.removeEvent(window, 'DOMMouseScroll', self.events.trackmousewheel);
                                if(!window.opera) fdSliderController.removeEvent(window,   'mousewheel', self.events.trackmousewheel);
                        },
                        trackmousewheel: function(e) {
                                if(!self._kbEnabled) return;
                                var delta = 0;
                                var e = e || window.event;
                                if (e.wheelDelta) {
                                        delta = e.wheelDelta/120;
                                        if (window.opera && window.opera.version() < 9.2) delta = -delta;
                                } else if(e.detail) {
                                        delta = -e.detail/3;
                                };
                                if(delta) {
                                        var xtmp = self._vertical ? self.handle.offsetTop : self.handle.offsetLeft;
                                        var wtmp = self._vertical ? self.outerWrapper.offsetHeight - self.handle.offsetHeight : self.outerWrapper.offsetWidth - self.handle.offsetWidth;
                                        var inc  = self._inp.tagName.toLowerCase() == "input" ? Math.round(self._incPx / 2) < 1 ? 1 : Math.round(self._incPx / 2) : self._incPx;
                                        if(self._vertical) inc = -inc;
                                        if(delta < 0) {
                                                xtmp += inc;
                                                xtmp = Math.ceil(xtmp);
                                        } else {
                                                xtmp -= inc;
                                                xtmp = Math.floor(xtmp);
                                        };
                                        if(xtmp < 0) xtmp = 0;
                                        else if(xtmp > wtmp) xtmp = wtmp;

                                        if(self._vertical) self.handle.style.top = xtmp + "px";
                                        else self.handle.style.left = xtmp + "px";
                                        self.updateInput(xtmp);
                                };
                                return self.events.stopevent(e);
                        },
                        onkeypress: function(e) {
                                if (e == null) e = document.parentWindow.event;
                                if ((e.keyCode >= 35 && e.keyCode <= 40) || !self._kbEnabled) {
                                        return self.events.stopevent(e);
                                };
                        },
                        onkeydown: function(e) {
                                if(!self._kbEnabled) return true;

                                if(e == null) e = document.parentWindow.event;
                                var kc = e.keyCode != null ? e.keyCode : e.charCode;

                                if ( kc < 35 || kc > 40 ) return true;

                                var xtmp = self._vertical ? self.handle.offsetTop : self.handle.offsetLeft;
                                var wtmp = self._vertical ? self.outerWrapper.offsetHeight - self.handle.offsetHeight : self.outerWrapper.offsetWidth - self.handle.offsetWidth;
                                var inc  = self._inp.tagName.toLowerCase() == "input" ? Math.round(self._incPx / 2) < 1 ? 1 : Math.round(self._incPx / 2) : self._incPx;

                                if(self._vertical) inc = -inc;

                                if( kc == 37 || kc == 40 ) {
                                        // left, up
                                        xtmp -= inc;
                                        xtmp = Math.floor(xtmp);
                                } else if( kc == 39 || kc == 38) {
                                        // right, down
                                        xtmp += inc;
                                        xtmp = Math.ceil(xtmp);
                                } else if( kc == 35 ) {
                                        // max
                                        xtmp = wtmp;
                                } else if( kc == 36 ) {
                                        // min
                                        xtmp = 0;
                                }

                                if(xtmp < 0) xtmp = 0;
                                else if(xtmp > wtmp) xtmp = wtmp;

                                self.handle.style[self._vertical ? "top" : "left"] = xtmp + "px";
                                self.updateInput(xtmp);
                                
                                // Opera doesn't let us cancel key events so the up/down arrows and home/end buttons will scroll the screen - which sucks
                                return self.events.stopevent(e);
                        },
                        onchange: function( e ) {
                                self.resetHandlePosition();
                                self.doCallback();
                                return true;
                        },
                        onmouseover: function( e ) {
                                /*@cc_on@*/
                                /*@if(@_jscript_version <= 5.6)
                                if(this.className.search(/focused/) != -1) {
                                        this.className = this.className.replace("fd-fc-slider-hover", "") +' fd-fc-slider-hover';
                                        return;
                                }
                                /*@end@*/
                                this.className = this.className.replace(/fd\-slider\-hover/g,"") +' fd-slider-hover';
                        },
                        onmouseout: function( e ) {
                                /*@cc_on@*/
                                /*@if(@_jscript_version <= 5.6)
                                if(this.className.search(/focused/) != -1) {
                                        this.className = this.className.replace("fd-fc-slider-hover", "");
                                        return;
                                }
                                /*@end@*/
                                this.className = this.className.replace(/fd\-slider\-hover/g,"");
                        },
                        onHmouseup:function(e) {
                                e = e || window.event;
                                fdSliderController.removeEvent(document, 'mousemove', self.events.trackmouse);
                                fdSliderController.removeEvent(document, 'mouseup', self.events.onHmouseup);
                                self._drag = false;
                                self._kbEnabled = true;

                                // Opera fires the blur event when the mouseup event occurs on a button, so we attept to force a focus
                                if(window.opera) try { setTimeout(function() { self.events.onfocus(); }, 0); } catch(err) {};
                                
                                return self.events.stopevent(e);
                        },
                        onHmousedown: function(e) {
                                e = e || window.event;
                                self._mouseX    = self._vertical ? e.clientY : e.clientX;
                                self.handleX    = parseInt(self._vertical ? self.handle.offsetTop : self.handle.offsetLeft)||0;
                                self._drag      = true;
                                self._kbEnabled = false;

                                fdSliderController.addEvent(document, 'mousemove', self.events.trackmouse);
                                fdSliderController.addEvent(document, 'mouseup', self.events.onHmouseup);
                                
                                // Safari will not "focus" on the button on mouse events, so we attempt to force a focus
                                if(window.devicePixelRatio || (document.all && !window.opera)) try { setTimeout(function() { self.handle.focus(); }, 0); } catch(err) {};
                        },
                        onmouseup: function( e ) {
                                e = e || window.event;
                                fdSliderController.removeEvent(document, 'mouseup', self.events.onmouseup);
                                if(!self._tween) {
                                        clearTimeout(self._timer);
                                        self._timer = null;
                                        self._kbEnabled = true;
                                }
                                self.doCallback();
                                return self.events.stopevent(e);
                        },
                        trackmouse: function( e ) {
                                if (!e) var e = window.event;
                                var x = self._vertical ? self.handleX + (e.clientY-self._mouseX) : self.handleX + (e.clientX-self._mouseX);
                                if(x < 0) x = 0;
                                var max = self._vertical ? self.outerWrapper.offsetHeight - self.handle.offsetHeight : self.outerWrapper.offsetWidth - self.handle.offsetWidth;
                                if(x > max) x = max;
                                if(self._vertical) self.handle.style.top = x + "px";
                                else self.handle.style.left = x + "px";
                                self.updateInput(x);
                        },
                        onmousedown: function( e ) {
                                var targ;
                                if (!e) var e = window.event;
                                if (e.target) targ = e.target;
                                else if (e.srcElement) targ = e.srcElement;
                                if (targ.nodeType == 3) targ = targ.parentNode;

                                if(targ.className.search("fd-slider-handle") != -1) {
                                        return true;
                                };
                                
                                try { setTimeout(function() { self.handle.focus(); }, 0); } catch(err) {};

                                clearTimeout(self._timer);
                                self._timer = null;
                                self._kbEnabled = false;
                                self.locate();
                                self._drag      = false;
                                var posx        = 0;
                                var sLft        = 0;
                                var sTop        = 0;

                                // Internet Explorer doctype woes
                                if (document.documentElement && document.documentElement.scrollTop) {
                                        sTop = document.documentElement.scrollTop;
                                        sLft = document.documentElement.scrollLeft;
                                } else if (document.body) {
                                        sTop = document.body.scrollTop;
                                        sLft = document.body.scrollLeft;
                                };

                                if (e.pageX)            posx = self._vertical ? e.pageY : e.pageX;
                                else if (e.clientX)     posx = self._vertical ? e.clientY + sTop : e.clientX + sLft;

                                var diff = Math.round((self._vertical) ? self.handle.offsetHeight / 2 : self.handle.offsetWidth / 2);
                                posx -= self._vertical ? self._y + diff : self._x + diff;
                                        
                                if(posx < 0) posx = 0;
                                else if(!self._vertical && posx > self.outerWrapper.offsetWidth - self.handle.offsetWidth)  posx = self.outerWrapper.offsetWidth - self.handle.offsetWidth;
                                else if(self._vertical && posx > self.outerWrapper.offsetHeight - self.handle.offsetHeight) posx = self.outerWrapper.offsetHeight - self.handle.offsetHeight;

                                if(self._tween) {
                                        self.tweenTo(posx);
                                } else {
                                        fdSliderController.addEvent(document, 'mouseup', self.events.onmouseup);
                                        self._posx = posx;
                                        self.onTimer();
                                };
                        }
                };

                this.onTimer = function() {
                        var xtmp = self._vertical ? self.handle.offsetTop : self.handle.offsetLeft;
                        if(self._posx < xtmp) {
                                xtmp -= self._incPx;
                                xtmp = Math.floor(xtmp);
                                if(xtmp < self._posx) xtmp = self._posx;
                        } else {
                                xtmp += self._incPx;
                                xtmp = Math.ceil(xtmp);
                                if(xtmp > self._posx) xtmp = self._posx;
                        };
                        xtmp = Math.round(xtmp);
                        self.handle.style[self._vertical ? "top" : "left"] = xtmp + "px";
                        self.updateInput(xtmp);
                        if(xtmp != self._posx) self._timer = setTimeout(self.onTimer, 200);
                        else self._kbEnabled = true;
                };

                this.locate = function(){
                        var curleft = 0;
                        var curtop  = 0;
                        var obj = self.outerWrapper;
                        // Try catch for IE's benefit
                        try {
                                while (obj.offsetParent) {
                                        curleft += obj.offsetLeft;
                                        curtop  += obj.offsetTop;
                                        obj      = obj.offsetParent;
                                };
                        } catch(err) {}
                        self._x = curleft;
                        self._y = curtop;
                };

                this.tweenTo = function(x){
                        self._kbEnabled = false;
                        self._tweenX = parseInt(x);
                        self._tweenB = parseInt(self._vertical ? self.handle.style.top : self.handle.style.left);
                        self._tweenC = self._tweenX - self._tweenB;
                        self._tweenD = 20;
                        self._frame  = 0;
                        if(!self._timer) self._timer = setTimeout(self.tween,50);
                };

                this.tween = function(){
                        self._frame++;
                        var c = self._tweenC;
                        var d = 20;
                        var t = self._frame;
                        var b = self._tweenB;
                        var x = Math.ceil((t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b);

                        self.handle.style[self._vertical ? "top" : "left"] = x + "px";
                        self.updateInput(x);
                        if(t!=d && !self._md) self._timer = setTimeout(self.tween,20);
                        else {
                                self.handle.style[self._vertical ? "top" : "left"] = self._tweenX + "px";
                                clearTimeout(self._timer);
                                self._timer = null;
                                self._kbEnabled = true;
                        };
                };

                this.updateInput = function(x) {
                        var max = self._vertical ? self.outerWrapper.offsetHeight - self.handle.offsetHeight : self.outerWrapper.offsetWidth - self.handle.offsetWidth;
                        var inc = max / self._range;

                        var val = Number(self._min) + Math.abs(Math.floor(x / inc));
                        if(self._vertical) val = -val;
                        
                        if(val < self._min) val = self._min;
                        else if(val > self._max) val = self._max;

                        val = (val <= self._min + (self._max / 2)) ? Math.round(val) : Math.ceil(val);

                        self.setInputValue(val);
                        self.doCallback();
                };
                
                this.setInputValue = function(val) {
                        if(self._inp.tagName.toLowerCase() == "select") {
                                try {
                                        self._inp.options[val].selected = true;
                                        self.setAttrNS(self.handle, self.NS_STATE, "valuenow", self._inp.options[val].value);
                                        self.setAttrNS(self.handle, self.NS_STATE, "valuetext", self._inp.options[val].text);
                                } catch (err) {};
                        } else {
                                self._inp.value = val;
                                self.setAttrNS(self.handle, self.NS_STATE, "valuenow", val);
                                self.setAttrNS(self.handle, self.NS_STATE, "valuetext", val);
                        };
                };
                
                this.doCallback = function() {
                        if(self._callback) {
                                var func;
                                if(self._callback.indexOf(".") != -1) {
                                        var split = self._callback.split(".");
                                        func = window;
                                        for(var i = 0, f; f = split[i]; i++) {
                                                if(f in func) {
                                                        func = func[f];
                                                } else {
                                                        func = "";
                                                        break;
                                                };
                                        };
                                } else if(self._callback in window) {
                                        func = window[self._callback];
                                };
                                if(typeof func == "function") { func(); };
                                func = null;
                        };
                };
                
                this.resetHandlePosition = function() {
                        var value = self._inp.tagName.toLowerCase() == "input" ? parseInt(self._inp.value, 10) : self._inp.selectedIndex;
                        if(isNaN(value) || value < self._min) value = self._min;
                        else if(value > self._max) value = self._max;
                        self.setInputValue(value);
                        var max = self._vertical ? self.outerWrapper.offsetHeight - self.handle.offsetHeight : self.outerWrapper.offsetWidth - self.handle.offsetWidth;
                        var inc = max / self._range;
                        var tot = value - self._min;
                        var pos = (tot * inc < (self._min + (self._range / 2))) ? Math.floor(tot * inc) : Math.ceil(tot * inc);
                        if(self._vertical) {
                                self.handle.style.top = Math.abs(max - pos) + "px";
                        } else {
                                self.handle.style.left = pos + "px";
                        };
                };
                
                this.setAttrNS = function(elmTarget, uriNamespace, sAttrName, sAttrValue) {
                        if (typeof document.documentElement.setAttributeNS != 'undefined') {
                                elmTarget.setAttributeNS(uriNamespace, sAttrName, sAttrValue);
                        } else {
                                var nsMapping = {
                                        "http://www.w3.org/1999/xhtml":"x:",
                                        "http://www.w3.org/2005/07/aaa":"aaa:"
                                };
                                elmTarget.setAttribute(nsMapping[uriNamespace] + sAttrName, sAttrValue);
                        };
                };
                
                this.findLabel = function() {
                        var label;
                        if(self._inp.parentNode && self._inp.parentNode.tagName.toLowerCase() == "label") label = self._inp.parentNode;
                        else {
                                var labelList = document.getElementsByTagName('label');
                                // loop through label array attempting to match each 'for' attribute to the id of the current element
                                for(var lbl = 0; lbl < labelList.length; lbl++) {
                                        // Internet Explorer requires the htmlFor test
                                        if((labelList[lbl]['htmlFor'] && labelList[lbl]['htmlFor'] == self._inp.id) || (labelList[lbl].getAttribute('for') == self._inp.id)) {
                                                label = labelList[lbl];
                                                break;
                                        };
                                };
                        };
                        if(label && !label.id) { label.id = inp.id + "_label_" + fdSliderController.uniqueid++; };
                        return label;
                };
                
                this.build = function() {
                        if(self._hideInput) self._inp.style.display = "none";
                        else fdSliderController.addEvent(self._inp, 'change', self.events.onchange);

                        self.outerWrapper              = document.createElement('div');
                        self.outerWrapper.className    = "fd-slider" + (self._vertical ? "-vertical " : " ") + self._classname;
                        self.outerWrapper.id           = "fd-slider-" + inp.id;

                        self.wrapper                   = document.createElement('span');
                        self.wrapper.className         = "fd-slider-inner";

                        self.bar                       = document.createElement('span');
                        self.bar.className             = "fd-slider-bar";

                        self.handle                    = document.createElement('button');
                        self.handle.className          = "fd-slider-handle";
                        
                        self.handle.appendChild(document.createTextNode(" "));
                        
                        self.handle.setAttribute("type", "button");
                        self.handle.setAttribute("tabindex", "0");
                        
                        self.outerWrapper.appendChild(self.wrapper);
                        self.outerWrapper.appendChild(self.bar);
                        self.outerWrapper.appendChild(self.handle);
                        
                        self._inp.parentNode.insertBefore(self.outerWrapper, self._inp);

                        // ARIA tabindex
                        self.handle.setAttribute("tabindex", "0");

                        /*@cc_on@*/
                        /*@if(@_win32)
                        self.handle.unselectable       = "on";
                        self.bar.unselectable          = "on";
                        self.wrapper.unselectable      = "on";
                        self.outerWrapper.unselectable = "on";
                        /*@end@*/

                        fdSliderController.addEvent(self.outerWrapper, "mouseover", self.events.onmouseover);
                        fdSliderController.addEvent(self.outerWrapper, "mouseout",  self.events.onmouseout);
                        fdSliderController.addEvent(self.outerWrapper, "mousedown", self.events.onmousedown);
                        fdSliderController.addEvent(self.handle,       "keydown",   self.events.onkeydown);
                        fdSliderController.addEvent(self.handle,       "keypress",  self.events.onkeypress);
                        fdSliderController.addEvent(self.handle,       "focus",     self.events.onfocus);
                        fdSliderController.addEvent(self.handle,       "blur",      self.events.onblur);
                        fdSliderController.addEvent(self.handle,       "mousedown", self.events.onHmousedown);
                        fdSliderController.addEvent(self.handle,       "mouseup",   self.events.onHmouseup);
                        fdSliderController.addEvent(window,            "resize",    self.events.redrawEvent);

                        // Add ARIA accessibility info programmatically
                        self.setAttrNS(self.handle, self.NS_XHTML, "role", "wairole:slider");         // role:slider
                        self.setAttrNS(self.handle, self.NS_STATE, "valuemin", self._min);            // aaa:valuemin
                        self.setAttrNS(self.handle, self.NS_STATE, "valuemax", self._max);            // aaa:valuemax
                        //self.setAttrNS(self.handle, self.NS_STATE, "valuenow", self._inp.value);      // aaa:valuenow
                        
                        var lbl = self.findLabel();
                        if(lbl) {
                                self.setAttrNS(self.handle, self.NS_STATE, 'labelledby', lbl.id);     // aaa:labelledby
                                self.handle.id = "fd-slider-handle-" + inp.id;
                                /*@cc_on
                                /*@if(@_win32)
                                lbl.setAttribute("htmlFor", self.handle.id);
                                @else @*/
                                lbl.setAttribute("for", self.handle.id);
                                /*@end
                                @*/
                        };
                        
                        // Are there page instructions - the creation of the instructions has been left up to you fine reader...
                        if(document.getElementById("fd_slider_describedby")) {
                                self.setAttrNS(self.handle, self.NS_STATE, 'describedby', "fd_slider_describedby");     // aaa:describedby
                        };

                        self.events.redraw();
                };

                this.destroy = function() {
                        try {
                                self._callback = null;
                                fdSliderController.removeEvent(self.outerWrapper, "mouseover", self.events.onmouseover);
                                fdSliderController.removeEvent(self.outerWrapper, "mouseout",  self.events.onmouseout);
                                fdSliderController.removeEvent(self.outerWrapper, "mousedown", self.events.onmousedown);
                                fdSliderController.removeEvent(self.handle,       "keydown",   self.events.onkeydown);
                                fdSliderController.removeEvent(self.handle,       "keypress",  self.events.onkeypress);
                                fdSliderController.removeEvent(self.handle,       "focus",     self.events.onfocus);
                                fdSliderController.removeEvent(self.handle,       "blur",      self.events.onblur);
                                fdSliderController.removeEvent(self.handle,       "mousedown", self.events.onHmousedown);
                                fdSliderController.removeEvent(self.handle,       "mouseup",   self.events.onHmouseup);
                                fdSliderController.removeEvent(window,            "resize",    self.events.redraw);
                                if (window.addEventListener && !window.devicePixelRatio) window.removeEventListener('DOMMouseScroll', self.events.trackmousewheel, false);
                                else {
                                        fdSliderController.removeEvent(document, "mousewheel", self.events.trackmousewheel);
                                        fdSliderController.removeEvent(window,   "mousewheel", self.events.trackmousewheel);
                                };
                        } catch(err) {}

                        self.wrapper = self.bar = self.handle = self.outerWrapper = self._timer = null;
                };
                
                var self = this;
                self.build();
        };

        fdSliderController = {
                sliders: {},
                uniqueid: 0,
                forms: {},
                
                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, true ); }
                },
                removeEvent: function(obj, type, fn) {
                        if( obj.detachEvent ) {
                                try {
                                        obj.detachEvent( "on"+type, obj[type+fn] );
                                        obj[type+fn] = null;
                                } catch(err) { };
                        } else { obj.removeEventListener( type, fn, true ); }
                },
                onload: function(e) {
                        for(slider in fdSliderController.sliders) { fdSliderController.sliders[slider].resetHandlePosition(); }
                },
                joinNodeLists: function() {
                        if(!arguments.length) { return []; }
                        var nodeList = [];
                        for (var i = 0; i < arguments.length; i++) {
                                for (var j = 0, item; item = arguments[i][j]; j++) { nodeList[nodeList.length] = item; };
                        };
                        return nodeList;
                },
                construct: function( e ) {
                        var regExp_1 = /fd_range_([-]{0,1}[0-9]+){1}_([-]{0,1}[0-9]+){1}/;
                        var regExp_2 = /fd_callback_([\S-]+)/;
                        var regExp_3 = /fd_classname_([a-zA-Z0-9_\-]+)/;
                        var inputs   = fdSliderController.joinNodeLists(document.getElementsByTagName('input'), document.getElementsByTagName('select'));
                        var range, callback, classname, hide, tween, vertical;

                        for(var i = 0, inp; inp = inputs[i]; i++) {
                                if((inp.tagName.toLowerCase() == "input" && inp.type == "text" && inp.className && inp.className.search(regExp_1) != -1) || (inp.tagName.toLowerCase() == "select" && inp.className.search(/fd_slider/) != -1)) {
                                        // Create an id if necessary
                                        if(!inp.id) inp.id == "sldr" + fdSliderController.uniqueid++;
                                        // Has the slider already been created?
                                        if(document.getElementById("fd-slider-"+inp.id)) continue;
                                        if(inp.tagName.toLowerCase() == "select") {
                                                range = [0, inp.options.length - 1];
                                                // Always hide the selectlist
                                                hide = true;
                                        } else {
                                                // range
                                                range = inp.className.match(regExp_1);
                                                range = [range[1], range[2]]
                                                // hide associated input
                                                hide  = inp.className.search(/fd_hide_input/ig) != -1;
                                        };
                                        // callback function
                                        callback =  inp.className.search(regExp_2) != -1 ? inp.className.match(regExp_2)[1].replace("-", ".") : "";
                                        // extra classname to assign to the wrapper div
                                        classname = inp.className.search(regExp_3) != -1 ? inp.className.match(regExp_3)[1] : "";
                                        // use the tween animation
                                        tween = inp.className.search(/fd_tween/ig) != -1;
                                        // vertical
                                        vertical = inp.className.search(/fd_vertical/ig) != -1;
                                        fdSliderController.sliders[inp.id] = new fdSlider(inp, range, callback, classname, hide, tween, vertical);
                                };
                        };
                },

                deconstruct: function( e ) {
                        for(slider in fdSliderController.sliders) { fdSliderController.sliders[slider].destroy(); };
                        fdSliderController.sliders = null;
                        fdSliderController.removeEvent(window, "load",   fdSliderController.construct);
                        fdSliderController.removeEvent(window, "unload", fdSliderController.deconstruct);
                        /*@cc_on@*/
                        /*@if(@_win32)
                        fdSliderController.removeEvent(window, "load",   function() { setTimeout(fdSliderController.onload, 200) });
                        /*@end@*/
                }
        }
})();

fdSliderController.addEvent(window, "unload", fdSliderController.deconstruct);
fdSliderController.addEvent(window, "load",   fdSliderController.construct);
/*@cc_on@*/
/*@if(@_win32)
fdSliderController.addEvent(window, "load",   function() { setTimeout(fdSliderController.onload, 200) });
/*@end@*/
