////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package flashx.textLayout.elements
{
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.engine.GraphicElement;
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	
	import flashx.textLayout.compose.FlowDamageType;
	import flashx.textLayout.compose.TextFlowLine;
	import flashx.textLayout.container.ContainerController;
	import flashx.textLayout.edit.EditManager;
	import flashx.textLayout.edit.IEditManager;
	import flashx.textLayout.edit.ISelectionManager;
	import flashx.textLayout.events.DamageEvent;
	import flashx.textLayout.events.ModelChange;
	import flashx.textLayout.formats.BlockProgression;
	import flashx.textLayout.formats.Float;
	import flashx.textLayout.tlf_internal;
	import flashx.undo.UndoManager;
	
	use namespace tlf_internal;
	
	/** 
	 * TableCellElement is an item in a TableElement. It most commonly contains one or more ParagraphElement objects.
	 *
	 * 
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 *
	 */
	public final class TableCellElement extends TableFormattedElement
	{		
		private var _x:Number;
		private var _y:Number;
		private var _width:Number;
		private var _height:Number;

		private var _parcelIndex:int;
		private var _container:CellContainer;
		private var _enableIME:Boolean = true;
		private var _damaged:Boolean = true;
		private var _controller:ContainerController;

		private var _rowSpan:uint = 1;
		private var _columnSpan:uint = 1;
		private var _rowIndex:int = -1;
		private var _colIndex:int = -1;
		private var _includeDescentInCellBounds:Boolean;
		
		public function TableCellElement()
		{
			super();
			_controller = new ContainerController(container,NaN,NaN);
		}

		/** @private */
		override protected function get abstract():Boolean
		{ return false; }
		
		/** @private */
		tlf_internal override function get defaultTypeName():String
		{ return "td"; }
		
		/** @private */
		tlf_internal override function canOwnFlowElement(elem:FlowElement):Boolean
		{// Table cells have no TLF children. Instead it contains its own TextFlow.
			return (elem is FlowElement);
		}

		public function isDamaged():Boolean {
			return _damaged || (_textFlow && _textFlow.flowComposer.isDamaged(_textFlow.textLength));
		}
		
		private var _savedPaddingTop:Number = 0;
		private var _savedPaddingBottom:Number = 0;
		private var _savedPaddingLeft:Number = 0;
		private var _savedPaddingRight:Number = 0;
		
		public function compose():Boolean {
			
			var pt:Number = getEffectivePaddingTop();
			var pb:Number = getEffectivePaddingBottom();
			var pl:Number = getEffectivePaddingLeft();
			var pr:Number = getEffectivePaddingRight();

			if(pt != _savedPaddingTop)
			{
				_controller.paddingTop = _savedPaddingTop = pt;
			}
			if(pb != _savedPaddingBottom)
			{
				_controller.paddingBottom = _savedPaddingBottom = pb;
			}
			if(pl != _savedPaddingLeft)
			{
				_controller.paddingLeft = _savedPaddingLeft = pl;
			}
			if(pr != _savedPaddingRight)
			{
				_controller.paddingRight = _savedPaddingRight = pr;
			}

			var table:TableElement = getTable();
			
			_damaged = false;
			
			var compWidth:Number = 0;
			for(var i:int=0;i<columnSpan;i++)
			{
				if (table && table.getColumnAt(colIndex+i)) {
					compWidth += table.getColumnAt(colIndex+i).columnWidth;
				}
				
			}
			width = compWidth;

			if (_textFlow && _textFlow.flowComposer) {
				return _textFlow.flowComposer.compose();
			}
			
			return false;
		}
		
		public function update():Boolean
		{
			if(_textFlow && _textFlow.flowComposer){
				return _textFlow.flowComposer.updateAllControllers();
			}
			return false;
		}
		
		public function get parcelIndex():int
		{
			return _parcelIndex;
		}
		
		public function set parcelIndex(value:int):void
		{
			_parcelIndex = value;
		}
		
		public function get rowIndex():int
		{
			return _rowIndex;
		}
		
		public function set rowIndex(value:int):void
		{
			_rowIndex = value;
		}
		
		public function get colIndex():int
		{
			return _colIndex;
		}
		
		public function set colIndex(value:int):void
		{
			_colIndex = value;
		}
		
		protected var _textFlow:TextFlow;
		
		public function get textFlow():TextFlow {
			
			if (_textFlow == null) {
				var flow:TextFlow = new TextFlow();
				
				if (table && table.getTextFlow() && table.getTextFlow().interactionManager is IEditManager) {
					flow.interactionManager = new EditManager(IEditManager(_textFlow.interactionManager).undoManager);
				}
				else if(table && table.getTextFlow() && table.getTextFlow().interactionManager) {
					var im:Class = getDefinitionByName(getQualifiedClassName(table.getTextFlow().interactionManager)) as Class;
					flow.interactionManager = new im();
				}
				else {
					flow.normalize();
				}
				
				textFlow = flow;

			}
			
			return _textFlow;
		}
		
		public function set textFlow(value:TextFlow):void
		{
			if (_textFlow) {
				_textFlow.removeEventListener(DamageEvent.DAMAGE, handleCellDamage);
				_textFlow.flowComposer.removeAllControllers();
			}
			
			_textFlow = value;
			_textFlow.parentElement = this;
			_textFlow.flowComposer.addController(_controller);
			_textFlow.addEventListener(DamageEvent.DAMAGE, handleCellDamage);
			
		}
		
		public function get controller():ContainerController {
			return _controller;
		}
		
		private function handleCellDamage(ev:DamageEvent):void{
			damage();
		}

		public function get enableIME():Boolean
		{
			return _enableIME;
		}

		public function set enableIME(value:Boolean):void
		{
			_enableIME = value;
		}
		
		public function get container():CellContainer{
			if(!_container){
				_container = new CellContainer(enableIME);
				_container.element = this;
			}
			
			return _container;
		}

		/**
		 * Gets the width.
		 **/
		public function get width():Number
		{
			return _width;
		}

		/**
		 * @private
		 **/
		public function set width(value:Number):void
		{
			if(_width != value) {
				_damaged = true;
			}
			
			_width = value;
			
			_controller.setCompositionSize(_width, _controller.compositionHeight);
		}
		
		/**
		 * Returns the height of the cell. 
		 **/
		public function get height():Number
		{
			//return getRowHeight(); not sure if we should always use row height
			return _height;
		}

		/**
		 * @private
		 **/
		public function set height(value:Number):void
		{
			if (_height != value) {
				_damaged = true;
			}
			
			_height = value;
			
			_controller.setCompositionSize(_controller.compositionWidth, _height);
		}
		
		public function getComposedHeight():Number
		{
			var descent:Number = 0;
			if(!includeDescentInCellBounds)
			{
				if(_textFlow.flowComposer && _textFlow.flowComposer.numLines)
				{
					var lastLine:TextFlowLine = _textFlow.flowComposer.getLineAt(_textFlow.flowComposer.numLines-1);
					if(lastLine)
						descent = lastLine.descent;
				}
			}
			return (_controller.getContentBounds().height - descent);
		}
		
		public function getRowHeight():Number
		{
			return getRow() ? getRow().composedHeight : NaN;
		}

		public function get rowSpan():uint
		{
			return _rowSpan;
		}

		public function set rowSpan(value:uint):void
		{
			if(value >= 1)
				_rowSpan = value;
		}

		public function get columnSpan():uint
		{
			return _columnSpan;
		}

		public function set columnSpan(value:uint):void
		{
			if(value >= 1)
				_columnSpan = value;
		}
		
		public function updateCompositionShapes():void{
			_controller.updateCompositionShapes();
		}
		
		/**
		 * Return the row that this cell is part of or null 
		 * if not part of a row.
		 **/
		public function getRow():TableRowElement
		{
			return table ? table.getRowAt(rowIndex) : null;
		}
		
		/**
		 * Returns the next cell in the table or null if not part of a
		 * table or no cells exist after this cell.
		 **/
		public function getNextCell():TableCellElement {
			return table ? table.getNextCell(this) : null;
		}
		
		/**
		 * Returns the previous cell in the table or null if not part of a
		 * table or no cells exist before this cell.
		 **/
		public function getPreviousCell():TableCellElement {
			return table ? table.getPreviousCell(this) : null;
		}

		public function get x():Number
		{
			return container.x;
		}

		public function set x(value:Number):void
		{
			container.x = value;
		}

		public function get y():Number
		{
			return container.y;
		}

		public function set y(value:Number):void
		{
			container.y = value;
		}

		public function damage():void
		{
			if (table) {
				table.hasCellDamage = true;
			}
			
			_damaged = true;
		}
		
		/**
		 * Adds in the table cell spacing, border stroke width. 
		 * We may be able to set this value when the format changes. 
		 * For now we just want to get it to work. 
		 **/
		public function getTotalPaddingWidth():Number {
			var paddingAmount:Number = 0;
			
			// no textflow is no padding
			if (!textFlow) {
				return 0;
			}
			
			if (table && table.cellSpacing!=undefined) {
				paddingAmount += table.cellSpacing;
			}
			
			if (textFlow.computedFormat.blockProgression == BlockProgression.RL) {
				paddingAmount += Math.max(getEffectivePaddingTop() + getEffectivePaddingBottom(), getEffectiveBorderTopWidth() + getEffectiveBorderBottomWidth());
			}
			else {
				paddingAmount += Math.max(getEffectivePaddingLeft() + getEffectivePaddingRight(), getEffectiveBorderLeftWidth() + getEffectiveBorderRightWidth());
			}
			
			return paddingAmount;
		}
		
		/**
		 * Adds in the table cell spacing, border stroke height. 
		 * We may be able to set this value when the format changes. 
		 **/
		public function getTotalPaddingHeight():Number {
			var paddingAmount:Number = 0;
			
			// no textflow is no padding
			if (!textFlow) {
				return 0;
			}
			
			if (table && table.cellSpacing!=undefined) {
				paddingAmount += table.cellSpacing;
			}
			
			if (textFlow.computedFormat.blockProgression == BlockProgression.RL) {
				paddingAmount += Math.max(getEffectivePaddingLeft() + getEffectivePaddingRight(), getEffectiveBorderLeftWidth() + getEffectiveBorderRightWidth());
			}
			else {
				paddingAmount += Math.max(getEffectivePaddingTop() + getEffectivePaddingBottom(), getEffectiveBorderTopWidth() + getEffectiveBorderBottomWidth());
			}
			
			return paddingAmount;
		}

		public function get includeDescentInCellBounds():Boolean
		{
			return _includeDescentInCellBounds;
		}

		public function set includeDescentInCellBounds(value:Boolean):void
		{
			_includeDescentInCellBounds = value;
		}

		
	}
}
