/**
 * 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 _goods: Goods;

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

	private waterSvga
	private water2Svga
	private boomSvga
	private playerSvgaReset
	private playerSvgaRun
	private playerSvgaOver
	private bg1
	private bg2
	private bg3
	private bg4
	private bg
	private labelScore
	


	setup() {
		if (this._hasSetup) {
			return;
		}
		this._hasSetup = true;

		this.bg = new engine.Container();
		this.bg.mouseEnabled = false;
		this.addChild(this.bg);

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

		//创建文字
		this.labelScore = new engine.BitmapText();
		this.labelScore.font = props.fontName;
		this.labelScore.scaleX = this.labelScore.scaleY = 1;
		this.addChild(this.labelScore);
	
	

		this.waterSvga=createSvga("碰到金币svga")
		this.water2Svga=createSvga("碰到粽子svga")
		this.boomSvga=createSvga("碰到石头svga")
		// this.playerSvga=createSvga("玩家")
		this.playerSvgaReset= new engine.Sprite(getTextureByName('玩家静止'))
		this.playerSvgaRun= createSvga("玩家滑动")
		this.playerSvgaOver= createSvga("玩家翻船")
		this.bg1= new engine.Sprite(getTextureByName('循环背景1'))
		this.bg2= new engine.Sprite(getTextureByName('循环背景2'))
		this.bg3= new engine.Sprite(getTextureByName('循环背景1'))
		this.bg4= new engine.Sprite(getTextureByName('循环背景2'))
		this.player.addChild(this.playerSvgaReset);
		this.player.addChild(this.playerSvgaRun);
		this.player.addChild(this.playerSvgaOver);
		 this.addChild(this.waterSvga);
		 this.addChild(this.water2Svga);
		 this.addChild(this.boomSvga);
		 this.addChild(this.player);
		this.bg.addChild(this.bg1);
		this.bg.addChild(this.bg2);
		this.bg.addChild(this.bg3);
		this.bg.addChild(this.bg4);
		
		// this.playerSvga.gotoAndPlay(1);

		this.waterSvga.visible = false
		this.water2Svga.visible = false
		this.boomSvga.visible = false
		this.setPlayState(this.playerSvgaReset)
		
		this.visible=false;
		setTimeout(()=>{
			this.visible=true;
			//this.player.anchorY = this.player.height / 2;
		//	this.player.anchorX = this.player.width / 2;
			this.player.x = props.playerPositionX;
			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.playerSvgaRun.x=props.playerRunPosition3Offset[0]
			this.playerSvgaRun.y=props.playerRunPosition3Offset[1]

			this.playerSvgaOver.x=props.playerOverPosition3Offset[0]
			this.playerSvgaOver.y=props.playerOverPosition3Offset[1]

			this.bg1.y=0
			this.bg2.y=this.bg1.height
			this.bg3.y=this.bg1.height+this.bg2.height
			this.bg4.y=this.bg1.height+this.bg2.height+this.bg3.height

			engine.Tween.get(this.playerSvgaReset, {loop:true})
			.to({y:10}, 500)
			.to({y:0}, 500)
			.to({y:10}, 500)
			.call(()=>{});

			// 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);
		this.rectBg.addEventListener(engine.Event.ENTER_FRAME, this.enterFrame, this);
	
	}


	setBoomPosition(svga,callback?){
		svga.x=this.player.x;
		svga.y=this.player.y;
		if(svga==this.waterSvga){
			svga.x+=props.boomPosition1Offset[0]
			svga.y+=props.boomPosition1Offset[1]
		}else if(svga==this.water2Svga){
			svga.x+=props.boomPosition2Offset[0]
			svga.y+=props.boomPosition2Offset[1]
		}else if(svga==this.boomSvga){
			svga.x+=props.boomPosition3Offset[0]
			svga.y+=props.boomPosition3Offset[1]
		} 

		svga.visible=true;
		svga.play(true,false)
		svga.once(engine.Event.END_FRAME, ()=>{
			svga.visible=false;
			if(callback){
				callback()
			}		
		}, this);

	}

	enterFrame(){
		if(this.bg.y>=0){
			this.bg.y=-this.bg3.y
		}
		if(this.gameIng){
			this.bg.y += (4 * this.speed)
		}
	}


	/**
	 * 重置场景
	 */
	reset() {
		this.recycleGoods()
		this.score = 0;
		this.speed = props.speed;
		this.bg.y=-this.bg3.y

		this.player.anchorY = this.player.height / 2;
		this.player.anchorX = this.player.width / 2;
		this.player.x = props.playerPositionX;
		this.player.y = props.playerPositionY;
		this.setPlayState(this.playerSvgaReset)
	}


	setPlayState(svga){
		this.playerSvgaReset.visible=false
		this.playerSvgaRun.visible=false
		this.playerSvgaOver.visible=false
		console.log(svga)
		svga.visible=true;
        if(svga==this.playerSvgaOver){
			svga.play(false, false)
			svga.once(engine.Event.END_FRAME, ()=>{
			}, this);
		}else if(svga==this.playerSvgaRun){
			svga.play()
		}
	}

	/**
	 * 开始
	 */
	start() {
		this.gameIng = true;
		this.creatNpc()
		this.beginNpc()
		this.countdown = props.countDown;
		this.setPlayState(this.playerSvgaRun)
	
		this.countdownTimer = setInterval(() => {
			if (this.gameIng) {
				if (this.countdown > 0) {
					engine.globalEvent.dispatchEvent('dragon-boat-race-time-update', {
						time: this.countdown,
					});
					this.countdown -= 1
				} else {
					engine.globalEvent.dispatchEvent('dragon-boat-race-game-over', {
						score: this.score,
						reason: 1
					});
					this.died()
				}
				this.score += Math.round(this.speed*props.runScore);
				engine.globalEvent.dispatchEvent('dragon-boat-race-score-update', {
					score: this.score,
				});
			}
		}, 1000)
	}

	/**
	 * npc开始掉落
	 */
	beginNpc() {
		this.timer = setTimeout(() => {
			if (this.gameIng) {
				this.speed += props.acceleratedSpeed;
				this.speed += props.acceleratedSpeed;
				if(this.speed>props.maxSpeed){
					this.speed=props.maxSpeed
				}
				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)
		//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 (goods["lifeState"]&&this.hasHit(this.player, goods)) {
						goods["lifeState"]=false;
						if (goods["npcType"] == "rain0") {
							console.log("碰到雨滴")
							this.score += props.rainScore
							if(this.score<0){
								this.score=0;
							}
							this.setBoomPosition(this.waterSvga)
							 engine.Tween.get(goods, null, null, true)
							 .to({scaleX: 0,scaleY:0}, 200)
							 .call(()=>{this.removeNpc(goods)});
						

						}else if (goods["npcType"] == "rain1") {
							console.log("碰到雨滴")
							this.score += props.rain2Score
							if(this.score<0){
								this.score=0;
							}
							this.setBoomPosition(this.water2Svga)
							 engine.Tween.get(goods, null, null, true)
							 .to({scaleX: 0,scaleY:0}, 200)
							 .call(()=>{this.removeNpc(goods)});

						} else if (goods["npcType"] == "boom"||goods["npcType"] == "stone") {
							console.log("碰到炸弹")
							this.setBoomPosition(this.boomSvga,()=>{
								engine.globalEvent.dispatchEvent('dragon-boat-race-game-over', {
									score: this.score,
									reason: 2
								});
								this.died()
							})
							this.setPlayState(this.playerSvgaOver)
							this.pause()
						
						}
						engine.globalEvent.dispatchEvent('dragon-boat-race-score-update', {
							score: this.score,
						});
					
						
					}
				}
			}

		}, 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.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
	}
}
