import { Runner } from "./Runner";
import Sprite3D = Laya.Sprite3D;
import { EventManager, EventType } from "./EventManager";
import { GameState, GameManager } from "./GameManager";
import CameraManager from "./CameraManager";
import Vector3 = Laya.Vector3;
import Vector2 = Laya.Vector2;
import { GameUtils } from "../../GameUtils/GameUtils";
import { ScenceManager } from "./ScenceManager";
import PoolManager from "./PoolManager";
import { ResourcesManager, effecttype } from "./ResourcesManager";
import { LevelManager } from "./LevelManager";
import { Stage, Level, HeroData } from "./LevelData";
import { WindowManager, WindowType } from "../../Window/WindowManager";
import { Queue } from "./Queue";
import { PlayerAccount, AccountUser } from "../Network/PlayerAccount";

export enum InputState
{
    None,ClickDown,ClickUp,Slider
}

export class Player
{
    static Instance:Player;
    constructor(_sprite:Sprite3D)
    {
        this.m_sprite = _sprite;
        this.m_model = this.m_sprite.getChildAt(0) as Sprite3D;;
        this.m_runner = _sprite.addComponent(Runner) as Runner;
        this.m_runner.m_speed = LevelManager.Instance.curLevel.playerspeed;
        Queue.Instance.signup(this.m_runner);
        this.m_runner.name = "hehe";
        Player.Instance = this;
        //this.m_runner.Ai = true;
        this.RegEvent();
    }

    m_sprite:Sprite3D;
    m_model:Sprite3D;
    m_runner:Runner;
    m_inputState:InputState = InputState.None;

    static CanInput = true;

    Reset(_sprite:Sprite3D)
    {
        this.m_sprite = _sprite;
        this.m_model = this.m_sprite.getChildAt(0) as Sprite3D;;
        this.m_runner.m_effect = this.m_sprite.getChildByName("effect")as Sprite3D;
        this.m_runner.Id = 6;
        this.m_runner = _sprite.addComponent(Runner) as Runner;
        this.m_runner.OnLand = true;
        this.m_inputState = InputState.None;
        this.m_runner.name = "hehe";
        Queue.Instance.signup(this.m_runner);
        this.RegEvent();
    }

    RegEvent()
    {
        Laya.stage.on(Laya.Event.MOUSE_DOWN,this,this.OnClickDown);
        Laya.stage.on(Laya.Event.MOUSE_UP,this,this.OnClickUp);
        Laya.stage.on(Laya.Event.MOUSE_OUT,this,this.OnClickUp);
        
        EventManager.EventOn(EventType.InputState,this,this.OnInput);
        //EventManager.EventOn(EventType.OutLand,this,this.OutLand);
        //EventManager.EventOn(EventType.OnLand,this,this.OnLand);
        //EventManager.GameStateEventOn(GameState.Idle,this,this.OnEnterIdle);
        EventManager.GameStateEventOn(GameState.Playing,this,this.OnEnterPlaying);
        EventManager.GameStateEventOn(GameState.Win,this,this.OnPlayerWin);
        EventManager.GameStateEventOn(GameState.Die,this,this.OnPlayerDie);
        EventManager.GameStateEventOn(GameState.End,this,this.OnGameOver);


    }
    UnRegEvent()
    {
        Laya.stage.off(Laya.Event.MOUSE_DOWN,this,this.OnClickDown);
        Laya.stage.off(Laya.Event.MOUSE_UP,this,this.OnClickUp);
        Laya.stage.off(Laya.Event.MOUSE_OUT,this,this.OnClickUp);

        EventManager.EventOff(EventType.InputState,this,this.OnInput);
        //EventManager.EventOff(EventType.OutLand,this,this.OutLand);
        //EventManager.EventOff(EventType.OnLand,this,this.OnLand);
        //EventManager.GameStateEventOff(GameState.Idle,this,this.OnEnterIdle);
        EventManager.GameStateEventOff(GameState.Playing,this,this.OnEnterPlaying);
        EventManager.GameStateEventOff(GameState.Win,this,this.OnPlayerWin);
        EventManager.GameStateEventOff(GameState.Die,this,this.OnPlayerDie);
        EventManager.GameStateEventOff(GameState.End,this,this.OnGameOver);

        Laya.timer.clearAll(this);
    }

    OnClickDown(e)
    {
        if(e.target instanceof Laya.UIComponent)
        {
            return;
        }

        this.m_inputState = InputState.ClickDown;
        if(!Player.CanInput)return;
        EventManager.EventTrigger(EventType.InputState,InputState.ClickDown);
    }
    OnClickUp(e)
    {
        if(e.target instanceof Laya.UIComponent)
        {
            return;
        }

        this.m_inputState = InputState.ClickDown;
        if(!Player.CanInput)return;
        EventManager.EventTrigger(EventType.InputState,InputState.ClickUp);
    }

    OnSlider()
    {
        this.m_inputState = InputState.Slider;
        if(!Player.CanInput)return;
        EventManager.EventTrigger(EventType.InputState,InputState.Slider);
    }

    OnInput(_state:InputState)
    {
        if(_state == InputState.ClickDown)
        {
            this.OnInputDown();
        }
        if(_state == InputState.ClickUp)
        {
            this.OnInputUp();
        }
        if(_state == InputState.Slider)
        {
            this.OnInputSlider();
        }
    }

    RessetPlayer(_hero:HeroData = null)
    {
        if(this.m_runner.m_hat)PoolManager.Instance.RecoverMeshSprite3D(this.m_runner.m_hat);
        if(this.m_runner.m_cb)PoolManager.Instance.RecoverMeshSprite3D(this.m_runner.m_cb);
        if(this.m_runner.m_crown)this.m_runner.m_crown.active = true;PoolManager.Instance.RecoverMeshSprite3D(this.m_runner.m_crown);
        if(this.m_sprite)PoolManager.Instance.RecoverMeshSprite3D(this.m_sprite);

        var playerid = Number(PlayerAccount.CurrentAccount.CurAccountData.GetUser(AccountUser.equip_hero));
        if(_hero)playerid = _hero.id;
        var player = ResourcesManager.Instance.roleassets[playerid].getChildAt(0) as Sprite3D;
        var playermodel = PoolManager.Instance.CreatMeshSprite3D(player,"");
        var startpoint = new Vector3(0,0,10);
        playermodel.transform.position = startpoint;

        var hatid = Number(PlayerAccount.CurrentAccount.CurAccountData.GetUser(AccountUser.equip_hat));
        if(hatid > 0)
        {
            var hat = ResourcesManager.Instance.hatasset[hatid];
            var hatmodel = PoolManager.Instance.CreatMeshSprite3D(hat,"");
            var head = playermodel.getChildAt(0).getChildAt(0) as Laya.Sprite3D;
            head.addChild(hatmodel);
            hatmodel.transform.localPosition = new Laya.Vector3(0.06,0,0);
            hatmodel.transform.localRotationEuler = new Laya.Vector3(0,90,0);
        }
        
        var cbid = Number(PlayerAccount.CurrentAccount.CurAccountData.GetUser(AccountUser.equip_hat));
        if(cbid > 0)
        {
            var cb = ResourcesManager.Instance.cbasset[cbid];
            var cbmodel = PoolManager.Instance.CreatMeshSprite3D(cb,"");
            var back = playermodel.getChildAt(0).getChildAt(1) as Laya.Sprite3D;
            back.addChild(cbmodel);
            cbmodel.transform.localPosition = new Laya.Vector3(0,-0.01,0);
            cbmodel.transform.localRotationEuler = new Laya.Vector3(-25,90,180);
        }

        ScenceManager.Instance.GameScence.addChild(playermodel);

        this.m_runner.Id = 6;

        CameraManager.Instance.StopFollow();
        ScenceManager.Instance.GameCamera.transform.position = new Vector3(0,0.6,8.5);
        ScenceManager.Instance.GameCamera.transform.rotationEuler = new Vector3(-5,180,0);

        this.Reset(playermodel);
    }

    ClearPlayer()
    {
        this.m_runner.m_flySprite.active = true;
        this.m_runner.m_crown.active = true;
        PoolManager.Instance.RecoverMeshSprite3D(this.m_runner.m_flySprite);
        PoolManager.Instance.RecoverMeshSprite3D(this.m_runner.m_crown);
        if(this.m_runner.m_hat)PoolManager.Instance.RecoverMeshSprite3D(this.m_runner.m_hat);
        if(this.m_runner.m_cb)PoolManager.Instance.RecoverMeshSprite3D(this.m_runner.m_cb);
        PoolManager.Instance.RecoverMeshSprite3D(this.m_sprite);
        CameraManager.Instance.StopFollow();
        ScenceManager.Instance.GameCamera.transform.position = new Vector3(0,0.6,8.5);
        ScenceManager.Instance.GameCamera.transform.rotationEuler = new Vector3(-5,180,0);
    }

    RevivePlayer()
    {
        var stage = this.m_runner.curstage;
        this.m_runner.die = false;
        this.m_runner.m_crown.active = false;
        this.m_sprite.transform.position = new Vector3(0,stage.starty + 5,stage.startz + 5);
        this.m_runner.SetMove();
        this.m_runner.curspeed = this.m_runner.m_speed;
        this.m_runner.SetFly();
        ScenceManager.Instance.GameCamera.transform.position = new Vector3(0,this.m_sprite.transform.position.y + 0.6,this.m_sprite.transform.position.z - 1.5);
        CameraManager.Instance.SetFollow(this.m_sprite.transform);
        Player.CanInput = true;
    }

    get CurLevelPrecent()
    {
        return this.m_runner.m_sprite.transform.position.z/LevelManager.Instance.curLevel.endroadsprite.transform.position.z;
    }

    OnEnterIdle()
    {
        CameraManager.Instance.SetFollow(this.m_sprite.transform);
    }

    OnEnterPlaying()
    {
        CameraManager.Instance.SetFollow(this.m_sprite.transform);
    }

    OnPlayerWin()
    {
        Player.CanInput = false;
        this.m_runner.Stop();
        CameraManager.Instance.StopFollow();
        //this.m_runner.m_animator.play("win");
        ScenceManager.Instance.GameLight.transform.rotationEuler = new Vector3(-50,0,0);
        var camera = ScenceManager.Instance.GameCamera;
        var camerapos = new Vector3(1,this.m_sprite.transform.position.y + 1.5,this.m_sprite.transform.position.z + 2.5);
        var lookpos = new Vector3(this.m_sprite.transform.position.x,this.m_sprite.transform.position.y + 0.5,this.m_sprite.transform.position.z);
        GameUtils.TweenLookAtMove(camera.transform,camerapos,this.m_sprite.transform.position,1.5,()=>
        {
            Laya.timer.once(1000,this,()=>
            {
                GameManager.Instance.ChangeState(GameState.End,true);
            })
        });
    }
    OnPlayerDie()
    {
        Player.CanInput = false;
        this.m_runner.Stop();
        CameraManager.Instance.StopFollow();
        //this.m_runner.m_animator.play("lose");
        // var camera = ScenceManager.Instance.GameCamera;
        // var camerapos = new Vector3(0,this.m_sprite.transform.position.y + 1,this.m_sprite.transform.position.z + 1);
        // var lookpos = new Vector3(this.m_sprite.transform.position.x,this.m_sprite.transform.position.y + 0.5,this.m_sprite.transform.position.z);
        GameManager.Instance.ChangeState(GameState.Revive);
    }

    OnGameOver()
    {
        this.offestx = 0;
        this.UnRegEvent();
    }

    curMousePos = new Vector2(0,0);
    OnInputDown()
    {
        this.curMousePos = new Laya.Vector2(Laya.MouseManager.instance.mouseX,Laya.MouseManager.instance.mouseY);
        Laya.timer.frameLoop(1,this,this.OnSlider);
    }

    OnInputUp()
    {
        this.offestx = 0;
        this.m_runner.BackRote();
        Laya.timer.clear(this,this.OnSlider);
    }

    offestx = 0;

    OnInputSlider()
    {
        var MousePos = new Laya.Vector2(Laya.MouseManager.instance.mouseX,Laya.MouseManager.instance.mouseY);
        var offestX = MousePos.x - this.curMousePos.x;

        offestX = offestX > 100?100:offestX;
        offestX = offestX < -100?-100:offestX;
        //EventManager.EventTrigger(EventType.Hover,Math.round(offestX));

        this.offestx = GameUtils.lerp(this.offestx,offestX,0.015);

        this.m_runner.MoveX(-this.offestx);

        var dir = new Vector3(-offestX*0.005,0,0);

        if(!this.m_runner.fly)this.m_runner.TurnDir(dir);

        this.curMousePos = MousePos;
    }
}