////////////////////////////////////////////////////////////////////////////////
//
//  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 mx.binding
{

import mx.collections.errors.ItemPendingError;
import mx.core.mx_internal;
import flash.utils.Dictionary;

use namespace mx_internal;

[ExcludeClass]

/**
 *  @private
 */
public class Binding
{
    include "../core/Version.as";

    // Certain errors are normal during binding execution, so we swallow them.
    // 1507 - invalid null argument 
    // 2005 - argument error (null gets converted to 0) 
    mx_internal static var allowedErrors:Object = generateAllowedErrors();
    mx_internal static function generateAllowedErrors():Object
    {
        var o:Object = {};
        o[1507] = 1;
        o[2005] = 1;
        return o;
    }
    
    //--------------------------------------------------------------------------
	//
	//  Constructor
	//
	//--------------------------------------------------------------------------

    /**
     *  Create a Binding object
	 *
     *  @param document The document that is the target of all of this work.
	 *
     *  @param srcFunc The function that returns us the value
	 *  to use in this Binding.
	 *
     *  @param destFunc The function that will take a value
	 *  and assign it to the destination.
	 *
     *  @param destString The destination represented as a String.
	 *  We can then tell the ValidationManager to validate this field.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function Binding(document:Object, srcFunc:Function,
						    destFunc:Function, destString:String,
							srcString:String = null)
    {
		super();

        this.document = document;
        this.srcFunc = srcFunc;
        this.destFunc = destFunc;
        this.destString = destString;
        this.srcString = srcString;
        this.destFuncFailed = false;

        if (this.srcFunc == null)
        {
            this.srcFunc = defaultSrcFunc;
        }

        if (this.destFunc == null)
        {
            this.destFunc = defaultDestFunc;
        }

        _isEnabled = true;
        isExecuting = false;
        isHandlingEvent = false;
        hasHadValue = false;
        uiComponentWatcher = -1;

        BindingManager.addBinding(document, destString, this);
    }

 	//--------------------------------------------------------------------------
	//
	//  Variables
	//
	//--------------------------------------------------------------------------

    /**
     *  @private
     *  Internal storage for isEnabled property.
     */
    mx_internal var _isEnabled:Boolean;

    /**
     *  @private
     *  Indicates that a Binding is enabled.
     *  Used to disable bindings.
     */
    mx_internal function get isEnabled():Boolean
    {
        return _isEnabled;
    }

    /**
     *  @private
     */
    mx_internal function set isEnabled(value:Boolean):void
    {
        _isEnabled = value;
        
        if (value)
        {
            processDisabledRequests();
        }
    }
    
	/**
 	 *  @private
     *  Indicates that a Binding is executing.
	 *  Used to prevent circular bindings from causing infinite loops.
     */
    mx_internal var isExecuting:Boolean;

	/**
 	 *  @private
     *  Indicates that the binding is currently handling an event.
     *  Used to prevent us from infinitely causing an event
	 *  that re-executes the the binding.
     */
    mx_internal var isHandlingEvent:Boolean;
    
    /**
     *  @private
     *  Queue of watchers that fired while we were disabled.
     *  We will resynch with our binding if isEnabled is set to true
     *  and one or more of our watchers fired while we were disabled.
     */
    mx_internal var disabledRequests:Dictionary;

	/**
 	 *  @private
     *  True as soon as a non-null or non-empty-string value has been used.
     *  We don't auto-validate until this is true
     */
    private var hasHadValue:Boolean;

	/**
 	 *  @private
     *  This is no longer used in Flex 3.0, but it is required to load
     *  Flex 2.0.0 and Flex 2.0.1 modules.
     */
    public var uiComponentWatcher:int;

	/**
 	 *  @private
     *  It's possible that there is a two-way binding set up, in which case
     *  we'll do a rudimentary optimization by not executing ourselves
     *  if our counterpart is already executing.
     */
    public var twoWayCounterpart:Binding;

    /**
     *  @private
     *  If there is a twoWayCounterpart, hasHadValue is false, and
     *  isTwoWayPrimary is true, then the twoWayCounterpart will be
     *  executed first.
     */
    public var isTwoWayPrimary:Boolean;

    /**
     *  @private 
     *  True if a wrapped function call does not throw an error.  This is used by
     *  innerExecute() to tell if the srcFunc completed successfully.
     */
    private var wrappedFunctionSuccessful:Boolean;

 	//--------------------------------------------------------------------------
	//
	//  Properties
	//
	//--------------------------------------------------------------------------

    /**
     *  All Bindings hang off of a document for now,
	 *  but really it's just the root of where these functions live.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    mx_internal var document:Object;

	/**
     *  The function that will return us the value.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    mx_internal var srcFunc:Function;

	/**
     *  The function that takes the value and assigns it.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    mx_internal var destFunc:Function;
    
    /**
     * @private 
     */
    mx_internal var destFuncFailed:Boolean;

	/**
     *  The destination represented as a String.
	 *  This will be used so we can signal validation on a field.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    mx_internal var destString:String;

	/**
     *  The source represented as a String.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 4
     */
    mx_internal var srcString:String;

	/**
	 * 	@private
	 *  Used to suppress calls to destFunc when incoming value is either
	 *	a) an XML node identical to the previously assigned XML node, or
	 *  b) an XMLList containing the identical node sequence as the previously assigned XMLList
	 */
	private var lastValue:Object;


 	//--------------------------------------------------------------------------
	//
	//  Methods
	//
	//--------------------------------------------------------------------------

    private function defaultDestFunc(value:Object):void
    {
        var chain:Array = destString.split(".");
        var element:Object = document;
        var i:uint = 0;

        if (chain[0] == "this")
        {
            i++;
        }

        while (i < (chain.length - 1))
        {
            element = element[chain[i++]];
            //if the element does not exist : avoid exception as it's heavy on memory allocations
            if (element == null) {
                destFuncFailed = true;
                if (BindingManager.debugDestinationStrings[destString])
                {
                    trace("Binding: destString = " + destString + ", error = 1009");
                }
                return;
            }
        }

        element[chain[i]] = value;
    }

    private function defaultSrcFunc():Object
    {
        return document[srcString];
    }

    /**
     *  Execute the binding.
	 *  Call the source function and get the value we'll use.
	 *  Then call the destination function passing the value as an argument.
	 *  Finally try to validate the destination.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function execute(o:Object = null):void
    {
        if (!isEnabled)
        {
            if (o != null)
            {
                registerDisabledExecute(o);
            }
            return;
        }

        if (twoWayCounterpart && !twoWayCounterpart.hasHadValue && twoWayCounterpart.isTwoWayPrimary)
        {
            twoWayCounterpart.execute();
            hasHadValue = true;
            return;
        }

        if (isExecuting || (twoWayCounterpart && twoWayCounterpart.isExecuting))
        {
            // If there is a twoWayCounterpart already executing, that means that it is
            // assigning something of value so even though we won't execute we should be
            // sure to mark ourselves as having had a value so that future executions will
            // be correct.  If isExecuting is true but we re-entered, that means we
            // clearly had a value so setting hasHadValue is safe.
            hasHadValue = true;
            return;
        }

        try
        {
            isExecuting = true;
            wrapFunctionCall(this, innerExecute, o);
        }
        catch(error:Error)
        {
            if (allowedErrors[error.errorID] == null)
                throw error;
        }
        finally
        {
            isExecuting = false;
        }
    }

    /**
     * @private 
     * Take note of any execute request that occur when we are disabled. 
     */
    private function registerDisabledExecute(o:Object):void
    {
        if (o != null)
        {
            disabledRequests = (disabledRequests != null) ? disabledRequests : 
                new Dictionary(true);
            
            disabledRequests[o] = true;
        }
    }  
    
    /**
     * @private 
     * Resynch with any watchers that may have updated while we were disabled.
     */
    private function processDisabledRequests():void
    {
        if (disabledRequests != null)
        {
            for (var key:Object in disabledRequests) 
            {
                execute(key);
            }

            disabledRequests = null;
        }
    }  
    
    
    /**
	 *  @private
	 *  Note: use of this wrapper needs to be reexamined. Currently there's at least one situation where a
	 *	wrapped function invokes another wrapped function, which is unnecessary (i.e., only the inner function
	 *  will throw), and also risks future errors due to the 'wrappedFunctionSuccessful' member variable
	 *  being stepped on. Leaving alone for now to minimize pre-GMC volatility, but should be revisited for
	 *  an early dot release.
	 *  Also note that the set of suppressed error codes below is repeated verbatim in Watcher.wrapUpdate.
	 *  These need to be consolidated and the motivations for each need to be documented.
     */
    protected function wrapFunctionCall(thisArg:Object, wrappedFunction:Function, object:Object = null, ...args):Object
    {
        wrappedFunctionSuccessful = false;

        try
        {
            var result:Object = wrappedFunction.apply(thisArg, args);
            if(destFuncFailed == true) {
                destFuncFailed = false;
                return null;
            }
            wrappedFunctionSuccessful = true;
            return result;
        }
        catch(error:Error)
        {
			if (error is ItemPendingError) {
	            (error as ItemPendingError).addResponder(new EvalBindingResponder(this, object));
	            if (BindingManager.debugDestinationStrings[destString])
	            {
	                trace("Binding: destString = " + destString + ", error = " + error);
	            }
			} else if (error is RangeError) {
	            if (BindingManager.debugDestinationStrings[destString])
	            {
	                trace("Binding: destString = " + destString + ", error = " + error);
	            }
			} else {
	            // Certain errors are normal when executing a srcFunc or destFunc,
	            // so we swallow them:
	            //   Error #1006: Call attempted on an object that is not a function.
	            //   Error #1009: null has no properties.
	            //   Error #1010: undefined has no properties.
	            //   Error #1055: - has no properties.
	            //   Error #1069: Property - not found on - and there is no default value
	            // We allow any other errors to be thrown.
	            if ((error.errorID != 1006) &&
	                (error.errorID != 1009) &&
	                (error.errorID != 1010) &&
	                (error.errorID != 1055) &&
	                (error.errorID != 1069))
	            {
	                throw error;
	            }
	            else
	            {
	                if (BindingManager.debugDestinationStrings[destString])
	                {
	                    trace("Binding: destString = " + destString + ", error = " + error);
	                }
	            }
			}
        }

        return null;
    }

	/**
	 *	@private
	 *  true if XMLLists x and y contain the same node sequence.
	 */
	private static function nodeSeqEqual(x:XMLList, y:XMLList):Boolean
	{
		var n:uint = x.length();
		if (n == y.length())
		{
			for (var i:uint = 0; i < n && x[i] === y[i]; i++)
			{
			}
			return i == n;
		}
		else
		{
			return false;
		}
	}

    /**
	 *  @private
     */
    private function innerExecute():void
    {
        destFuncFailed = false;
        var value:Object = wrapFunctionCall(document, srcFunc);

        if (BindingManager.debugDestinationStrings[destString])
        {
            trace("Binding: destString = " + destString + ", srcFunc result = " + value);
        }

        if (hasHadValue || wrappedFunctionSuccessful)
        {
        	//	Suppress binding assignments on non-simple XML: identical single nodes, or
        	//	lists over identical node sequences.
			//	Note: outer tests are inline for efficiency
        	if (!(lastValue is XML && lastValue.hasComplexContent() && lastValue === value) &&
        		!(lastValue is XMLList && lastValue.hasComplexContent() && value is XMLList &&
        			nodeSeqEqual(lastValue as XMLList, value as XMLList)))
        	{
	            destFunc.call(document, value);

                if(destFuncFailed == false) {
                    //	Note: state is not updated if destFunc throws
                    lastValue = value;
                    hasHadValue = true;
	            }
	        }
        }
    }

    /**
	 *  This function is called when one of this binding's watchers
	 *  detects a property change.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
    public function watcherFired(commitEvent:Boolean, cloneIndex:int):void
    {
        if (isHandlingEvent)
            return;

        try
        {
	        isHandlingEvent = true;
			execute(cloneIndex);
		}
		finally
		{
        	isHandlingEvent = false;
        }
    }
}

}
