import { ButtonComponent, EventTouch, GraphicsComponent, instantiate, LabelComponent, loader, Node, Prefab, ProgressBarComponent, SpriteComponent, SpriteFrame, _decorator } from 'cc';
import { GUIMediator } from '../../../engines/gui/GUIMediator';
import { LoadingView } from '../../../engines/loadingView/LoadingView';
import { DataModelEventType } from '../../../engines/models/DataModelEventType';
import { SceneManager } from '../../../engines/scenes/SceneManager';
import { SoundManager } from '../../../engines/sounds/SoundManager';
import GameConfigManager from '../../models/GameConfigManager';
import { GameModel } from '../../models/GameModel';
import { GamePropertys } from '../../models/GamePropertys';
import { GameController } from './GameController';
import { WeaponBase } from './weapons/WeaponBase';
const { ccclass, property } = _decorator;

@ccclass('FightingMediator')
export class FightingMediator extends GUIMediator {
    
    @property({
        type:GraphicsComponent
    })
    DrawingBoard:GraphicsComponent=null;

    @property({
        type:SpriteComponent
    })
    SkillIcon:SpriteComponent=null;

    @property({
        type:LabelComponent
    })
    SkillLabel:LabelComponent=null;

    @property({
        type:Prefab
    })
    BulletUIPrefab:Prefab=null;

    @property({
        type:Node
    })
    BulletClip:Node=null;

    /**
     * 子弹数量
     */
    @property({
        type:LabelComponent
    })
    BulletCount:LabelComponent=null;

    @property({
        type:ButtonComponent
    })
    leftFireButton:ButtonComponent=null;

    @property({
        type:ButtonComponent
    })
    middleFireButton:ButtonComponent=null;

    @property({
        type:ButtonComponent
    })
    rightFireButton:ButtonComponent=null;

    @property({
        type:Node
    })
    killCountGroup:Node=null;
    @property({
        type:LabelComponent
    })
    killCountText:LabelComponent=null;

    /**
     * 怪物数量
     */
    @property({
        type:LabelComponent
    })
    monsterCountText:LabelComponent=null;

    /**
     * 积分
     */
    @property({
        type:LabelComponent
    })
    integralLabel:LabelComponent=null;


    /**
     * 怒气值进度条
     */
    @property({
        type:ProgressBarComponent
    })
    angerCountProgrssBar:ProgressBarComponent=null;

    /**
     * 怒气值技能按钮
     */
    @property({
        type:ButtonComponent
    })
    angerSkillButton:ButtonComponent=null;

    /**
     * 栅栏血量进度条
     */
    @property({
        type:ProgressBarComponent
    })
    fenceHpProgrssBar:ProgressBarComponent=null;

    /**
     * 栅栏血量文字
     */
    @property({
        type:LabelComponent
    })
    fenceHpLabel:LabelComponent=null;

    /**
     * 换弹动画
     */
    @property({
        type:ProgressBarComponent
    })
    reloadProgrssBar:ProgressBarComponent=null;

    /**
     * 怪物血条层
     */
    @property({
        type:Node
    })
    monsterHPUILayer:Node=null;

    /**
     * 第几天
     */
    @property({
        type:LabelComponent
    })
    levelLabel:LabelComponent=null;

    @property({
        type:Node
    })
    teachingNode:Node=null;

    /**
     * 弹夹子弹池
     */
    bulletPool:Node[]=[];

    /**
     * 资源引用
     */
    private assetsRef:Prefab[];
    
    /**
     * 显示状态
     */
    private onShowed:boolean=false;
    start () {
        // Your initialization goes here.
    }

    constructor(){
        super();
        console.log("创建！");
    }

    OnShow():void{
        this.onShowed=false;
        this.LoadAssets();
        if(GameModel.single.isNewPlayer){
            this.teachingNode.active=true;
        }else{
            this.teachingNode.active=false;
        }
    }

    private __OnShow():void{
        GameController.single.monsterHPUILayer=this.monsterHPUILayer;
        GameController.single.Init(this);
        this.AddEvents();
        this.RefreshView();

        SoundManager.single.PlayMusic("sounds/combat");
        SoundManager.single.PlaySound("zombie","sounds/zombie",true);

        this.InitSkillIcon();
        this.onShowed=true;
    }

    private LoadAssets():void{
        //先清理老资源
        if(this.assetsRef){
            let deps:string[];
            this.assetsRef.forEach(element => {
                deps=loader.getDependsRecursively(element);
                loader.release(deps);
            });
            this.assetsRef.length=0;
            this.assetsRef=null;
        }

        let urls:string[]=[];
        //武器
        let weaponConfig:any=GameConfigManager.GetWeaponConfig(GameModel.single.currentWeaponId);
        urls.push(weaponConfig.prefab);

        //栅栏
        let fenceConfig:any=GameConfigManager.GetFenceConfig(GameModel.single.fenceId);
        urls.push(fenceConfig.prefab);
        
        //本关用到的怪物资源
        let levelConfig:any=GameConfigManager.GetLevelConfig(GameModel.single.currentLevel);
        let monsterConfig:any;
        levelConfig.monsters.forEach(element => {
            monsterConfig=GameConfigManager.GetMonsterConfig(element.monsterId);
            if(urls.indexOf(monsterConfig.prefab)<0){
                urls.push(monsterConfig.prefab);
            }
        });

        //枪口火焰
        urls.push("d3d/gunFire/GunFire");

        //怪物血条
        urls.push("ui/components/MonsterHPUI");

        //加载
        loader.loadResArray(urls,Prefab,this.LoadAssetsProgress.bind(this),this.LoadAssetsComplete.bind(this));
    }

    private LoadAssetsProgress(index:number,total:number,item):void{
        LoadingView.single.UpdateProgress(index/total);
    }

    private LoadAssetsComplete(error:Error,assets):void{
        if(error){
            console.error(error);
        }
        this.assetsRef=assets;
        this.__OnShow();
    }


    OnHide():void{
        this.onShowed=false;
        this.RemoveEvents();
        SoundManager.single.PlayMusic("sounds/main");
        SoundManager.single.StopSound("Weapon");
        SoundManager.single.StopSound("WeaponLeft");
        SoundManager.single.StopSound("WeaponRight");
        SoundManager.single.StopSound("zombie");
    }

    private AddEvents():void{
        this.leftFireButton.node.on(Node.EventType.TOUCH_START,this.FireButtonTouchStart,this);
        this.middleFireButton.node.on(Node.EventType.TOUCH_START,this.FireButtonTouchStart,this);
        this.rightFireButton.node.on(Node.EventType.TOUCH_START,this.FireButtonTouchStart,this);

        this.leftFireButton.node.on(Node.EventType.TOUCH_END,this.FireButtonTouchEnd,this);
        this.middleFireButton.node.on(Node.EventType.TOUCH_END,this.FireButtonTouchEnd,this);
        this.rightFireButton.node.on(Node.EventType.TOUCH_END,this.FireButtonTouchEnd,this);

        GameController.single.weapon.AddEvent(WeaponBase.EVENT_BULLET_CHANGE,this,this.bulletCountChanged,0);
        GameModel.single.AddEvent(DataModelEventType.PROPERTY_CHANGED,this,this.GameModelPropertyEventHandler,0);
    }

    private RemoveEvents():void{
        this.leftFireButton.node.off(Node.EventType.TOUCH_START,this.FireButtonTouchStart,this);
        this.middleFireButton.node.off(Node.EventType.TOUCH_START,this.FireButtonTouchStart,this);
        this.rightFireButton.node.off(Node.EventType.TOUCH_START,this.FireButtonTouchStart,this);

        this.leftFireButton.node.off(Node.EventType.TOUCH_END,this.FireButtonTouchEnd,this);
        this.middleFireButton.node.off(Node.EventType.TOUCH_END,this.FireButtonTouchEnd,this);
        this.rightFireButton.node.off(Node.EventType.TOUCH_END,this.FireButtonTouchEnd,this);

        GameController.single.weapon.RemoveEvent(WeaponBase.EVENT_BULLET_CHANGE,this,this.bulletCountChanged);
        GameModel.single.RemoveEvent(DataModelEventType.PROPERTY_CHANGED,this,this.GameModelPropertyEventHandler);
    }

    private GameModelPropertyEventHandler(key:string):void{
        switch (key) {
            case GamePropertys.killCount://杀死怪物
                this.CallNextFrame(this.KillCountChangedHandler.bind(this));
                break;
            case GamePropertys.angerCount://怒气值变化
                this.CallNextFrame(this.AngerCountChangedHandler.bind(this));
                break;
            case GamePropertys.integral://积分变化
                this.CallNextFrame(this.RefreshIntegral.bind(this));
                break;
            default:
                break;
        }
    }

    private KillCountChangedHandler():void{
        this.RefreshKillCount();
        this.RefreshMonsterCount();
    }

    
    private AngerCountChangedHandler():void{
        this.RefreshAngerCount();
    }


    private InitSkillIcon():void{
        let skillConfig:any=GameConfigManager.GetSkillConfig(GameController.single.weapon.weaponConfig.skill);
        loader.loadRes(skillConfig.icon+"/spriteFrame",SpriteFrame,(err,asset:SpriteFrame)=>{
            if(err!=null){
                console.log("技能图标加载失败")
                return;
            }
            this.SkillIcon.spriteFrame=asset;
        });
        this.SkillLabel.string=skillConfig.name.toString();
    }

    /**
     * 刷新弹夹
     */
    RefreshBulletClip():void{
        let max:number=Math.min(10,GameController.single.weapon.bulletCount);
        while(this.BulletClip.children.length!=max){
            let bullet:Node;
            //增加
            if(this.BulletClip.children.length<max){
                bullet=this.CreateBullet();
                this.BulletClip.addChild(bullet);
            }else{//删除
                bullet=this.BulletClip.children[0];
                this.BulletClip.removeChild(bullet);
                this.DisposeBullet(bullet);
            }
        }
        if(GameController.single.currentSkill!=null&&GameController.single.currentSkill.infiniteAmmo){
            this.BulletCount.string="∞";
        }else{
            this.BulletCount.string=GameController.single.weapon.bulletCount.toString();
        }
    }

    RefreshView():void{
        this.RefreshBulletClip();
        this.RefreshKillCount();
        this.RefreshAngerCount();
        this.RefreshFenceHp();
        this.RefreshMonsterCount();
        this.RefreshIntegral();
        this.levelLabel.string="第"+GameModel.single.currentLevel+"天";
    }
    
    /**
     * 连杀
     */
    RefreshKillCount():void{
        this.killCountText.string=GameModel.single.killCount.toString();
    }

    /**
     * 怒气值
     */
    RefreshAngerCount():void{
        if(GameModel.single.angerCount<GameController.single.weapon.weaponConfig.maxAnger){
            this.angerSkillButton.node.active=false;
        }else{
            this.angerSkillButton.node.active=true;
        }
        this.angerCountProgrssBar.progress=GameModel.single.angerCount/GameController.single.weapon.weaponConfig.maxAnger;
    }
    
    /**
     * 栅栏HP
     */
    RefreshFenceHp():void{
        this.fenceHpProgrssBar.progress=GameController.single.fence.hp/GameController.single.fence.maxHp;
        this.fenceHpLabel.string=GameConfigManager.GetFenceConfig(GameModel.single.currentFenceId).name+" "+GameController.single.fence.hp+"/"+GameController.single.fence.maxHp;
    }

    /**
     * 怪物数量
     */
    RefreshMonsterCount():void{
        this.monsterCountText.string=GameModel.single.killCount+"/"+GameController.single.monsterTotalCount;
    }

    /**
     * 积分
     */
    RefreshIntegral():void{
        this.integralLabel.string=GameModel.single.integral.toString();
    }
    
    private fenceHp:number=0;
    update (deltaTime: number) {
        if(this.onShowed==false){
            return;
        }
        super.update(deltaTime);
        if(GameController.single.fence!=null&&GameController.single.fence.node!=null){
            this.RefreshFenceHp();
            this.fenceHp=GameController.single.fence.hp;
        }
        if(GameController.single.weapon.reloadProgress<0||GameController.single.weapon.reloadProgress>=1){
            this.reloadProgrssBar.node.active=false;
        }else{
            this.reloadProgrssBar.node.active=true;
            this.reloadProgrssBar.progress=GameController.single.weapon.reloadProgress;
        }
    }

    private currentFireButtonNode:Node;
    FireButtonTouchStart(e:EventTouch):void{
        if(this.teachingNode.active){
            this.teachingNode.active=false;
        }
        this.currentFireButtonNode=e.target as Node;
        if(e.target==this.leftFireButton.node){
            GameController.single.TryFire(1);
        }else if(e.target==this.middleFireButton.node){
            GameController.single.TryFire(2);
        }else{
            GameController.single.TryFire(3);
        }
    }

    FireButtonTouchEnd(e:EventTouch):void{
        if(e.target!=this.currentFireButtonNode){
            return;
        }
        GameController.single.TryFire(0);
    }

    /**
     * 使用技能
     */
    UseSkill():void{
        if(GameModel.single.angerCount<GameController.single.weapon.weaponConfig.maxAnger){
            return;
        }
        GameController.single.UseSkill();
    }

    /**
     * 返回主界面
     */
    BackToPrepareScene():void{
        GameController.single.OnGameOver(2);
        SceneManager.single.Swicth("PrepareScene");
        this.HideSelf();
    }

    private bulletCountChanged():void{
        this.RefreshBulletClip();
    }

    /**
     * 从池中创建子弹
     */
    private CreateBullet():Node{
        if(this.bulletPool.length>0){
            return this.bulletPool.shift();
        }
        return instantiate(this.BulletUIPrefab);
    }
    private DisposeBullet(bullet:Node){
        if(this.bulletPool.indexOf(bullet)<0){
            this.bulletPool.push(bullet);
        }else{
            console.error("重复回收弹夹子弹");
        }
    }

    /**
     * 暂停游戏
     */
    pauseGame():void{
        if(GameController.single.paused){
            GameController.single.PlayGame();
        }else{
            GameController.single.PauseGame();
        }
    }

    /**
     * 跳过教学
     */
    SkipTeaching():void{
        
    }
}
