////////////////////////////////////////////////////////////////////////////////
//
//  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.property
{
	import flashx.textLayout.debug.assert;
	import flashx.textLayout.elements.ListElement;
	import flashx.textLayout.tlf_internal;
	
	use namespace tlf_internal;
	
	[ExcludeClass]
	public class CounterContentHandler extends PropertyHandler
	{
		// check to see if this handler has a custom exporter that must be used when owningHandlerCheck is true
		public override function get customXMLStringHandler():Boolean
		{ return true; }
		
		public override function toXMLString(val:Object):String
		{ 
			if (val.hasOwnProperty("counter"))
				return val.ordered == null ? "counter(ordered)" : "counter(ordered," + val.ordered + ")";
			if (val.hasOwnProperty("counters"))
			{
				var rslt:String = "counters(ordered";
				if (val.suffix != null)
				{
					rslt += ",\"" + val.suffix + "\"";
					if (val.ordered)
						rslt += "," + val.ordered;
				}
				rslt += ")"
				return rslt;
			}
			return val.toString();
		}
		
		/** matches counter(ordered) */
		static private  const _counterContentPattern1:RegExp = /^\s*counter\s*\(\s*ordered\s*\)\s*$/;
		/** matches counter(ordered,ListStyleType) */
		static private  const _counterContentPattern2:RegExp = /^\s*counter\s*\(\s*ordered\s*,\s*\S+\s*\)\s*$/;
		
		/** matches counters(ordered) */
		static private  const _countersContentPattern1:RegExp = /^\s*counters\s*\(\s*ordered\s*\)\s*$/;
		/** matches counters(ordered,"suffix") */
		static private  const _countersContentPattern2:RegExp = /^\s*counters\s*\(\s*ordered\s*,\s*".*"\s*\)\s*$/;
		/** matches counters(ordered,"suffix",ListStyleType) */
		static private  const _countersContentPattern3:RegExp = /^\s*counters\s*\(\s*ordered\s*,\s*".*"\s*,\s*\S+\s*\)\s*$/;
		
		// return a value if this handler "owns" this property - otherwise return undefined
		public override function owningHandlerCheck(newVal:*):*
		{ 
			var listStyleType:String;
			
			// check for the more efficient parsed representation
			if (!(newVal is String))
				return newVal.hasOwnProperty("counter") || newVal.hasOwnProperty("counters") ? newVal : undefined;
			
			if (_counterContentPattern1.test(newVal))
				return newVal;
			
			if (_counterContentPattern2.test(newVal))
			{
				// need to validate the specified listStyleType
				listStyleType = extractListStyleTypeFromCounter(newVal);
				return ListElement.listSuffixes[listStyleType] !== undefined ? newVal : undefined;
			}
			
			if (_countersContentPattern1.test(newVal))
				return newVal;
			
			if (_countersContentPattern2.test(newVal))
				return newVal;
			
			if (_countersContentPattern3.test(newVal))
			{
				listStyleType = extractListStyleTypeFromCounters(newVal);
				return ListElement.listSuffixes[listStyleType] !== undefined ? newVal : undefined;
			}
			
			return undefined;
		}
		
		static private const _counterBeginPattern:RegExp = /^\s*counter\s*\(\s*ordered\s*,\s*/g;
		static private const _trailingStuff:RegExp = /\s*\)\s*/g
			
		/** @private - from _counterContentPattern2  counters(ordered,"suffix") */
		static tlf_internal function extractListStyleTypeFromCounter(s:String):String
		{
			CONFIG::debug { assert(_counterContentPattern2.test(s),"Bad Parameter to extractListStyleTypeFromCounter"); }
			_counterBeginPattern.lastIndex = 0;
			_counterBeginPattern.test(s);
			s = s.substr(_counterBeginPattern.lastIndex);

			_trailingStuff.lastIndex = 0;
			_trailingStuff.test(s);
			s = s.substr(0,_trailingStuff.lastIndex-1);

			return s;
		}
		
		static private const _countersTillSuffixPattern:RegExp = /^\s*counters\s*\(\s*ordered\s*,\s*"/g;
		static private const _afterSuffixPattern2:RegExp = /^"\s*\)\s*$/

		/** @private - from _countersContentPattern2  */
		static tlf_internal function extractSuffixFromCounters2(s:String):String
		{
			CONFIG::debug { assert(_countersContentPattern2.test(s),"Bad Parameter to extractListStyleTypeFromCounter2"); }
			_countersTillSuffixPattern.lastIndex = 0;
			_countersTillSuffixPattern.test(s);
			s = s.substr(_countersTillSuffixPattern.lastIndex);
			
			var rslt:String = "";
			while (!_afterSuffixPattern2.test(s))
			{
				rslt += s.substr(0,1);
				s = s.substr(1);
			}
			
			return rslt;
		}	
		
		static private const _afterSuffixPattern3:RegExp = /^"\s*,\s*\S+\s*\)\s*$/
		
		static tlf_internal function extractSuffixFromCounters3(s:String):String
		{
			CONFIG::debug { assert(_countersContentPattern3.test(s),"Bad Parameter to extractListStyleTypeFromCounter2"); }
			_countersTillSuffixPattern.lastIndex = 0;
			_countersTillSuffixPattern.test(s);
			s = s.substr(_countersTillSuffixPattern.lastIndex);
			
			var rslt:String = "";
			while (!_afterSuffixPattern3.test(s))
			{
				rslt += s.substr(0,1);
				s = s.substr(1);
			}
			
			return rslt;
		}
		
		static private const _countersTillListStyleTypePattern:RegExp = /^\s*counters\s*\(\s*ordered\s*,\s*".*"\s*,\s*/g;
		
		/** @private - from _countersContentPattern2 */
		static tlf_internal function extractListStyleTypeFromCounters(s:String):String
		{
			CONFIG::debug { assert(_countersContentPattern3.test(s),"Bad Parameter to extractListStyleTypeFromCounter"); }
			_countersTillListStyleTypePattern.lastIndex = 0;
			_countersTillListStyleTypePattern.test(s);
			s = s.substr(_countersTillListStyleTypePattern.lastIndex);
			
			_trailingStuff.lastIndex = 0;
			_trailingStuff.test(s);
			s = s.substr(0,_trailingStuff.lastIndex-1);
			
			return s;
		}
			
		/** parse the input string and create a valid input value */
		public override function setHelper(newVal:*):*
		{ 
			var s:String = newVal as String;
			
			var listStyleType:String;
			var suffix:String;
			
			if (s == null)
				return newVal;	// assume its an object that's been parsed already
			
			if (_counterContentPattern1.test(newVal))
				return { counter:"ordered" }; 

			if (_counterContentPattern2.test(newVal))
			{
				listStyleType = extractListStyleTypeFromCounter(newVal);
				return { counter:"ordered", ordered:listStyleType };
			}
			
			if (_countersContentPattern1.test(newVal))
				return { counters:"ordered" }; 
			
			if (_countersContentPattern2.test(newVal))
			{
				suffix = extractSuffixFromCounters2(newVal);
				return { counters:"ordered", suffix:suffix }; 
			}
			
			if (_countersContentPattern3.test(newVal))
			{
				listStyleType = extractListStyleTypeFromCounters(newVal);
				suffix = extractSuffixFromCounters3(newVal);
				return { counters:"ordered", suffix:suffix, ordered:listStyleType };
			}
			
			return undefined;
		}
	}
}
