////////////////////////////////////////////////////////////////////////////////
//
//  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 {
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.InteractiveObject;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.TextEvent;
import flash.system.Capabilities;
import flash.text.TextField;
import flash.ui.Keyboard;


/**
 *  The test step that fakes a keyboard event
 *  MXML attributes:
 *  type (optional)
 *  charCode
 *  ctrlKey (optional)
 *  keyCode (optional)
 *  keyLocation (optional)
 *  shiftKey (optional)
 *  waitTarget (optional)
 *  waitEvent (optional)
 *  timeout (optional);
 *  cancelable (optional)
 */


public class DispatchKeyEvent extends TestStep
{
	// These are constants from flash.ui.Keyboard.  They are not
	// available in non-AIR compilations, so they are reproduced here
	// to avoid compile errors.
	// If they change in AIR, these will need to be updated.
	public static const FLASH_UI_KEYBOARD_BACK:uint = 0x01000016;
	public static const FLASH_UI_KEYBOARD_MENU:uint = 0x01000012;
	public static const FLASH_UI_KEYBOARD_SEARCH:uint = 0x0100001F;
	
    private var inDispatchKey:Boolean;
    private var gotFocusIn:Boolean;
    private var charSequence:Array;
    private var keySequence:Array;
    private var currentRepeat:int;
    private var currentKey:int;
    private var sendBoth:Boolean;
    
    /**
     *  Set the target's property to the specified value
     */
    override protected function doStep():void
    {
        UnitTester.blockFocusEvents = false;

        sendBoth = false;

        if (!type)
        {
            sendBoth = true;
            type = "keyDown";
        }
        
        var i:int;
        var n:int;
        charSequence = new Array();
        keySequence = new Array();
		
		
        if (charCode)
        {
            charSequence.push(charCode);
            keySequence.push(keyCode ? keyCode : CharCodeToKeyCode[charCode] ? CharCodeToKeyCode[charCode] : charCode);
        }
        else if (keyCode)
        {
            charSequence.push(KeyCodeToCharCode[keyCode] ? KeyCodeToCharCode[keyCode] : 0);
            keySequence.push(keyCode);
        }
        else if (char)
        {
            n = char.length;
            for (i = 0; i < n; i++)
            {
                var c:uint = char.charCodeAt(i) 
                charSequence.push(c);
                keySequence.push(CharCodeToKeyCode[c]);
            }
        }
        else if (key || keys)
        {
            var sequence:Array;
            if (key)
                sequence = [ key ];
            else
                sequence = keys;
            n = sequence.length;
            for (i = 0; i < n; i++)
            {
                var kc:uint = Keyboard[sequence[i]];
                if (kc == 0)
                {
                    testResult.doFail(key + " is not a valid flash.ui.Keyboard constant");
                    UnitTester.blockFocusEvents = true;
                    return;
                }
                keySequence.push(kc);
                charSequence.push(KeyCodeToCharCode[kc] ? KeyCodeToCharCode[kc] : 0);
            }
        }
        else
        {
            testResult.doFail("no keys specified");
            UnitTester.blockFocusEvents = true;
            return;
        }
		
        try
        {
            for (i = 0; i < repeatCount; i++)
            {
                var m:int = charSequence.length;
                for (var j:int = 0; j < m; j++)
                {
                    var event:KeyboardEvent = new KeyboardEvent(type, true, cancelable); // all keyboard events bubble
                    event.ctrlKey = ctrlKey;
                    event.shiftKey = shiftKey;
                    event.charCode = charSequence[j];
                    event.keyCode = keySequence[j];
                    event.keyLocation = keyLocation;

                    if (keySequence[j] == Keyboard.TAB)
                    {
                        // if we don't see a focusIn, focus is being set
                        // asynchronously so we need to wait.
                        currentRepeat = i;
                        currentKey = j;
                        gotFocusIn = false;
                        root.addEventListener("focusIn", focusInHandler);
                        inDispatchKey = true;
                        dispatchKey(j, event);
                        inDispatchKey = false;
                        if (!gotFocusIn)
                            break;
                    }
                    else
                        dispatchKey(j, event);
                }
            }
        }
        catch (e1:Error)
        {
            TestOutput.logResult("Exception thrown in DispatchKeyEvent.");
            testResult.doFail (e1.getStackTrace()); 
        }

        UnitTester.blockFocusEvents = true;
    }

    /**

     *  (Optional) name of a UI object whose Window/Stage

     *  will be used to dispatch the event

     */

    public var window:String;



    /**
     *  The type of the event to send (keyUp, keyDown, etc).
     *  If not set, we'll send both a keyDown and a keyUp
     */
    public var type:String;

    /**
     *  The char or sequence of chars to send as a string/char if you don't know the charCode (optional)
     */
    public var char:String;

    /**
     *  The charCode property on the KeyboardEvent (optional)
     */
    public var charCode:uint;

    /**
     *  The ctrlKey property on the KeyboardEvent (optional)
     */
    public var ctrlKey:Boolean;

    /**
     *  The Keyboard key if you don't know the keyCode (optional)
     */
    public var key:String;

    /**
     *  The sequence of keys (optional) e.g ["LEFT", "UP"]
     */
    public var keys:Array;

    /**
     *  The keyCode property on the KeyboardEvent (optional)
     */
    public var keyCode:uint;

    /**
     *  The keyLocation property on the KeyboardEvent (optional)
     */
    public var keyLocation:uint;

    /**
     *  The number of times to repeat the sequence (optional)
     */
    public var repeatCount:uint = 1;

    /**
     *  The shiftKey property on the KeyboardEvent (optional)
     */
    public var shiftKey:Boolean;

    /**
     *  Designate the created event to be cancelable. by default, they are not
     */
    public var cancelable:Boolean = false;

    /**
     *  The FlashPlayer TextField doesn't actually handle keyboard events so we have to
     *  emulate them
     */
    private function emulateKey(actualTarget:Object, event:KeyboardEvent):void
    {
        var begin:int = actualTarget.selectionBeginIndex;
        var end:int = actualTarget.selectionEndIndex;
        var caret:int = actualTarget.caretIndex;
        // trace("begin =", begin, "end =", end, "caret =", caret);

        if (event.keyCode == Keyboard.LEFT)
        {
            if (event.shiftKey)
            {
                if (caret > 0)
                {
                    if (caret == begin)
                    {
                        begin--;
                        // last param defines caret position
                        actualTarget.setSelection(end, begin);
                    }
                    else if (caret == end)
                    {
                        end--;
                        if (end < begin)
                            begin = end;
			            actualTarget.setSelection(end, begin);

                    }
                }
            }
            else
            {
                if (begin != end)
                    actualTarget.setSelection(begin, begin);

               else if (caret > 0)
                    actualTarget.setSelection(caret - 1, caret - 1);
            }
        }
        else if (event.keyCode == Keyboard.RIGHT)
        {
            if (event.shiftKey)
            {
                if (caret < actualTarget.length)
                {
                    if (caret == end)
                    {
                        end++;
                        actualTarget.setSelection(begin, end);

                    }
                    else if (caret == begin)
                    {
                        begin++;
                        if (end < begin)
                            end = begin;
                        // last param defines caret position
                        actualTarget.setSelection(end, begin);

                    }
                }
            }
            else
            {
                if (begin != end)
                    actualTarget.setSelection(end, end); 

               else if (caret > 0)
                    actualTarget.setSelection(caret + 1, caret + 1);
            }
        }
    }

    private function focusInHandler(focusEvent:Event):void
    {
        gotFocusIn = true;        
        root.removeEventListener("focusIn", focusInHandler);
        if (inDispatchKey)
            return;
        
        for (var i:int = currentRepeat; i < repeatCount; i++)
        {
            var m:int = charSequence.length;
            for (var j:int = currentKey + 1; j < m; j++)
            {
                var event:KeyboardEvent = new KeyboardEvent(type, true, cancelable); // all keyboard events bubble
                event.ctrlKey = ctrlKey;
                event.shiftKey = shiftKey;
                event.charCode = charSequence[j];
                event.keyCode = keySequence[j];
                event.keyLocation = keyLocation;
                
                if (keySequence[j] == Keyboard.TAB)
                {
                    currentRepeat = i;
                    currentKey = j;
                    gotFocusIn = false;
                    root.addEventListener("focusIn", focusInHandler);
                    inDispatchKey = true;
                    dispatchKey(j, event);
                    inDispatchKey = false;
                    if (!gotFocusIn)
                        break;
                }                
                else
                    dispatchKey(j, event);
            }
        }
    }
    
    private function dispatchKey(index:int, event:KeyboardEvent):void
    {
        // note that we don't check Window activation since we want to run in the background
        // and window activation is a player function
        
        var actualTarget:Object;
        
        if (window)
        {
            actualTarget = context.stringToObject(window);
            actualTarget = actualTarget.stage.focus;
        }
        else
        {
            actualTarget = root.stage.focus;
            if (!actualTarget)
            {
                actualTarget = UnitTester.getFocus();
            }
        }
        
        // BACK, MENU, and SEARCH are buttons on mobile (Android) devices.  
        // On Android devices right now, actualTarget is still null at this point.  Dispatching the event to the stage works.
        // Using the constants in flash.ui.Keyboard will cause an error in a non-AIR runs, so the constants are also defined
        // in this file, above.  There is risk here.
        if (keySequence[index] == FLASH_UI_KEYBOARD_BACK ||
            keySequence[index] == FLASH_UI_KEYBOARD_MENU ||
            keySequence[index] == FLASH_UI_KEYBOARD_SEARCH){
            
            actualTarget = root.stage;
        }
        
        if (actualTarget)
        {
            var targetType:TypeInfo = context.getTypeInfo(actualTarget);
            var isTextView:Boolean = targetType.isAssignableTo("spark.components::RichEditableText");
            
            
            if (actualTarget is TextField)
            {
                if (event.charCode)
                {
                    if (actualTarget.type == "input")
                    {
                        actualTarget.replaceSelectedText(String.fromCharCode(event.charCode));
                        // actualTarget.dispatchEvent(new Event("change", true));
                        actualTarget.dispatchEvent(new Event("change"));
                    }
                }
                else
                {
                    if (actualTarget.selectable)
                        emulateKey(actualTarget, event);
                }
            }
            
            actualTarget.dispatchEvent(event);
            
            
            
            if (isTextView)
            {
                if (event.keyCode == Keyboard.DELETE ||
                    
                    event.keyCode == Keyboard.BACKSPACE ||
                    
                    event.keyCode == Keyboard.INSERT ||
                    
                    ctrlKey)
                    
                {
                    
                    // don't send TEXT_INPUT event
                    
                }
                    
                else
                    
                {
                    
                    var textEvent:TextEvent = new TextEvent(TextEvent.TEXT_INPUT, true, true);
                    
                    textEvent.text = String.fromCharCode(charSequence[index]);
                    
                    actualTarget.dispatchEvent(textEvent);
                    
                }
                
            }
            
            if (keySequence[index] == Keyboard.TAB && type == "keyDown")
            {
                var fm:Object;
                var newTarget:Object = actualTarget;
                while (!fm && newTarget)
                {   
                    if ("focusManager" in newTarget)
                        fm = newTarget["focusManager"];
                    newTarget = newTarget.parent;
                }
                newTarget = null;
                if (fm)
                {
                    try
                    {
                        newTarget = fm.getNextFocusManagerComponent(shiftKey);
                    }
                    catch (e:Error)
                    {
                        // ignore error thrown here.  Should only throw if the
                        // current FM became inactive as a result of dispatching
                        // the key event.  We don't really care too much about
                        // getting an accurate newTarget in this case because
                        // newTarget is often wrong since the Player is offering
                        // it up and the Player has that wonky algorithm for
                        // determining newTarget.   In theory, none of our code
                        // truly cares as long as it doesn't point to old focus
                        // object.
                    }
                }
                
                actualTarget.dispatchEvent(new FocusEvent(FocusEvent.KEY_FOCUS_CHANGE, true, true, InteractiveObject(newTarget), shiftKey, Keyboard.TAB));
            }
            
            if (sendBoth)
            {
                event = new KeyboardEvent("keyUp", true, cancelable);
                event.ctrlKey = ctrlKey;
                event.shiftKey = shiftKey;
                event.charCode = charSequence[index];
                event.keyCode = keySequence[index];
                event.keyLocation = keyLocation;
                actualTarget.dispatchEvent(event);
            }
        }
        else
        {
            if (keySequence[index] == Keyboard.TAB && type == "keyDown")
            {
                
                var thisRoot:DisplayObject
                
                // note that we don't check Window activation since we want to run in the background
                // and window activation is a player function
                if (window)
                {
                    thisRoot = context.stringToObject(window).root;
                }
                else
                    thisRoot = root;
                try
                {
                    thisRoot.stage.dispatchEvent(new FocusEvent(FocusEvent.KEY_FOCUS_CHANGE, true, true, InteractiveObject(actualTarget), shiftKey, Keyboard.TAB));
                }
                catch(se2:SecurityError)
                {
                    thisRoot.dispatchEvent(new FocusEvent(FocusEvent.KEY_FOCUS_CHANGE, true, true, InteractiveObject(actualTarget), shiftKey, Keyboard.TAB));
                }
            }						
            
        }
    }
    
    private var KeyCodeToCharCode:Object = {
                    8: 8,
                    13: 13,
                    96: 48,
                    97: 49,
                    98: 50,
                    99: 51,
                    100: 52, 
                    101: 53,
                    102: 54,
                    103: 55,
                    104: 56,
                    105: 57,
                    106: 42,
                    107: 43,
                    109: 45,
                    110: 46,
                    111: 47
    }

    private var CharCodeToKeyCode:Object = {
                    13: 13,
                    33: 49,
                    34: 222,
                    35: 51,
                    36: 52,
                    37: 53,
                    38: 55,
                    39: 222,
                    40: 57,
                    41: 48,
                    42: 56,
                    43: 187,
                    44: 188,
                    45: 189,
                    46: 190,
                    47: 191,
                    48: 48,
                    49: 49,
                    50: 50,
                    51: 51,
                    52: 52,
                    53: 53,
                    54: 54,
                    55: 55,
                    56: 56,
                    57: 57,
                    58: 186,
                    59: 186,
                    60: 188,
                    61: 187,
                    62: 190,
                    63: 191,
                    64: 50,
                    65: 65,
                    66: 66,
                    67: 67,
                    68: 68,
                    69: 69,
                    70: 70,
                    71: 71,
                    72: 72,
                    73: 73,
                    74: 74,
                    75: 75,
                    76: 76,
                    77: 77,
                    78: 78,
                    79: 79,
                    80: 80,
                    81: 81,
                    82: 82,
                    83: 83,
                    84: 84,
                    85: 85,
                    86: 86,
                    87: 87,
                    88: 88,
                    89: 89,
                    90: 90,
                    91: 219,
                    92: 220,
                    93: 221,
                    94: 54,
                    95: 189,
                    96: 192,
                    97: 65,
                    98: 66,
                    99: 67,
                    100: 68,
                    101: 69,
                    102: 70,
                    103: 71,
                    104: 72,
                    105: 73,
                    106: 74,
                    107: 75,
                    108: 76,
                    109: 77,
                    110: 78,
                    111: 79,
                    112: 80,
                    113: 81,
                    114: 82,
                    115: 83,
                    116: 84,
                    117: 85,
                    118: 86,
                    119: 87,
                    120: 88,
                    121: 89,
                    122: 90,
                    123: 219,
                    124: 220,
                    125: 221,
                    126: 192
    }

    /**
     *  customize string representation
     */
    override public function toString():String
    {
        var s:String = "DispatchKeyEvent";
        if (charCode)
            s += ": charCode = " + charCode.toString();
        if (keyCode)
            s += ": keyCode = " + keyCode.toString();
        if (char)
            s += ": char = " + char;
        if (key)
            s += ": key = " + key;
        if (keys)
            s += ": keys = " + keys.toString();
        if (type)
            s += ", type = " + type;
        if (shiftKey)
            s += ", shiftKey = " + shiftKey.toString();
        if (ctrlKey)
            s += ", ctrlKey = " + ctrlKey.toString();
        if (repeatCount)
            s += ", repeatCount = " + repeatCount.toString();
        return s;
    }
}

}
