/**
 * Created by rockyl on 2018/8/16.
 */

import { props } from '../props';
import { playSound, createSvga } from './utils';
import ObjectPool = engine.ObjectPool;
import { Platform } from './Platform';
import { PrizeGood } from './PrizeGood';
import { getTextureByName } from './utils';
import { Goods } from './Goods';
import { PoolName } from './object-pool-init';
import SoundMgr from './SoundMgr';
interface playerProp extends engine.Container {
  // x速度
  vx?: number;
  // y速度
  vy?: number;
  isMovingLeft?: boolean;
  isMovingRight?: boolean;
  isDead?: boolean | string;
  dir?: string;
  // deadInfo:object;
  draw?(): void;
  jump?(): void;
  jumpHigh?(): void;
}

export default class GameView extends engine.Container {
  private _hasSetup;
  gravity: number = 0.2;
  bottomY: number = 5;
  jumpCount: number = 0;
  baseY: number;
  flag = 0;
  loopFrame: any;
  prizeGoodList: { number: PrizeGood };
  diedIndex: number;
  rectHeight: number;
  addTimer: NodeJS.Timer | null;
  iconX = 0;
  //玩家
  private player: playerProp;

  //触摸层
  private rectBg: engine.Container;
  //npc层
  private NpcBg: engine.Container;

  //当前分数
  private score;

  //游戏状态
  private gameIng;

  //npc出身计时器
  private timer;
  //倒计时计时器
  private countdownTimer: any;
  //倒计时
  private countdown: number;

  //当前速度
  private speed: number;

  // 当前场景上面的物品
  private goodsItems = [];

  private _goods: Goods;

  constructor() {
    super();
    // this.platformCount = 10
    this.once(engine.Event.ADDED_TO_STAGE, this.setup, this);
    // engine.globalEvent.addEventListener('jump-more-score', , this);
  }
  platformCount = 12;
  platformGap = 0;
  platPosition = 0;
  platforms = [];
  newPlatforms = [];
  cashNum = 0;

  private waterSvga;
  private boomSvga;
  private playerSvga;
  private addScoreIcon;

  setup() {
    if (this._hasSetup) {
      return;
    }
    this._hasSetup = true;
    this.NpcBg = new engine.Container();
    this.NpcBg.alpha = 1;
    this.NpcBg.width = 0;
    this.NpcBg.height = 0;
    this.addChild(this.NpcBg);

    this.player = new engine.Container();

    this.player.vx = 0;
    this.player.vy = 11;
    this.player.isMovingLeft = false;
    this.player.isMovingRight = false;
    this.player.isDead = false;
    this.player.jump = () => {
      this.player.vy = -10;
      this.playerSvga.play(false, false);
    };

    this.playerSvga = createSvga('玩家abc');
    this.player.addChild(this.playerSvga);
    // this.playerSvga.gotoAndPlay(1);
    this.visible = false;
    this.addScoreIcon = new engine.Sprite(getTextureByName('加分'));
    this.addScoreIcon.visible = false;
    this.player.addChild(this.addScoreIcon);

    setTimeout(() => {
      this.visible = true;
      this.playerSvga.anchorY = this.playerSvga.height / 2;
      this.playerSvga.anchorX = this.playerSvga.width / 2;
      this.player.anchorY = this.player.height / 2;
      this.player.anchorX = this.player.width / 2;
      this.player.x = 375 - this.player.width / 2;
      // this.addScoreIcon.x = this.player.width + 20;
      this.iconX = this.player.width + 20;
      this.addScoreIcon.y =
        this.player.height / 2 - this.addScoreIcon.height / 2 + 20;

      // this.player.y = props.playerPositionY;
    }, 300);
    this.score = 0;
    this.rectBg = new engine.Container();
    // this.rectBg.alpha = 0;
    this.rectBg.width = 750;
    this.rectBg.height = 1624;
    this.rectHeight = this.stage.height - this.rectBg.height;
    this.rectBg.y = this.rectHeight;

    // this.bottom = 1624
    this.addChild(this.rectBg);
    this.player.y = this.rectBg.height;
    this.baseY = this.rectBg.height - this.bottomY;

    this.rectBg.addEventListener(
      engine.MouseEvent.CLICK,
      this.onDownStage,
      this
    );
  }

  base() {}
  // 创建台阶
  createPlatform(needGhost: boolean = false) {
    let platform = new Platform();
    platform.x = Math.random() * (this.width - platform.width);

    this.platPosition += this.rectBg.height / this.platformCount;
    let platform2 = new Platform();

    //左边出现的位置
    let left = platform.x;
    if (left > this.width / 2) {
      platform2.x =
        Math.random() * (platform.x - platform.width) - platform.width / 2;
    } else {
      platform2.x =
        platform.x +
        platform.width +
        Math.random() * (this.width - platform.x - platform.width * 1.5);
    }
    platform2.y = platform.y = this.platPosition;
    if (needGhost && !platform.prizeFlag) {
      platform.ghostFlag = Math.random() < platform.ghostOdds ? true : false;
      if (platform.ghostFlag) platform.ghostIcon.visible = true;
    }
    return [platform, platform2];
  }
  changePlatformGap(to: number) {
    if (this.platformCount == to) return;
    this.platformCount = to;
    let min = this.rectBg.height;
    for (let i = 0; i < this.platforms.length; i++) {
      if (min > this.platforms[i].y) {
        min = this.platforms[i].y;
      }
    }
    this.platPosition =
      min - this.rectBg.height / this.platformCount + this.rectBg.height;
    let newList = [];
    for (let i = 0; i < this.platformCount; i++) {
      newList.push(...this.createPlatform(true));
    }

    this.newPlatforms = newList;

    this.newPlatforms.forEach(p => {
      if (p.isNew && !p.addStatus) {
        this.rectBg.addChild(p);
        p.addStatus = true;
      }
    });
    this.platforms.forEach(p => {
      p.isNew = false;
      // // 如果有狼层级变高
      this.rectBg.addChild(p);
      // if (p.ghostFlag) {
      //   this.rectBg.addChild(p);
      // }
    });
    this.platforms = this.platforms.concat(this.newPlatforms);
    // console.log(this.platforms);
  }
  // 台阶展示
  platformInit() {
    for (let i = 0; i < this.platformCount; i++) {
      this.platforms.push(...this.createPlatform());
    }
    this.platforms.forEach((p, i) => {
      this.rectBg.addChild(p);
    });
  }
  // getNewPlatform(){

  // }
  // 兔子跳起
  playerJump() {
    this.player.y += this.player.vy;
    this.player.vy += this.gravity;

    if (
      this.player.vy > 0 &&
      this.player.x + 15 < 260 &&
      this.player.x + this.player.width - 15 > 155 &&
      this.player.y + this.player.height > 475 &&
      this.player.y + this.player.height < 500
    ) {
      return this.player.jump();
    }

    if (this.player.isMovingLeft === true) {
      this.player.x += this.player.vx;
      this.player.vx -= 0.1;
    } else {
      this.player.x += this.player.vx;
      if (this.player.vx < 0) this.player.vx += 0.07;
    }

    if (this.player.isMovingRight === true) {
      this.player.x += this.player.vx;
      this.player.vx += 0.1;
    } else {
      this.player.x += this.player.vx;
      if (this.player.vx > 0) this.player.vx -= 0.07;
    }

    if (this.player.vx > 4) this.player.vx = 4;
    else if (this.player.vx < -4) this.player.vx = -4;

    if (
      this.player.y + this.player.height > this.baseY &&
      this.baseY < this.rectBg.height
    ) {
      this.player.jump();
    }

    if (
      this.baseY > this.rectBg.height &&
      this.player.y + this.player.height > this.rectBg.height &&
      this.player.isDead != 'lol'
    ) {
      this.player.isDead = true;
      SoundMgr.instance.playEffect('jumpdied');
    }

    if (this.player.x > this.width) this.player.x = 0 - this.player.width;
    else if (this.player.x < 0 - this.player.width)
      this.player.x = this.width - this.player.width;

    if (this.player.y >= this.rectBg.height / 2 - this.player.height / 2) {
      this.player.y += this.player.vy;
      this.player.vy += this.gravity;
    }

    //高度过半 重新创建台阶 滚动效果
    else {
      if (this.player.y < this.height / 2) {
        this.player.y -= this.player.vy;
      }
      if (this.newPlatforms.length > 0) {
        this.platforms.forEach((p, i) => {
          if (this.player.vy < 0) {
            p.y -= this.player.vy;
          }
          if (this.player.y < this.height / 2) {
            p.y -= this.player.vy;
          }
          // if (p.isNew && !p.addStatus) {
          //   this.rectBg.addChild(p);
          //   p.addStatus = true;
          //   // this.newPlatforms.length--;
          // }
          // // 如果有狼层级变高
          // if (!p.isNew && p.ghostFlag) {
          //   this.rectBg.addChild(p);
          // }
          if (p.y > this.height) {
            if (p.isNew == false) {
              this.cashNum++;
              if (
                this.cashNum ==
                this.platforms.length - this.newPlatforms.length
              ) {
                let list = this.platforms.splice(0, this.cashNum);
                // console.log(this.platforms);
                this.newPlatforms = [];
                // for (let p of list) {
                //   this.rectBg.removeChild(p);
                // }
                for (let i = 0; i < list.length; i++) {
                  this.rectBg.removeChild(list[i]);
                }
                this.cashNum = 0;
              }
            }

            p.y = p.y - this.rectBg.height * 2;
          }
        });
      } else {
        this.platforms.forEach((p, i) => {
          if (this.player.vy < 0) {
            p.y -= this.player.vy;
          }
          if (this.player.y < this.height / 2) {
            p.y -= this.player.vy;
          }
          if (p.y > this.height) {
            if (i % 2 == 0) {
              this.platforms[i].x =
                Math.random() * (this.width - this.platforms[i].width);
              if (i != 0) {
                p.getStatus();
              }
            } else {
              let last = this.platforms[i - 1],
                left = last.x;
              // p.y = last.y
              if (left > this.width / 2) {
                p.x = Math.random() * (last.x - p.width) - p.width / 2;
              } else {
                p.x =
                  last.x +
                  p.width +
                  Math.random() * (this.width - last.x - p.width * 1.5);
              }
            }
            p.y = p.y - this.rectBg.height;
          }
        });
      }

      this.baseY -= this.player.vy;

      this.player.vy += this.gravity;
      if (this.player.vy >= 0) {
        this.player.y += this.player.vy;
        this.player.vy += this.gravity;
      }

      //  向上跳加分
      // this.score++;

      // engine.globalEvent.dispatchEvent('jump-more-score-update', {
      //   score: this.score
      // });

      if (this.score > 30 && this.score < 60) {
        this.changePlatformGap(11);
      } else if (this.score > 60 && this.score < 120) {
        this.changePlatformGap(10);
      } else if (this.score > 120) {
        this.changePlatformGap(8);
      }
    }
    if (this.player.isDead === false) this.collides();
    if (this.player.isDead == true) {
      this.gameOver();
    }
  }
  playMusic() {
    SoundMgr.instance.playEffect('bgm', true);
  }
  // 跳上台阶检测
  collides() {
    this.platforms.forEach((p, i) => {
      if (
        this.player.vy > 0 &&
        p.state === 0 &&
        this.player.x + 55 < p.x + p.width &&
        this.player.x + this.player.width - 30 > p.x &&
        this.player.y + this.player.height + 15 > p.y &&
        this.player.y + this.player.height + 15 < p.y + p.height
      ) {
        // console.log("左边：" ,  this.player.x + this.player.width - 30  > p.x);
        // console.log("右边：" ,  this.player.x + 30< p.x + p.width);
        // console.log(this.player.x + 40, p.x + p.width);

        if (p.prizeFlag) {
          SoundMgr.instance.playEffect('prize');
          this.score += props.prizeScore;

          engine.globalEvent.dispatchEvent('jump-more-score-update', {
            score: this.score
          });
          p.prizeFlag = false;
          p.prizeIcon.visible = false;
          if (p.x > this.rectBg.width - p.width * 1.5) {
            this.addScoreIcon.x = -20 - this.addScoreIcon.width;
            // console.log(this.addScoreIcon.x);
          } else {
            this.addScoreIcon.x = this.iconX;
          }
          this.addScoreIcon.visible = true;
          if (this.addTimer) {
            clearTimeout(this.addTimer);
          }
          this.addTimer = setTimeout(() => {
            this.addScoreIcon.visible = false;
          }, 1000);
        } else if (p.ghostFlag) {
          SoundMgr.instance.playEffect('ghost');
          this.diedIndex = i;
          this.gameOver();
        } else {
          this.player.jump();
        }
      }
    });
  }

  gameOver() {
    this.platforms.forEach((p, i) => {
      p.y -= 12;
    });

    if (this.player.y > this.rectBg.height / 2 && this.flag === 0) {
      this.player.y -= 8;
      this.player.vy = 0;
    } else if (this.player.y + this.player.height > this.rectBg.height) {
      // console.log('showGoMenu');
      // this.player.isDead = 'lol';
    }
    engine.globalEvent.dispatchEvent('jump-more-game-over', {
      score: this.score
    });
    // console.log('showGoMenu');
    this.player.isDead = 'lol';
    // setTimeout(() => {
    //   this.resume();
    // }, 3000);
  }
  rectBgCalc() {
    // if(this.player.y < this.height/2){
    // 	this.rectBg.y-=this.player.vy;
    // }
  }
  gameRevive() {
    this.player.isDead = false;
    let random = Math.floor(Math.random() * 3) * 2;

    this.player.x = this.platforms[random].x;
    this.player.y = this.platforms[random].y;
    this.player.vx = 0;
    this.player.vy = 11;
    this.platforms.forEach((p, i) => {
      p.ghostFlag = false;
      p.ghostIcon.visible = false;
    });
  }
  update_my() {
    this.playerJump();
    // if (this.platforms[0].ghostFlag || this.platforms[1].ghostFlag) {
    //   console.log(this.platforms[0]);
    // }

    this.rectBg.addChild(this.player);
  }

  /**
   * 重置场景
   */
  reset() {
    this.removeEventListener(engine.Event.ENTER_FRAME, this.test, this);
    SoundMgr.instance.stopEffect('bgm');
    this.recycleGoods();
    this.player.vx = 0;
    this.player.vy = 11;
    this.player.isMovingLeft = false;
    this.player.isMovingRight = false;
    this.player.x = 375 - this.player.width / 2;
    this.player.y = this.rectBg.height - 200;
    this.rectBg.y = this.rectHeight;
    this.platPosition = 0;
    this.score = 0;
    // this.cashNum = 0
    this.platformCount = 12;
    this.platformGap = 0;
    this.baseY = this.rectBg.height - this.bottomY;
    this.player.isDead = false;
    this.platformInit();
    this.playerJump();
  }

  /**
   * 开始
   */
  start() {
    // this.platformInit();
    this.aniLoop();
    this.playMusic();
  }

  /**
   * 暂停
   */
  pause() {
    this.gameIng = false;
  }

  /**
   * 恢复
   */
  revive() {
    this.gameIng = true;
  }

  /**
   * 重新开始
   */
  async resume() {
    this.reset();
    this.start();
  }

  test;

  aniLoop() {
    this.addEventListener(
      engine.Event.ENTER_FRAME,
      (this.test = () => {
        this.update_my();
      }),
      this
    );
  }

  /**
   * 玩家死亡
   */
  private died() {
    this.score = 0;
    this.pause();
  }

  /**
   * 回收指定物品
   * @param goods 物品
   */
  private removeNpc(goods) {
    this.NpcBg.removeChild(goods);
    ObjectPool.recycleObject(PoolName, goods);
    this.removeEventListener(
      engine.Event.ENTER_FRAME,
      () => {
        this.update_my();
      },
      this
    );
    let index = this.goodsItems.indexOf(goods);
    if (index > -1) {
      this.goodsItems.splice(index, 1);
    }
  }

  /**
   * 回收对象
   */
  private recycleGoods() {
    for (let p of this.platforms) {
      this.rectBg.removeChild(p);
    }
    this.newPlatforms = [];
    this.platforms = [];
  }

  private moveCatchX = 0;
  private playerCatchX = 0;

  /**
   * 碰撞检测
   * @param a a盒子
   * @param b b盒子
   */
  private hasHit(a, b) {
    if (
      Math.abs(a.x + a.width / 2 - (b.x + b.width / 2)) <
        a.width / 2 + b.width / 2 &&
      Math.abs(a.y + a.height / 2 - (b.y + b.height / 2)) <
        a.height / 2 + b.height / 2
    ) {
      return true;
    } else {
      return false;
    }
  }

  private onDownStage = e => {
    if (e.stageX < this.width / 2) {
      this.player.dir = 'left';
      this.player.isMovingLeft = true;
      this.playerSvga.scaleX = -1;
      setTimeout(() => {
        this.player.isMovingLeft = false;
      }, 500);
    } else {
      this.player.dir = 'right';
      this.player.isMovingRight = true;
      this.playerSvga.scaleX = 1;
      setTimeout(() => {
        this.player.isMovingRight = false;
      }, 500);
    }
  };
  private onMoveStage = e => {
    if (this.gameIng) {
      this.player.x = this.playerCatchX + (e.localX - this.moveCatchX);
    }
  };

  private onOutStage = e => {
    // this.moveCatchX = 0;
    // console.log(e);

    if (e.stageX < this.width / 2) {
      this.player.dir = 'left';
      this.player.isMovingLeft = false;
    } else {
      this.player.dir = 'right';
      this.player.isMovingRight = false;
    }
  };
}
