////////////////////////////////////////////////////////////////////////////////
//
//  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 com.adobe.linguistics.spelling
{
	import com.adobe.linguistics.spelling.framework.SpellingService;
	import com.adobe.linguistics.spelling.framework.ui.IHighlighter;
	import com.adobe.linguistics.spelling.framework.ui.IWordProcessor;
	import com.adobe.linguistics.spelling.framework.ui.TLFWordProcessor;
	import com.adobe.linguistics.utils.Token;
	
	import flash.display.Sprite;
	import flash.events.ContextMenuEvent;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuItem;
	
	import flashx.textLayout.container.ContainerController;
	import flashx.textLayout.elements.FlowLeafElement;
	import flashx.textLayout.elements.ParagraphElement;
	import flashx.textLayout.elements.TextFlow;

	/** Custom container controller for populating context menu and hanlding menu item selection  */
	internal class SquigglyCustomContainerController extends ContainerController implements ISpellingContainerController
	{
		private var disableMenuItem:ContextMenuItem = new ContextMenuItem("Disable spell checking",true);
		private var enableMenuItem:ContextMenuItem = new ContextMenuItem("Enable spell checking");		
		
		private var controlMenuItemList:Array = new Array();
		private var suggestionMenuItemList:Array = new Array();
		private var _spellingEnabled:Boolean;
		private var _contextMenu:ContextMenu;
		private var mTextHighlighter:IHighlighter;
		private var mWordProcessor:IWordProcessor;
		private var mSpellEngine:SpellingService;
		private var mTextFlow:TextFlow;
		private var _ignoreWordFunctionProcessor:Function;
		private var _misspelledToken:Token;
		private var _misspelled:String;
		
		public function SquigglyCustomContainerController(container:Sprite,textHighlighter:IHighlighter, wordProcessor:IWordProcessor, engine:SpellingService,
														  func:Function, compositionWidth:Number=100,compositionHeight:Number=100)
		{
			super (container, compositionWidth, compositionHeight);
			mTextHighlighter = textHighlighter;
			mWordProcessor = wordProcessor;
			mSpellEngine = engine;
			_ignoreWordFunctionProcessor = func;
			
			spellingEnabled = true;
		}
		
		/** Overridden to add custom items to the context menu */
		override protected function createContextMenu():ContextMenu
		{
			// Get the default context menu used by TLF for editable flows
			_contextMenu = super.container.contextMenu as ContextMenu;
			if (_contextMenu == null)
				_contextMenu = super.createContextMenu();
				
			
			enableMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handleEnableSpellCheck);
			disableMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handleDisableSpellCheck);
			controlMenuItemList.push(enableMenuItem);
			controlMenuItemList.push(disableMenuItem);
			
			_contextMenu.customItems.push(disableMenuItem);
			_contextMenu.customItems.push(enableMenuItem);
			
			// Listen for menu selection
			_contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, updateCustomMenuItems);
			
			return _contextMenu;
		}
		
		/** Update the state of the custom menu items before the context menu is displayed */
		private function updateCustomMenuItems(event:ContextMenuEvent):void 
		{
			/* Clear the context menu */
			//spellingEnabled= mTextHighlighter.spellingEnabled;
			//SpellUI.doSpelling1();
			var removedNum:int = 0;
			var count:uint = _contextMenu.customItems.length;
			for (var j:uint=count; j>0; j--) {
				if ( isWordItem(_contextMenu.customItems[j-1]) ) {
					_contextMenu.customItems.splice(j-1,1);
					removedNum++
				}
			}
			if ( removedNum != suggestionMenuItemList.length ) {
				trace("internal error");
			}
			
			
			suggestionMenuItemList = new Array();
			
			// localized entries
			var entries:Object = SpellUIForTLF.getSpellingMenuEntries();
			disableMenuItem.caption = entries.disable;
			enableMenuItem.caption = entries.enable;				
			
			if (spellingEnabled == true) {
				(mWordProcessor as TLFWordProcessor).textFlowContainerController = this;
				
				//trace("stageX " +  super.container.stage.mouseX);
				//trace("stageY " +  super.container.stage.mouseY);
				//trace("mouseX " +  super.container.mouseX);
				//trace("mouseY " +  super.container.mouseY);
				_misspelledToken = mWordProcessor.getWordAtPoint(this.container.mouseX, this.container.mouseY);
				if (_misspelledToken==null) return;
				var currentLeaf:FlowLeafElement = this.textFlow.findLeaf(_misspelledToken.first);
				var currentParagraph:ParagraphElement = currentLeaf ? currentLeaf.getParagraph() : null;
				_misspelled = 	currentParagraph.getText().substring(_misspelledToken.first - currentParagraph.getAbsoluteStart(), 
																		_misspelledToken.last - currentParagraph.getAbsoluteStart());
				if ((_misspelled==null) || (_misspelled == "")) return;
				
				if (mSpellEngine.checkWord(_misspelled)==true) return;				
				
				var suseAddToItem:ContextMenuItem = new ContextMenuItem(entries.add);
				suseAddToItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handleAddToItemSelect);
				suggestionMenuItemList.push(suseAddToItem);
				_contextMenu.customItems.splice(0,0,suseAddToItem);	
				//var result:Array = mWordProcessor.getSuggestionsAtPoint();
				var resultVector:Vector.<String> = mSpellEngine.getSuggestions(_misspelled);
				var result:Array = new Array();
				if (resultVector) {
					for each (var w:String in resultVector)
					result.push(w);
				}
				if (result!=null) {
					for (var i:int=result.length-1;i>=0;i-- ) {
						var suseMenuItem:ContextMenuItem = new ContextMenuItem(result[i]);
						suseMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handleSuseItemSelect);
						suggestionMenuItemList.push(suseMenuItem);
						//_contextMenu.customItems.push(suseMenuItem);
						_contextMenu.customItems.splice(0,0,suseMenuItem);
					}
				}
			}
		}
		
		private function handleAddToItemSelect(event:ContextMenuEvent):void
		{
			if ( _ignoreWordFunctionProcessor == null ) return;
			
			/*
			var menuEntry:String = (event.currentTarget as ContextMenuItem).caption;
			var start:uint = 5;
			var end:uint = menuEntry.length - 15;
			var word:String = menuEntry.substring(start, end);
			*/
			_ignoreWordFunctionProcessor(_misspelled);
			SpellUIForTLF.UITable[SpellUIForTLF.parentComp[super.textFlow]].doSpellingJob();
		}
		
		private function handleSuseItemSelect(event:ContextMenuEvent):void
		{
			mWordProcessor.replaceText(_misspelledToken, (event.currentTarget as ContextMenuItem).caption );
			SpellUIForTLF.UITable[SpellUIForTLF.parentComp[super.textFlow]].doSpellingJob();
		}
			
		private function set spellingEnabled(value:Boolean) :void {
			_spellingEnabled = value;
			disableMenuItem.visible=spellingEnabled;
			enableMenuItem.visible=!spellingEnabled;
		}
		private function get spellingEnabled():Boolean {
			return this._spellingEnabled;
		}
		
		private function isWordItem(item:ContextMenuItem):Boolean {
			
			for ( var i:int=0; i<suggestionMenuItemList.length; ++i ) {
				if ( suggestionMenuItemList[i] == item ) return true;
			}
			return false;
		}
		
		private function isControlItem(item:ContextMenuItem):Boolean {
			for (var i:int=0; i<controlMenuItemList.length; ++i) {
				if ( controlMenuItemList[i] == item) return true;
			}
			return false;
		}
		
		private function handleEnableSpellCheck(event:ContextMenuEvent):void
		{
			spellingEnabled= true;
			//mTextHighlighter.spellingEnabled= spellingEnabled;
			//SpellUI.doSpellingJob();
			//dispatchEvent(new Event(Event.RENDER));
			
			SpellUIForTLF.UITable[SpellUIForTLF.parentComp[this.textFlow]].spellingEnabled = spellingEnabled;
			SpellUIForTLF.UITable[SpellUIForTLF.parentComp[this.textFlow]].doSpellingJob();
			//spellCheckRange(getValidFirstWordIndex(), getValidLastWordIndex());
		}
		private function handleDisableSpellCheck(event:ContextMenuEvent):void
		{
			spellingEnabled= false;
			SpellUIForTLF.UITable[SpellUIForTLF.parentComp[this.textFlow]].spellingEnabled = spellingEnabled;
			mTextHighlighter.clearSquiggles();
		}
		
		public function cleanUpContextMenu():void
		{
			mTextHighlighter=null;
			mWordProcessor=null;
			spellingEnabled = false;
			_ignoreWordFunctionProcessor=null;
			
			_contextMenu.removeEventListener(ContextMenuEvent.MENU_SELECT, updateCustomMenuItems);
			
			var removedNum:int = 0;
			var count:uint = _contextMenu.customItems.length;
			for (var j:uint=count; j>0; j--) {
				if ( isWordItem(_contextMenu.customItems[j-1]) || isControlItem(_contextMenu.customItems[j-1]) ) {
					_contextMenu.customItems.splice(j-1,1);
					removedNum++
				}
			}
			if ( removedNum != suggestionMenuItemList.length + controlMenuItemList.length ) {
				trace("internal error");
			}
			
			suggestionMenuItemList = null;
			controlMenuItemList = null;
		}
		
	}
}