import React from 'react';
import addClass from 'reneco-utils/addClass';

import './TouchScroll.sass';

export default class TouchScroll extends React.Component {
    state = {
        leftMargin: 0,
        enable: true
    }
    scrollStarted = null
    $items={}
    touchStart = e => { this.state.enable && this.startSlide(e.touches[0].clientX, e.touches[0].clientY); }
    touchEnd = e => { this.stopSlide(); }
    touchSlide = e => { this.state.enable && this.toSlide(e.touches[0].clientX, e.touches[0].clientY); }
    startSlide(x, y){
        this.scrollStarted = {
            x: x,
            y: y
        };
    }
    stopSlide(){
        this.scrollStarted = null;
    }
    select(ix) {
        let ixPosition = Object.keys(this.$items)
            .sort()
            .slice(0, ix)
            .reduce((prevVal, curVal) => {
                return prevVal + this.$items[curVal].offsetWidth;
            }, 0); 
        if(
            ixPosition > this.state.leftMargin + this.$Box.offsetWidth 
            || ixPosition < -this.state.leftMargin) {
                this.slideTo(-ixPosition);
            }
    }
    getSliderWidth() {
        return Object.keys(this.$items).reduce((prevVal, curVal) => {
            return prevVal + this.$items[curVal].offsetWidth;
        }, 0);
    }
    fixLeftMargin(value) {
        let maxMargin = 0,
            minMargin = (this.getSliderWidth() - this.$Box.offsetWidth) * (-1);
        return value < minMargin
            ? minMargin
            : (value > maxMargin
                ? maxMargin
                : value);
    }
    slideTo(leftMargin) {
        leftMargin = this.fixLeftMargin(leftMargin);
        if (leftMargin !== this.state.leftMargin) {
            this.setState({
                leftMargin: leftMargin
            });
        }
    }
    toSlide = (x, y) => {
        if(this.scrollStarted !== null) {
            this.slideTo(this.state.leftMargin + x - this.scrollStarted.x);
        }
    }
    onClickNext = () => {
        this.slideTo(this.state.leftMargin - this.$Box.offsetWidth);
    }
    onClickPrev = () => {
        this.slideTo(this.state.leftMargin + this.$Box.offsetWidth);
    }
    checkEnable = () => {
        let enable = this.$Box.offsetWidth <= this.getSliderWidth();
        if(enable !== this.state.enabled) {
            this.enable = enable;
            this.setState({
                enable: enable
            });
        }
    }
    componentWillUnmount() {
        window.removeEventListener('resize', this.checkEnable);
        this.$items = {};
        this.scrollStarted = null;
    }
    componentDidMount() {
        // this.toSlide = throttle(this.toSlide, 300);
        this.checkEnable();
        window.addEventListener('resize', this.checkEnable);
    }
    render() {
        let props = this.props,
            state = this.state,
            baseClass = 'slider-touch-scroll';
        return (<div
            style={props.style || {}}
            className={addClass(
                addClass(
                    baseClass,
                    props.className
                ),
                state.enable && baseClass + '-enabled'
            )}
        >
            <div
                ref={ref => { this.$Box = ref; }}
                className={baseClass + '-box'}
                onTouchStart={this.touchStart}
                onTouchEnd={this.touchEnd}
                onTouchCancel={this.touchEnd}
                onTouchMove={this.touchSlide}
            >
                <div
                    style={{
                        marginLeft: state.leftMargin
                    }}
                    className={baseClass + '-items'}
                >
                    {React.Children.map(props.children, (item, ix) => {
                        return (<div
                            className={baseClass + '-item'}
                            ref={ref => { this.$items[ix] = ref; }}
                            key={ix}
                        >
                            { item }
                        </div>);
                    })}
                </div>
            </div>
            {state.enable && <button onClick={this.onClickPrev} className={baseClass + '-button-left'} />}
            {state.enable && <button onClick={this.onClickNext} className={baseClass + '-button-right'} />}
        </div>);
    }
}
