if (!ask) var ask = {};
if (!ask.ui) ask.ui = {};

/****************************************************************************************
 * [Class: DialogBase]
 * DialogBase is the base class for ask.ui.AjaxDialog and ask.ui.Dialog.  It contains
 * code that's common between the AjaxDialog and Dialog. 
 ****************************************************************************************/

/**
 * Constructor for DialogBase.  For what the arguments mean, see
 * the constructor comments for AjaxDialog and Dialog.
 */
ask.ui.DialogBase = function(id, title, width, options) {
    this.id = id;
    this.title = title;
    this.width = width;
    this.options = options || {};
    this.cover = null; // iframe cover for IE6

    var _this = this;
    this.closeButtonHandler = this.options.closeButtonHandler || function() { _this.hide() };
    this.windowResizedHandler = function() { _this.windowResized() };
    this.windowScrolledHandler = function () { _this.windowScrolled() };
};

/**
 * Class Variables
 */
a10.util.extend(ask.ui.DialogBase, {
    JSP_PREFIX: 'http://' + GlobalNav.Constants.askDomain + '/',
    SCRIPT_PREFIX: 'inc/js/a10f/dialogs/'
});

/**
 * Instance Methods
 */
a10.util.extend(ask.ui.DialogBase.prototype, {
    /**
     * Contains show() logic shared by both AjaxDialog and Dialog.  It's meant to be
     * extended by the subclasses.  
     */
    show: function() {
        var _this = this;
        
        if (ask.closeAllPopUps) ask.closeAllPopUps();
        $('dialogTitle').innerHTML = this.title;

        a10.event.addListener($('dialogCloseButton'), 'click', this.closeButtonHandler);
        a10.event.addListener(window, 'resize', this.windowResizedHandler);
        a10.event.addListener(window, "scroll", this.windowScrolledHandler);

        $('dialogContent').style.padding = this.options.noDefaultPadding? '0' : '';
    },

    /**
     * This method is called by the subclasses's implementations of show()
     * after the content is swapped in.  It makes the dialog visible on screen. 
     */
    afterSwap: function() {
        if (a10.browser.isIE6() && this.width) $('dialog').style.width = this.width + 'px';

        this.centerDialog(true);

        this.updateLightBoxCoverSize();
        a10.element.show('lightboxCover');
        a10.element.show('lightbox');

        if (a10.browser.isIE6()) {
            if (!this.cover) this.cover = new a10.IFrameCover('dialog');
            this.cover.show();
        }

        if (this.options.focusOn) {
            var elt = a10.form.getElements(this.options.focusOn)[0];
            try {
                elt.focus();
            } catch (e) {
                //ignore if can't focus on element
            }
        }
    },

    /**
     * Contains hide() logic shared by both AjaxDialog and Dialog.  It's meant to be
     * extended by the subclasses.
     */
    hide: function() {
        a10.event.removeListener($('dialogCloseButton'), 'click', this.closeButtonHandler);
        a10.event.removeListener(window, 'resize', this.windowResizedHandler);        
        a10.event.removeListener(window, "scroll", this.windowScrolledHandler);

        // Clear styles that may have been overridden
        $('dialogContent').style.padding = '';
        $('dialog').style.width = '';

        if (a10.browser.isIE6()) this.cover.hide();
        a10.element.hide('lightboxCover');
        a10.element.hide('lightbox');

         if(this.options && this.options.onAfterClose) {
            this.options.onAfterClose();
        }
    },

    /**
     * Centers the dialog on screen.  
     */
    centerDialog: function(forced) {
        var windowDim = a10.browser.innerDimension();

        var lightbox = $("lightbox");

        if(lightbox && (lightbox.style.display != 'none' || forced)){
            lightbox.style.left = 400 + "px";
            var top = 100;

            if(a10.browser.isIE6()){
               top += a10.util.scrollTop();
            }

            if(top < 0) top = 0; //set top to a non-negative num, else the top of the dialog will be hidden

            lightbox.style.top = top + "px";
            if (a10.browser.isIE6()) {
                if (this.cover) this.cover.reposition();
            }
        }
    },

    /**
     * An IE6-only hack.  IE6 uses absolute instead of fixed position for the lightbox cover.  For some
     * reason, the setting its height to 100% doesn't cover the entire page.  This function
     * is thus needed to calculate the page height and set the height of lightbox cover explicitly.
     */
    updateLightBoxCoverSize: function() {
        if (!a10.browser.isIE6()) return; 

        var cover = $('lightboxCover');

        var lrail = $('leftRail');
        var mrail = $('midRail');
        var rrail = $('rightRail');

        var maxh;
        if(lrail) {
            //reply page
            var lh = lrail.offsetTop + lrail.offsetHeight;
            var mh = mrail.offsetTop + mrail.offsetHeight;
            var rh = rrail.offsetTop + rrail.offsetHeight;
            maxh = lh;
            if (mh > maxh) maxh = mh;
            if (rh > maxh) maxh = rh;
        } else {
            //normal pages
            maxh = document.body.offsetHeight;
        }

        cover.style.height = maxh +"px";
    },

    windowResized: function() {
        this.updateLightBoxCoverSize();
        this.centerDialog();
    },

    windowScrolled: function() {
        if(a10.browser.isIE6() ){  //Emulated fixed position for IE6 only
            this.centerDialog();
        }
    }
});



/****************************************************************************************
 * [Class: AjaxDialog]
 * AjaxDialog differs from Dialog in that it loads its content via an AJAX request
 * after the user invokes the dialog.  For a tutorial on its usage, see:
 * https://intranet.iacsam.com/wiki/display/SiteEng/Modal+Dialog. The API documentation
 * below assumes you have read this document. 
 ****************************************************************************************/

/**
 * Constructor for AjaxDialog.  
 *
 * @id the special ID that identifies the HTML and JavaScript files to load.
 * @title title to display in the dialog's title bar.
 * @width width (in pixels) of the dialog.  This argument is used by IE6 only, to workaround
 *        an IE6 bug where if no width is specified, the dialog would expand to the
 *        full width of the page.  For all other browsers (IE7 included), the width of the
 *        dialog is automatically calculated from its content.  It is useful, during prototyping,
 *        to set this argument to null and test on a non-IE6 browser until the proper width is
 *        determined. 
 * @options a hash of additional options:
 *
 *          Options             Description
 *          js                  Additional external JavaScripts to include.  Specified as URLs
 *                              in an array.
 *          disableCache        Disables browser caching of the asychronously loaded content HTML
 *                              and JavaScript.  Should be specified when the content is expected
 *                              to change.  Default is false.
 *          focusOn             ID of the form to focus on.
 *          noDefaultPadding    Disable the default padding around the content area.  By default
 *                              the content area has some padding around it.
 *          closeButtonHandler  Supply a custom handler (function reference) for the close button
 *                              (the 'x' button on the title bar).  The default handler simply closes
 *                              the dialog.  This can be useful when you want some additional logic
 *                              to be performed before or after the dialog closes.  
 */
ask.ui.AjaxDialog = function(id, title, width, options) {
    ask.ui.AjaxDialog.baseConstructor.call(this, id, title, width, options);
};

a10.util.subclass(ask.ui.AjaxDialog, ask.ui.DialogBase);

/**
 * Instance Methods
 */
a10.util.extend(ask.ui.AjaxDialog.prototype, {
    show: function() {
        // Need to declare _this before the AJAX request for the content is sent.  Because
        // if the content is cached by the browser, the call to a10.ajax.get() will execute
        // onSuccess() immediately before _this is actually defined, resulting in an object
        // not found error.  This problem was observed on IE7.  
        var _this = this;

        ask.ui.AjaxDialog.superClass.show.call(this);

        // Request content and swap it in on success
        var cacheBuster = this.options.disableCache? '?cacheBuster=' + new Date().getTime() : '';
        a10.ajax.get(ask.ui.DialogBase.JSP_PREFIX + this.id + cacheBuster, onSuccess, onFailure);

        function onSuccess(response) {
            $('dialogContent').innerHTML = response.responseText;

            a10.util.insertScript(ask.ui.DialogBase.SCRIPT_PREFIX + _this.id + '.js', 'modalDialogScript');
            if (_this.options.js) {
                for (var i=0; i<_this.options.js.length; i++) {
                    a10.util.insertScript(_this.options.js[i], 'modalDialogScript');
                }
            }

            _this.afterSwap();
        }

        function onFailure(response) {
            alert("Failed to retrieve dialog contant: " +  response.statusText);
        }

    },
    hide: function() {
        if(this.options && this.options.onClose && !this.options.onClose()) {
            //onclose event handler requesting to keep the dialog open
            return;
        }

        // Remove the JavaScripts loaded for this dialog, as it may interfere with
        // other JavaScripts on the page or subsequently opened dialogs.
        a10.util.removeElementsWithClass('modalDialogScript');
        ask.ui.AjaxDialog.superClass.hide.call(this);
    }
});


/****************************************************************************************
 * [Class: Dialog]
 * Unlike AjaxDialog, Dialog has its content embedded in the page.  For a tutorial on its usage,
 * see: https://intranet.iacsam.com/wiki/display/SiteEng/Modal+Dialog. The API documentation
 * below assumes you have read this document.
 ****************************************************************************************/

/**
 * Constructor for Dialog.
 *
 * @id ID of the content fragment element.
 * @title See AjaxDialog.
 * @width  See AjaxDialog.
 * @options see AjaxDialog. 
 */
ask.ui.Dialog = function(id, title, width, options) {
    ask.ui.Dialog.baseConstructor.call(this, id, title, width, options);
};

a10.util.subclass(ask.ui.Dialog, ask.ui.DialogBase);

/**
 * Instance Methods
 */
a10.util.extend(ask.ui.Dialog.prototype, {
    show: function() {
        
        ask.ui.Dialog.superClass.show.call(this);

        // Swap in content
        $('dialogContent').innerHTML = '';
        $('dialogContent').appendChild($(this.id));
        a10.element.show(this.id);

        this.afterSwap();
    },

    /**
     * This function, other than hiding the dialog, will preserve its content (the element
     * whose ID is specified in the constructor) by moving it into the document's body and
     * making it invisible.  That way, if the dialog is invoked again, the content will still be there. 
     */
    hide: function() {
        if(this.options && this.options.onClose && !this.options.onClose()) {
            //onclose event handler requesting to keep the dialog open
            return;
        }

        var content = $('dialogContent').firstChild;
        a10.element.hide(content);
        document.body.appendChild(content); // Preserve content

        ask.ui.Dialog.superClass.hide.call(this);
    }
});


/**
 * Invoke the callback function dialogLoaded(). 
 */
if (typeof dialogLoaded != "undefined") {

    dialogLoaded();
}


