﻿/// <reference name="MicrosoftAjax.js"/>
/// <reference name="Pacem.Web.Extensions.Tween.Tween.js" assembly="Pacem.Web.Extensions"/>
/// <reference name="AjaxControlToolkit.Common.CommonScripts.js" assembly="AjaxControlToolkit"/>
/// <reference name="AjaxControlToolkit.Compat.Timer.Timer.js" assembly="AjaxControlToolkit"/>
Type.registerNamespace('Pacem.UI');

Pacem.UI.RotationStatus = function() { };
Pacem.UI.RotationStatus.prototype = {
    playing: 0,
    paused: 1
}
Pacem.UI.RotationStatus.registerEnum("Pacem.UI.RotationStatus");

// custom event args
Pacem.UI.RotationChangingEventArgs = function(targetIndex) {
    /// <summary>
    /// Event arguments used when the index of a rotation is about to change.
    /// </summary>
    /// <param name="targetIndex" type="Number" mayBeNull="false">
    /// Index that the rotator is about to reach.
    /// </param>
    Pacem.UI.RotationChangingEventArgs.initializeBase(this);
    this._targetIndex = targetIndex;
}
Pacem.UI.RotationChangingEventArgs.prototype = {
    get_targetIndex: function() {
        /// <value type="Number" DomElement="false" mayBeNull="false">
        /// Index that the rotator is about to reach.
        /// </value>
        return this._targetIndex;
    }
}
Pacem.UI.RotationChangingEventArgs.registerClass('Pacem.UI.RotationChangingEventArgs', Sys.EventArgs);

// content rotator
Pacem.UI.ContentRotatorBehavior = function(element) {

    Pacem.UI.ContentRotatorBehavior.initializeBase(this, [element]);

    this._contentReferences = [];
    this._contents = [];
    this._playControl;
    this._pauseControl;
    this._currentIndex = -1;
    this._targetIndex = 0;
    this._interval = 5.0;
    this._transitionDuration = 0.5;
    this._autoPlay = true;
    this._status = Pacem.UI.RotationStatus.playing;
    this._tween = null;
    this._tickHandler = null;
    this._timer = null;
    this._focusControl = null;
    this._clickHandler;
    this._playClickHandler;
    this._pauseClickHandler;
    this._targetIndexVariable = "pacem_rotationTargetIndex";
    this._suppressPostBack = false;
}

Pacem.UI.ContentRotatorBehavior.prototype = {

    initialize: function() {
        Pacem.UI.ContentRotatorBehavior.callBaseMethod(this, 'initialize');

        var el = this.get_element();
        this._clickHandler = Function.createDelegate(this, this._onClick);
        // getting array
        this._contents = [];
        for (var j = 0; j < this._contentReferences.length; j++) {
            if (this._contentReferences[j].ElementID != "") {
                var json = { element: $get(this._contentReferences[j].ElementID), index: j };
                this._contents.push(json);
                if (this._contentReferences[j].ButtonID != "") {
                    json.button = $get(this._contentReferences[j].ButtonID);
                    json.css = this._contentReferences[j].ButtonFocusCssClass;
                    json.button[this._targetIndexVariable] = j;
                    $addHandler(json.button, "click", this._clickHandler);
                }
            }
        }
        if (this._contents.length == 0) return;

        if (this._playControl) {
            this._playClickHandler = Function.createDelegate(this, this._onPlayClick);
            $addHandler(this._playControl, "click", this._playClickHandler);
        }
        if (this._pauseControl) {
            this._pauseClickHandler = Function.createDelegate(this, this._onPauseClick);
            $addHandler(this._pauseControl, "click", this._pauseClickHandler);
        }

        this._timer = new Sys.Timer();
        this._tickHandler = Function.createDelegate(this, this._onTick);
        this._timer.add_tick(this._tickHandler);
        if (this._autoPlay == true)
            this._onTick();
        else
            this._status = Pacem.UI.RotationStaus.paused;
    },

    dispose: function() {
        if (this._tween)
            this._tween.dispose();

        if (this._playControl)
            $removeHandler(this._playControl, "click", this._playClickHandler);

        if (this._pauseControl)
            $removeHandler(this._pauseControl, "click", this._pauseClickHandler);

        for (var j = 0; j < this._contents.length; j++) {
            var btn = this._contents[j].button;
            if (btn)
                $removeHandler(btn, "click", this._clickHandler);
        }

        this._timer.remove_tick(this._tickHandler);
        this._timer.dispose();
        //
        Pacem.UI.ContentRotatorBehavior.callBaseMethod(this, 'dispose');
    },

    add_indexChanged: function(handler) {
        /// <summary>
        /// Add an event handler for the indexChanged event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// RoutedEvent handler
        /// </param>
        /// <returns />
        this.get_events().addHandler('indexChanged', handler);
    },
    remove_indexChanged: function(handler) {
        /// <summary>
        /// Remove an event handler from the indexChanged event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// RoutedEvent handler
        /// </param>
        /// <returns />
        this.get_events().removeHandler('indexChanged', handler);
    },
    raiseIndexChanged: function(eventArgs) {
        /// <summary>
        /// Raise the indexChanged event
        /// </summary>
        /// <param name="eventArgs" type="Sys.EventArgs" mayBeNull="false">
        /// Event arguments for the indexChanged event
        /// </param>
        /// <returns />
        var handler = this.get_events().getHandler('indexChanged');
        if (handler) {
            handler(this, eventArgs);
        }
    },

    add_indexChanging: function(handler) {
        /// <summary>
        /// Add an event handler for the indexChanged event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// RoutedEvent handler
        /// </param>
        /// <returns />
        this.get_events().addHandler('indexChanging', handler);
    },
    remove_indexChanging: function(handler) {
        /// <summary>
        /// Remove an event handler from the indexChanged event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// RoutedEvent handler
        /// </param>
        /// <returns />
        this.get_events().removeHandler('indexChanging', handler);
    },
    raiseIndexChanging: function(eventArgs) {
        /// <summary>
        /// Raise the indexChanged event
        /// </summary>
        /// <param name="eventArgs" type="Pacem.UI.RotationChangingEventArgs" mayBeNull="false">
        /// Event arguments for the indexChanged event
        /// </param>
        /// <returns />
        var handler = this.get_events().getHandler('indexChanging');
        if (handler) {
            handler(this, eventArgs);
        }
    },
    _refreshTicker: function() {
        var interval = parseInt(this._interval * 1000);
        this._timer.set_interval(interval);
        this._timer.set_enabled(true);
    },
    _notifyIndexChanged: function() {
        this.raiseIndexChanged(Sys.EventArgs.Empty);
        this._targetIndex = this._currentIndex + 1;
        if (this._status == Pacem.UI.RotationStatus.playing) {
            this._refreshTicker();
        }
    },
    _onClick: function(evt) {
        if (this._suppressPostBack) {
            evt.preventDefault();
            evt.stopPropagation();
        }
        if (this._tween != null && this._tween.get_status() == Pacem.UI.TweenStatus.playing) return;
        this._timer.set_enabled(false);
        this._targetIndex = evt.target[this._targetIndexVariable];
        this._onTick(this._name);
    },
    _onPlayClick: function(evt) {
        if (this._suppressPostBack) {
            evt.preventDefault();
            evt.stopPropagation();
        }
        if (this._status != Pacem.UI.RotationStatus.playing)
            this.play();
    },
    _onPauseClick: function(evt) {
        if (this._suppressPostBack) {
            evt.preventDefault();
            evt.stopPropagation();
        }
        if (this._status != Pacem.UI.RotationStatus.paused)
            this.pause();
    },
    _onTick: function() {
        var me = this;
        if (me._targetIndex >= me._contents.length)
            me._targetIndex = 0;
        // raise changing
        var eargs = new Pacem.UI.RotationChangingEventArgs(me._targetIndex);
        me.raiseIndexChanging(eargs);
        if (me._currentIndex == -1) // starting
        {
            $common.setElementOpacity(me.get_element(), 0);
            me._startFadeIn();
        }
        else
            me._startFadeOut();
    },
    _startFadeOut: function() {
        var start = $common.getElementOpacity(this.get_element());
        if (this._tween)
            this._tween.dispose();
        this._tween = $create(Pacem.UI.Tween, { 'property': 'opacity', 'easingFunc': Pacem.UI.Easing.Sine.easeInOut, 'start': start, 'finish': 0.0, 'duration': this._transitionDuration / 2.0 },
        { 'motionChanged': this._tweenChanged, 'motionFinished': Function.createDelegate(this, this._tweenFinished1) }, null, this.get_element());
    },
    _startFadeIn: function() {
        if (this._focusControl)
            this.get_element().removeChild(this._focusControl);
        this._focusControl = this._contents[this._targetIndex].element;
        this.get_element().appendChild(this._focusControl);
        //
        if (this._tween)
            this._tween.dispose();
        this._tween = $create(Pacem.UI.Tween, { 'property': 'opacity', 'easingFunc': Pacem.UI.Easing.Sine.easeInOut, 'start': 0.0, 'finish': 1.0, 'duration': this._transitionDuration / 2.0 },
        { 'motionChanged': this._tweenChanged, 'motionFinished': Function.createDelegate(this, this._tweenFinished2) }, null, this.get_element());
    },
    _tweenChanged: function(sender, args) {
        // opacity
        $common.setElementOpacity(sender.get_object(), args.get_currentPosition());
    },
    _tweenFinished1: function(sender, args) {
        // fade-out finished
        // -> eventually reset css
        if (this._contents[this._currentIndex].button && this._contents[this._currentIndex].css)
            Sys.UI.DomElement.removeCssClass(this._contents[this._currentIndex].button, this._contents[this._currentIndex].css);
        // -> launch fade-in
        this._startFadeIn();
    },
    _tweenFinished2: function(sender, args) {
        // fixing undesired IE behavior on PNG's
        if (sender.get_object().style.filter && sender.get_object().style.removeAttribute)
            sender.get_object().style.removeAttribute('filter');
        // fade-in finished -> fire events
        this._currentIndex = this._targetIndex;
        // -> eventually set css
        if (this._contents[this._currentIndex].button && this._contents[this._currentIndex].css)
            Sys.UI.DomElement.addCssClass(this._contents[this._currentIndex].button, this._contents[this._currentIndex].css);
        this._notifyIndexChanged();
    },
    /*
    PUBLIC METHODS
    */
    play: function() {
        this._status = Pacem.UI.RotationStatus.playing;
        this._onTick();
    },
    pause: function() {
        this._status = Pacem.UI.RotationStatus.paused;
        this._timer.set_enabled(false);
    },
    /*
    PUBLIC PROPERTIES
    */
    get_status: function() {
        return this._status;
    },

    get_currentIndex: function() {
        return this._currentIndex;
    },

    get_suppressPostBack: function() {
        /// <value type="Boolean">
        /// Whether or not to suppress postbacks generated when button elements are clicked.
        /// </value>
        return this._suppressPostBack;
    },
    set_suppressPostBack: function(value) {
        this._suppressPostBack = value;
    },

    get_playControl: function() {
        return this._playControl;
    },
    set_playControl: function(value) {
        this._playControl = value;
    },

    get_pauseControl: function() {
        return this._pauseControl;
    },
    set_pauseControl: function(value) {
        this._pauseControl = value;
    },

    get_contentReferences: function() {
        return this._contentReferences;
    },
    set_contentReferences: function(value) {
        this._contentReferences = value;
    },

    get_autoPlay: function() {
        return this._autoPlay;
    },
    set_autoPlay: function(value) {
        this._autoPlay = value;
    },

    get_interval: function() {
        return this._interval;
    },
    set_interval: function(value) {
        this._interval = value;
    },

    get_transitionDuration: function() {
        return this._transitionDuration;
    },
    set_transitionDuration: function(value) {
        this._transitionDuration = value;
    }
}
Pacem.UI.ContentRotatorBehavior.registerClass('Pacem.UI.ContentRotatorBehavior', AjaxControlToolkit.BehaviorBase);


if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();