<template>
	<view  class="fulled tm-slider " :class="[step > 0 ? 'pb-36' : 'pb-24']"
		:style="{ height: vertical ? heightpx + 'px' : 'auto', width: vertical ? '5px' : '100%'}">
		<view class=" tm-slider-id fulled " :class="[vertical ? 'vertical' : 'flex-between']">
			<!-- 左边label -->
			<view v-if="showLeft" class="label_slider left  flex-col text-size-xs text-grey-darken-1"
				:class="[vertical ? '' : 'flex-center']">
				<slot name="left" :data="{ value: value, color: color_tmeme, icon: leftIcon,max:max }">
					<tm-icons v-if="leftIcon && !vertical" size="28" :name="leftIcon" :color="color_tmeme"></tm-icons>
					<view class="text-size-xs text-grey-darken-1 ">{{ value }}</view>
				</slot>
			</view>
			<!-- 条子内容 -->
			<view class="slider_id " 
				:style="{ width: vertical ? 'auto' : sliderWidth + 'px', height: vertical ? sliderWidth + 'px' : '5px' }">
				<view class="slider_id_bg  round-10" :class="[bgColor,black_tmeme?'bk':'']"></view>
				<view
					:style="{ width: vertical ? '100%' : active_width + '%', height: vertical ? active_width + '%' : '100%' }"
					class="slider_id_active round-10 " :class="[color_tmeme,black_tmeme?'bk':'']"></view>
				<view  :style="{ left: vertical ? 0 : barLeft + 'px', top: vertical ? barLeft + 'px' : 0 }"
					@touchcancel="barEnd" @touchstart="barStart" @touchend="barEnd" @touchmove.stop.prevent="barMove"
					@mouseleave="barEnd" @mousedown="barStart" @mouseup="barEnd" @mousemove.stop.prevent="barMove"
					class="slider_bar border-white-a-2  rounded" :class="[color_tmeme,black_tmeme?'bk':'', ` shadow-${color_tmeme}-10`]">
					<view v-if="showTopTips||showTip" class="slider_bar_showbg border-white-a-1" :class="[color_tmeme,black_tmeme?'bk':'']"></view>
					<view v-if="showTopTips||showTip" class="slider_bar_num text-size-xs flex-center" :class="[color_tmeme,black_tmeme?'bk':'']">
						<slot name="tips" :data="value">{{ value }}</slot>
					</view>
				</view>
				<!-- 步长刻度尺 -->
				<view class="kdc_wk ">
					<view v-for="(item, index) in kdcNum" :key="index"
						:style="{ left: vertical ? 0 : item.left, top: vertical ? item.left : 0 }" :class="[color_tmeme,black_tmeme?'bk':'']"
						class="kdc_wk_item rounded  border-white-a-1 ">
						<view class="kdc_wk_item_label  pl-0" :class="[vertical ? 'pl-24' : 'pa-24']">
							<text class="text-size-xs text-grey-darken-1 ">{{ item.kedu }}</text>
						</view>
					</view>
				</view>
			</view>
			<!-- 右边label -->
			<view v-if="showRight" class="label_slider right  flex-col text-size-xs text-grey-darken-1"
				:class="[vertical ? 'flex-end' : 'flex-center']">
				<slot name="right" :data="{ value: value, color: color_tmeme, icon: rightIcon,max:max }">
					<tm-icons v-if="rightIcon && !vertical" size="28" :name="rightIcon" :color="color_tmeme"></tm-icons>
					<view class="text-size-xs text-grey-darken-1 ">{{ max }}</view>
				</slot>
			</view>
		</view>
	</view>
</template>

<script>

	/**
	 * 滑块
	 * @property {Number} value = [0] 赋值，如果需要同步使用value.sync推荐使用v-model绑定。
	 * @property {Boolean} vertical = [true|false] 默认：false,是否启用竖向模式。
	 * @property {Number} height = [200] 默认：200,竖向模式时才有作用。
	 * @property {Number} width = [] 默认：0,横向时起作用，如果为0自动获取外层宽度。
	 * @property {Boolean} show-left = [true|false] 默认：false,显示左边数据。
	 * @property {Boolean} show-right = [true|false] 默认：false,显示右边数据。
	 * @property {Number} max = [] 默认：100,显示的最大刻度。
	 * @property {Number} value-diog = [] 默认：0,取值小数点后几位
	 * @property {Boolean} disabled = [true|false] 默认：false, 是否禁用。
	 * @property {Boolean} showTip = [true|false] 默认：false, 始终显示进度标签。
	 * @property {Number} step = [10|20] 默认：0, 步长,设置请尽量大于20.太小滑动容易过小出问题。
	 * @property {String} color = [primary] 默认：primary,  主题颜色名称。
	 * @property {String} bg-color = [grey-lighten-2] 默认：grey-lighten-2,  底部不活动的背景色,颜色名称。
	 * @property {String} left-icon = [] 默认：icon-minus,   左边图标
	 * @property {String} right-icon = [] 默认：icon-plus,   右边图标
	 * @property {String} name = [] 默认：''，提交表单时的的字段名称标识
	 * @property {Function} change 同v-model和value相等的参数，变动时触发。
	 * @example <tm-slider v-model="checked"  ></tm-slider>
	 * 
	 */
	import tmIcons from "@/tm-vuetify/components/tm-icons/tm-icons.vue"
	export default {
		name:'tm-slider',
		components:{tmIcons},
		model:{
			prop:'value',
			event:'input'
		},
		props: {
			//提交表单时的的字段名称
			name:{
				type:String,
				default:''
			},
			vertical: Boolean, //是否启用竖向模式。需要和height配合使用。
			// 单位upx.
			height: {
				type: Number,
				default: 200
			},
			width: {
				type: Number,
				default: 0
			},
			showLeft: Boolean, //显示左边
			showRight: Boolean, //显示右边
			// 最大刻度。
			max: {
				type: Number,
				default: 100
			},
			// 默认的数据。不能大于max.,使用.sync修饰。双向绑定数据。
			value: {
				type: Number,
				default: 0
			},
			// 取值小数点后几位。默认为0
			valueDiog: {
				type: Number,
				default: 0
			},
			// 是否禁用。
			disabled: Boolean,
			//步长。默认为0,设置请尽量大于0.太小滑动容易过小出问题。
			step: {
				type: Number,
				default: 0
			},
			// 主题颜色名称。
			color: {
				type: String,
				default: 'primary'
			},
			// 底部不活动的背景色,颜色名称。。
			bgColor: {
				type: String,
				default: 'grey-lighten-2'
			},
			// 左边图标名称。
			leftIcon: {
				type: String | Boolean,
				default: 'icon-minus'
			},
			// 右边图标名称。
			rightIcon: {
				type: String | Boolean,
				default: 'icon-plus'
			},
			// 始终显示进度提示窗
			showTip: {
				type: Boolean,
				default: false
			},
			// 跟随主题色的改变而改变。
			fllowTheme:{
				type:Boolean|String,
				default:true
			},
			black: {
				type: Boolean,
				default: null
			},
		},
		watch: {
			value: function(val) {
				let rdl = this.sliderWidth * (Math.abs(val) / Math.abs(this.max));
				this.barLeft = rdl >= this.sliderWidth || rdl < 0 ? this.sliderWidth : rdl;
				
			},
			barLeft: function() {
				let value = (this.barLeft / this.sliderWidth) * this.max;
				
				if (!isNaN(value)) {
					if (this.valueDiog > 0) {
						let s = value.toString();

						let st = s.split('.');

						let ruslt = 0;
						if (st.length > 1) {
							ruslt = parseFloat(st[0] + '.' + st[1].substring(0, this.valueDiog));
						} else {
							ruslt = parseFloat(s);
						}
						this.$emit('update:value', ruslt);
						this.$emit('input', ruslt);
						this.$emit('change', ruslt);
					} else {
						this.$emit('update:value', parseInt(value));
						this.$emit('input', parseInt(value));
						this.$emit('change', parseInt(value));
					}
				}
			}
		},
		computed: {
			black_tmeme: function() {
				if (this.black !== null) return this.black;
				return this.$tm.vx.state().tmVuetify.black;
			},
			// 计算刻度尺的数量
			kdcNum: function() {
				if (Math.abs(this.step) <= 0) return [];
				let jlv = Math.abs(this.step) / Math.abs(this.max);
				let left_width = jlv * (this.sliderWidth - 0);
				let kd_num = parseInt(this.sliderWidth / left_width);
				let ar = [];
				for (let i = 0; i <= kd_num; i++) {
					ar.push({
						index: i, //顺序
						left: i * left_width + 'px', //距离左边距离
						kedu: this.step * i //当前刻度数量。
					});
				}
				return ar;
			},
			//比例
			active_width: function() {
				return (this.barLeft / this.sliderWidth) * 100;
			},
			heightpx: function() {
				return uni.upx2px(this.height);
			},
			color_tmeme:function(){
				if(this.$tm.vx.state().tmVuetify.color!==null&&this.$tm.vx.state().tmVuetify.color && this.fllowTheme){
					return this.$tm.vx.state().tmVuetify.color;
				}
				return this.color;
			},
		},
		data() {
			return {
				sliderWidth: 0,
				x: 0,
				startMove: false,
				barLeft: 0,
				isError: false,
				showTopTips: false
			};
		},
		async mounted() {
			this.$nextTick(async function() {
				await this.getwidth();
				if (Math.abs(this.value) > Math.abs(this.max)) {
					this.isError = true;
					return;
				}
				let rdl = this.sliderWidth * (Math.abs(this.value) / Math.abs(this.max));
				this.barLeft = rdl >= this.sliderWidth || rdl < 0 ? this.sliderWidth : rdl;
			});
		},
		methods: {
			barStart(e) {
				
				if (this.disabled || this.isError) return;
				if(e.type.indexOf('mouse')>-1&&e.changedTouches.length==0){
					this.x = (this.vertical ? e.pageY : e.pageX) - this.barLeft;
					this.startMove = true;
					this.showTopTips = true;
				}else{
					if (e.changedTouches.length > 0) {
						this.x = (this.vertical ? e.changedTouches[0].pageY : e.changedTouches[0].pageX) - this.barLeft;
						this.startMove = true;
						this.showTopTips = true;
					}
				}
				
				this.$nextTick(function(){
					this.$emit('start',this.value)
				})
			},
			barEnd(e) {
				
				if (this.disabled || this.isError) return;
				this.startMove = false;
				this.showTopTips = false;
				this.$nextTick(function(){
					this.$emit('end',this.value)
				})
			},
			barMove(e) {
				if (this.disabled || this.isError) return;
				if (!this.startMove) return;
				let left = 0;
				if(e.type.indexOf('mouse')>-1&&e.changedTouches.length==0){
					left = (this.vertical ? e.pageY : e.pageX) - this.x;
				}else{
					left = (this.vertical ? e.changedTouches[0].pageY : e.changedTouches[0].pageX) - this.x;
				}
				if (left <= 0) {
					this.barLeft = 0;
					return;
				}
				if (left >= this.sliderWidth) {
					this.barLeft = this.sliderWidth;
					return;
				}
				let nowStep = parseInt(Math.abs(left - this.barLeft));
				let bdi = parseInt((this.step / this.max) * this.sliderWidth);
				
				if (nowStep >= bdi) {
					// 每一小段的值。
					
					if(this.step!==0){
						let kedud = this.sliderWidth / (this.max / this.step);
						this.barLeft = Math.round(left / kedud) * kedud;
					}else{
						this.barLeft = left;
					}
				}
				
			},
			async getwidth() {
				let res = await this.$Querey('.tm-slider-id', this).catch(e=>{});
				res[0].width = res[0].width||uni.upx2px(this.width);
				res[0].height = res[0].height||uni.upx2px(this.height);
				if (this.showLeft === false && this.showRight === false) {
					this.sliderWidth = this.vertical ? res[0].height : res[0].width;
					return;
				}
				if (this.showLeft !== false && this.showRight !== false) {
					
					this.sliderWidth = (this.vertical ? res[0].height : res[0].width) - uni.upx2px(this.vertical ? 50 :
						100) * 2;
					return;
				}
				if (this.showLeft === true || this.showRight === true) {
					this.sliderWidth = (this.vertical ? res[0].height : res[0].width) - uni.upx2px(this.vertical ? 50 :
						100);
				}
			}
		}
	};
</script>

<style lang="scss" scoped>
	.label_slider {
		flex-shrink: 0;

		&.left,
		&.right {
			width: 100upx;
		}
	}

	.tm-slider-id {
		width: 100%;

		.slider_id {
			position: relative;
			height: 4px;

			.slider_id_bg {
				width: 100%;
				height: 100%;
			}

			.slider_id_active {
				width: 100%;
				height: 100%;
				position: absolute;
				top: 0;
				left: 0;
				z-index: 5;
			}

			.slider_bar {
				position: absolute;
				width: 40upx;
				height: 40upx;
				left: 0;
				top: 0;
				margin-top: -22upx;
				z-index: 10;

				.slider_bar_showbg {
					position: absolute;
					width: 50upx;
					height: 50upx;
					border-radius: 30upx;
					border-bottom-left-radius: 5upx;
					transform: rotate(-45deg);
					bottom: 60upx;
					left: -9upx;
					animation: roteScaleTop_BG 0.3s ease-in-out;
				}

				.slider_bar_num {
					position: absolute;
					width: 50upx;
					height: 50upx;
					border-radius: 50upx;
					left: -8upx;
					bottom: 60upx;
					line-height: 50upx;
					text-align: center;
					background: transparent !important;
					animation: roteScaleTop 0.3s ease-in-out;
				}
			}

			.kdc_wk {
				width: 100%;
				height: 100%;
				position: absolute;
				z-index: 6;
				left: 0;
				top: -2upx;

				.kdc_wk_item {
					width: 10upx;
					height: 10upx;
					position: absolute;
					z-index: 7;
					text-align: center;

					.kdc_wk_item_label {
						margin-left: -100%;
					}
				}
			}
		}

		&.vertical {
			height: 100%;

			.label_slider {
				flex-shrink: 0;

				&.left,
				&.right {
					width: auto;
					height: 50upx;
				}
			}

			.slider_bar {
				margin-left: -18upx;
			}

			.kdc_wk {
				top: 0upx;

				.kdc_wk_item {
					.kdc_wk_item_label {
						margin-left: 100%;
						margin-top: -15upx;
					}
				}
			}
		}
	}
	
	@keyframes roteScaleTop_BG{
		0%{
			transform: scale(0.9) translateY(20rpx) rotate(-45deg);
			opacity: 0;
		}
		100%{
			transform: scale(1)  translateY(0rpx) rotate(-45deg);
			opacity: 1;
		}
	}
	@keyframes roteScaleTop{
		0%{
			transform: scale(0.9) translateY(20rpx);
			opacity: 0;
		}
		100%{
			transform: scale(1)  translateY(0rpx);
			opacity: 1;
		}
	}
</style>
