import { _decorator, Animation, Component, macro, Node, Sprite, SpriteFrame, Vec2, Vec3 } from 'cc';
import { TowerData } from '../DataItem/ItemData';
import { resMgr } from '../Frames/ResourcesMgr';
import { GameMgr } from './GameFrameWork/GameMgr';
import { MapMgr } from './GameFrameWork/MapMgr';
import { TowerUI } from './GameFrameWork/TowerUI';
import { BulletMgr } from './GameFrameWork/BulletMgr';
import { MonsterMgr } from './GameFrameWork/MonsterMgr';
import { Tools } from './Tools/Tools';
const { ccclass, property } = _decorator;

@ccclass('Tower')
export class Tower extends Component {
     private _tilePos: Vec2 = null;
     private _atkRadiums: number = 0;
     private _lv: number = 1;
     private _atkTarget: Node = null;
     //炮
     protected _gun: Node = null;
     //地盘
     protected _chassis: Node = null;
     //塔的数据
     protected _data: TowerData = null;
     protected _isFire: boolean = false;
     //保存面向攻击对象的旋转角度
     protected _targetAngle: number = 0;
     //子弹的动画精灵帧的数组
     protected _bulletFrames: SpriteFrame[] = [];
     //自己的动画的精灵帧
     protected _aniFrames: SpriteFrame[] = [];
     //动画组件
     protected _ani: Animation = null;

     protected onLoad(): void {
          this._gun = this.node.getChildByName("Gun");
          this._chassis = this.node.getChildByName("Chassis");
     }

     protected setAni(){
          for(let i = 1; i <= this._data.fireAniCount; i++){
               this._aniFrames.push(resMgr.getSpriteFrame(this._data.fireAniImg + this._lv + i));
          }
          this._ani = Tools.createAnimation(this._aniFrames, 20, this._gun);
     }

     init(data: TowerData, pos: Vec3) {

          this._data = data;

          //子弹动画精灵帧
          for(let i = 1; i <= data.bulletAniCount; i++){
               this._bulletFrames.push(resMgr.getSpriteFrame(data.bulletAniImg + this._lv + i));
          }

          this._atkRadiums = data.atkRadiums[this._lv - 1];

          const frame = resMgr.getSpriteFrame(data.chassis[0]);
          this._chassis.getComponent(Sprite).spriteFrame = frame;
          this.node.setPosition(pos);

          //炮的图片
          this._gun.getComponent(Sprite).spriteFrame
               = resMgr.getSpriteFrame(data.fireAniImg + this._lv + "1");

          this._tilePos = GameMgr.Instance.getModuler(MapMgr).getTiledByPos(new Vec2(pos.x, pos.y));

          
     }

     protected _attack(){
          //一定不要写代码 只是为了产生多态 其实是一个接口 实现不同的派生类的方法
     }

     protected stopAttack(){

     }

     //开火
     protected _fire(){
          this._isFire = true;

          this._attack();
          
     }

     protected _unFire(){
          //this.unscheduleAllCallbacks();
          this._isFire = false;
          this.stopAttack();
     }

     bTouch(pos: Vec2): boolean {
          const tiled = GameMgr.Instance.getModuler(MapMgr).getTiledByPos(new Vec2(pos.x, pos.y));
          if (this._tilePos.equals(tiled)) {
               this.showUI();
               return true;
          };
          return false;
     }

     showUI() {
          GameMgr.Instance.getModuler(TowerUI).show(this.node.position)
     }

     protected update(dt: number): void {
          if(this._atkTarget){
               //旋转角度
               const vec: Vec3 = this._getVec(this._atkTarget).normalize();
               let angle = Vec3.angle(new Vec3(0, 1), vec);
               if(vec.x > 0){
                    angle  *= -1;
               }
               //this.unscheduleAllCallbacks();
               //弧度转角度
               this._targetAngle = angle / Math.PI * 180;
               if(this._data.rotate){
                    this._gun.angle = this._targetAngle;
               }
               
          }
          if(this._isFire){

               //已经锁定的目标 是否死亡（销毁） 是否走出攻击范围
               const dis = this._getVec(this._atkTarget).length();
               if(dis > this._atkRadiums){
                    this._atkTarget = null;
                    this._unFire();
               }
               return;
          }
          if(this._findMonster()){
               this._fire();
          }
          
     }

     private _findMonster(){
          const monsters: Node[] = GameMgr.Instance.getModuler(MonsterMgr).node.children;
          for(const node of monsters){
               //计算node和自己的距离
               const dis: number = this._getVec(node).length();
               if(dis <= this._atkRadiums){
                    this._atkTarget = node;
                    return true;
                    //this._fire();
               }
          }
          return false;
     }

     protected _getVec(node: Node): Vec3{
          return node.position.clone().subtract(this.node.position);
     }


}


