class Scene {
	layers: {[key:string]: Layer; };
	layerCount:number;
	game:Game;
	mode:string[];
	showed:Trigger;
	hid:Trigger;
	ended:Trigger;
	started:Trigger;
	root:Layer;

	constructor(game:Game) {
		this.game = game;
		this.layers = {};
		this.root = new Layer(this);
		this.layers["root"] = this.root;
		this.layerCount = 1;
		this.mode = new string[];
		this.started = new Trigger();
		this.ended = new Trigger();
		this.showed = new Trigger();
		this.hid = new Trigger();
	}

	currentMode():string {
		return this.mode.length == 0 ? null : this.mode[this.mode.length - 1];
	}

	getLayerArray():Layer[] {
		var ret = new Layer[];
		for (var i in this.layers)
			ret.push(this.layers[i]);
		return ret;
	}

	enablePointingEvent() {
		this.root.enablePointingEvent();
	}

	disablePointingEvent() {
		this.root.disablePointingEvent();
	}

	changeMode(mode:string) {
		var linkMode = this.currentMode();
		if (linkMode && this[linkMode+"Hide"]) {
			this[linkMode+"Hide"]();
		}

		this.mode.push(mode);
		if (mode) {
			if (this[mode+"Start"]) {
				this[mode+"Start"]();
			}
			if (this[mode+"Show"]) {
				this[mode+"Show"]();
			}
		}
	}

	endCurrentMode(newMode?:string) {
		if (this.mode.length == 0) {
			this.end();
			return;
		}

		var mode = this.mode.pop();
		if (mode) {
			if (this[mode+"End"]) {
				this[mode+"End"]();
			}
		}
		var linkMode = this.currentMode();
		if (linkMode && this[linkMode+"Show"]) {
			this[linkMode+"Show"]();
		}
		if (newMode)
			this.changeMode(newMode);
	}

	createLayer(name:string, size?:CommonSize):Layer {
		for (var i in this.layers) {
			if (! this.layers[i].hasBuffer()) {
				this.layers[i].createBuffer();
			}
		}
		this.layers[name] = new Layer(this);
		if (size) {
			this.layers[name].width = size.width;
			this.layers[name].height = size.height;
		}
		this.layers[name].createBuffer();
		this.layerCount++;
		return this.layers[name];
	}

	deleteLayer(name:string) {
		if (name == "root")
			throw "can not delete root layer";

		this.layers[name].destroy();
		delete this.layers[name];
		this.layerCount--;
		if (this.layerCount == 1) {
			this.root.deleteBuffer();
		}
	}

	destroy() {
		for (var i in this.layers)
			this.layers[i].destroy();
	}

	end() {
		this.game.endScene();
	}

	refresh() {
		for (var i in this.layers)
			this.layers[i].refresh();
	}

	scrollTo(x:number, y:number, layerName?:string) {
		if (! layerName)
			layerName = "root";

		if (this.layers[layerName].x != x || this.layers[layerName].y != y)
			this.layers[layerName].moveTo(x, y);
	}

	scrollBy(x:number, y:number, layerName?:string) {
		if (x == 0 && y == 0)
			return;

		if (! layerName)
			layerName = "root";

		this.layers[layerName].moveBy(x, y);
	}

	append(entity:E, layerName?:string) {
		if (! layerName) {
			this.root.append(entity);
		} else {
			this.layers[layerName].append(entity);
		}
	}

	removeEntity(entity:E) {
		for (var i in this.layers) {
			this.layers[i].removeChild(entity);
		}
	}
}