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

import { props } from "../props";
import { playSound, createSvga } from "./utils";
import ObjectPool = engine.ObjectPool;
import { getTextureByName } from "./utils";
import { Goods } from "./Goods";
import { PoolName } from "./object-pool-init";



export default class GameView extends engine.Container {

	private _hasSetup;

	//玩家
	private player: engine.Container;
	//触摸层
	private rectBg: engine.Rect;
	//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.once(engine.Event.ADDED_TO_STAGE, this.setup, this);
	}

	private waterSvga
	private boomSvga
	private playerSvga

	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.mouseEnabled = false;
	//	this.player.fillColor="rgba(0, 0, 0,1)"
		//console.log(this.player.fillColor)
	
		this.addChild(this.player);

		this.waterSvga=createSvga("水花")
		this.playerSvga=createSvga("玩家")
		this.boomSvga=createSvga("炸弹svga")
		this.player.addChild(this.playerSvga);
		this.player.addChild(this.waterSvga);
		this.player.addChild(this.boomSvga);
		this.playerSvga.gotoAndPlay(1);

		this.visible=false;
		setTimeout(()=>{
			this.visible=true;
			// this.player.width=this.playerSvga.width;
			// this.player.height=this.playerSvga.height;
			this.player.anchorY = this.player.height / 2;
			this.player.anchorX = this.player.width / 2;
			console.log(this.player.width)
			console.log(this.playerSvga.width)
			this.player.x = 375 - this.player.width / 2;
			this.player.y = props.playerPositionY;
		},300)

		
		this.rectBg = new engine.Rect();
		this.rectBg.alpha = 0;
		this.rectBg.width = 750;
		this.rectBg.height = 1624;
		this.addChild(this.rectBg)

		this.rectBg.addEventListener(engine.MouseEvent.MOUSE_DOWN, this.onDownStage, this);
		this.rectBg.addEventListener(engine.MouseEvent.MOUSE_MOVE, this.onMoveStage, this);
		this.rectBg.addEventListener(engine.MouseEvent.MOUSE_OUT, this.onOutStage, this);

	
	}


	/**
	 * 重置场景
	 */
	reset() {
		this.recycleGoods()
	}

	/**
	 * 开始
	 */
	start() {
		this.score = 0;
		this.speed = 1
		this.gameIng = true;
		this.creatNpc()
		this.beginNpc()
		this.countdown = props.countDown;
		
		this.countdownTimer = setInterval(() => {
			if (this.gameIng) {
				if (this.countdown > 0) {
					engine.globalEvent.dispatchEvent('food-fell-time-update', {
						time: this.countdown,
					});
					this.countdown -= 1
				} else {
					engine.globalEvent.dispatchEvent('food-fell-game-over', {
						score: this.score,
						reason: 1
					});
					this.died()
				}
			}
		}, 1000)
	}

	/**
	 * npc开始掉落
	 */
	beginNpc() {
		this.timer = setTimeout(() => {
			if (this.gameIng) {
				this.speed += props.acceleratedSpeed;
				this.creatNpc()
			}
			//递归执行
			this.beginNpc()
		}, 2000 / this.speed)
	}

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

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

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

	/**
	 * 创建NPC
	 */
	private creatNpc() {
		let goods = this._goods = <Goods>ObjectPool.getObject(PoolName);
		this.goodsItems.push(goods)
		this.NpcBg.addChild(goods);
		goods.addEventListener(engine.Event.ENTER_FRAME, goods["onGoodsEnter"] = () => {
			if (goods.y > 1624) {
				this.removeNpc(goods)
			} else {
				if (this.gameIng) {
					//速度叠加
					goods.y += (4 * this.speed)
					//如果玩家和物品发生碰撞
					if (this.hasHit(this.player, goods)) {
						
						if (goods["npcType"] == "rain") {
							console.log("碰到雨滴")
							this.score += props.rainScore
							this.waterSvga.visible=true;
							this.waterSvga.play(false, false)
							this.waterSvga.once(engine.Event.END_FRAME, ()=>{
								this.waterSvga.visible=false;
							}, this);
						} else if (goods["npcType"] == "stone") {
							console.log("碰到石头")
							this.score += props.stoneScore
						} else if (goods["npcType"] == "boom") {
							console.log("碰到炸弹")
							this.boomSvga.visible=true;
							this.boomSvga.play(false, false)
							this.boomSvga.once(engine.Event.END_FRAME, ()=>{
								this.boomSvga.visible=false;
							}, this);
							engine.globalEvent.dispatchEvent('food-fell-game-over', {
								score: this.score,
								reason: 2
							});
							this.died()
						}
						engine.globalEvent.dispatchEvent('food-fell-score-update', {
							score: this.score,
						});
						this.removeNpc(goods)
					}
				}
			}

		}, this);
	}

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

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

	/**
	 * 回收对象
	 */
	private recycleGoods() {
		clearTimeout(this.timer)
		clearInterval(this.countdownTimer)
		for (let goods of this.goodsItems) {
			if (goods) {
				this.removeChild(goods);
				ObjectPool.recycleObject(PoolName, goods);
				goods.removeEventListener(engine.Event.ENTER_FRAME, goods["onGoodsEnter"], this);
			}
		}
		this.goodsItems = []
	}

	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) => {
		this.moveCatchX = e.localX;
		this.playerCatchX = this.player.x
	}

	private onMoveStage = (e) => {
		if (this.gameIng) {
			this.player.x = this.playerCatchX + (e.localX - this.moveCatchX)
		}
	}

	private onOutStage = (e) => {
		this.moveCatchX = 0
	}
}
