﻿// README
//
// There are two steps to adding a property:
//
// 1. Create a member variable to store your property
// 2. Add the get_ and set_ accessors for your property
//
// Remember that both are case sensitive!


/// <reference name="MicrosoftAjax.debug.js" />
/// <reference name="AjaxControlToolkit.ExtenderBase.BaseScripts.js" assembly="AjaxControlToolkit" />


Type.registerNamespace('Pacem.UI');

Pacem.UI.CollapsiblePanelBehavior = function(element) {
    Pacem.UI.CollapsiblePanelBehavior.initializeBase(this, [element]);
    // property values
    this._animationDuration = 0.5;
    this._collapsed = false;
    this._expandControl = null;
    this._collapseControl = null;
    this._textLabel = null;
    this._collapsedText = '';
    this._expandedText = '';
    this._imageControl = null;
    this._expandedImage = null;
    this._collapsedImage = null;
    this._suppressPostBack = false;
    this._autoExpand = null;
    this._autoCollapse = null;
    // handler delegates
    this._collapseClickHandler = null;
    this._expandClickHandler = null;

    // the div we wrap around the panel contents
    this._childDiv = null;
    this._tween = null;
    this._easingFunc = Pacem.UI.Easing.Sine.easeOut;
}
Pacem.UI.CollapsiblePanelBehavior.prototype = {
    initialize: function() {
        Pacem.UI.CollapsiblePanelBehavior.callBaseMethod(this, 'initialize');
        //
        this._setupChildDiv();
        var element = this.get_element();


        if (this._collapseControl == this._expandControl) {
            this._collapseClickHandler = Function.createDelegate(this, this._togglePanel);
            this._expandClickHandler = null; // we don't need both if we're toggling.
        } else {
            this._collapseClickHandler = Function.createDelegate(this, this._collapsePanel);
            this._expandClickHandler = Function.createDelegate(this, this._expandPanel);
        }

        if (this._collapseControl)
            $addHandler(this._collapseControl, 'click', this._collapseClickHandler);

        if (this._expandControl && this._expandClickHandler)
            $addHandler(this._expandControl, 'click', this._expandClickHandler);


        var lastState = Pacem.UI.CollapsiblePanelBehavior.callBaseMethod(this, 'get_ClientState');
        var raise = false;
        if (lastState && lastState != '') {
            var lastValue = Boolean.parse(lastState);
            if (lastValue != this._collapsed) {
                this._collapsed = lastValue;
                raise = true;
            }
        }

        this._setupCoherentAppearance();
        if (this._collapsed) {
            element.style.height = "0px";
            if (raise) {
                this.raiseCollapsed(Sys.EventArgs.Empty);
            }
        } else {
            element.style.height = 'auto';
            // Firefox messes up the layout if I show the elements having overflow hidden and height 0 (!?)
            Sys.UI.DomElement.setVisible(this._childDiv, true);
            Sys.UI.DomElement.setVisible(element, true);
            if (raise) {
                this.raiseExpanded(Sys.EventArgs.Empty);
            }
        }
    },

    dispose: function() {
        if (this._collapseClickHandler) {
            if (this._collapseControl)
                $removeHandler(this._collapseControl, 'click', this._collapseClickHandler);
            this._collapseClickHandler = null;
        }
        if (this._expandClickHandler) {
            if (this._expandControl)
                $removeHandler(this._expandControl, 'click', this._expandClickHandler);
            this._expandClickHandler = null;
        }
        //
        Pacem.UI.CollapsiblePanelBehavior.callBaseMethod(this, 'dispose');
    },

    _setupChildDiv: function() {

        var e = this.get_element();
        this._childDiv = e.cloneNode(false);
        this._childDiv.id = '';
        // move all children into the div.
        while (e.hasChildNodes()) {
            var child = e.childNodes[0];
            child = e.removeChild(child);
            this._childDiv.appendChild(child);
        }
        //On Parent
        e.style.padding = "";
        e.style.border = "";
        e.style.overflow = 'hidden';
        e.className = '';
        //Delete some style after cloneNode
        //On Clone
        this._childDiv.style.position = "";
        this._childDiv.style.margin = "";

        e.appendChild(this._childDiv);
    },
    togglePanel: function() {
        if (this._collapsed)
            this.expandPanel();
        else
            this.collapsePanel();
    },
    _togglePanel: function(evt) {
        if (this._suppressPostBack) {
            evt.preventDefault();
            evt.stopPropagation();
        }
        this.togglePanel();
    },
    expandPanel: function() {
        Sys.UI.DomElement.setVisible(this._childDiv, true);
        Sys.UI.DomElement.setVisible(this.get_element(), true);
        var bounds0 = Sys.UI.DomElement.getBounds(this.get_element());
        var bounds1 = Sys.UI.DomElement.getBounds(this._childDiv);
        this._doTween(bounds0.height, bounds1.height, this._expandStarted, this._expandFinished);
    },
    _expandPanel: function(evt) {
        if (this._suppressPostBack) {
            evt.preventDefault();
            evt.stopPropagation();
        }
        this.expandPanel();
    },
    collapsePanel: function(evt) {
        Sys.UI.DomElement.setVisible(this._childDiv, true);
        Sys.UI.DomElement.setVisible(this.get_element(), true);
        var bounds0 = Sys.UI.DomElement.getBounds(this.get_element());
        this._doTween(bounds0.height, 0, this._collapseStarted, this._collapseFinished);
    },
    _collapsePanel: function(evt) {
        if (this._suppressPostBack) {
            evt.preventDefault();
            evt.stopPropagation();
        }
        this.collapsePanel();
    },
    _doTween: function(start, finish, func_ing, func_ed) {
        if (this._tween && this._tween.get_status() == Pacem.UI.TweenStatus.playing) {
            this._tween.pause();
            this._tween["collapsibleBehavior"] = null;
        }
        if (this._tween)
            this._tween.dispose();
        this._tween = $create(Pacem.UI.Tween,
            { 'isCssProperty': true, 'easingFunc': this._easingFunc, 'property': 'height', 'unit': Pacem.UI.Unit.pixels, 'start': start, 'finish': finish, 'duration': this._animationDuration },
            { 'motionStarted': func_ing, 'motionFinished': func_ed }, null, this.get_element());
        this._tween["collapsibleBehavior"] = this;
    },
    _setClientState: function() {
        var value = this._collapsed.toString();
        Pacem.UI.CollapsiblePanelBehavior.callBaseMethod(this, 'set_ClientState', [value]);
    },

    _expandStarted: function(sender, args) {
        sender["collapsibleBehavior"].raiseExpanding(Sys.EventArgs.Empty);
    },
    _collapseStarted: function(sender, args) {
        sender["collapsibleBehavior"].raiseCollapsing(Sys.EventArgs.Empty);
    },
    _expandFinished: function(sender, args) {
        var me = sender["collapsibleBehavior"];
        me._setupState(false);
        me.get_element().style.height = 'auto';
        me.raiseExpanded(Sys.EventArgs.Empty);
    },
    _collapseFinished: function(sender, args) {
        var me = sender["collapsibleBehavior"];
        me._setupState(true);
        me.raiseCollapsed(Sys.EventArgs.Empty);
    },
    _setupState: function(collapsed) {
        this._collapsed = collapsed;
        this._setupCoherentAppearance();
        this._setClientState();
    },
    _setupCoherentAppearance: function() {
        var img = this._collapsed ? this._collapsedImage : this._expandedImage;
        var txt = this._collapsed ? this._collapsedText : this._expandedText;
        if (this._imageControl && this._imageControl.src && img) {
            this._imageControl.src = img;
            this._imageControl.title = txt;
        }
        if (this._textLabel)
            this._textLabel.innerHTML = txt;
    },

    add_collapsing: function(handler) {
        /// <summary>
        /// Add an event handler for the collapsing event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// Event handler
        /// </param>
        /// <returns />
        this.get_events().addHandler('collapsing', handler);
    },
    remove_collapsing: function(handler) {
        /// <summary>
        /// Remove an event handler from the collapsing event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// Event handler
        /// </param>
        /// <returns />
        this.get_events().removeHandler('collapsing', handler);
    },
    raiseCollapsing: function(eventArgs) {
        /// <summary>
        /// Raise the collapsing event
        /// </summary>
        /// <param name="eventArgs" type="Sys.CancelEventArgs" mayBeNull="false">
        /// Event arguments for the collapsing event
        /// </param>
        /// <returns />
        var handler = this.get_events().getHandler('collapsing');
        if (handler) {
            handler(this, eventArgs);
        }
    },

    add_collapsed: function(handler) {
        /// <summary>
        /// Add an event handler for the collapsed event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// Event handler
        /// </param>
        /// <returns />
        this.get_events().addHandler('collapsed', handler);
    },
    remove_collapsed: function(handler) {
        /// <summary>
        /// Remove an event handler from the collapsed event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// Event handler
        /// </param>
        /// <returns />
        this.get_events().removeHandler('collapsed', handler);
    },
    raiseCollapsed: function(eventArgs) {
        /// <summary>
        /// Raise the collapsed event
        /// </summary>
        /// <param name="eventArgs" type="Sys.EventArgs" mayBeNull="false">
        /// Event arguments for the collapsed event
        /// </param>
        /// <returns />
        var handler = this.get_events().getHandler('collapsed');
        if (handler) {
            handler(this, eventArgs);
        }
    }, add_expanding: function(handler) {
        /// <summary>
        /// Add an event handler for the expanding event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// Event handler
        /// </param>
        /// <returns />
        this.get_events().addHandler('expanding', handler);
    },
    remove_expanding: function(handler) {
        /// <summary>
        /// Remove an event handler from the expanding event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// Event handler
        /// </param>
        /// <returns />
        this.get_events().removeHandler('expanding', handler);
    },
    raiseExpanding: function(eventArgs) {
        /// <summary>
        /// Raise the expanding event
        /// </summary>
        /// <param name="eventArgs" type="Sys.CancelEventArgs" mayBeNull="false">
        /// Event arguments for the expanding event
        /// </param>
        /// <returns />
        var handler = this.get_events().getHandler('expanding');
        if (handler) {
            handler(this, eventArgs);
        }
    },

    add_expanded: function(handler) {
        /// <summary>
        /// Add an event handler for the expanded event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// Event handler
        /// </param>
        /// <returns />
        this.get_events().addHandler('expanded', handler);
    },
    remove_expanded: function(handler) {
        /// <summary>
        /// Remove an event handler from the expanded event
        /// </summary>
        /// <param name="handler" type="Function" mayBeNull="false">
        /// Event handler
        /// </param>
        /// <returns />
        this.get_events().removeHandler('expanded', handler);
    },
    raiseExpanded: function(eventArgs) {
        /// <summary>
        /// Raise the expanded event
        /// </summary>
        /// <param name="eventArgs" type="Sys.EventArgs" mayBeNull="false">
        /// Event arguments for the expanded event
        /// </param>
        /// <returns />
        var handler = this.get_events().getHandler('expanded');
        if (handler) {
            handler(this, eventArgs);
        }
    },

    get_isCollapsed: function() {
        /// <value type="Boolean">
        /// Whether or not the panel is collapsed
        /// </value>
        return this._collapsed;
    },
    set_isCollapsed: function(value) {
        this._collapsed = value;
    },

    get_collapseControl: function() {
        /// <value type="String">
        /// The control used to collapse the target when clicked
        /// </value>
        return this._collapseControl;
    },
    set_collapseControl: function(value) {
        this._collapseControl = value;
    },

    get_expandControl: function() {
        /// <value type="String">
        /// The control used to expand the target when clicked
        /// </value>
        return this._expandControl;
    },
    set_expandControl: function(value) {
        this._expandControl = value;
    },

    get_animationDuration: function() {
        /// <value type="Boolean">
        /// Whether to add a scrollbar when the contents are larger than the target (the contents will be clipped if false)
        /// </value>
        return this._animationDuration;
    },
    set_animationDuration: function(value) {
        this._scrollContents = value;
    },

    get_suppressPostBack: function() {
        /// <value type="Boolean">
        /// Whether or not to suppress postbacks generated when the collapseControl or expandControl elements are clicked
        /// </value>
        return this._suppressPostBack;
    },
    set_suppressPostBack: function(value) {
        this._suppressPostBack = value;
    },

    get_textLabel: function() {
        /// <value type="String">
        /// The element where the "status text" for the target will be placed
        /// </value>
        return this._textLabel;
    },
    set_textLabel: function(value) {
        this._textLabel = value;
    },

    get_expandedText: function() {
        /// <value type="String">
        /// Text to show in the textLabel when the target is expanded.  This text is also used as the alternate text of the image if ImageControlID has been provided.
        /// </value>
        return this._expandedText;
    },
    set_expandedText: function(value) {
        this._expandedText = value;
    },

    get_collapsedText: function() {
        /// <value type="String">
        /// Text to show in the textLabel when the target is collapsed.  This text is also used as the alternate text of the image if ImageControlID has been provided.
        /// </value>
        return this._collapsedText;
    },
    set_collapsedText: function(value) {
        this._collapsedText = value;
    },

    get_imageControl: function() {
        /// <value type="String">
        /// The <img> element where an icon indicating the collapsed status of the target will be placed
        /// </value>
        return this._imageControl;
    },
    set_imageControl: function(value) {
        this._imageControl = value;
    },

    get_expandedImage: function() {
        /// <value type="String">
        /// Path to an image to show in the imageControl when the target is expanded
        /// </value>
        return this._expandedImage;
    },
    set_expandedImage: function(value) {
        this._expandedImage = value;
    },

    get_collapsedImage: function() {
        /// <value type="String">
        /// Path to an image to show in the imageControl when the target is collapsed
        /// </value>
        return this._collapsedImage;
    },
    set_collapsedImage: function(value) {
        this._collapsedImage = value;
    }

    //    get_autoExpand: function() {
    //        /// <value type="Boolean">
    //        /// Whether to automatically expand the target when the mouse is moved over it
    //        /// </value>
    //        return this._autoExpand;
    //    },
    //    set_autoExpand: function(value) {
    //        this._autoExpand = value;
    //    },

    //    get_autoCollapse: function() {
    //        /// <value type="Boolean">
    //        /// Whether to automatically collapse the target when the mouse is moved off of it
    //        /// </value>
    //        return this._autoCollapse;
    //    },
    //    set_autoCollapse: function(value) {
    //        this._autoCollapse = value;
    //    }
}
Pacem.UI.CollapsiblePanelBehavior.registerClass('Pacem.UI.CollapsiblePanelBehavior', AjaxControlToolkit.BehaviorBase);

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();