
// Copyright © 2009. Wilbert Brants. All Rights Reserved.

package km.components {

import km.core.*;
import km.math.*;
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.*;

/** The BitmapLabel component class.<br>
* The BitmapLabel class has a bitmap text instead of a normal dynamic text to allow for text rotation.<br>
* A lot of the properties of the BitmapLabel class are similar to those of the flash.text.TextField class.<br>
* It's recommended to study information on that class if you want to know more about them.
* @example
<listing version="3.0">
import km.components.~~;

var l:BitmapLabel = new BitmapLabel();
l.setSize(20,120);
l.move(20,20);

l.icon = new BitmapData(8, 8, false, 0xc0b0a0);
l.textRotation = 270;
l.labelPlacement = 'top';
l.align = 'center';
l.valign = 'bottom';
l.text = 'Label';

addChild(l);
</listing>
* @see flash.text.TextField
*/
public class BitmapLabel extends UIComponent {

	/** @private */ public static const cloneObjs:Array = [];
	/** @private */ public static const cloneProps:Array = ['wordWrap', 'align', 'textColor', 'defaultTextFormat', 'embedFonts', 'labelPlacement', 'valign'].concat(UIComponent.cloneProps);
	
	private var _tfB:Bitmap = new Bitmap();
	private var _tfM:Matrix = new Matrix(1, 0, 0, 1, 0, -2);
	private var _tf:TextField = new TextField();
	private var _icon:Image = new Image();
	private var _rct:Rectangle = new Rectangle();
	private var _align:String = 'left';
	private var _valign:String = 'center';
	private var _placement:String = 'right';
	private var _background:Boolean;
	private var _bgColor:uint = 0xffffff;
	private var _textRotation:int;
	private var _textWidth:int;
	private var _textHeight:int;
	private var _xo:int;
	private var _yo:int;

	/** The default size of a bitmap label is 120 x 20 pixels. */
	public function BitmapLabel():void {
		super();
		_tf.defaultTextFormat = new TextFormat('_sans');
		addChild(_tfB);
		addChild(_icon);
		setSize(120,20);
	}

	/** @private */
	override protected function draw():void {
		if (_background){
			graphics.clear();
			graphics.beginFill(_bgColor);
			graphics.drawRect(0, 0, _width, _height);
		}
		_rct.width = Math.min(_width, _icon.width); 
		_rct.height = Math.min(_height, _icon.height); 
		_icon.scrollRect = _rct;
		_textWidth = _width;
		_textHeight = _height;
		if (_placement == 'top' || _placement == 'bottom'){
			_textHeight -= _rct.height;
		} else {
			_textWidth -= _rct.width;
		}
		if (_textRotation % 180){
			_xo = _textWidth; // swap width and height 
			_textWidth = _textHeight;
			_textHeight = _xo;
		}
		if (_tf.wordWrap){
			_tf.width = _textWidth;
		} else {
			_textWidth = _tf.textWidth ? Math.min(_tf.textWidth + 4, _textWidth) : 0;
			_tf.width = _textWidth;
			_textHeight = Math.min(_tf.textHeight, _textHeight);
		}
		_tf.height = _textHeight + 4;
		if (_textWidth && _textHeight){
			if (_tfB.bitmapData && _tfB.bitmapData.width == _textWidth && _tfB.bitmapData.height == _textHeight){
				_tfB.bitmapData.fillRect(_tfB.bitmapData.rect, 0);
			} else {
				_tfB.bitmapData = new BitmapData(_textWidth, _textHeight, true, 0);
			}
			_tfB.bitmapData.draw(_tf, _tfM);
			if (_textRotation % 180){
				_xo = _textWidth; // swap width and height 
				_textWidth = _textHeight;
				_textHeight = _xo;
			}	
		} else {
			_tfB.bitmapData = null;
		}
		_xo = _textWidth + _rct.width;
		_yo = _textHeight + _rct.height;
		if (_align == 'right'){
			_xo = _width - _xo;
			_icon.x = _width - _rct.width;
			_tfB.x = _width - _textWidth;
		} else if (_align == 'center'){
			_xo = _width - _xo >> 1;
			_icon.x = _width - _rct.width >> 1;
			_tfB.x = _width - _textWidth >> 1;
		} else {
			_xo = 0;
			_icon.x = 0;
			_tfB.x = 0;
		}
		if (_valign == 'top'){
			_yo = 0;
			_icon.y = 0;
			_tfB.y = 0;
		} else if (_valign == 'bottom'){
			_yo = _height - _yo;
			_icon.y = _height - _rct.height;
			_tfB.y = _height - _textHeight;
		} else {
			_yo = _height - _yo >> 1;
			_icon.y = _height - _rct.height >> 1;
			_tfB.y = _height - _textHeight >> 1;
		}
		if (_placement == 'top'){
			_tfB.y = _yo
			_icon.y = _yo + _textHeight;
		} else if (_placement == 'bottom'){
			_icon.y = _yo
			_tfB.y = _yo + _icon.height;
		} else if (_placement == 'left'){
			_tfB.x = _xo
			_icon.x = _xo + _textWidth;
		} else {
			_icon.x = _xo;
			_tfB.x = _xo + _icon.width;
		}
		if (_textRotation){
			if (_textRotation == 90){
				_tfB.x += _textWidth;
			} else if (_textRotation == 180){
				_tfB.x += _textWidth;
				_tfB.y += _textHeight;
			} else {
				_tfB.y += _textHeight;
			}
		}
	}

	/** Horizontal alignment within the bounding box.<br>Possible values are 'left', 'right' and 'center'.
	* @default 'left'
	*/
	public function get align():String { return _align; } 
	public function set align(v:String):void { _align = v; update(); } 

	/** */
	public function get backgroundColor():uint { return _bgColor; } 
	public function set backgroundColor(v:uint):void { _bgColor = v; update(); } 

	/** */
	public function get background():Boolean { return _background; } 
	public function set background(v:Boolean):void { _background = v; update(); } 

	/** */
	public function get defaultTextFormat():TextFormat { return _tf.defaultTextFormat; } 
	public function set defaultTextFormat(v:TextFormat):void { _tf.defaultTextFormat = v; update(); } 

	/** */
	public function get embedFonts():Boolean { return _tf.embedFonts; } 
	public function set embedFonts(v:Boolean):void { _tf.embedFonts = v; update(); } 

	/** */
	public function get htmlText():String { return _tf.htmlText; } 
	public function set htmlText(v:String):void { _tf.htmlText = v; update(); } 

	/** */
	public function get icon():BitmapData { return _icon._bd; } 
	public function set icon(v:BitmapData):void {
		if (v){
			_icon._bd = v;
			_icon.setSize(v.width, v.height);
		} else if (_icon._bd){
			_icon._bd = null;
			_icon.setSize(0, 0);
		}
		update();
	} 

	/** */
	public function get length():int { return _tf.length; } 

	/** Placement of the label text.<br>Possible values are 'left', 'right', 'top' and 'bottom'.
	* @default 'right'
	*/
	public function get labelPlacement():String { return _placement; } 
	public function set labelPlacement(v:String):void { _placement = v; update(); } 

	/** */
	public function get text():String { return _tf.text; } 
	public function set text(v:String):void { _tf.text = v; update(); } 

	/** */
	public function get textColor():uint { return _tf.textColor; } 
	public function set textColor(v:uint):void { _tf.textColor = v; update(); } 

	/** Rotation of the text.<br>Possible values are 0, 90, 180 and 270. */
	public function get textRotation():int { return _textRotation; } 
	public function set textRotation(v:int):void {
		_textRotation = v % 90 ? 0 : (v + 720) % 360;
		_tfB.rotation = _textRotation;
		update();
	} 

	/** Vertical alignment within the bounding box.<br>Possible values are 'top', 'bottom' and 'center'.
	* @default 'center'
	*/
	public function get valign():String { return _valign; } 
	public function set valign(v:String):void { _valign = v; update(); } 

	/** */
	public function get wordWrap():Boolean { return _tf.wordWrap; } 
	public function set wordWrap(v:Boolean):void { _tf.wordWrap = v; update(); } 

}
}
