/**
 * 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;
	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 viewVisible=true;


	private _goods: Goods;

	constructor() {
		super();
		this.once(engine.Event.ADDED_TO_STAGE, this.setup, this);
	}

	private waterSvga
	private stoneSvga
	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.stoneSvga=createSvga("石头svga")
		// this.playerSvga=createSvga("玩家")
		this.playerSvga= new engine.Sprite(getTextureByName('玩家'))
		this.boomSvga=createSvga("炸弹svga")
		this.player.addChild(this.playerSvga);
		this.player.addChild(this.stoneSvga);
		this.player.addChild(this.waterSvga);
		this.player.addChild(this.boomSvga);
		// this.playerSvga.gotoAndPlay(1);

		

		this.waterSvga.visible = false
		this.stoneSvga.visible = false
		this.boomSvga.visible = false
		
		this.visible=false;
		setTimeout(()=>{
			this.visible=true;
			this.player.anchorY = this.player.height / 2;
			this.player.anchorX = this.player.width / 2;
			this.player.x = 375 - this.player.width / 2;
			this.player.y = props.playerPositionY;

			this.stoneSvga.x = this.player.width / 2 - 	this.stoneSvga.width/2 + props.boomPosition1Offset[0];
			this.stoneSvga.y = this.player.height / 2 - this.stoneSvga.height/2 + props.boomPosition1Offset[1];

			this.waterSvga.x = this.player.width / 2 - 	this.waterSvga.width/2+ props.boomPosition2Offset[0];
			this.waterSvga.y = this.player.height / 2 - this.waterSvga.height/2 + props.boomPosition2Offset[1];

			this.boomSvga.x = this.player.width / 2 - 	this.boomSvga.width/2+ props.boomPosition3Offset[0];
			this.boomSvga.y = this.player.height / 2 - this.boomSvga.height/2 + props.boomPosition3Offset[1];

			// this.stoneSvga.x=props.boomPositionOffset[0]
			// this.stoneSvga.y=props.boomPositionOffset[1]

			// this.waterSvga.x=props.boomPositionOffset[0]
			// this.waterSvga.y=props.boomPositionOffset[1]

			// this.boomSvga.x=props.boomPositionOffset[0]
			// this.boomSvga.y=props.boomPositionOffset[1]

			
		},300)

		
		this.rectBg = new engine.Container();
		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);


		document.addEventListener("visibilitychange",()=>{
			if(document.visibilityState=="visible"){
				this.viewVisible=true;
			}
			if(document.visibilityState=="hidden"){
				this.viewVisible=false;
			}
		})

		this.addEventListener(engine.Event.ENTER_FRAME, this.enterFrame,this)
	
	}

	enterFrame(){
		this.updateTime()
		this.updateTimeBeginNpc()
	}


	/**
	 * 重置场景
	 */
	reset() {
		this.score = props.speed
		this.recycleGoods()
		this.player.x = 375 - this.player.width / 2;
	}

	/**
	 * 开始
	 */
	start() {
		this.score = 0;
		this.speed = 1
		this.gameIng = true;
		//this.creatNpc()
		this.beginNpc()
		this.countdown = props.countDown;
	}

	cacheTime=0
	updateTime(){
		if(Date.now()-this.cacheTime>1000){
			this.cacheTime=Date.now()
		}else{
			return;
		}
		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()
			}
		}
	}

	/**
	 * npc开始掉落
	 */
	beginNpc() {
		// this.timer = setTimeout(() => {
			
		// 	//递归执行
		// 	this.beginNpc()
		// }, 2000 / this.speed)
	}

	cacheTime2=0
	updateTimeBeginNpc(){
		if(Date.now()-this.cacheTime2>(2000 / this.speed)){
			this.cacheTime2=Date.now()
		}else{
			return;
		}
		if (this.gameIng) {
			this.speed += props.acceleratedSpeed;
			if(this.speed >= props.maxSpeed){
				this.speed = props.maxSpeed
			}
			this.creatNpc()
		}
	}

	/**
	 * 暂停
	 */
	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)
		//console.log(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"].indexOf("rain") > -1) {
							//console.log("碰到雨滴")
							this.score += props.rainScore;
							this.waterSvga.visible=true;
						//	this.waterSvga.x= goods.x - this.player.x;
							this.waterSvga.play(false, false)
							this.waterSvga.once(engine.Event.END_FRAME, ()=>{
								this.waterSvga.visible=false;
							}, this);

							if(this.score<0){
								this.score=0;
							}

						} else if (goods["npcType"] == "stone") {
							//console.log("碰到石头")
							this.score += props.stoneScore
							if(this.score<0){
								this.score=0;
							}
							this.stoneSvga.visible=true;
							this.stoneSvga.play(false, false)
							this.stoneSvga.once(engine.Event.END_FRAME, ()=>{
								this.stoneSvga.visible=false;
							}, this);
						} else if (goods["npcType"] == "boom") {
							//console.log("碰到炸弹")
							this.boomSvga.visible=true;
							this.boomSvga.play(false, false)
							this.died()
							this.boomSvga.once(engine.Event.END_FRAME, ()=>{
								this.boomSvga.visible=false;
								engine.globalEvent.dispatchEvent('food-fell-game-over', {
									score: this.score,
									reason: 2
								});
							}, this);
						}
						engine.globalEvent.dispatchEvent('food-fell-score-update', {
							score: this.score,
						});
						this.removeNpc(goods)
					}
				}
			}

		}, this);
	}

	/**
	 * 玩家死亡
	 */
	private died() {
		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.NpcBg.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) {

		let playerH=a.height
		let playerW=a.width
		let playerX=a.x
		if(props.playerHeight){
			playerH=props.playerHeight
		}
		if(props.playerWidth){
			playerW=props.playerWidth
			playerX=a.x+(a.width-props.playerWidth)/2
		}

		if (
			Math.abs((playerX + playerW / 2) - (b.x + b.width / 2)) < playerW / 2 + b.width / 2
			&&
			// Math.abs((a.y + a.height / 2 ) - (b.y + b.height / 2)) < a.height / 2 + b.height / 2
			Math.abs((a.y + playerH / 1.3 ) - (b.y + b.height / 2)) < playerH / 2 + b.height / 2
		) {
			return true;
		} else {
			return false;
		}
	}

	private onDownStage = (e) => {
		this.moveCatchX = e.localX;
		this.playerCatchX = this.player.x
	}

	private onMoveStage = (e) => {
		let maxStageBound=props.maxStageBound;
		if (this.gameIng) {
			let playerX=this.playerCatchX + (e.localX - this.moveCatchX)
			if(playerX<maxStageBound){
				this.player.x=maxStageBound
			}else if(playerX+this.player.width+maxStageBound>750){
				this.player.x=750-maxStageBound-this.player.width
			}else{
				this.player.x=playerX
			}
		}
	}

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