/**
 * 8方向摇杆
 */
const {ccclass, property} = cc._decorator;

@ccclass
export default class Joystick_8d extends cc.Component {

    @property({
        type: cc.Node,
        displayName: '按下显示效果',
    })
    mTouchView: cc.Node = null;

    @property({
        type: cc.Node,
        displayName: '摇杆中心',
    })
    mCneter: cc.Node = null;

    @property({
        type: cc.Sprite,
        displayName: '上',
    })
    mUp: cc.Sprite = null;

    @property({
        type: cc.Sprite,
        displayName: '下',
    })
    mDown: cc.Sprite = null;

    @property({
        type: cc.Sprite,
        displayName: '左',
    })
    mLeft: cc.Sprite = null;

    @property({
        type: cc.Sprite,
        displayName: '右',
    })
    mRight: cc.Sprite = null;

    @property({
        type: cc.SpriteFrame,
        displayName: '点击高亮',
    })
    mTouchOn: cc.SpriteFrame = null;

    @property({
        type: cc.SpriteFrame,
        displayName: '灰色',
    })
    mTouchOff: cc.SpriteFrame = null;

    private tmpDir = {x:0,y:0}
    /**
     * @runing 行走
     * @angle 角度
     * @distance 距离[0-1]
     */
    private callback:(dir:any)=>void;
    onLoad () {
        this.mTouchView.active = false;
        this._initTouchEvent();
    }
    public setCallback(callback:(dir:cc.Vec2)=>void){
        this.callback = callback;
    }
    //对圆圈的触摸监听
    private _initTouchEvent() {
        this.node.on(cc.Node.EventType.TOUCH_START, this._touchStartEvent, this);
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this._touchMoveEvent, this);
        // // 触摸在圆圈内离开或在圆圈外离开后，摇杆归位，player速度为0
        this.node.on(cc.Node.EventType.TOUCH_END, this._touchEndEvent, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this._touchEndEvent, this);

        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyPressed, this);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyReleased, this);
    }

    private _touchStartEvent(event) {
        let p1  = this.node.convertToNodeSpaceAR(event.getLocation());
        let p2 = this.mCneter.getPosition();
        let distance = this._getDistance(p1,p2);
        // cc.log('distance = ',distance);
        if(distance > 10 &&distance < 175){
            this.mTouchView.active = true;
            this.mTouchView.x = p1.x;
            this.mTouchView.y = p1.y;
            let angle = this._getAngle(p1,p2);
            let dir = this.getDir(angle);
            this.updateIcon(dir);
            if(this.callback){
                this.callback(dir);
            }
        }
    }

    private _touchMoveEvent(event) {
        if(this.mTouchView.active){
            let p1 = this.node.convertToNodeSpaceAR(event.getLocation());
            let p2 = this.mCneter.getPosition();
            this.mTouchView.x = p1.x;
            this.mTouchView.y = p1.y;
            let angle = this._getAngle(p1,p2);
            let dir = this.getDir(angle);
            this.updateIcon(dir);
            if(this.callback){
                this.callback(dir);
            }
        }
    }
    private _touchEndEvent(event) {
        this.stop();
    }
    
    private onKeyPressed(event) {
        let keyCode = event.keyCode;
        switch(keyCode) {
            case cc.macro.KEY.w:
            case cc.macro.KEY.up:
                this.tmpDir.y = 1;
                break;
            case cc.macro.KEY.s:
            case cc.macro.KEY.down:
                this.tmpDir.y = -1;
                break;
            case cc.macro.KEY.a:
            case cc.macro.KEY.left:
                this.tmpDir.x = -1;
                break;
            case cc.macro.KEY.d:
            case cc.macro.KEY.right:
                this.tmpDir.x = 1;
                break;
        }
        this.updateIcon(this.tmpDir);
        if(this.callback){
            this.callback(this.reviseValue());
        }
    }

    private onKeyReleased(event) {
        let keyCode = event.keyCode;
        switch(keyCode) {
            case cc.macro.KEY.w:
            case cc.macro.KEY.up:
                this.tmpDir.y = 0;
                break;
            case cc.macro.KEY.s:
            case cc.macro.KEY.down:
                this.tmpDir.y = 0;
                break;
            case cc.macro.KEY.a:
            case cc.macro.KEY.left:
                this.tmpDir.x = 0;
                break;
            case cc.macro.KEY.d:
            case cc.macro.KEY.right:
                this.tmpDir.x = 0;
                break;
        }
        this.updateIcon(this.tmpDir);
        if(this.callback){
            this.callback(this.reviseValue());
        }
    }
    private reviseValue(){
        let pos = {
            x:this.tmpDir.x,
            y:this.tmpDir.y
        };
        let ax = Math.abs(pos.x);
        let ay = Math.abs(pos.y);
        if(ax != ay){
            if(ax == 1){
                pos.x = pos.x*1.4;
            }else if(ay == 1){
                pos.y = pos.y*1.4;
            }
        }
        return pos;
    }

    public stop(){
        this.mTouchView.active = false;
        this.updateIcon(null);
        if(this.callback){
            this.callback({x:0,y:0});
        }
    }
    //计算弧度并返回
    private _getAngle(p1,p2):number {
        return Math.atan2(p1.y - p2.y, p1.x - p2.x) * (180 / Math.PI);
    }
    //计算两点间的距离并返回
    private _getDistance(pos1: cc.Vec2, pos2: cc.Vec2) {
        return Math.sqrt(Math.pow(pos1.x - pos2.x, 2) + Math.pow(pos1.y - pos2.y, 2));
    }
    /**
     * 根据弧度获取方向
     * @param angle 
     */
    private getDir(angle:number){
        if(angle >= -30 && angle < 30){
            return {x:1.4,y:0}
        }else if(angle >= 30 && angle < 60){
            return {x:1,y:1}
        }else if(angle >= 60 && angle < 120){
            return {x:0,y:1.4}
        }else if(angle >= 120 && angle < 150){
            return {x:-1,y:1}
        }else if(angle >= 150 && angle < 180){
            return {x:-1.4,y:0}
        }else if(angle >= -180 && angle < -150){
            return {x:-1.4,y:0}
        }else if(angle >= -150 && angle < -120){
            return {x:-1,y:-1}
        }else if(angle >= -120 && angle < -60){
            return {x:0,y:-1.4}
        }else if(angle >= -60 && angle < -30){
            return {x:1,y:-1}
        }
    }
    private updateIcon(dir){
        if(dir){
            if(dir.x == 0){
                this.mLeft.spriteFrame = this.mTouchOff;
                this.mRight.spriteFrame = this.mTouchOff;
            }else if(dir.x > 0){
                this.mLeft.spriteFrame = this.mTouchOff;
                this.mRight.spriteFrame = this.mTouchOn;
            }else{
                this.mLeft.spriteFrame = this.mTouchOn;
                this.mRight.spriteFrame = this.mTouchOff;
            }
        
            if(dir.y == 0){
                this.mUp.spriteFrame = this.mTouchOff;
                this.mDown.spriteFrame = this.mTouchOff;
            }else if(dir.y > 0){
                this.mUp.spriteFrame = this.mTouchOn;
                this.mDown.spriteFrame = this.mTouchOff;
            }else{
                this.mUp.spriteFrame = this.mTouchOff;
                this.mDown.spriteFrame = this.mTouchOn;
            }
        }else{
            this.mLeft.spriteFrame = this.mTouchOff;
            this.mRight.spriteFrame = this.mTouchOff;
            this.mUp.spriteFrame = this.mTouchOff;
            this.mDown.spriteFrame = this.mTouchOff;
        }
    }


    
}
