﻿package Captions{
	
	import flash.display.BitmapData;
	import flash.display.Bitmap
	import flash.display.MovieClip;
	import flash.display.SpreadMethod;
	import flash.display.Sprite;
	import flash.events.Event;
	import fl.data.DataProvider;
	import flash.net.FileReference;
	import flash.net.FileFilter;
	import flash.events.MouseEvent
	import flash.display.SimpleButton;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.getDefinitionByName;
	import flash.geom.ColorTransform;
	import comp.textformatter.TextPropertiesComponent
	import flash.display.Shape;
	import comp.transformTool.TransformTool;
	import flash.geom.Matrix;
	import flash.geom.Transform;

	public class ArrowWidget extends MovieClip{
		
		private var formatterMc:MovieClip;
		private var xmlParams:XMLList;
		private var xmlConfig:XMLList;
		private var mainXMLConfig:XML;
		private var mcRef:MovieClip;
		private var fileRef:FileReference;
		private var mcCaption:MovieClip;
		private var txt:TextField;
		private var mcIcon:MovieClip;
		private var txtRef;
		private var textHolder:MovieClip;
		private var arrowChild:MovieClip;
		private var actionBln:Boolean = false;
		private var defaultTool:TransformTool;
		private var currTool:TransformTool;
		private var customTool:TransformTool;
		private var bmd:BitmapData;
		private var bmp:Bitmap;
		private var txtMatrix:Matrix;
		private var captionMatrix:Matrix;
		public function ArrowWidget(){
			
		}
		
		public function setData(xml:XMLList, textMc:MovieClip){
			xmlParams = xml;
			formatterMc = textMc;
		}
		public function setConfig(xml:XML){
			var arrStyles:DataProvider = new DataProvider()
			
			mainXMLConfig = xml;
			xmlConfig = xml.styles.style
			for (var i = 0; i < xmlConfig.length(); i++)
			{
				arrStyles.addItem( { label:xmlConfig[i].@label, data:xmlConfig[i].@movieclip } );
			}
			
			themeCombo.dataProvider = arrStyles;
			themeCombo.selectedIndex = Number(xmlParams.@themeLabel);
		}
		
		private function captionThemeChanged(evt){
			xmlParams.@themeLabel = evt.target.selectedIndex;
			currTool.target = null;
			xmlParams.@style = themeCombo.selectedItem.data;
			mcRef.removeChild(mcCaption);
			mcCaption = new MovieClip();
			var obj:Class = getDefinitionByName(xmlParams.@style) as Class
			var mc = new obj();			
			mcCaption.addChild(mc);	
			mcCaption.x = 0;
			mcCaption.y = 0;
			
			arrowChild = MovieClip(mcCaption.getChildAt(0)).arrowMC;

			arrowChild.transform.matrix = captionMatrix;
			xmlParams.@arrowHead = int(arrowChild.arrowHead.width);
			xmlParams.@arrowTail = int(arrowChild.arrowTail.width);
			
			arrowHead.setData(xmlParams.@arrowHead, 10, 999)

			arrowTail.setData(xmlParams.@arrowTail, 10, 999)
			
			changeFillColor();
			changeBorderColor();
			mcRef.addChildAt(mcCaption, 1)
			// event handlers for selecting objects and changing tools
			mcCaption.addEventListener(MouseEvent.MOUSE_DOWN, select);
			textHolder.addEventListener(MouseEvent.MOUSE_DOWN, select);
			sp.addEventListener(MouseEvent.MOUSE_DOWN, selectNull);
			/*=================================================*/
			
			sp.refreshPane();
		}
		private function resetBtnClicked(e:MouseEvent):void
		{
			arrowChild.transform.matrix = new Matrix();
			mcCaption.x = 0;
			mcCaption.y = 0;
			arrowChild.x = (sp.width/2)// - arrowChild.width
			arrowChild.y = (sp.height/2)// - arrowChild.height;// mcCaption.height / 2;
			
			captionMatrix = arrowChild.transform.matrix
			
			xmlParams.@a = captionMatrix.a;
			xmlParams.@b = captionMatrix.b;
			xmlParams.@c = captionMatrix.c;
			xmlParams.@d = captionMatrix.d;
			xmlParams.@tx = captionMatrix.tx;
			xmlParams.@ty = captionMatrix.ty;
			
			fillRequiredCB.selected = false;
			strokeRequiredCB.selected = false;
			toggleFillRequired(null)
			toggleStrokeRequired(null)
			
			//1, 0, 0, 1, (Number(sp.width / 2)-(textHolder.width/2)), (Number(xmlParams.@ty)+(arrowChild.height/2))
			txtMatrix = new Matrix()
			
			resetTextFormat();
			txtMatrix.tx = 42//(Number(sp.width / 2)-(textHolder.width/2));
			txtMatrix.ty = 138//(arrowChild.y + arrowChild.height);
			textHolder.transform.matrix = txtMatrix;
			
			xmlParams.text.@a = txtMatrix.a;
			xmlParams.text.@b = txtMatrix.b;
			xmlParams.text.@c = txtMatrix.c;
			xmlParams.text.@d = txtMatrix.d;
			xmlParams.text.@tx = txtMatrix.tx;
			xmlParams.text.@ty = txtMatrix.ty;
			
			//arrowChild.arrowHead.x = 0;
			//arrowChild.arrowTail.x = 0;
			
			currTool.target = null;
			
			sp.refreshPane();			
			
		}
		
		public function init(){
			mcRef = new MovieClip();

			setDefaultData();
			addEvents();
		}
		
		function toBoolean(str:String):Boolean{
			var res:Boolean = false;
			if(str.toLowerCase() == "true"){
				res = true;
			}
			return res;
		}
		
		private function addEvents(){
			formatterMc.addEventListener(TextPropertiesComponent.VALUECHANGED, fontValuesChanged);
			
			fillRequiredCB.addEventListener(MouseEvent.CLICK, toggleFillRequired);
			strokeRequiredCB.addEventListener(MouseEvent.CLICK, toggleStrokeRequired);
			
			fillColorMc.addEventListener(Event.CHANGE, fillColorChanged);
			borderColorMc.addEventListener(Event.CHANGE, borderColorChanged)
			captionText.addEventListener(Event.CHANGE, captionTextChanged);
			
			arrowHead.addEventListener(SizeSelector.CHANGE, arrowHeadChangeHandler);
			arrowTail.addEventListener(SizeSelector.CHANGE, arrowTailChangeHandler);
			
			themeCombo.addEventListener(Event.CHANGE, captionThemeChanged);
			
			arrowHead.addEventListener(SizeSelector.REMOVE_TRANSFORM, removeTransform);
			arrowTail.addEventListener(SizeSelector.REMOVE_TRANSFORM, removeTransform);
			formatterMc.sizeSelectorMc.addEventListener(SizeSelector.REMOVE_TRANSFORM, removeTransform);
			
			defaultTool.addEventListener(TransformTool.CONTROL_UP, objectUpdateHandler);
			resetBtn.addEventListener(MouseEvent.CLICK, resetBtnClicked);
		}
		
		private function removeTransform(e:Event):void 
		{
			currTool.target = null;
		}
		
		private function objectUpdateHandler(e:Event):void 
		{			
			var targetObject = e.target.target;
			if (targetObject.name.indexOf("textHolder") == 0)
			{
				txtMatrix = e.target.toolMatrix;
				
				xmlParams.text.@a = e.target.toolMatrix.a;
				xmlParams.text.@b = e.target.toolMatrix.b;
				xmlParams.text.@c = e.target.toolMatrix.c;
				xmlParams.text.@d = e.target.toolMatrix.d;
				xmlParams.text.@tx = e.target.toolMatrix.tx;
				xmlParams.text.@ty = e.target.toolMatrix.ty;
				drawBitmapData();
			}
			else if (targetObject.name.indexOf("arrowMC") == 0)
			{
				captionMatrix = e.target.toolMatrix;
				arrowChild.transform.matrix = captionMatrix;
				xmlParams.@a = captionMatrix.a;
				xmlParams.@b = captionMatrix.b;
				xmlParams.@c = captionMatrix.c;
				xmlParams.@d = captionMatrix.d;
				xmlParams.@tx = captionMatrix.tx;
				xmlParams.@ty = captionMatrix.ty;
			}
			//xmlParams.text.@width = txtWidth.getData();
			sp.refreshPane();
		}
		
		private function fontValuesChanged(e:Event){
			setTextFormat();
		}
		
		private function setTextFormat() {
			var txtProp:XML = new XML(formatterMc.getData());
			var tf:TextFormat = new TextFormat(txtProp.font.@face, txtProp.font.@size, txtProp.color.@textColor, toBoolean(txtProp.textDecoration.@bold), toBoolean(txtProp.textDecoration.@italic), toBoolean(txtProp.textDecoration.@underline)) 
			txt.setTextFormat(tf);
			if(txtProp.color.@highlightRequired == "true"){
				txt.background = true
				txt.backgroundColor = uint(txtProp.color.@highlightColor)
			}else{
				txt.background = false
			}
			//xmlParams.text.@width = mcHiddenText.width;
			xmlParams.text.@height = mcHiddenText.height;
			drawBitmapData();
		}
		
		private function resetTextFormat() {
			var myXML = xmlParams.parent();
			myXML.textProperties = XML(mainXMLConfig.textProperties.toString());
			formatterMc.setData(myXML.textProperties)
			formatterMc.init();
			setTextFormat();
		}
		
			
		
		
		private function captionTextChanged(e:Event) {
			currTool.target = null;
			txt.text = captionText.text;
			xmlParams.text = captionText.text;
			xmlParams.text.@height = mcHiddenText.height;	
			var txtProp:XML = new XML(formatterMc.getData());
			if (captionText.text == "")
			{
				formatterMc.highlightRequiredCB.enabled = false;	
				formatterMc.highlightRequiredCB.selected = false;	
				txtProp.color.@highlightRequired = "false";
			}
			else
			{
				formatterMc.highlightRequiredCB.enabled = true;					
				txtProp.color.@highlightRequired = txtProp.color.@highlightState;
				formatterMc.highlightRequiredCB.selected = toBoolean(txtProp.color.@highlightRequired);
			}
			formatterMc.hightLightChangeHandler(null);
			setTextFormat();
			sp.refreshPane();
		}
		
		private function arrowHeadChangeHandler(e:Event) {
			xmlParams.@arrowHead = arrowHead.getData();
			arrowChild.arrowHead.width = xmlParams.@arrowHead;
			captionMatrix = arrowChild.transform.matrix;
			xmlParams.@a = captionMatrix.a;
			xmlParams.@b = captionMatrix.b;
			xmlParams.@c = captionMatrix.c;
			xmlParams.@d = captionMatrix.d;
			xmlParams.@tx = captionMatrix.tx;
			xmlParams.@ty = captionMatrix.ty;
			sp.refreshPane();
		}
		
		private function arrowTailChangeHandler(e:Event){
			xmlParams.@arrowTail = arrowTail.getData();
			arrowChild.arrowTail.width = xmlParams.@arrowTail;		
			captionMatrix = arrowChild.transform.matrix;
			xmlParams.@a = captionMatrix.a;
			xmlParams.@b = captionMatrix.b;
			xmlParams.@c = captionMatrix.c;
			xmlParams.@d = captionMatrix.d;
			xmlParams.@tx = captionMatrix.tx;
			xmlParams.@ty = captionMatrix.ty;
			sp.refreshPane();
		}
		
		private function fillColorChanged(e:Event):void{
			xmlParams.@fillColor = fillColorMc.selectedColor
			changeFillColor()
		}
		private function borderColorChanged(e:Event):void{
			xmlParams.@borderColor = borderColorMc.selectedColor
			changeBorderColor();
		}
		
		private function setDefaultData(){
			var arrStyles:DataProvider = new DataProvider()
			var toSelectIndex:int = 0;
				
			mcCaption = new MovieClip();
			mcCaption.name = "mcCaption"
			var obj:Class = getDefinitionByName(xmlParams.@style) as Class
			var mc = new obj()
			mcCaption.addChild(mc);
			mcCaption.x = 0;
			mcCaption.y = 0;
			
			captionMatrix = new Matrix(xmlParams.@a, xmlParams.@b, xmlParams.@c, xmlParams.@d, xmlParams.@tx, xmlParams.@ty)
			arrowChild = MovieClip(mcCaption.getChildAt(0)).arrowMC;
			
			arrowChild.arrowHead.width = xmlParams.@arrowHead;
			arrowChild.arrowTail.width = xmlParams.@arrowTail;

			arrowChild.transform.matrix = captionMatrix;
			
			arrowHead.setData(xmlParams.@arrowHead, 10, 999)
			arrowHead.init();
			arrowTail.setData(xmlParams.@arrowTail, 10, 999)
			arrowTail.init();			

			arrowChild.arrowHead.x = 0;
			arrowChild.arrowTail.x = arrowChild.arrowHead.x;
			
			
			fillColorMc.selectedColor = uint(xmlParams.@fillColor)
			borderColorMc.selectedColor = uint(xmlParams.@borderColor)
			fillRequiredCB.selected = toBoolean(xmlParams.@fillColorRequired);
			strokeRequiredCB.selected = toBoolean(xmlParams.@borderColorRequired);
			changeFillColor()
			changeBorderColor();
			
			captionText.htmlText = xmlParams.text.split("\\n").join("\n");
			
			//======== Hidden text movie clip for Bitmap ===========
			txtMatrix = new Matrix(xmlParams.text.@a, xmlParams.text.@b, xmlParams.text.@c, xmlParams.text.@d, xmlParams.text.@tx, xmlParams.text.@ty)
			txt = mcHiddenText.captionText;
			txt.htmlText = xmlParams.text.split("\\n").join("\n");
			txt.autoSize = "left";
			txt.wordWrap = true;
			txt.multiline = true;

			textHolder = new MovieClip();
			textHolder.name = "textHolder";
			//drawBitmapData();
			setTextFormat();
			//======================================================
			
			mcRef.addChild(textHolder);
			mcRef.addChild(mcCaption)
			
			if(xmlParams.@order == "0"){
				mcRef.setChildIndex(textHolder, 1);
			}
			
			/*======== Transform tool implementation =========*/
			// default tool
			defaultTool = new TransformTool();
			defaultTool.rotationEnabled = true;
			defaultTool.registrationEnabled = false;
			currTool = defaultTool;
			
			mcRef.addChild(defaultTool);
			
			// event handlers for selecting objects and changing tools
			mcCaption.addEventListener(MouseEvent.MOUSE_DOWN, select);
			textHolder.addEventListener(MouseEvent.MOUSE_DOWN, select);
			sp.addEventListener(MouseEvent.MOUSE_DOWN, selectNull);
			/*=================================================*/
			sp.source = mcRef;
			sp.refreshPane();
		}
		
		private function toggleFillRequired(e:MouseEvent):void 
		{
			xmlParams.@fillColorRequired = fillRequiredCB.selected;
			
			if (fillRequiredCB.selected)
			{
				changeFillColor()
			}else{
				if (arrowChild.arrowHead.fill != null) {
					arrowChild.arrowHead.fill.transform.colorTransform = new ColorTransform();
					arrowChild.arrowTail.fill.transform.colorTransform = new ColorTransform();
				}
			}
		}
		private function toggleStrokeRequired(e:MouseEvent):void 
		{
			xmlParams.@borderColorRequired = strokeRequiredCB.selected;
			if (strokeRequiredCB.selected)
			{
				changeBorderColor();
			}else{
				if (arrowChild.arrowHead.stroke != null) {
					arrowChild.arrowHead.stroke.transform.colorTransform = new ColorTransform();
					arrowChild.arrowTail.stroke.transform.colorTransform = new ColorTransform();
				}
			}
		}
		private function changeFillColor(){
			
			var colorT:ColorTransform = new ColorTransform();
			if(xmlParams.@fillColorRequired == "true"){
				colorT.color = uint(xmlParams.@fillColor)
			}
			if (arrowChild.arrowHead.fill == null) {
				fillColorMc.visible = false;
				fillColorLabelMc.visible = false;
				fillRequiredCB.visible = false;
			}else {
				fillColorMc.visible = true;
				fillColorLabelMc.visible = true;
				fillRequiredCB.visible = true;
				arrowChild.arrowHead.fill.transform.colorTransform = colorT
			}
			if(arrowChild.arrowTail.fill != null){
				arrowChild.arrowTail.fill.transform.colorTransform = colorT
			}
		}
		private function changeBorderColor(){
			var colorT:ColorTransform = new ColorTransform();
			if(xmlParams.@borderColorRequired == "true"){
				colorT.color = uint(xmlParams.@borderColor);
			}
			if (arrowChild.arrowHead.stroke == null) {
				borderColorMc.visible = false;
				borderColorLabelMc.visible = false;
				strokeRequiredCB.visible = false;
			}else {
				borderColorMc.visible = true;
				borderColorLabelMc.visible = true;
				strokeRequiredCB.visible = true;
				arrowChild.arrowHead.stroke.transform.colorTransform = colorT
			}
			if(arrowChild.arrowTail.stroke != null){
				arrowChild.arrowTail.stroke.transform.colorTransform = colorT
			}
		}
		private function drawBitmapData()
		{
			if (bmp != null)
			{
				bmp.bitmapData = null;
			}
			if (bmd != null)
			{
				bmd.dispose();
			}			
			bmd = new BitmapData(xmlParams.text.@width, xmlParams.text.@height, false);
			bmd.draw(mcHiddenText, null, null, null, null, true);
			bmp = new Bitmap();
			bmp.name = "bmp"
			bmp.bitmapData = bmd;			
			textHolder.addChild(bmp);	
			
			textHolder.transform.matrix = txtMatrix;
			sp.refreshPane();
		}
		
		private function selectNull(e:MouseEvent):void 
		{
			if (e.target.name.indexOf("instance") == 0)
			{
				currTool.target = null;
			}
		}
		
		private function removeTool(e:MouseEvent):void 
		{
			currTool.target = null;
		}
		
		private function select(event) {
			
			trace(event.target.name);
			
			if (event.target.name.indexOf("instance") == 0)
			{
				currTool.target = null;
			}
			else if (event.target.name.indexOf("instance") == -1 && event.target is MovieClip) 
			{
				if (event.target.name.indexOf("textHolder") == 0)
				{
					currTool.scaleEnabled = false;
					currTool.skewEnabled = false;
					currTool.target = event.target as Sprite;
					mcRef.setChildIndex(textHolder, 1);
					xmlParams.@order = "0";
				}
				else
				{
					currTool.scaleEnabled = true;
					currTool.skewEnabled = false;
					
					currTool.target = event.target.parent.parent as Sprite;
					mcRef.setChildIndex(mcCaption, 1);
					xmlParams.@order = "1"
				}
				toolInit();
			}			
		}
		
		private function toolInit():void {
			// raise
			//currTool.parent.setChildIndex(currTool, currTool.parent.numChildren - 1);			
			// center registration for customTool
			//if (currTool == customTool) {
				currTool.registration = currTool.boundsCenter;
				//currTool.raiseNewTargets = true
			//}
		}
		
		
	}
}