import Vector3 = Laya.Vector3;
import {GameManager} from "./GameManager";
import { EventManager, StageState } from "../Tools/EventManager";
import { GameTools, Transform3DHelper } from "../Tools/GameTools";
import {PlayerControl} from "./PlayerControl";
import { AssetManager } from "../Tools/AssetManager";
import { Runner } from "./Runner";
import GamePool from "../Tools/GamePool";
import { AccountManager } from "../Net/AccountManager";
import InGameView from "../View/InGameView";
import { StageControl } from "./StageControl";
import { AudioManager, MusicType } from "../Tools/AudioManager";
//npc状态
export enum NpcState{Attack,Idle,Win,Pursue,Run,Die}

export class NpcRunner extends Laya.Script{
    private static ins:NpcRunner;
    //npc模型
    public m_npcmodel:Laya.Sprite3D;
    //npc动画控制器
    public m_npcanimator:Laya.Animator;
    //距离玩家多远开始奔跑
    public m_distance:number = 20;
    //距离玩家多远开始攻击
    public m_distanceatk:number = 5;
    //是否死亡
    public DIE:boolean = false;
    //npc速度
    public m_npcspeed:number = 0;
    //是否已经攻击过玩家
    public atked:boolean = false;
    //是否已经击中玩家
    public wined:boolean = false;
    
    //游戏是否开始
    public begin:boolean = false;
    
    //前边被击中
    public frontdie:boolean = false;
    //后背被击中
    public reardie:boolean = false;




    public npc_state:NpcState;

    public canmove:boolean = false;

    public player:Laya.Sprite3D;
    constructor(){
        super();
        NpcRunner.ins = this;
        EventManager.StageOn(StageState.Start,this,this.Begin);
        EventManager.StageOn(StageState.Lose,this,this.GameOver);
        EventManager.StageOn(StageState.Win,this,this.GameOver);
        EventManager.StageOn(StageState.Press,this,this.AddSpeed)
        EventManager.StageOn(StageState.UnPress,this,this.SlowSpeed)
    }
    public static get Instance():NpcRunner{
        if(NpcRunner.ins){
            return NpcRunner.ins
        }
        else{
            return new NpcRunner();
        }
    }
    onAwake(){
        this.m_npcmodel = this.owner as Laya.Sprite3D;
        this.m_npcanimator = this.owner.getComponent(Laya.Animator) as Laya.Animator;
        this.player = PlayerControl.Instance.Player;

        this.m_distance = AccountManager.Instance.curplayerData.NpcRunDistance*1.65;
        this.m_distanceatk = AccountManager.Instance.curplayerData.NpcAtkDistance*1.65;
        let stage = Number(AccountManager.Instance.curplayerData.GainAccount("stage"));
        if(stage == 1){
            this.m_npcspeed = 0.1;
        }
        else{
            this.m_npcspeed = StageControl.Instance.curstage.npcspeed;
        }
    }
    Begin(){
        this.ChangeState(NpcState.Idle);
        this.begin = true;
    }
    dir = new Vector3();
    currotV = new Vector3();
    currot = new Laya.Quaternion;

    CurrectRotate = new Laya.Quaternion();
    
    onUpdate(){
        if(!this.begin)return
        if(this.npc_state == NpcState.Die)return;
        if(this.frontdie || this.reardie){
            this.ChangeState(NpcState.Die);
            return;
        }
        let stage = Number(AccountManager.Instance.curplayerData.GainAccount("stage"));
        var distance = Vector3.distance(this.player.transform.position,this.m_npcmodel.transform.position);
        if(distance<this.m_distance && distance>this.m_distanceatk && !this.atked && stage>2){
            Vector3.subtract(this.player.transform.position,this.m_npcmodel.transform.position,this.currotV);
            Vector3.normalize(this.currotV,this.currotV);
            this.m_npcmodel.transform.lookAt(new Vector3(this.m_npcmodel.transform.position.x-this.currotV.x,this.m_npcmodel.transform.position.y,this.m_npcmodel.transform.position.z-this.currotV.z),new Vector3(0,1,0));
            this.NPCMoveDir=this.currotV;
            this.canmove = true;
            this.ChangeState(NpcState.Run);
        }
        else if(distance <= this.m_distanceatk && !this.atked && stage>2){
            Vector3.subtract(this.player.transform.position,this.m_npcmodel.transform.position,this.currotV);
            Vector3.normalize(this.currotV,this.currotV);
            this.m_npcmodel.transform.lookAt(new Vector3(this.m_npcmodel.transform.position.x-this.currotV.x,this.m_npcmodel.transform.position.y,this.m_npcmodel.transform.position.z-this.currotV.z),new Vector3(0,1,0));
            this.NPCMoveDir=this.currotV;
            // this.canmove = false;
            this.atked = true;
            this.ChangeState(NpcState.Attack);
        }
        this.Move(this.NPCMoveDir,this.m_npcspeed);
        this.RayCheck();
    }

    NPCMoveDir:Vector3;
    curspeed = 0;
    offest = new Vector3();
    curpos = new Vector3();
    //移动
    Move(_dir:Vector3,_speed:number){
        if(this.canmove ){
            var sp = GameTools.Instance.lerp(this.curspeed,_speed,0.1);
            this.curspeed = sp;
            Vector3.scale(_dir,this.curspeed,this.offest);
            Vector3.add(this.m_npcmodel.transform.position,this.offest,this.curpos);
            Vector3.lerp(this.m_npcmodel.transform.position,this.curpos,0.15,this.curpos);
            this.curpos = new Vector3(this.curpos.x,this.curpos.y,this.curpos.z);
            this.m_npcmodel.transform.position = this.curpos;
        }
    }
    AddSpeed(){
        this.m_npcspeed = StageControl.Instance.curstage.npcspeed;
    }
    SlowSpeed(){
        this.m_npcspeed = StageControl.Instance.curstage.npcspeed/2;
    }
    GameOver(){
        EventManager.StageOff(StageState.Press,this,this.AddSpeed);
        EventManager.StageOff(StageState.UnPress,this,this.SlowSpeed);
        EventManager.StageOff(StageState.Start,this,this.Begin);
    }
    ChangeState(_state:NpcState){
        if(this.npc_state == _state) return
        this.npc_state = _state;
        switch (this.npc_state) {
            case NpcState.Attack:
                this.Attack();
                break;
            case NpcState.Pursue:
                this.Pursue();
                break;
            case NpcState.Win:
                this.Win();
                break;
            case NpcState.Idle:
                this.Idle();
                break;
            case NpcState.Run:
                this.Run();
                break;
            case NpcState.Die:
                this.Die();
                break;
        }
    }
    //站立
    Idle(){
        this.m_npcanimator.play("idle");
    }
    //攻击
    Attack(){
        this.m_npcanimator.play("atk");
        Laya.timer.once(500,this,()=>{
            this.canmove = false;
        })
        // Laya.timer.frameLoop(1,this,()=>{
        //     if(this.m_npcanimator.getCurrentAnimatorPlayState(0).normalizedTime>=1){
        //         // this.atked = true;
        //         // this.canmove = false;
        //         // this.m_npcanimator.play("win");
        //         Laya.timer.clearAll(this);
        //     }
        // })
    }
    //获胜
    Win(){
        this.m_npcanimator.play("win");
    }
    //追赶
    Pursue(){

    }
    //奔跑
    Run(){
        this.m_npcanimator.play("run");
    }
    die = false;
    Die(){
        if(this.die)return 
        this.die = true;
        AudioManager.playMusic(MusicType.die);
        this.PiaoZi();
        EventManager.StageOff(StageState.Start,this,this.Begin);
        // Laya.timer.clearAll(this);
        Laya.timer.once(500,this,()=>{
            GamePool.Instance.RecoveryModel(this.m_npcmodel);
        })
        if(this.frontdie){
            this.m_npcanimator.play("diefront");
        }
        else if(this.reardie){
            this.m_npcanimator.play("dierear");
        }
        this.canmove = false;
        // GameManager.Instance.KillNum++;
        // InGameView.Instance.InitUI();
    }
    PiaoZi(){
        let headshoot = new Laya.Image();
        headshoot.skin = "Game/res/textrue/headshoot.png";
        headshoot.scaleX = 1;
        headshoot.scaleY = 1;
        headshoot.anchorX = 0.5;
        headshoot.anchorY = 0.5;
        Laya.stage.addChild(headshoot);
        Laya.timer.once(1000,this,()=>{
            headshoot.visible = false;
            // Laya.timer.clear(this,this.UIFollow);
        })
        GameManager.Instance.UIArray.push(headshoot);
        let UIPos = this.m_npcmodel.getChildByName("UIPos") as Laya.Sprite3D;
        let screenpos1 = new Vector3();
        // Laya.timer.frameLoop(1,this,()=>{
        //     AssetManager.Instance.maincamera.worldToViewportPoint(UIPos.transform.position,screenpos);
        //     headshoot.pos(screenpos.x,screenpos.y);
        // })
        Laya.timer.frameLoop(1,this,this.UIFollow,[UIPos,headshoot,screenpos1]);
    }
    UIFollow(UIPos:Laya.Sprite3D,UI:Laya.Image,POS:Laya.Vector3){
        AssetManager.Instance.maincamera.worldToViewportPoint(UIPos.transform.position,POS);
        UI.pos(POS.x,POS.y);
    }
    
    RayCheck(){
       if(this.wined)return;
       let startpos = new Vector3(this.m_npcmodel.transform.position.x,this.m_npcmodel.transform.position.y+1.5,this.m_npcmodel.transform.position.z);
       let dir = Transform3DHelper.getForward(this.m_npcmodel.transform);
       let ray = new Laya.Ray(startpos,dir);
       let hitres = new Laya.HitResult();
       let isHit = AssetManager.Instance.mainscene.physicsSimulation.rayCast(ray,hitres,1,200);
       if(isHit){
           let target = hitres.collider.owner.parent as Laya.Sprite3D;
           if(target.name == "player"){ 
            let runner = target.getComponent(Runner) as Runner;
            let ani = target.getComponent(Laya.Animator) as Laya.Animator;
            if(!runner.Invincible){
                Laya.timer.once(150,this,()=>{
                    runner.isdead = true;
                    this.wined = true;
                })
            }
           }
           else if(target.name == "bonfire"){
               this.ChangeState(NpcState.Die);
               this.wined = true;
           }
           else if(target.name == "stone"){

           }
           else if(target.name == ""){

           }
       }
    }

}