class Obstacle {
	private static _instance: Obstacle;
	static get instance(): Obstacle {
		if (!this._instance) {
			this._instance = new Obstacle();
		}
		return this._instance;
	}

	private obstacleScroller: Scroller;
	private contaniner: egret.DisplayObjectContainer;
	private typesCtor: Object = {
		cylinder: UI_Cylinder,
		luck: UI_Luck,
		puddle: UI_Puddle,
		railing: UI_Railing,
		wallow: UI_Wallow
	}
	private nodePools: Object = {
		cylinder: [],
		luck: [],
		puddle: [],
		railing: [],
		wallow: []
	}
	public constructor() {
		GameMgr.instance.addEventListener(Channel.RUN_MSG, this.onReceived, this);
	}

	private onReceived(ev: egret.Event): void {
		let {data} = ev;

		if (data.obstacle) {
			let {obstacle, track, timestamp} = data;
			let x = Math.abs(this.contaniner.x) + GameMgr.instance.main.stage.stageWidth;
			track.forEach(tk => {
				let ote = this.getNodeFromPool(obstacle);
				ote.timestamp = timestamp;
				ote.x = x;
				ote.y = tk * 70;
				this.contaniner.addChild(ote);
			})
		}
	}

	public setObstacleContainer(contaniner: egret.DisplayObjectContainer): void {
		this.contaniner = contaniner;
		this.obstacleScroller = new Scroller({ contaniner: this.contaniner, speed: Index.speed, autoRun: true });
	}

	getNodeFromPool(type): UI_BaseObstacle {
		let nodePool = this.nodePools[type];
		if (nodePool.length) {
			return nodePool.pop();
		} else {
			let ctor = this.typesCtor[type];
			return new ctor();
		}
	}

	pushNodeInPool(ctor: { type: string }): void {
		this.nodePools[ctor.type].push(ctor)
	}
}