/*global jQuery, window */
(function ($) {

    $.widget('ui.smgslider', {
        _init: function () {

            if (this.options.id === 'defaultId') {
                this.options.id = this.element.attr('id');
            }

            var o = this.options;

            if (o.startHidden) {
                this.element.css('visibility', 'hidden');
            }

            if ($('input#' + o.id + 'Min').length) {
                o.min = parseFloat($('input#' + o.id + 'Min').val());
            } else if (o.min === null) {
                o.min = 0;
            } else {
                o.min = parseFloat(o.min);
            }

            if ($('input#' + o.id + 'Max').length) {
                o.max = parseFloat($('input#' + o.id + 'Max').val());
            } else if (o.max === null) {
                o.max = 1;
            } else {
                o.max = parseFloat(o.max);
            }

            o.step = parseFloat(o.step);


            this.element.append('<p class="sliderTitle" id="' + o.id + 'Title"></strong>')
                    .append('<p class="sliderLabel" id="' + o.id + 'Label"></p>')
                    .append('<div id="' + o.id + 'Slider"></div>');

            this.slider = $('div#' + o.id + 'Slider').slider({
                range: true,
                max: o.max,
                min: o.min,
                step: o.step,
                values: [o.min, o.max],
                slide: function (event, ui) {
                    $(event.target.parentNode).smgslider('slide');
                },
                stop: function (event, ui) {
                    $(event.target.parentNode).smgslider('stop');
                }
            });

            this._updateLabel();
            this._updateTitle();

            // Display the slider after a timeout
            if (o.startHidden) {
                window.setTimeout('$("div#' + o.id + '").css("visibility", "visible");', o.displayTimeout);
            }

        },

        // Public functions
        slide: function () {
            this._updateLabel();
        },

        stop: function () {
            var values = [false, false];

            if (this.options.unboundedMin && $(this.slider).slider("values")[0] === this.options.min) {
                // Leave as false
            } else {
                values[0] = $(this.slider).slider("values")[0];
            }

            if (this.options.unboundedMax && $(this.slider).slider("values")[1] === this.options.max) {
                // Leave as false
            } else {
                values[1] = $(this.slider).slider("values")[1];
            }

            this.options.ajaxCallback(this._round(values, this.options.step));
        },

        reconfigure: function (methodOptions) {
            this.options.title = (methodOptions.title === null) ? this.options.title : methodOptions.title;
            this.options.min = (methodOptions.min === null) ? this.options.min : parseFloat(methodOptions.min);
            this.options.max = (methodOptions.max === null) ? this.options.max : parseFloat(methodOptions.max);
            this.options.step = (methodOptions.step === null) ? this.options.step : parseFloat(methodOptions.step);
            this._updateTitle();
            this.reset();
        },

        reset: function () {
            $(this.slider).slider('option', 'min', this.options.min);
            $(this.slider).slider('option', 'max', this.options.max);
            $(this.slider).slider('option', 'values', [this.options.min, this.options.max]);
            $(this.slider).slider('option', 'step', this.options.step);
            this._updateLabel([this.options.min, this.options.max]);
        },

        disable: function () {
            this.element.css('border', '2px solid red');
            $(this.slider).slider('disable');
            this.element.hide();
        },

        enable: function () {
            this.element.css('border', 'none');
            $(this.slider).slider('enable');
            this.element.show();
        },

        // Private functions
        _updateLabel: function () {
            var values = $(this.slider).slider('values'),
                labelText = '';
            if (this.options.unboundedMin && values[0] === this.options.min) {
                labelText = this.options.lessThanSymbol;
            }
            labelText += this._formatValue(this._round(values[0], this.options.step)) +
                         ' - ' +
                         this._formatValue(this._round(values[1], this.options.step));
            if (this.options.unboundedMax && values[1] === this.options.max) {
                labelText += this.options.moreThanSymbol;
            }
            labelText += this.options.labelSuffix;
            $('p#' + this.options.id + 'Label').text(labelText);
        },

        _updateTitle: function () {
            $('p#' + this.options.id + 'Title').text(this.options.title);
        },

        _formatValue: function (number) {
            var numberString = number.toString(),
                i = numberString.length % 3,
                ret = '0';
            if (number > 999) {
                ret = numberString.substr(0, i);

                for (; i < numberString.length; i = i + 3) {
                    if (ret.length > 0) {
                        ret = ret + ",";
                    }
                    ret = ret + numberString.substr(i, 3);
                }
            } else {
                ret = numberString;
            }
            return ret;
        },

        _round: function (x, step) {
            if (this.options.dontRound) {
                return x;
            } else {
                var factor = 1 / step,
                    i;
                if ($.isArray(x)) {
                    for (i = 0; i < x.length; i = i + 1) {
                        x[i] = Math.round(x[i] * factor) / factor;
                    }
                    return x;
                } else {
                    return Math.round(x * factor) / factor;
                }
            }
        }
    });

    $.extend($.ui.smgslider, {
        version: "0.9",
        defaults: {
            id: 'defaultId',
            title: "",
            min: null,
            max: null,
            step: 1,
            labelSuffix: "",
            ajaxCallback: true,
            dontRound: false,
            startHidden: true,
            displayTimeout: 500,
            unboundedMin: false,
            lessThanSymbol: '<',
            unboundedMax: false,
            moreThanSymbol: '+'
        }
    });

}(jQuery));
