
import { _decorator, Component, Node, Vec2, EventTouch, v2, UITransform, view, v3, tween } from 'cc';
import { MapEvent, MapMoveData} from './BroadcastMap';
import MapConfig from '../MapConfig';
import MapUtils from './MapUtils';
import { MoveDir } from './Types';
import { UIFixed } from './UIForm';
const { ccclass, property } = _decorator;

const MIN_MOVE_OFFSET = 20;

@ccclass("BaseMap")
export class BaseMap extends UIFixed {

    protected mapId = new Vec2(0, 0);
    protected canTouch = false;

    private targetMapId: Vec2 = null;           // 目标地图
    private touching = false;
    private moveDir: MoveDir = 0;                // 1 X轴移动, -1    

    onLoad() {
        MapConfig.maps[MapUtils.getMapKey(this.mapId)] = this;
        this.node.setPosition(MapUtils.getMapPos(this.mapId));
        this.addEvent();
        this.canTouch = true;
    }

    start () {
        
    }

    onBeforMove(data: MapMoveData) {
        if(!this.mapId.equals(data.currMapId) && !this.mapId.equals(data.targetMapId)) return ;
        if(this.mapId.equals(data.targetMapId)) {            
            this.node.setPosition(MapUtils.getMapPosByDir(data.dir, -1));
            this.node.active = true;
        }
    }

    onMove(data: MapMoveData) {
        if(!this.mapId.equals(data.currMapId) && !this.mapId.equals(data.targetMapId)) return ;
        let offset = v3();
        switch(data.dir) {
            case MoveDir.Left:
            case MoveDir.Right:
                offset.x = data.delta.x;
                break;
            case MoveDir.Up:
            case MoveDir.Down:
                offset.y = data.delta.y;
                break;
        }
        this.node.setPosition(this.node.getPosition().add(offset));
    }

    onAfterMove(data: MapMoveData) {
        if(!this.mapId.equals(data.currMapId) && !this.mapId.equals(data.targetMapId)) return ;
        let targetPos = v3(0, 0 ,0);
        if(data.currMapId.equals(this.mapId)) { // 需要被移出
            targetPos = MapUtils.getMapPosByDir(data.dir, 1)
        }

        let time = targetPos.clone().subtract(this.node.getPosition()).length() / 2000;
        tween(this.node).to(time, {position: targetPos}).start();
        MapConfig.currMapId = data.targetMapId;
    }

    onTouchStart(e: EventTouch) {
        if(!this.canTouch) return ;
        this.touching = true;
    }
    onTouchMove(e: EventTouch) {
        if(!this.canTouch || !this.touching) return ;
        let offset = e.getLocation().subtract(e.getStartLocation());        
        if(offset.length() < MIN_MOVE_OFFSET) return ;
        if(this.moveDir == 0) {
            if(Math.abs(offset.x) > Math.abs(offset.y)) {
                this.moveDir = offset.x < 0 ? MoveDir.Left : MoveDir.Right;
            }else {
                this.moveDir = offset.y < 0 ? MoveDir.Down : MoveDir.Up;
            }
            
            let targetMapId = MapUtils.getNextMap(this.mapId.clone(), this.moveDir, -1);
            if(!targetMapId || !MapConfig.maps[MapUtils.getMapKey(targetMapId)]) return ;

            this.targetMapId = targetMapId;
            MapEvent.onBeforMove.dispatch({
                currMapId: this.mapId,
                targetMapId: this.targetMapId,
                dir: this.moveDir,
                delta: e.getDelta()
            });
        }
        if(!this.targetMapId) return;
        // 检查是否有这个map
        if(!MapConfig.maps[MapUtils.getMapKey(this.targetMapId)]) return ;

        MapEvent.onMoveMap.dispatch({
            currMapId: this.mapId,
            targetMapId: this.targetMapId,
            dir: this.moveDir,
            delta: e.getDelta()
        });
    }
    onTouchEnd(e: EventTouch) {
        if(!this.canTouch || !this.touching) return ;
        this.touching = false;
        if(this.targetMapId) {
            MapEvent.onAfterMove.dispatch({
                currMapId: this.mapId,
                targetMapId: this.targetMapId,
                dir: this.moveDir
            });
        }
        this.moveDir = 0;
        this.targetMapId = null;
    }

    onDestroy() {
        this.removeEvent();
    }

    private addEvent() {
        let node = this.node.getChildByName("bg")
        node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        node.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);

        MapEvent.onBeforMove.on(this.onBeforMove, this);
        MapEvent.onMoveMap.on(this.onMove, this);
        MapEvent.onAfterMove.on(this.onAfterMove, this);
    }
    private removeEvent() {
        let node = this.node.getChildByName("bg")
        node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
        node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        node.off(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);

        MapEvent.onBeforMove.remove(this.onBeforMove, this);
        MapEvent.onMoveMap.remove(this.onMove, this);
        MapEvent.onAfterMove.remove(this.onAfterMove, this);
    }

    update (dt: number) {
        
    }
}