import React from 'react';
import getOffsetRect from 'reneco-utils/getOffsetRect';
import addClass from 'reneco-utils/addClass';

import './Slider.scss';

export default class Slider extends React.Component {
    _drag=null;
    _width=0;
    _offsetLeft=0;
    constructor(props) {
        super(props);
        this.state = {
            drag: null,
            positions: [],
            values: props.values
        }
    }
    resize() {
        const {values} = this.state,
            {min, max} = this.props;
        this._width = this.$box.offsetWidth;
        this._offsetLeft = getOffsetRect(this.$box).x;
        this.setState({positions: values.map(v => this.calculatePosition(v, min, max))});
    }
    componentDidMount() {
        this.resize();
        window.addEventListener('mouseup', this.onMouseOut);
        window.addEventListener('mousemove', this.onMouseMove);
    }
    calculatePosition(value, min, max) {
        return value * this._width / (max - min);
    }
    onMouseDown(ix, e) {
        this.setState({drag: ix});
    }
    onMouseOut = e => {
        if(this.state.drag !== null) {
            this.setState({drag: null});
            this.props.onChange && this.props.onChange(this.state.values);
        }
    }
    onMouseMove = e => {
        if(this.state.drag !== null) {
            const {min, max} = this.props,
                value = (max - min) * (e.screenX - this._offsetLeft)/this._width,
                values = this.state.values.slice(),
                positions = this.state.positions.slice(),
                {drag} = this.state;
            values[drag] = Math.max(
                Math.min(
                    values[drag+1] !== undefined ? values[drag+1] : max,
                    max,
                    value
                ),
                values[drag-1] !== undefined ? values[drag-1] : min,
                min
            );
            positions[drag] = this.calculatePosition(values[drag], min, max);
            this.setState({ values, positions });
        }
    }
    render() {
        const baseClass = 'ui slider',
            {positions, drag} = this.state,
            {max, min} = this.props;

        return (<div
            draggable={false}
            ref={ref => this.$box=ref }
            className={baseClass}
        >
            {positions.map((v, ix) => {
                return (<div
                    key={ix}
                    draggable={false}
                    style={{ left: v-15 }}
                    onMouseDown={e => this.onMouseDown(ix, e)}
                    className={addClass(`${baseClass}-handle`, drag === ix && 'grab')}
                />);
            })}
        </div>);
    }
}