import Sprite3D = Laya.Sprite3D;
import Vector3 = Laya.Vector3;
import { AssetManager } from "../Tools/AssetManager";
import { Transform3DHelper, GameTools } from "../Tools/GameTools";
import { EventManager, StageState } from "../Tools/EventManager";
import GamePool from "../Tools/GamePool";
import { Hostage } from "./Hostage";
import { AccountManager } from "../Net/AccountManager";
import { PlayerControl } from "./PlayerControl";
import { NpcState } from "./NpcRunner";
import { GameManager } from "./GameManager";
import InGameView from "../View/InGameView";
import { StageControl } from "./StageControl";
import { AudioManager, MusicType } from "../Tools/AudioManager";
export enum ChaseNpcState{Idle,Run,Die,Atk};
export class ChaseNpc extends Laya.Script{
    private static ins:ChaseNpc;
    //人质
    public m_hostage:Sprite3D;
    public m_chasenpcmodel:Sprite3D;
    public m_chasenpcanimator:Laya.Animator;
    public m_chasenpcstate:ChaseNpcState;
    public frontdie:boolean = false;
    public reardie:boolean = false;
    public canmove:boolean = false;
    public isdead:boolean = false;
    public atked:boolean = false;
    //游戏是否开始
    public begin:boolean = false;
    //npc速度
    public m_chasenpcspeed:number = 0;

    //开始追赶的距离
    public pursuediatance:number = 0;
    //开始攻击的距离
    public atkdistance:number = 10;
    //npc扑向人质时的速度
    public NPCRushSpeed:number = 0;
    //npc距离玩家的距离
    public Distance:number = 0;
    //npc追出去的距离
    public ChaseDistance:number = 0;

    //npc初始位置
    public NpcStartPos:Vector3 = new Vector3();


    constructor(){
        super();
        ChaseNpc.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():ChaseNpc{
        if(ChaseNpc.ins){
            return ChaseNpc.ins
        }
        else{
            return new ChaseNpc();
        }
    }
    onAwake(){
        this.m_chasenpcmodel = this.owner as Laya.Sprite3D;
    }

    onStart()
    {
        this.m_chasenpcanimator = this.m_chasenpcmodel.getComponent(Laya.Animator) as Laya.Animator;
        this.m_hostage = this.owner.parent.parent.getChildByName("player").getChildAt(0) as Laya.Sprite3D;
        this.NpcStartPos = this.m_chasenpcmodel.transform.position.clone();

        this.m_chasenpcspeed = StageControl.Instance.curstage.npcspeed;
        this.Distance = AccountManager.Instance.curplayerData.NpcChaseDistance*1.65;
        this.ChaseDistance = AccountManager.Instance.curplayerData.NpcRushDistance*1.65;
        this.NPCRushSpeed = AccountManager.Instance.curplayerData.NPCRushSpeed;
    }

    Begin(){
        this.ChangeState(ChaseNpcState.Run);
        this.begin = true;
    }
    dir = new Vector3();
    currotV = new Vector3();
    currot = new Laya.Quaternion;
    NPCMoveDir:Vector3;
    CurrectRotate = new Laya.Quaternion();
    onUpdate(){
        if(!this.begin)return
        if(this.isdead)return
        let _host = this.m_hostage.getComponent(Hostage) as Hostage;
        if(_host.isdead){
            this.ChangeState(ChaseNpcState.Idle)
            return
        }
        if(this.frontdie || this.reardie){
            this.ChangeState(ChaseNpcState.Die);
            return
        }
        var distance = Vector3.distance(PlayerControl.Instance.Player.transform.position,this.m_chasenpcmodel.transform.position);

        if(distance < this.Distance  && !this.atked){
            Vector3.subtract(this.m_hostage.transform.position,this.m_chasenpcmodel.transform.position,this.currotV);
            Vector3.normalize(this.currotV,this.currotV);
            this.m_chasenpcmodel.transform.lookAt(new Vector3(this.m_chasenpcmodel.transform.position.x-this.currotV.x,this.m_chasenpcmodel.transform.position.y,this.m_chasenpcmodel.transform.position.z-this.currotV.z),new Vector3(0,1,0));
            this.NPCMoveDir = this.currotV;
            this.canmove = true;
            
            _host.canmove = true;
            // this.ChangeState(ChaseNpcState.Run);
            let _dis = this.m_chasenpcmodel.transform.position.z - this.NpcStartPos.z;
            if(_dis>= this.ChaseDistance){
                this.atked = true;
                this.m_chasenpcspeed = this.NPCRushSpeed;
                this.ChangeState(ChaseNpcState.Atk);
            }
        }
        // else if(distance <= this.atkdistance && !this.atked){
        //     Vector3.subtract(this.m_hostage.transform.position,this.m_chasenpcmodel.transform.position,this.currotV);
        //     Vector3.normalize(this.currotV,this.currotV);
        //     this.m_chasenpcmodel.transform.lookAt(new Vector3(this.m_chasenpcmodel.transform.position.x-this.currotV.x,this.m_chasenpcmodel.transform.position.y,this.m_chasenpcmodel.transform.position.z-this.currotV.z),new Vector3(0,1,0));
        //     this.NPCMoveDir=this.currotV;
        //     this.canmove = false;
        //     this.atked = true;
        //     this.ChangeState(ChaseNpcState.Atk);
        // }
        this.Move(this.NPCMoveDir,this.m_chasenpcspeed);
        this.RayCheck();
    }
    curspeed = 0;
    offest = new Vector3();
    curpos = new Vector3();
    Move(_dir:Vector3,_speed:number){
        let stage = Number(AccountManager.Instance.curplayerData.GainAccount("stage"));
        if(stage <= 2)return
        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_chasenpcmodel.transform.position,this.offest,this.curpos);
            Vector3.lerp(this.m_chasenpcmodel.transform.position,this.curpos,0.15,this.curpos);
            this.curpos = new Vector3(this.curpos.x,this.curpos.y,this.curpos.z);
            this.m_chasenpcmodel.transform.position = this.curpos;
        }
    }
    AddSpeed(){
        this.m_chasenpcspeed = StageControl.Instance.curstage.npcspeed;
    }
    SlowSpeed(){
        this.m_chasenpcspeed = 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);
        EventManager.StageOff(StageState.Lose,this,this.GameOver);
        EventManager.StageOff(StageState.Win,this,this.GameOver);
        // this.canmove = false;
    }
    ChangeState(_state:ChaseNpcState){
        if(this.m_chasenpcstate == _state) return
        this.m_chasenpcstate = _state;
        switch (this.m_chasenpcstate) {
            case ChaseNpcState.Atk:
                this.Attack();
                break;
            case ChaseNpcState.Idle:
                this.Idle();
                break;
            case ChaseNpcState.Run:
                this.Run();
                break;
            case ChaseNpcState.Die:
                this.Die();
                break;
        }
    }
    //站立
    Idle(){
        this.m_chasenpcanimator.play("idle");
    }
    //攻击
    Attack(){
        this.m_chasenpcanimator.play("atk");
        // this.canmove = false;
        // Laya.timer.frameLoop(1,this,this.AnimatorState);
        Laya.timer.once(500,this,()=>{
            this.canmove = false;
        })
    }
    //获胜
    Win(){
        this.m_chasenpcanimator.play("win");
    }
    //奔跑
    Run(){
        this.m_chasenpcanimator.play("run");
    }
    die = false;
    Die(){
        if(this.die)return 
        this.die = true;
        AudioManager.playMusic(MusicType.die);
        this.PiaoZi();
        // GameManager.Instance.KillNum++;
        // InGameView.Instance.InitUI();
        this.isdead = true;
        EventManager.StageOff(StageState.Start,this,this.Begin);
        // Laya.timer.clearAll(this);
        if(this.frontdie){
            this.m_chasenpcanimator.play("diefront");
        }
        if(this.reardie){
            this.m_chasenpcanimator.play("dierear");
        }
        this.m_chasenpcanimator.play("diefront");
        this.canmove = false;
    }
    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_chasenpcmodel.getChildByName("UIPos") as Laya.Sprite3D;
        let screenpos2 = new Vector3();
        Laya.timer.frameLoop(1,this,this.UIFollow,[UIPos,headshoot,screenpos2]);
    }
    UIFollow(UIPos:Laya.Sprite3D,UI:Laya.Image,POS:Laya.Vector3){
        AssetManager.Instance.maincamera.worldToViewportPoint(UIPos.transform.position,POS);
        UI.pos(POS.x,POS.y);
    }

    // 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_chasenpcmodel.transform.position.x,this.m_chasenpcmodel.transform.position.y+0.5,this.m_chasenpcmodel.transform.position.z);
       let dir = Transform3DHelper.getForward(this.m_chasenpcmodel.transform);
       let ray = new Laya.Ray(startpos,dir);
       let hitres = new Laya.HitResult();
       let isHit = AssetManager.Instance.mainscene.physicsSimulation.rayCast(ray,hitres,3,200);
       if(isHit){
           let target = hitres.collider.owner.parent as Laya.Sprite3D;
           if(target.name == "hostage"){
               let _hostage = target.getComponent(Hostage) as Hostage;
               _hostage.isdead = true; 
            //    this.canmove = false;
           }
           else if(target.name == "bonfire"){
               this.ChangeState(ChaseNpcState.Die);
           }
           else if(target.name == "stone"){
               this.m_chasenpcspeed = 0;
           }
           else if(target.name == ""){

           }
       }
    }

}