////////////////////////////////////////////////////////////////////////////////
//
//  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.compose
{	
	import flash.text.engine.TextLine;
	import flash.text.engine.TextLineValidity;
	import flash.utils.Dictionary;
	
	import flashx.textLayout.debug.assert;
	import flashx.textLayout.elements.Configuration;
	import flashx.textLayout.tlf_internal;
	
	use namespace tlf_internal;
	
	/** 
	 * The TextLineRecycler class provides support for recycling of TextLines.  Some player versions support a recreateTextLine.  Passing TextLines
	 * to the recycler makes them available for reuse.  This improves Player performance.
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */ 
	public class TextLineRecycler
	{
		static private var _textLineRecyclerEnabled:Boolean = Configuration.playerEnablesArgoFeatures;
		
		/** Controls if the TLF recycler enabled.   It can only be enabled in 10.1 or later players.
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 */
		static public function get textLineRecyclerEnabled():Boolean
		{ return _textLineRecyclerEnabled; }
		static public function set textLineRecyclerEnabled(value:Boolean):void
		{ _textLineRecyclerEnabled = value ? Configuration.playerEnablesArgoFeatures : false; }
		
		// manage a cache of TextLine's that can be reused
		// This version uses a dictionary that holds the TextLines as weak references
		static private var reusableLineCache:Dictionary = new Dictionary(true);
		
		/**
		 * Add a TextLine to the pool for reuse. TextLines for reuse should have null userData and null parent. 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 */

		static public function addLineForReuse(textLine:TextLine):void
		{
			CONFIG::debug { assert(textLine.parent == null && textLine.userData == null && (textLine.validity == TextLineValidity.INVALID || textLine.validity == TextLineValidity.STATIC),"textLine not ready for reuse"); }
			if (_textLineRecyclerEnabled)
			{
				CONFIG::debug 
				{
					for each (var line:TextLine in reusableLineCache)
					{
						 assert(line != textLine,"READDING LINE TO CACHE");
					}
				}
				CONFIG::debug { cacheTotal++; }
				reusableLineCache[textLine] = null;
			}
		} 
		CONFIG::debug
		{
			/** @private */
			static tlf_internal var cacheTotal:int = 0;
			/** @private */
			static tlf_internal var fetchTotal:int = 0;
			/** @private */
			static tlf_internal var hitTotal:int = 0;		
			
			static private function recordFetch(hit:int):void
			{
				fetchTotal++;
				hitTotal += hit;
				
				/*if ((fetchTotal%100) == 0)
					trace(fetchTotal,hitTotal,cacheTotal);*/
			}
		}
		
		/**
		 * Return a TextLine from the pool for reuse. 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 */

		static public function getLineForReuse():TextLine
		{
			if (_textLineRecyclerEnabled)
			{
				for (var obj:Object in reusableLineCache)
				{
					// remove from the cache
					delete reusableLineCache[obj];
					CONFIG::debug { assert(reusableLineCache[obj] === undefined,"Bad delete"); }
					CONFIG::debug { recordFetch(1); }
					return obj as TextLine;
				}
				CONFIG::debug { recordFetch(0); }
			}
			return null;
		}
		
		/** @private empty the reusableLineCache */
		static tlf_internal function emptyReusableLineCache():void
		{
			reusableLineCache = new Dictionary(true);
		}
	}
}
