/// <summary>
        /// Assigns the given callback to this Tweener/Sequence,
        /// overwriting any existing callbacks of the same type.
        /// </summary>
        protected virtual void ApplyCallback(bool p_wParms, CallbackType p_callbackType, TweenDelegate.TweenCallback p_callback, TweenDelegate.TweenCallbackWParms p_callbackWParms, params object[] p_callbackParms)
        {
            switch (p_callbackType)
            {
            case CallbackType.OnStart:
                onStart       = p_callback;
                onStartWParms = p_callbackWParms;
                onStartParms  = p_callbackParms;
                break;

            case CallbackType.OnUpdate:
                onUpdate       = p_callback;
                onUpdateWParms = p_callbackWParms;
                onUpdateParms  = p_callbackParms;
                break;

            case CallbackType.OnStepComplete:
                onStepComplete       = p_callback;
                onStepCompleteWParms = p_callbackWParms;
                onStepCompleteParms  = p_callbackParms;
                break;

            case CallbackType.OnComplete:
                onComplete       = p_callback;
                onCompleteWParms = p_callbackWParms;
                onCompleteParms  = p_callbackParms;
                break;

            case CallbackType.OnPlay:
                onPlay       = p_callback;
                onPlayWParms = p_callbackWParms;
                onPlayParms  = p_callbackParms;
                break;

            case CallbackType.OnPause:
                onPause       = p_callback;
                onPauseWParms = p_callbackWParms;
                onPauseParms  = p_callbackParms;
                break;

            case CallbackType.OnRewinded:
                onRewinded       = p_callback;
                onRewindedWParms = p_callbackWParms;
                onRewindedParms  = p_callbackParms;
                break;

            case CallbackType.OnPluginOverwritten:
                TweenWarning.Log("ApplyCallback > OnPluginOverwritten type is available only with Tweeners and not with Sequences");
                break;
            }
        }
        // ===================================================================================
        // METHODS ---------------------------------------------------------------------------

        public void AddTween(Tweener p_tween)
        {
            if (enabled)
            {
                // Check running tweens for eventual overwrite.
                List <ABSTweenPlugin> addPlugs = p_tween.plugins;

                int runningTweensCount = runningTweens.Count - 1;
                int addPlugsCount      = addPlugs.Count;

                for (int i = runningTweensCount; i > -1; --i)
                {
                    Tweener tw = runningTweens[i];
                    List <ABSTweenPlugin> twPlugins = tw.plugins;
                    int twPluginsCount = twPlugins.Count;

                    if (tw.target == p_tween.target)
                    {
                        // Check internal plugins.
                        for (int n = 0; n < addPlugsCount; ++n)
                        {
                            ABSTweenPlugin addPlug = addPlugs[n];
                            for (int c = twPluginsCount - 1; c > -1; --c)
                            {
                                ABSTweenPlugin plug = twPlugins[c];
                                if (plug.propName == addPlug.propName && (addPlug.pluginId == -1 || plug.pluginId == -1 || plug.pluginId == addPlug.pluginId))
                                {
                                    if (tw.isSequenced && p_tween.isSequenced && tw.contSequence == p_tween.contSequence)
                                    {
                                        goto NEXT_TWEEN;
                                    }
                                    if (!tw._isPaused && (!tw.isSequenced || !tw.isComplete))
                                    {
                                        // Overwrite old plugin.
                                        twPlugins.RemoveAt(c);
                                        twPluginsCount--;
                                        if (HOTween.isEditor && HOTween.warningLevel == WarningLevel.Verbose)
                                        {
                                            string t0 = addPlug.GetType().ToString();
                                            t0 = t0.Substring(t0.LastIndexOf(".") + 1);
                                            string t1 = plug.GetType().ToString();
                                            t1 = t1.Substring(t1.LastIndexOf(".") + 1);
                                            if (logWarnings)
                                            {
                                                TweenWarning.Log(t0 + " is overwriting " + t1 + " for " + tw.target + "." + plug.propName);
                                            }
                                        }
                                        // Check if whole tween needs to be removed.
                                        if (twPluginsCount == 0)
                                        {
                                            if (tw.isSequenced)
                                            {
                                                tw.contSequence.Remove(tw);
                                            }
                                            runningTweens.RemoveAt(i);
                                            tw.Kill(false);
                                        }
                                        // Dispatch eventual pluginOverwritten event
                                        if (tw.onPluginOverwritten != null)
                                        {
                                            tw.onPluginOverwritten();
                                        }
                                        else if (tw.onPluginOverwrittenWParms != null)
                                        {
                                            tw.onPluginOverwrittenWParms(new TweenEvent(tw, tw.onPluginOverwrittenParms));
                                        }
                                        // If whole tween was killed jump to next tween
                                        if (tw.destroyed)
                                        {
                                            goto NEXT_TWEEN;
                                        }
                                    }
                                }
                            }
                        }
                        NEXT_TWEEN :;
                    }
                }
            }

            runningTweens.Add(p_tween);
        }