var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
define(["require", "exports", 'react', '../../utilities/eventGroup/EventGroup', '../../utilities/KeyCodes', '../../utilities/css', '../../utilities/rtl', './Slider.scss'], function (require, exports, React, EventGroup_1, KeyCodes_1, css_1, rtl_1) {
    "use strict";
    (function (ValuePosition) {
        ValuePosition[ValuePosition["Previous"] = 0] = "Previous";
        ValuePosition[ValuePosition["Next"] = 1] = "Next";
    })(exports.ValuePosition || (exports.ValuePosition = {}));
    var ValuePosition = exports.ValuePosition;
    var _instance = 0;
    var Slider = (function (_super) {
        __extends(Slider, _super);
        function Slider(props) {
            var validProps = Slider.ensurePropsValid(props);
            _super.call(this, validProps);
            this._events = new EventGroup_1.EventGroup(this);
            this._onMouseDownOrTouchStart = this._onMouseDownOrTouchStart.bind(this);
            this._onMouseMoveOrTouchMove = this._onMouseMoveOrTouchMove.bind(this);
            this._onMouseUpOrTouchEnd = this._onMouseUpOrTouchEnd.bind(this);
            this._onKeyDown = this._onKeyDown.bind(this);
            this._id = "Slider-" + _instance++;
            this.state = {
                value: validProps.initialValue
            };
        }
        Slider.ensurePropsValid = function (props) {
            if (props.max <= props.min) {
                props.max = props.min + 1;
            }
            if (!props.step || props.step <= 0) {
                props.step = 1;
            }
            if (!props.initialValue || props.initialValue < props.min) {
                props.initialValue = props.min;
            }
            else if (props.initialValue > props.max) {
                props.initialValue = props.max;
            }
            return props;
        };
        /**
         * Invoked when a component is receiving new props. This method is not called for the initial render.
         */
        Slider.prototype.componentWillReceiveProps = function (newProps) {
            var validProps = Slider.ensurePropsValid(newProps);
            this.setState({
                value: validProps.initialValue
            });
        };
        Slider.prototype.componentWillUnmount = function () {
            this._events.dispose();
        };
        Slider.prototype.render = function () {
            var max = this.props.max;
            var min = this.props.min;
            var value = this.state.value;
            var label = this.props.label;
            var showValue = this.props.showValue;
            var isDisabled = this.props.isDisabled;
            var thumbOffsetPercent = (value - min) / (max - min) * 100;
            var ariaLabel = this.props.ariaLabel;
            var onMouseDownProp = isDisabled ? {} : { onMouseDown: this._onMouseDownOrTouchStart };
            var onTouchStartProp = isDisabled ? {} : { onTouchStart: this._onMouseDownOrTouchStart };
            var onKeyDownProp = isDisabled ? {} : { onKeyDown: this._onKeyDown };
            return (React.createElement("div", {ref: 'root'}, label && React.createElement("label", React.__spread({className: 'ms-Label'}, ariaLabel ? {} : { 'htmlFor': this._id }), label), React.createElement("div", {className: css_1.css('ms-Slider-wrapper', {
                'ms-Slider-showValue': showValue
            })}, React.createElement("div", React.__spread({ref: 'sliderLine', role: 'application', className: css_1.css('ms-Slider-line', {
                'ms-Slider-enabled': !isDisabled,
                'ms-Slider-disabled': isDisabled
            })}, onMouseDownProp, onTouchStartProp), React.createElement("span", React.__spread({ref: 'thumb', id: this._id, className: 'ms-Slider-thumb'}, isDisabled ? {} : { 'tabIndex': 0 }, {role: 'slider', "aria-valuenow": value, "aria-valuemin": min, "aria-valuemax": max}, ariaLabel ? { 'aria-label': ariaLabel } : {}, {style: rtl_1.getRTL() ?
                { 'right': thumbOffsetPercent + '%' } :
                { 'left': thumbOffsetPercent + '%' }}, onKeyDownProp)), React.createElement("span", {className: 'ms-Slider-active', style: { 'width': thumbOffsetPercent + '%' }}), React.createElement("span", {className: 'ms-Slider-inactive', style: { 'width': (100 - thumbOffsetPercent) + '%' }})), showValue && React.createElement("label", {className: 'ms-Label ms-Slider-value'}, value))));
        };
        Slider.prototype.focus = function () {
            if (this.refs.thumb) {
                this.refs.thumb.focus();
            }
        };
        Slider.prototype._onMouseDownOrTouchStart = function (event) {
            if (event.type === 'mousedown') {
                this._events.on(window, 'mousemove', this._onMouseMoveOrTouchMove, true);
                this._events.on(window, 'mouseup', this._onMouseUpOrTouchEnd, true);
            }
            else if (event.type === 'touchstart') {
                this._events.on(window, 'touchmove', this._onMouseMoveOrTouchMove, true);
                this._events.on(window, 'touchend', this._onMouseUpOrTouchEnd, true);
            }
            this._onMouseMoveOrTouchMove(event);
        };
        Slider.prototype._onMouseMoveOrTouchMove = function (event) {
            var max = this.props.max;
            var min = this.props.min;
            var step = this.props.step;
            var onChanged = this.props.onChanged;
            var steps = (max - min) / step;
            var sliderLength = this.refs.sliderLine.offsetWidth;
            var stepLength = sliderLength / steps;
            var sliderPositionRect = this.refs.sliderLine.getBoundingClientRect();
            var currentSteps;
            if (event.type === 'mousedown' || event.type === 'mousemove') {
                currentSteps = rtl_1.getRTL() ?
                    (sliderPositionRect.right - event.clientX) / stepLength :
                    (event.clientX - sliderPositionRect.left) / stepLength;
            }
            else if (event.type === 'touchstart' || event.type === 'touchmove') {
                currentSteps = rtl_1.getRTL() ?
                    (sliderPositionRect.right - event.touches[0].clientX) / stepLength :
                    (event.touches[0].clientX - sliderPositionRect.left) / stepLength;
            }
            var currentValue;
            // The value shouldn't be bigger than max or be smaller than min.
            if (currentSteps > Math.floor(steps)) {
                currentValue = max;
            }
            else if (currentSteps < 0) {
                currentValue = min;
            }
            else {
                currentValue = min + step * Math.round(currentSteps);
            }
            this.setState({
                value: currentValue
            });
            if (onChanged) {
                onChanged(currentValue);
            }
            event.preventDefault();
            event.stopPropagation();
        };
        Slider.prototype._onMouseUpOrTouchEnd = function () {
            this._events.off();
        };
        Slider.prototype._onKeyDown = function (event) {
            var max = this.props.max;
            var min = this.props.min;
            var step = this.props.step;
            var value = this.state.value;
            var onChanged = this.props.onChanged;
            var diff = 0;
            if (event.which === rtl_1.getRTLSafeKeyCode(KeyCodes_1.KeyCodes.left)) {
                diff = -step;
            }
            else if (event.which === rtl_1.getRTLSafeKeyCode(KeyCodes_1.KeyCodes.right)) {
                diff = step;
            }
            else {
                return;
            }
            var newValue = Math.min(max, Math.max(min, value + diff));
            this.setState({
                value: newValue
            });
            if (onChanged) {
                onChanged(newValue);
            }
            event.preventDefault();
            event.stopPropagation();
        };
        Slider.defaultProps = {
            step: 1,
            showValue: true,
            isDisabled: false
        };
        return Slider;
    }(React.Component));
    exports.Slider = Slider;
});
