<template>
    <label ref="elem" :id="unionId" :class="[$style.selectWrap,plain&&$style.plain,disabled&&$style.disabled]">
        <select :name="name">
            <option
                v-for="(item,index) in options"
                :key="index"
                :value="item.value"
                :selected="item.value==value?true:null"
            >{{item.text}}</option>
        </select>
        <template v-if="editable">
            <div :class="$style.selectedText">
                <input
                    type="text"
                    :value="editableText"
                    @input="editing"
                    @focus="isFocus=true"
                    @blur="isFocus=false"
                    :title="selectedText"
                />
            </div>
        </template>
        <template v-else>
            <Touch
                tag="div"
                :class="$style.selectedText"
                @tap="changeActiveStatus"
                :title="selectedText"
            ><div>{{selectedText}}</div></Touch>
        </template>

        <Touch
            tag="div"
            :class="$style.suffix"
            @tap="changeActiveStatus"
        >
            <cox-Triangle :direction="isActive?'top':'bottom'"/>
        </Touch>
        <div
            :key="dropPos"
            :class="[$style.dropdown,dropPos,dropPos&&isActive&&$style.show]"
            :style="dropDownStyle"
            ref="dropDown"
        >
            <div v-if="!everSeen">
                <ul v-if="getOptions.length>0">
                    <Touch
                        tag="li"
                        v-for="(item,index) in getOptions"
                        :key="index"
                        @tap="tapItem(item.value)"
                        :class="item.value==value&&$style.active"
                    >
                        <span :title="item.text">{{item.text}}</span>
                    </Touch>
                </ul>
                <ul v-else>
                    <li :class="$style.disabled">没有数据~</li>
                </ul>
            </div>
        </div>
    </label>
</template>

<script>
    const eventListener = (target, eventType, callback,isBubble=false)=>{
        if (target.addEventListener) {
            target.addEventListener(eventType, callback, isBubble);
            return ()=>{
                target.removeEventListener(eventType, callback, isBubble);
            };
        } else if (target.attachEvent) {
            target.attachEvent('on' + eventType, callback);
            return ()=>{
                target.detachEvent('on' + eventType, callback);
            };
        }
    };
    import Touch from "../external/Touch";
    export default {
        name: "Select",
        components: {Touch},
        props:{
            name:{
                type:String,
                default:''
            },
            placeholder:{
                type:String,
                default:''
            },
            options:{
                type:Array,
                default:[]
            },
            editable:{
                type:Boolean,
                default:false
            },
            mustChoose:{
                type:Boolean,
                default:true
            },
            plain:{
                type:Boolean
            },
            disabled:{
                type:Boolean,
                default:false
            },
            value:{}
        },
        data(){
            return {
                dropPos:null,                                          //下拉框位置
                enableFilter:false,                                     //是否开启筛选
                isActive:false,                                         //下拉框是否被激活（是否显示）
                isFocus:false,                                          //组件是否获取了焦点
                inputText:this.getTextByValue(),                        //输入框值
                dropDownStyle:{                                         //下拉框位置（样式）
                    left:0,
                    top:0,
                    width:0
                },
                unionId:'select'+Math.floor(Math.random()*100)+'id',    //unionId标识唯一组件id
                everEdit:true,                                          //编辑过

                everSeen:true                                           //下拉框从未显示过，用于优化mount速度
            }
        },
        watch:{
            options(newValue,oldValue){
                if(this.$equal&&this.$equal(newValue,oldValue)){
                    return;
                }
                let newText=this.getTextByValue();
                if(newText){
                    this.inputText=newText;
                }
            },
            value(newValue,oldValue){
                if(newValue===oldValue){
                    return;
                }
                let newText=this.getTextByValue();
                if(newText){
                    this.inputText=newText;
                }
            },
            isActive(newValue,oldValue){
                //当下拉框状态未发生变化时
                if(newValue===oldValue){
                    return;
                }
                //下拉框：触发
                if(newValue){
                    this.dropPos=null;
                    window.setTimeout(()=>{
                        this.changeDropDownPos();
                    },0)
                    return;
                }

                //下拉框：关闭
                this.everEdit=true;
                if(this.mustChoose){
                    this.inputText=this.getTextByValue();
                    return;
                }
                this.$emit('input',this.inputText);
            }
        },
        computed:{
            selectedText(){
                return this.getTextByValue()||this.placeholder;
            },
            editableText(){
                if(this.isFocus){
                    return this.inputText;
                }
                return this.inputText||this.placeholder;
            },
            getOptions(){
                if(this.inputText&&this.enableFilter){
                    if(this.everEdit){
                        return this.options;
                    }
                    return this.options.filter(function({value,text}){
                        if(value===null){
                            return false;
                        }
                        return String(text).indexOf(this.inputText)>=0;
                    }.bind(this))
                }
                else{
                    return this.options;
                }
            }
        },
        methods:{
            changeActiveStatus(){
                if(this.disable){
                    return;
                }
                //下拉框曾经显示过
                if(!this.isActive){
                    this.everSeen=false;
                }
                this.$emit(this.isActive?'close':'open');
                this.isActive=!this.isActive;
            },
            changeDropDownPos(){
                const originTarget=this.$refs.elem;
                var left=0, top=0;
                var tempTarget=originTarget;
                do{
                    let newTransform=getComputedStyle(tempTarget).transform;
                    if(!!newTransform&&newTransform!='none'){
                        break;
                    }
                    left+=Number(tempTarget.offsetLeft);
                    top+=Number(tempTarget.offsetTop);
                    tempTarget=tempTarget.offsetParent;
                    if(!tempTarget){
                        break;
                    }
                } while (true);
                var tempTarget=originTarget;
                do{
                    let newTransform=getComputedStyle(tempTarget).transform;
                    if(!!newTransform&&newTransform!='none'){
                        break;
                    }
                    left-=Number(tempTarget.scrollLeft);
                    top-=Number(tempTarget.scrollTop);
                    tempTarget=tempTarget.parentElement;
                    if(!tempTarget){
                        break;
                    }
                } while (true);

                let inputHeight=Number(originTarget.offsetHeight),
                    dropDownBoxHeight=Number(this.$refs.dropDown.offsetHeight),
                    verPos={};
                if(top+inputHeight+dropDownBoxHeight>window.innerHeight){
                    verPos={bottom:window.innerHeight-top+'PX'};
                    this.dropPos='top';
                }
                else{
                    verPos={top:top+inputHeight+'PX'};
                    this.dropPos='bottom';
                }
                this.dropDownStyle={
                    ...verPos,
                    left:left+'PX',
                    width:originTarget.offsetWidth+'PX'
                };
            },
            getTextByValue(value){
                for(let item of this.options){
                    if(item.value==(value?value:this.value)){
                        return item.text;
                    }
                }
                if(!this.mustChoose&&this.editable){
                    return this.value;
                }
                return '';
            },
            tapItem(value){
                this.isActive=false;
                if(this.value!==value){
                    this.$emit('input',value);
                    this.$emit('change',value);
                }
                this.inputText=this.getTextByValue(value);
            },
            closeDropDownBox(e){
                if(!this.isActive){
                    return;
                }
                var target=e.target;
                if(target===document){
                    this.isActive=false;
                    return;
                }
                while(target){
                    if(target.id.indexOf(this.unionId)>=0){
                        return;
                    }
                    target=target.parentElement;
                }
                this.isActive=false;
            },
            editing(e){
                let value=e.target.value;
                this.inputText=value;
                this.enableFilter=!!value;
                this.everEdit=false;
                this.isActive=true;
            }
        },
        mounted(){
            this._clickEvent=eventListener(document.body,'click',this.closeDropDownBox.bind(this));
            this._touchEvent=eventListener(document.body,'touchstart',this.closeDropDownBox.bind(this));
            this._scrollEvent=eventListener(document,'scroll',this.closeDropDownBox.bind(this),true);
            this._resizeEvent=eventListener(window,'resize',this.changeDropDownPos.bind(this));
            this.$emit('mounted',this.value);
        },
        beforeDestroy(){
            this._clickEvent();
            this._touchEvent();
            this._scrollEvent();
            this._resizeEvent();
        }
    }
</script>

<style module lang="scss">
    @value FormItemBorderColor,FormItemBorderColor_Focus,FormItemTextColor from '../../cssInjection/stylization.scss';
    @import '../../cssInjection/cssFunction.scss';
    @import '../../cssInjection/cssLayout.scss';
    .selectWrap{
        vertical-align: middle;
        font-size: 14px;
        display: inline-block;
        width: 150px;
        max-width: 100%;
        min-width: 110PX;
        height: 2.5em;
        cursor: pointer;
        position: relative;
        $suffixWidth:32px;
        &.plain{
            border-radius: 0px !important;
            height: 2em;
            li{
                line-height: 1.6em;
                height: 1.6em;
                min-height: 1.6em;
            }
        }
        &.focus{
            border-color: FormItemBorderColor_Focus;
        }
        &.disabled{
            background-color: rgb(235, 235, 228);
        }
        >select{
            display: none;
        }
        >.selectedText{
            font-size: 1em;
            position: absolute;
            z-index: 2;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            border: 1px solid FormItemBorderColor;
            border-radius: 0;
            background-color: #FFF;
            @extend %FlexRowStartCenter;
            padding-left: 0.6em;
            padding-right: $suffixWidth;
            text-align: left;
            >*{
                color: FormItemTextColor;
                font-size: 1em;
            }
            >div{
                width: 100%;
                line-height: 1em;
                white-space: nowrap;
                overflow: hidden;
                font-size: 1em;
                text-overflow: ellipsis;
            }
            >input{
                width: 100%;
                height: 100%;
                text-overflow: ellipsis;
            }
        }
        >.suffix{
            position: absolute;
            z-index: 3;
            right: 0;
            top: 0;
            width: $suffixWidth;
            height: 100%;
            @extend %FlexRowCenter;
            >div{
                width: 0;
                height: 0;
            }
        }
        >.dropdown{
            box-sizing: content-box;
            padding: 5PX;
            margin-left: -5PX;
            overflow: hidden;
            $itemHeight:36px;
            position: fixed;
            z-index: 20;
            /*left: 0;*/
            /*top: 100%;*/
            /*width: 100%;*/
            $duration:200ms;
            pointer-events: none;
            visibility: hidden;
            transition-property: pointer-events,visibility;
            transition-duration: 0s;
            transition-delay: 0s;
            &:global{
                &.top{
                    padding-top:10PX;
                    padding-bottom: 0;
                    >div{
                        border-radius: 4PX 4PX 0 0;
                        transform: translateY(100%);
                    }
                }
                &.bottom{
                    margin-top: -5PX;
                    >div{
                        border-radius: 0 0 4PX 4PX;
                        transform: translateY(-100%);
                        box-shadow: 0 2px 2px 0 rgba(0,0,0,.3);
                    }
                }
            }
            &.show{
                pointer-events: auto;
                visibility: visible;
                >div{
                    transform: translateY(0) !important;
                }
            }
            >div{
                background-color: #e9e9e9;
                box-sizing: content-box;
                padding-top: 2PX;
                margin-top: -2PX;
                width: 100%;
                max-height: $itemHeight*5;
                transition: transform $duration;
                overflow-x: hidden;
                overflow-y: auto;
                @include ScrollBarStyle();
                >ul{
                    width: 100%;
                    padding: 3PX 0;
                    >li{
                        text-align: left !important;
                        display: block;
                        width: 100%;
                        font-size: 1em;
                        padding: 0 4px;
                        line-height: 1.8em;
                        height: 1.8em;
                        min-height: 1.8em;
                        border-radius: 4PX;
                        white-space: nowrap;
                        text-overflow: ellipsis;
                        overflow: hidden;
                        &:hover:not(.disabled){
                            background-color: rgb(188,180,176);
                            background-image: linear-gradient(180deg,rgba(255,255,255,0.4) 0%,rgba(255,255,255,0) 100%);
                        }
                        &.active{
                            color: #FFF !important;
                            background-color: #304156 !important;
                        }
                        &.disabled{
                            cursor: default;
                        }
                    }
                }
            }
        }
    }
</style>