/*
 * @Descripttion: 循环滚动容器  只支持竖向滚动或横向滚动,
 * @version: 1.0.0
 * @Author: YeeChan
 * @Date: 2020-07-17 10:32:52
 */

import FMTouchMaskView, { SlideDirection, FMTouchEvent } from "./FMTouchMaskView";
import { FMListener, callFM_custom, handleFM_custom } from "../Interface/FMInterface";
import Utilit from "../Util/Utilit";
import FMItemLayout from "./FMItemLayout";

const { ccclass, property, requireComponent, disallowMultiple, menu } = cc._decorator;

@ccclass
// @requireComponent(cc.ScrollView)
@disallowMultiple() //防止多个相同类型(或子类型)的组件被添加到同一个节点
//@menu('FM组件/FMScrollViewLoop')
export default class FMScrollViewLoop extends FMTouchMaskView {

    //是否自动移动
    @property()
    private _isAutoMoveType: boolean = true;
    @property({ tooltip: "自动滚动", type: cc.Boolean })
    set isAutoMoveType(val: boolean) {
        this._isAutoMoveType = val;
    }
    get isAutoMoveType() { return this._isAutoMoveType; }


    //--------------------------------------
    //广告标签
    protected ad_tag_custom: any;
    //更新的回调
    protected fmListenerUpdateData_custom: FMListener;

    //layout list
    protected arrayAliveListLayout_custom: FMItemLayout[] = []
    //自由的节点
    protected arrayFreeListLayout_custom: FMItemLayout[] = []

    //一个屏幕中的layout数量
    private viewLayoutNum_custom: number = 0;
    //超出的个数
    private viewLayoutGapNum_custom: number = 3;
    //总共的个数
    private viewLayoutSum_custom: number = 0;


    //初始的下标
    private startIndexItem_custom: number = 0;
    //是否可以更新item相关
    private isCanUpdateItems_custom: boolean = false;
    //点击了 触发停止
    private isTouchStop_custom: boolean = false;
    //外部需要控制的是否可以update
    private _isCanScrollViewLoopUpdate_custom: boolean = true;


    protected isAutoMoveWayLeftUp_custom: boolean = true;//是否自动移动往左或上 还是右或下
    //自动移动后等待的时间
    protected autoMoveWaitTime_custom: number = 60;
    //自动移动的一次的距离格子数量 0不启用 
    protected autoMoveWaitNum_custom: number = 1;
    //移动的数据
    protected autoMoveSpeed_custom: number = 3;
    //

    //当次移动的距离大小
    private _nextMoveLength_custom: number = 0;
    //当下需要等待的时间
    private _waitTimeNum_custom: number = 0;
    private _moveState_custom: number = 0;//0正常移动 1等待



    protected _init_custom(): boolean {
        if (super._init_custom()) {
            if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
                this.viewLayoutNum_custom = Math.ceil(this.node.width / (this.itemPrefabWidth_custom));
            } else if (this._slideDirection == SlideDirection.VERTICAL) {//垂直
                this.viewLayoutNum_custom = Math.ceil(this.node.width / (this.itemPrefabHeight_custom));
            }
            //创建的个数 
            this.viewLayoutSum_custom = this.viewLayoutNum_custom + this.viewLayoutGapNum_custom * 2

            let pos = 0;
            for (let index = 0; index < this.viewLayoutSum_custom; index++) {
                let layoutScript = this.cloneLayout_custom();
                let layout = layoutScript.node;
                if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
                    layout.x = pos;
                    layout.y = 0;
                    pos = pos + layout.width;
                } else if (this._slideDirection == SlideDirection.VERTICAL) {//垂直
                    layout.x = 0;
                    layout.y = pos;
                    pos = pos - layout.height
                }
                this.arrayAliveListLayout_custom.push(layoutScript);
            }
            this.isCanUpdateItems_custom = true;
            return true;
        }
        return false;
    }

    /**
     * 外部调用
     * @param _listener 
     */
    public setFMListenerUpdateItem_custom(_listener: FMListener) {
        this.fmListenerUpdateData_custom = _listener;
    }



    /**
     * 设置自动移动的数据
     * @param way 方向
     * @param moveWaitNum 移动的格子 0持续
     * @param waitTime 移动的格子后停顿的时间 s
     * @param speed 速度
     */
    public setAutoData_custom(way: number, moveWaitNum?: number, waitTime?: number, speed?: number, bgColor?: string) {
        this.isAutoMoveWayLeftUp_custom = way == 0 ? true : false;
        this.autoMoveWaitNum_custom = moveWaitNum ? Math.abs(moveWaitNum) : 0;
        this.autoMoveWaitTime_custom = waitTime ? Math.abs(waitTime) * 60 : 60;
        this.autoMoveSpeed_custom = speed ? Math.abs(speed) : 3;
        if (bgColor) {
            this.node.color = Utilit.colorHex2Rgb_custom(bgColor);
        }

    }


    /**
     * 是否点击了
     */
    public isTouchStopView_custom() {
        return this.isTouchStop_custom;
    }

    /**
     * 外部控制是否update
     */
    public setCanScrollViewLoopUpdate_custom(_update: boolean) {
        this._isCanScrollViewLoopUpdate_custom = _update;
    }

    /**
     * 设置广告的自定义标签
     * @param tag 
     */
    public setAdTag_custom(tag: any) {
        this.ad_tag_custom = tag;
        for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
            const element = this.arrayAliveListLayout_custom[index];
            element.setAdTag_custom(this.ad_tag_custom);
        }
        for (let index = 0; index < this.arrayFreeListLayout_custom.length; index++) {
            const element = this.arrayFreeListLayout_custom[index];
            element.setAdTag_custom(this.ad_tag_custom);
        }
    }




    //外部初始数据
    public initUpdateItems_custom() {
        this._init_custom();
        this.startIndexItem_custom = 0;
        if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
            let pos = - this.itemPrefabWidth_custom * 3;
            for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
                const element = this.arrayAliveListLayout_custom[index];
                element.setPointX_custom(pos);
                element.setItemIndex_custom(this.startIndexItem_custom + index);
                pos = pos + this.itemPrefabWidth_custom
            }
        } else { //垂直
            let pos = this.itemPrefabHeight_custom * 3;
            for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
                const element = this.arrayAliveListLayout_custom[index];
                element.setPointY_custom(pos);
                element.setItemIndex_custom(this.startIndexItem_custom + index);
                pos = pos - this.itemPrefabHeight_custom
            }
        }
        this._updateNextLengthTime_custom();
    }

    protected update(dt: number): void {
        if (this.isCanUpdateItems_custom && this._isCanScrollViewLoopUpdate_custom) {
            this.updateScrollingItems_custom();
            if (this.isAutoMoveType == true) {//判断类型是自动移动类型
                this._updateAutoMove_custom();
            }
        }
    }

    /**
     * 更新子节点的数据内容
     * @param index  第几个大的
     * @param childIndex 第几个小的
     */
    protected listenerUpdateInitItem_custom(sum: number) {
        if (this.fmListenerUpdateData_custom) {
            let data = callFM_custom(this.fmListenerUpdateData_custom, sum);
            return data;
        }
    }

    /**
     * 自动移动
     */
    public _updateAutoMove_custom() {
        if (this.isTouchStopView_custom()) {
            return;
        }
        if (this._moveState_custom == 0) {
            if (this.isAutoMoveWayLeftUp_custom) {
                if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
                    this.content_custom.x = this.content_custom.x - this.autoMoveSpeed_custom
                } else {
                    this.content_custom.y = this.content_custom.y + this.autoMoveSpeed_custom
                }
            } else {
                if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
                    this.content_custom.x = this.content_custom.x + this.autoMoveSpeed_custom
                } else {
                    this.content_custom.y = this.content_custom.y - this.autoMoveSpeed_custom
                }
            }
            if (this.autoMoveWaitNum_custom > 0) {//0 持续移动
                this._nextMoveLength_custom = this._nextMoveLength_custom - this.autoMoveSpeed_custom;
                if (this._nextMoveLength_custom <= 0) {
                    this._moveState_custom = 1;
                }
            }
        } else {
            this._waitTimeNum_custom = this._waitTimeNum_custom + 1;
            if (this._waitTimeNum_custom >= this.autoMoveWaitTime_custom) {
                this._waitTimeNum_custom = 0;
                this._updateNextLengthTime_custom();
            }
        }

    }

    /**
     * 消息
     * @param event 
     */
    protected _dispatchEvent_custom(event: FMTouchEvent) {
        if (event == FMTouchEvent.Scrolling) {
            //this.updateScrollingItems();
        } else if (event == FMTouchEvent.TouchStart) {
            this.isTouchStop_custom = true;
        } else if (event == FMTouchEvent.TouchEnded) {
            this._updateNextLengthTime_custom();
            this.isTouchStop_custom = false;
        }
    }

    /**
     * 更新下次移动需要的数据
     */
    protected _updateNextLengthTime_custom() {
        if (this.autoMoveWaitNum_custom > 0) {
            if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
                this._nextMoveLength_custom = this.autoMoveWaitNum_custom * this.itemPrefab.data.width
                if (this.isAutoMoveWayLeftUp_custom) {
                    for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
                        const element = this.arrayAliveListLayout_custom[index];
                        let vcx = this.content_custom.x + element.node.x;
                        if (vcx > -element.node.width && vcx < 0) {
                            this._nextMoveLength_custom = this._nextMoveLength_custom + vcx;
                            break;
                        }
                    }
                } else {
                    for (let index = this.arrayAliveListLayout_custom.length - 1; index >= 0; index--) {
                        const element = this.arrayAliveListLayout_custom[index];
                        let vcx = this.content_custom.x + element.node.x;
                        if (vcx < this.node.width + element.node.width && vcx > this.node.width) {
                            vcx = vcx - this.node.width;
                            this._nextMoveLength_custom = this._nextMoveLength_custom - vcx;
                            break;
                        }
                    }
                }
            } else {//垂直
                this._nextMoveLength_custom = this.autoMoveWaitNum_custom * this.itemPrefab.data.height
                if (this.isAutoMoveWayLeftUp_custom) {
                    for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
                        const element = this.arrayAliveListLayout_custom[index];
                        let vcy = this.content_custom.y + element.node.y;
                        if (vcy < element.node.height && vcy > 0) {
                            this._nextMoveLength_custom = this._nextMoveLength_custom - vcy;
                            break;
                        }
                    }
                } else {
                    for (let index = this.arrayAliveListLayout_custom.length - 1; index >= 0; index--) {
                        const element = this.arrayAliveListLayout_custom[index];
                        let vcy = this.content_custom.y + element.node.y - element.node.height;
                        if (vcy > -(this.node.height + element.node.height) && vcy < -this.node.height) {
                            vcy = vcy + this.node.height;
                            this._nextMoveLength_custom = this._nextMoveLength_custom + vcy;
                            break;
                        }
                    }
                }
            }
        }
        this._waitTimeNum_custom = 0;
        this._moveState_custom = 0;
    }




    //更新
    protected updateScrollingItems_custom() {
        let arrayLive: FMItemLayout[] = []
        if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
            for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
                const element = this.arrayAliveListLayout_custom[index];
                if (this.content_custom.x + element.getPointX_custom() < - this.itemPrefabWidth_custom * 3) {//左 超过三个标准 移除
                    this.addFreeItem_custom(element);
                } else if (element.getPointX_custom() + this.content_custom.x > this.node.width + this.itemPrefabWidth_custom * 3) { //右 超过三个标准 移除
                    this.addFreeItem_custom(element);
                } else { //中间区域 激活
                    arrayLive.push(element);
                }
            }
            if (arrayLive[0].getPointX_custom() + this.content_custom.x > - this.itemPrefabWidth_custom) {//起始的 低于一个标准 创建一个
                let element = this.getFreeItem_custom();
                element.setPointX_custom(arrayLive[0].getPointX_custom() - this.itemPrefabWidth_custom);
                element.setItemIndex_custom(arrayLive[0].getItemIndex_custom() - 1)
                arrayLive.splice(0, 0, element);
                element.node.active = true;
            }
            if (arrayLive[arrayLive.length - 1].getPointX_custom() + this.content_custom.x < + this.node.width + this.itemPrefabWidth_custom) {//结尾的 低于一个标准 创建一个
                const element = this.getFreeItem_custom()
                element.setPointX_custom(arrayLive[arrayLive.length - 1].getPointX_custom() + this.itemPrefabWidth_custom);
                element.setItemIndex_custom(arrayLive[arrayLive.length - 1].getItemIndex_custom() + 1)
                arrayLive.push(element);
                element.node.active = true;
            }
        } else { //垂直
            for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
                const element = this.arrayAliveListLayout_custom[index];
                if (element.getPointY_custom() + this.content_custom.y > this.itemPrefabHeight_custom * 3) {//上 超过三个标准 移除
                    this.addFreeItem_custom(element);
                } else if (element.getPointY_custom() < -(this.content_custom.y + this.node.height + this.itemPrefabHeight_custom * 3)) { //下 超过三个标准 移除
                    this.addFreeItem_custom(element);
                } else { //中间区域 激活
                    arrayLive.push(element);
                }
            }
            if (arrayLive[0].getPointY_custom() + this.content_custom.y <= this.itemPrefabHeight_custom) {//起始的 低于一个标准 创建一个
                let element = this.getFreeItem_custom();
                element.setPointY_custom(arrayLive[0].getPointY_custom() + this.itemPrefabHeight_custom);
                element.setItemIndex_custom(arrayLive[0].getItemIndex_custom() - 1)
                arrayLive.splice(0, 0, element);
                element.node.active = true;
            }
            if (arrayLive[arrayLive.length - 1].getPointY_custom() >= -(this.content_custom.y + this.node.height + this.itemPrefabHeight_custom)) {//结尾的 低于一个标准 创建一个
                const element = this.getFreeItem_custom()
                element.setPointY_custom(arrayLive[arrayLive.length - 1].getPointY_custom() - this.itemPrefabHeight_custom);
                element.setItemIndex_custom(arrayLive[arrayLive.length - 1].getItemIndex_custom() + 1)
                arrayLive.push(element);
                element.node.active = true;
            }
        }
        this.arrayAliveListLayout_custom = arrayLive;
    }
    /**
       * 创建一个
       */
    private cloneLayout_custom(): FMItemLayout {
        let layout = cc.instantiate(this.itemPrefab);
        let script = layout.getComponent(FMItemLayout);
        script.setAdTag_custom(this.ad_tag_custom)
        script.setFMListenerUpdate_custom(handleFM_custom(this.listenerUpdateInitItem_custom, this));
        this.content_custom.addChild(layout);
        return script;
    }


    /**
     * 获取一个自由节点
     */
    private getFreeItem_custom(): FMItemLayout {
        let element = this.arrayFreeListLayout_custom.pop()
        if (!element) {
            element = this.cloneLayout_custom();
        }
        return element;
    }

    private addFreeItem_custom(item: FMItemLayout) {
        item.node.active = false;
        this.arrayFreeListLayout_custom.push(item);
    }


}