<!-- webview only -->
<template>
    <section class="bl___slider-container" @click.capture="$emit('click', $event)" @touchstart.capture="$emit('touchstart', $event)" @touchmove.capture="$emit('touchmove', $event)" @touchend.capture="$emit('touchend', $event)" @touchcancel.capture="$emit('touchcancel', $event)">
        <section class="progress-container" :style="{'margin': `0 ${buttonSize / 2}px`, 'background': backgroundColor}" ref="progressContainer" @click="handleClick">
            <section class="progress-bar" :style="{'width': `${buttonPosition}%`, 'background': activeColor}"></section>
            <section class="progress-switch" :style="{'width': `${buttonSize}px`, 'height': `${buttonSize}px`, 'left': `${buttonPosition}%`, 'background': blockColor}" @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"></section>
        </section>
        <section class="text-info" v-if="showValue">{{value}}</section>
    </section>
</template>

<script>
export default {
    name: 'BSlider',
    props: {
        min: {
            type: Number,
            default: 0
        },
        max: {
            type: Number,
            default: 100,
        },
        step: {
            type: Number,
            default: 1,
        },
        disabled: {
            type: Boolean,
            default: false,
        },
        value: {
            type: Number,
            default: 0,
        },
        activeColor: {
            type: String,
            default: '#ff5687',
        },
        backgroundColor: {
            type: String,
            default: '#e9e9e9',
        },
        blockSize: {
            type: Number,
            default: 28,
            validator(value) {
                return value >= 12 && value <= 28
            }
        },
        blockColor: {
            type: String,
            default: '#ffffff',
        },
        showValue: {
            type: Boolean,
            default: false,
        }
    },
    model: {
        prop: 'value',
        event: 'changeValue'
    },
    computed: {
        buttonSize() {
            return Math.max(12, Math.min(28, this.blockSize));
        },
        buttonPosition() {
            return (this.value - this.min) / (this.max - this.min) * 100;
        },
        accuracy() {
            let length = 0;

            while (this.step * Math.pow(10, length) % 1 !== 0) {
                length++;
            }

            return length;
        }
    },
    methods: {
        handleClick(e) {
            if (this.disabled) return;

            const offsetX = e.layerX || e.offsetX;
            const perWidth = this.$refs.progressContainer.clientWidth / ((this.max - this.min) / this.step);
            const steps = Math.round(offsetX / perWidth);
            const value = steps * this.step + this.min;
            this.$emit('change', {detail: {value: Math.max(this.min, Math.min(this.max, parseFloat(value.toFixed(this.accuracy))))}});
            this.$emit('changeValue', {detail: {value: Math.max(this.min, Math.min(this.max, parseFloat(value.toFixed(this.accuracy))))}});
        },
        handleTouchStart(e) {
            if (this.disabled) return;

            e.preventDefault();
        },
        handleTouchMove(e) {
            if (this.disabled) return;

            e.preventDefault();
            const perWidth = this.$refs.progressContainer.clientWidth / ((this.max - this.min) / this.step);
            const containerLeft = this.$refs.progressContainer.getBoundingClientRect().x || this.$refs.progressContainer.getBoundingClientRect().left;
            const steps = Math.round((e.touches[0].clientX - containerLeft) / perWidth);

            this.$emit('changing', {detail: {value: Math.max(this.min, Math.min(this.max, parseFloat((this.step * steps + this.min).toFixed(this.accuracy))))}});
            this.$emit('changeValue', {detail: {value: Math.max(this.min, Math.min(this.max, parseFloat((this.step * steps + this.min).toFixed(this.accuracy))))}});
        },
        handleTouchEnd(e) {
            if (this.disabled) return;

            e.preventDefault();
            this.$emit('change', {detail: {value: this.value}});
        },
    }
}
</script>

<style lang="less" scoped>
.bl___slider-container {
    display: flex;
    flex-direction: row;
    align-items: center;

    .progress-container {
        height: 10px;
        flex: 1 1 0%;
        position: relative;

        .progress-bar {
            height: 10px;
        }

        .progress-switch {
            position: absolute;
            left: 0;
            top: 50%;
            transform: translate(-50%, -50%);
            border: 1px solid #eeeeee;
            border-radius: 50%;
        }
    }

    .progress-text {
        flex: 0 0 auto;
        font-size: 14px;
        line-height: 14px;
        margin-left: 10px;
    }
}
</style>
