module jg {
	export class MessageWindow extends UIWindow {
		_nextCursor:Sprite;
		nextCursor:E;
		scriptOffset:number;
		script:string;
		normalSpeed:number;
		fastSpeed:number;
		readed:Trigger;
		isReaded:bool;
		textClip:Shape;
		hasNextCursor:bool;
		textArea:MultilineText;

		constructor(width:number, height:number, bgImage?:any, padding?:IRectangle) {
			super(width, height, bgImage, padding);

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

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

			var textArea = new MultilineText({
				width: this.width-this.padding.left-this.padding.right,
				height: this.height-this.padding.top-this.padding.bottom
			}, {
				x: this.padding.left,
				y: this.padding.top
			});
			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;
		}

		setTextArea(textArea:MultilineText) {
			if (this.textArea) {
				this.textArea.remove();
				this.textClip.remove();
			}
			textArea.animated.handle(this, this.onAnimated);
			this.textArea = textArea;
			this.textClip = new Shape(this.width, this.height);
			this.textClip.setClip(true);
			this.textClip.moveTo(textArea.x, textArea.y);
			this.append(this.textClip);
			this.append(textArea);
		}

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

		setText(text:string, offset?:number):number {
			var textArea = this.textArea;
			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.textArea;
			this.script = script;
			this.scriptOffset = textArea.setScript(script, offset);
			textArea.hideAll();
			this.deleteNextCursor();
			this.isReaded = false;
			return this.scriptOffset;
		}

		showNextCursor() {
			if (this.hasNextCursor)
				return;
			var nextCursor = this.nextCursor.createSprite();
			var textArea = this.textArea;
			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;
			this._nextCursor = nextCursor;
		}

		deleteNextCursor() {
			if (this.hasNextCursor) {
				this._nextCursor.remove();
				delete this._nextCursor;
				this.hasNextCursor = false;
			}
		}

		hide(fade?:bool) {
			if (fade)
				this.tl().fadeOut(200);
			else
				super.hide();
		}
		show(fade?:bool) {
			if (fade)
				this.tl().fadeIn(200);
			else
				super.show();
		}
		showText() {
			this.textArea.startAnimation();
		}
		fastMode() {
			this.textArea.animeSpeed = this.fastSpeed;
		}
		normalMode() {
			this.textArea.animeSpeed = this.normalSpeed;
		}
		showAll() {
			this.textArea.showAll();
		}
		next() {
			if (this.scriptOffset < 0)
				return false;
			this.oldWipeOut();
			this.setScript(this.script, this.scriptOffset);
			this.textArea.startAnimation();
		}

		oldWipeOut(time?:number) {
			if (time === undefined)
				time = 800;
			var textArea = this.textArea;
			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.textArea;
			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);
		}
	}
}