class MessageWindow extends E {
	nextCursor:E;
	padding:Rectangle;
	scriptOffset:number;
	script:string;
	normalSpeed:number;
	fastSpeed:number;
	readed:Trigger;
	isReaded:bool;
	textClip:Shape;
	hasNextCursor:bool;

	constructor(size:CommonSize, noDefault?:bool) {
		super();
		this.width = size.width;
		this.height = size.height;

		this.textClip = new Shape(this.width, this.height);
		this.textClip.setClip(true);

		this.padding = new Rectangle(8, 8, 8, 8);
		this.entities = [null, null, this.textClip, null];
		if (! noDefault)
			this.defaultSkin();

		this.normalSpeed = 400;
		this.fastSpeed = 800;

		this.readed = new Trigger();
		this.isReaded = true;
		this.hasNextCursor = false;
	}

	_activate(e:E) {
		e.scene = this.scene;
		e.parent = this;
		e.activate();
	}

	getBg():E {
		return this.entities[0];
	}
	setBg(bg:E) {
		if (this.entities[0])
			this.entities[0].destroy();
		this.entities[0] = bg;
		this._activate(bg);
	}

	getTextBg():E {
		return this.entities[1];
	}
	setTextBg(textWindow:E) {
		if (this.entities[1])
			this.entities[1].destroy();
		this.entities[1] = textWindow;
		this._activate(textWindow);
	}

	getTextArea():MultilineText {
		return <MultilineText>this.entities[3];
	}
	setTextArea(textArea:MultilineText) {
		if (this.entities[3])
			this.entities[3].destroy();
		this.entities[3] = textArea;
		this.textClip.moveTo(textArea.x, textArea.y);
		this.textClip.width = textArea.width;
		this.textClip.height = textArea.height;
		this._activate(textArea);
	}

	getNextCursor():E {
		return this.nextCursor;
	}
	setNextCursor(cursor:E) {
		this.nextCursor = cursor;
	}

	setText(text:string, offset?:number):number {
		var textArea = this.getTextArea();
		this.scriptOffset = textArea.setText(text, offset);
		this.script = textArea.script;
		textArea.hideAll();
		this.deleteNextCursor();
		this.isReaded = false;
		return this.scriptOffset;
	}
	setScript(script:string, offset?:number):number {
		var textArea = this.getTextArea();
		this.script = script;
		this.scriptOffset = textArea.setScript(script, offset);
		textArea.hideAll();
		this.deleteNextCursor();
		this.isReaded = false;
		return this.scriptOffset;
	}

	defaultSkin() {
		if (this.entities) {
			var childEntity;
			while (childEntity = this.entities.pop())
				childEntity.destroy();
		}
		var bgColor = JGUtil.createLinearGradient(
			new Rectangle(0, 0, this.width, this.height),
			["rgba(138,193,255,0.5)", "rgba(222, 235, 250, 0.5)"]
		);
		var bg:Shape = new Shape(
			this.width,
			this.height,
			ShapeStyle.fill,
			bgColor
		);
		this.setBg(bg);

		var textBg:Shape = new Shape(
			this.width-(this.padding.left+this.padding.right),
			this.height-(this.padding.top+this.padding.bottom),
			ShapeStyle.fill,
			"rgba(45,73,136,0.2)"
		);
		textBg.moveTo(this.padding.left, this.padding.top);
		this.setTextBg(textBg);

		var textArea = new MultilineText(
			{width: textBg.width-8, height:textBg.height-4},
			{x: textBg.x+4, y: textBg.y+2}
		);
		textArea.animated.handle(this, this.onAnimated);
		this.setTextArea(textArea);

		var cursor = new Line({x:0, y:0}, {x:6, y:8});
		cursor.addLine(12, 0);
		cursor.closePath = true;
		cursor.fill = true;
		cursor.setFillColor("rgba(255, 255, 255, 0.8)");
		cursor.width = 12;
		cursor.height = 8;
		this.nextCursor = cursor;
	}

	showNextCursor() {
		if (this.hasNextCursor)
			return;
		var nextCursor = this.nextCursor.createSprite();
		var textArea = this.getTextArea();
		var lastLine = textArea.lines[textArea.lines.length - 1];
		nextCursor.moveTo(
			this.width / 2 - nextCursor.width / 2,
			this.height - nextCursor.height - this.padding.bottom - 4
		);
		nextCursor.tl().moveBy(0, 4, 500).moveBy(0, -4, 500).delay(500).loop();
		this.append(nextCursor);
		this.hasNextCursor = true;
	}

	deleteNextCursor() {
		if (this.hasNextCursor) {
			this.entities[4].remove();
			this.hasNextCursor = false;
		}
	}

	hide(fade?:bool) {
		if (fade)
			this.tl().fadeOut(200);
		else
			this.setDrawOption("globalAlpha", 0);
	}
	show(fade?:bool) {
		if (fade)
			this.tl().fadeIn(200);
		else
			this.removeDrawOption("globalAlpha");
	}
	showText() {
		var textArea = this.getTextArea();
		textArea.startAnimation();
	}
	fastMode() {
		var textArea = this.getTextArea();
		textArea.animeSpeed = this.fastSpeed;
	}
	normalMode() {
		var textArea = this.getTextArea();
		textArea.animeSpeed = this.normalSpeed;
	}
	showAll() {
		var textArea = this.getTextArea();
		textArea.showAll();
	}
	next() {
		if (this.scriptOffset < 0)
			return false;
	}

	oldWipeOut(time?:number) {
		if (time === undefined)
			time = 800;
		var textArea = this.getTextArea();
		var old = textArea.createSprite();
		old.moveTo(textArea.x, textArea.y);
		this.append(old);
		var lastLine = textArea.lines[textArea.lines.length - 1];
		var movePoint = lastLine.offsetY + lastLine.height;
		textArea.moveTo(textArea.x, textArea.y + movePoint);
		old.tl().moveBy(0, -textArea.height, time).removeFromScene();
		textArea.tl().moveBy(0, -movePoint, (movePoint / textArea.height) * time);
	}
	oldFadeOut(time?:number) {
		if (time === undefined)
			time = 500;
		var textArea = this.getTextArea();
		var old = textArea.createSprite();
		old.moveTo(textArea.x, textArea.y);
		this.append(old);
		old.tl().fadeOut(time).removeFromScene();
	}

	onAnimated() {
		var hasNext = this.scriptOffset >= 0;
		if (hasNext)
			this.showNextCursor();

		this.isReaded = true;
		this.readed.fire(hasNext);
	}
}
