<template>
	<!-- #ifndef APP-NVUE -->
	<uv-popup 
		ref="pickerColorPopup"
		mode="bottom"
		:close-on-click-overlay="closeOnClickOverlay"
		@change="popupChange">
		<view class="uv-pick-color">
			<uv-toolbar
				:show="showToolbar"
				:cancelColor="cancelColor"
				:confirmColor="confirmColor"
				:cancelText="cancelText"
				:confirmText="confirmText"
				:title="title"
				:show-border="true"
				@cancel="cancelHandler"
				@confirm="confirmHandler"></uv-toolbar>
			<view 
				class="uv-pick-color__box"
				:style="{
					background:`rgb(${bgcolor.r},${bgcolor.g},${bgcolor.b})`
				}"
			>
				<!-- #ifdef H5 -->
				<view
					class="uv-pick-color__box__bg drag-box"
					@tap.stop.prevent="touchstart($event, 0)"
					@touchstart.stop.prevent="touchstart($event, 0)"
					@touchmove.stop.prevent="touchmove($event, 0)"
					@touchend.stop.prevent="touchend($event, 0)"
				>
				<!-- #endif -->
				<!-- #ifndef H5 -->
				<view
					class="uv-pick-color__box__bg drag-box"
					@touchstart.stop.prevent="touchstart($event, 0)"
					@touchmove.stop.prevent="touchmove($event, 0)"
					@touchend.stop.prevent="touchend($event, 0)"
				>
				<!-- #endif -->
					<view class="uv-pick-color__box__bg-mask"></view>
					<view 
						class="uv-pick-color__box__bg-pointer"
						:style="[pointerStyle]"
					>
					</view>
				</view>
			</view>
			<view class="uv-pick-color__control">
				<view class="uv-pick-color__control__alpha">
					<view 
						class="uv-pick-color__control__alpha--color"
						:style="{ background:`rgba(${rgba.r},${rgba.g},${rgba.b},${rgba.a})` }"
					></view>
				</view>
				<view class="uv-pick-color__control__item">
					<!-- #ifdef H5 -->
					<view
						class="uv-pick-color__control__item__drag drag-box"
						@tap.stop="touchstart($event, 1)"
						@touchstart.stop="touchstart($event, 1)"
						@touchmove.stop="touchmove($event, 1)"
						@touchend.stop="touchend($event, 1)"
					>
					<!-- #endif -->
					<!-- #ifndef H5 -->
					<view
						class="uv-pick-color__control__item__drag drag-box"
						@touchstart.stop="touchstart($event, 1)"
						@touchmove.stop="touchmove($event, 1)"
						@touchend.stop="touchend($event, 1)"
					>
					<!-- #endif -->
						<view class="uv-pick-color__control__item__drag--hue"></view>
						<view 
							class="uv-pick-color__control__item__drag--circle"
							:style="{ 
								left: $uv.getPx(site[1].left - 10,true)
							}"
						></view>
					</view>
					<!-- #ifdef H5 -->
					<view
						class="uv-pick-color__control__item__drag drag-box"
						@tap.stop="touchstart($event, 2)"
						@touchstart.stop="touchstart($event, 2)"
						@touchmove.stop="touchmove($event, 2)"
						@touchend.stop="touchend($event, 2)"
					>
					<!-- #endif -->
					<!-- #ifndef H5 -->
					<view
						class="uv-pick-color__control__item__drag drag-box"
						@touchstart.stop="touchstart($event, 2)"
						@touchmove.stop="touchmove($event, 2)"
						@touchend.stop="touchend($event, 2)"
					>
					<!-- #endif -->
						<view class="uv-pick-color__control__item__drag--alpha"></view>
						<view 
							class="uv-pick-color__control__item__drag--circle"
							:style="{ 
								left: $uv.getPx(site[2].left - 10,true)
							}"
						></view>
					</view>
				</view>
			</view>
			<view class="uv-pick-color__result">
				<view 
					class="uv-pick-color__result__select"
					hover-class="uv-hover-class"
					@click.stop="select"
				>
					<text class="text">切换</text>
					<text class="text">模式</text>
				</view>
				<view class="uv-pick-color__result__item" v-if="mode">
					<view class="uv-pick-color__result__item--value uv-border">
						<text>{{hex}}</text>
					</view>
					<view class="uv-pick-color__result__item--hex">
						<text>HEX</text>
					</view>
				</view>
				<template v-else>
					<view class="uv-pick-color__result__item">
						<view class="uv-pick-color__result__item--value uv-border">
							<text>{{rgba.r}}</text>
						</view>
						<view class="uv-pick-color__result__item--rgba">
							<text>R</text>
						</view>
					</view>
					<view class="uv-pick-color__result__gap"></view>
					<view class="uv-pick-color__result__item">
						<view class="uv-pick-color__result__item--value uv-border">
							<text>{{rgba.g}}</text>
						</view>
						<view class="uv-pick-color__result__item--rgba">
							<text>G</text>
						</view>
					</view>
					<view class="uv-pick-color__result__gap"></view>
					<view class="uv-pick-color__result__item">
						<view class="uv-pick-color__result__item--value uv-border">
							<text>{{rgba.b}}</text>
						</view>
						<view class="uv-pick-color__result__item--rgba">
							<text>B</text>
						</view>
					</view>
					<view class="uv-pick-color__result__gap"></view>
					<view class="uv-pick-color__result__item">
						<view class="uv-pick-color__result__item--value uv-border">
							<text>{{rgba.a}}</text>
						</view>
						<view class="uv-pick-color__result__item--rgba">
							<text>A</text>
						</view>
					</view>
				</template>
			</view>
			<view class="uv-pick-color__prefab">
				<view 
					class="uv-pick-color__prefab__item"
					v-for="(item,index) in colorList"
					:key="index"
				>
					<view 
						class="uv-pick-color__prefab__item--color"
						:style="{ background:`rgba(${item.r},${item.g},${item.b},${item.a})` }"
						@click.stop="setColorBySelect(item)"
					></view>
				</view>
			</view>
		</view>
	</uv-popup>
	<!-- #endif -->
	<!-- #ifdef APP-NVUE -->
	<view>
		<text>nvue暂不支持uv-pick-color组件</text>
	</view>
	<!-- #endif -->
</template>
<script>
	import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js';
	import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js';
	import { rgbToHsb, hsbToRgb, rgbToHex, colorList } from './colors.js';
	import props from './props.js';
	export default {
		name: 'uv-pick-color',
		emits: ['confirm', 'cancel', 'close', 'change'],
		mixins: [mpMixin, mixin, props],
		computed: {
			pointerStyle() {
				const style = {};
				style.top = this.$uv.addUnit(this.site[0].top - 8);
				style.left = this.$uv.addUnit(this.site[0].left - 8);
				return style;
			}
		},
		data() {
			return {
				showToolbar: false,
				// rgba 颜色
				rgba: {
					r: 0,
					g: 0,
					b: 0,
					a: 1
				},
				// hsb 颜色
				hsb: {
					h: 0,
					s: 0,
					b: 0
				},
				site: [{
					top: 0,
					left: 0
				}, {
					left: 0
				}, {
					left: 0
				}],
				index: 0,
				bgcolor: {
					r: 255,
					g: 0,
					b: 0,
					a: 1
				},
				hex: '#000000',
				mode: true,
				colorList: colorList
			};
		},
		watch: {
			prefabColor(newVal) {
				this.colorList = newVal;
			}
		},
		created() {
			// #ifdef APP-NVUE
			return this.$uv.error('nvue暂不支持uv-pick-color组件');
			// #endif
			this.rgba = this.color;
			if (this.prefabColor.length) this.colorList = this.prefabColor;
		},
		methods: {
			open() {
				this.$refs.pickerColorPopup.open();
				this.showToolbar = true;
				this.$nextTick(async () => {
					await this.$uv.sleep(350);
					this.getSelectorQuery();
				})
			},
			close() {
				this.$refs.pickerColorPopup.close();
			},
			popupChange(e) {
				if(!e.show) this.$emit('close');
			},
			// 点击工具栏的取消按钮
			cancelHandler() {
				this.$emit('cancel');
				this.close();
			},
			// 点击工具栏的确定按钮
			confirmHandler() {
				this.$emit('confirm', {
					rgba: this.rgba,
					hex: this.hex
				})
				this.close();
			},
			// 初始化
			init() {
				// hsb 颜色
				this.hsb = rgbToHsb(this.rgba);
				this.setValue(this.rgba);
			},
			async getSelectorQuery() {
				const data = await this.$uvGetRect('.drag-box',true);
				this.position = data;
				this.setColorBySelect(this.rgba);
			},
			// 选择模式
			select() {
				this.mode = !this.mode;
			},
			touchstart(e, index) {
				const { clientX, clientY } = e.touches[0];
				this.pageX = clientX;
				this.pageY = clientY;
				this.setPosition(clientX, clientY, index);
			},
			touchmove(e, index) {
				const { clientX, clientY } = e.touches[0];
				this.moveX = clientX;
				this.moveY = clientY;
				this.setPosition(clientX, clientY, index);
			},
			touchend(e, index) {},
			/**
			 * 设置位置
			 */
			setPosition(x, y, index) {
				this.index = index;
				const { top, left, width, height } = this.position[index];
				// 设置最大最小值
				this.site[index].left = Math.max(0, Math.min(parseInt(x - left), width));
				if (index === 0) {
					this.site[index].top = Math.max(0, Math.min(parseInt(y - top), height));
					// 设置颜色
					this.hsb.s = parseInt((100 * this.site[index].left) / width);
					this.hsb.b = parseInt(100 - (100 * this.site[index].top) / height);
					this.setColor();
					this.setValue(this.rgba);
				} else {
					this.setControl(index, this.site[index].left);
				}
			},
			/**
			 * 设置 rgb 颜色
			 */
			setColor() {
				const rgb = hsbToRgb(this.hsb);
				this.rgba.r = rgb.r;
				this.rgba.g = rgb.g;
				this.rgba.b = rgb.b;
			},
			/**
			 * 设置二进制颜色
			 * @param {Object} rgb
			 */
			setValue(rgb) {
				this.hex = `#${(rgbToHex(rgb))}`;
			},
			setControl(index, x) {
				const {
					top,
					left,
					width,
					height
				} = this.position[index];

				if (index === 1) {
					this.hsb.h = parseInt((360 * x) / width);
					this.bgcolor = hsbToRgb({
						h: this.hsb.h,
						s: 100,
						b: 100
					});
					this.setColor()
				} else {
					this.rgba.a = +(x / width).toFixed(1);
				}
				this.setValue(this.rgba);
			},
			setColorBySelect(getrgb) {
				const { r, g, b, a } = getrgb;
				let rgb = {};
				rgb = {
					r: r ? parseInt(r) : 0,
					g: g ? parseInt(g) : 0,
					b: b ? parseInt(b) : 0,
					a: a ? a : 0
				};
				this.rgba = rgb;
				this.hsb = rgbToHsb(rgb);
				this.changeViewByHsb();
			},
			changeViewByHsb() {
				const [a, b, c] = this.position;
				this.site[0].left = parseInt(this.hsb.s * a.width / 100);
				this.site[0].top = parseInt((100 - this.hsb.b) * a.height / 100);
				this.setColor(this.hsb.h);
				this.setValue(this.rgba);
				this.bgcolor = hsbToRgb({
					h: this.hsb.h,
					s: 100,
					b: 100
				});
				this.site[1].left = this.hsb.h / 360 * b.width;
				this.site[2].left = this.rgba.a * c.width;
			}
		}
	};
</script>
<style scoped lang="scss">
	$show-border: 1;
	@import '@/uni_modules/uv-ui-tools/libs/css/variable.scss';
	@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
	$height: 400rpx;
	/* #ifndef APP-NVUE */
	.uv-pick-color {
		&__box {
			position: relative;
			height: $height;
			background: rgb(255, 0, 0);
			margin: 20rpx;
			&__bg {
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				bottom: 0;
				background: linear-gradient(to right, #fff, rgba(255, 255, 255, 0));
				&-mask {
					position: absolute;
					top: 0;
					left: 0;
					right: 0;
					bottom: 0;
					height: $height;
					background: linear-gradient(to top, #000, rgba(0, 0, 0, 0));
				}
				&-pointer {
					position: absolute;
					top: -8px;
					left: -8px;
					z-index: 2;
					width: 16px;
					height: 16px;
					border: 1px #fff solid;
					border-radius: 8px;
				}
			}
		}
		&__control {
			@include flex;
			padding: 10rpx 20rpx;
			&__alpha {
				width: 100rpx;
				height: 100rpx;
				border-radius: 50rpx;
				background-color: #fff;
				background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee),linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee);
				background-size: 36rpx 36rpx;
				background-position: 0 0, 18rpx 18rpx;
				border: 1px #eee solid;
				overflow: hidden;
				&--color {
					width: 100%;
					height: 100%;
				}
			}
			&__item {
				flex: 1;
				@include flex(column);
				justify-content: space-between;
				height: 100rpx;
				padding: 6rpx 0 6rpx 30rpx;
			}
			&__item__drag {
				position: relative;
				height: 16px;
				background-color: #fff;
				background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee),
				linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee);
				background-size: 32rpx 32rpx;
				background-position: 0 0, 16rpx 16rpx;
				&--hue {
					width: 100%;
					height: 100%;
					background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%);
				}
				&--alpha {
					width: 100%;
					height: 100%;
					background: linear-gradient(to right, rgba(0, 0, 0, 0) 0%, rgb(0, 0, 0));
				}
				&--circle {
					position: absolute;
					top: -2px;
					width: 20px;
					height: 20px;
					box-sizing: border-box;
					border-radius: 10px;
					background: #fff;
					box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.1);
				}
			}
		}
		&__result {
			@include flex;
			padding: 20rpx;
			text-align: center;
			&__select {
				@include flex(column);
				justify-content: center;
				width: 100rpx;
				height: 100rpx;
				margin-right: 10px;
				border-radius: 10rpx;
				box-shadow: 1px 1px 2px 1px rgba(0, 0, 0, 0.1);
				font-size: 14px;
				color: #999;
			}
			&__item {
				flex: 1;
				height: 100rpx;
				&--value {
					height: 50rpx;
					line-height: 50rpx;
					border-radius: 4rpx;
					font-size: 28rpx;
					color: #999;
				}
				&--hex,
				&--rgba {
					height: 50rpx;
					line-height: 50rpx;
					font-size: 30rpx;
				}
			}
			&__gap {
				width: 10px;
				height: 10px;
			}
		}
		&__prefab {
			@include flex;
			margin: 0 -8rpx;
			padding: 0 20rpx 20rpx;
			flex-wrap: wrap;
			&__item {
				width: 50rpx;
				height: 50rpx;
				margin: 8rpx;
				border-radius: 6rpx;
				background-color: #fff;
				background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee),
					linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee);
				background-size: 36rpx 36rpx;
				background-position: 0 0, 18rpx 18rpx;
				border: 1px #eee solid;
				&--color {
					width: 100%;
					height: 100%;
					border-radius: 6rpx;
				}
			}
		}
	}
	/* #endif */
</style>