/*
* easy_apache.js                                  Copyright(c) 2013 cPanel, Inc.
*                                                           All rights Reserved.
* copyright@cpanel.net                                         http://cpanel.net
* This code is subject to the cPanel license. Unauthorized copying is prohibited
*/

var SELECT = YAHOO.util.Selector;
var EVENT = YAHOO.util.Event;
var DOM = YAHOO.util.Dom;
// Add namespace function to CPANEL namespace if it is not already defined.
// (This handles namespace support for cPanel 11.32 version)
if(CPANEL && !CPANEL.namespace) {
    CPANEL.namespace = function() {
        var a = arguments, o = null, i, j, d;
        for (i = 0; i < a.length; i = i + 1) {
            d = ("" + a[i]).split(".");
            o = window["CPANEL"];

            // CPANEL is implied, so it is ignored if it is included
            for (j = (d[0] === "CPANEL") ? 1 : 0; j < d.length; j = j + 1) {
                // Only create if it doesn't already exist
                o[d[j]] = o[d[j]] || {};
                o = o[d[j]];
            }
        }
        return o;
    };
}

// Add namespace for ea
CPANEL.namespace("CPANEL.ea");

/**
 * A module wrapper which wraps all the functionality for Easy Apache
 * Web User Interface.
 *
 * It contains some functionality used commonly throughout the wizard.
 */
(function(){

    var showText = " Show Info ",
    hideText = " Hide Info ",
    showDetailClass = "showDetail",
    hideDetailClass = "hideDetail",
    detailClass = "description",

    /**
     * Checks and unchecks all checkboxes within given 'container'
     * element, based on the provided 'state'.
     * @private
     * @param  {boolean} state  true: check, false: uncheck
     * @param  {HTMLElement} container The div element that contains checkbox list
     */
    _toggleCheckAll = function(state, container){
        if(container) {
            var checkList = SELECT.query("input[type=checkbox]", container);
            if(checkList && checkList.length>0){
                DOM.batch(checkList, function(chkbox){
                    chkbox.checked = state;
                });
            }
        }
    },

    /**
     * Shows/Hides details for the options
     * provided in the EA wizard steps.
     * @private
     * @param  {boolean} show
     * @param  {object} data - {container, linkIdSuffix}
     */
    _toggleDetail = function(show, data) {
        var displayStyle = "",
            linkText = "",
            linkCss = "",
            replaceCss = "";

        // Set variables for show/hide
        if(show){
            linkText = hideText;
            linkCss = hideDetailClass;
            replaceCss = showDetailClass;
        } else {
            displayStyle = "none";
            linkText = showText;
            linkCss = showDetailClass;
            replaceCss = hideDetailClass;
        }

        if(data) {
            var linkEl = SELECT.query("a[id^=" + data.linkIdSuffix + "]", data.container, true);
            var desc = SELECT.query("." + detailClass, data.container, true);
            if(desc){
                DOM.setStyle(desc, "display", displayStyle);
            }

            if(linkEl){
                linkEl.innerHTML = linkText;
                DOM.replaceClass(linkEl, replaceCss, linkCss);
            }
        }
    },

    /**
     * Opens a YUI dialog to ask for confirmation
     * @private
     * @param  {HTMLElement} button
     */
    confirmBuild = function(button) {
        _yuiDialog("Confirm Action",
            "Recompile Apache and PHP now?",
            "Ok", "Cancel", _recompileOk, _cancelConfirm, button );

        return false;
    },

    /**
     * Handle actions when ok is clicked in acknowledge dialog.
     * @private
     */
    _acknowledgeOk = function(e, submitButton) {

        if(submitButton){
            submitButton.onclick = function() { return true; };
            submitButton.click();
        }
    },

    /**
     * Handle actions when ok is clicked in recompile confirmation
     * dialog.
     * @private
     */
    _recompileOk = function(e, okData){

        _yuiDialog("Please acknowledge ",
            "<p class='errors'>Termination of the build process will result in data loss! The build process is designed to run in the background until complete. Prematurely killing this process will leave your Apache configuration in an unusable state requiring restoration from backups.</p>",
            "I Understand",
            "Go Back", _acknowledgeOk, _cancelConfirm, okData);

        this.hide();
    },

    /**
     * Handles when cancel is clicked in a dialog.
     * @private
     */
    _cancelConfirm = function(){
        this.hide();
    },

    /**
     * Creates a dialog using provided args and some addtional stuff.
     * @private
     * @param  {string} titleText
     * @param  {string} bodyText
     * @param  {string} okText
     * @param  {string} cancelText
     * @param  {object} okFunc
     * @param  {object} cancelFunc
     * @param  {object} okData
     * @param  {object} cancelData
     */
    _yuiDialog = function(titleText, bodyText, okText, cancelText, okFunc, cancelFunc, okData, cancelData) {
        var okHandler = okData ? { fn: okFunc, obj: okData} : okFunc;

        var cancelHandler = cancelData ? { fn: cancelFunc, obj: cancelData} : cancelFunc;
        var plainBodyText = _decodeHtml(bodyText);

        // Instantiate the Dialog
        var yuiConfirmBox = new YAHOO.widget.SimpleDialog(
        "yuiConfirmBox",
        {
            width: "300px",
            fixedcenter: true,
            visible: false,
            draggable: false,
            close: false,
            text: plainBodyText,
            modal: true,
            constraintoviewport: true,
            buttons: [
                { text: okText, handler: okHandler, isDefault: true },
                { text: cancelText,  handler: cancelHandler }
            ]
        } );

        yuiConfirmBox.setHeader(titleText);

        // Render the Dialog
        yuiConfirmBox.render(document.body);
        yuiConfirmBox.show();
    },

    /**
     * Returns the right sourceElement of the given
     * event object. This method addresses the browser
     * compatibility issues.
     * @param  {Event} eventObj
     * @return {HTMLElement}
     */
    _getSourceElement = function(eventObj){
        var source = null;
        if(!eventObj){
            return;
        }

        if(eventObj.target){
            source = eventObj.target;
        } else if(eventObj.srcElement){
            source = eventObj.srcElement;
        }
        return source;
    },

    /**
     * Decodes the given html encoded string.
     *
     * @method
     * @param  {String} value
     * @return {String}
     */
    _decodeHtml = function(value){
        var tempEl = document.createElement("span");
        tempEl.innerHTML = value;
        var plain_text = CPANEL.util.get_text_content(tempEl);
        return plain_text;
    },

    _displayPopup = function(popupId, headerText) {
        if( !popupId ){
            return;
        }

        // Instantiate the Dialog
        var yuiConfirmBox = new YAHOO.widget.SimpleDialog(
        popupId,
        {
            width: "500px",
            fixedcenter: true,
            visible: false,
            draggable: false,
            close: false,
            modal: true,
            constraintoviewport: true,
            buttons: [
                { text: "Close", handler: function(){this.hide();}, isDefault: true }
            ]
        } );

        yuiConfirmBox.setHeader(headerText);
        yuiConfirmBox.render();
        yuiConfirmBox.show();
    };


    /**
     * Class that provides functionality used by List profiles
     * step (Step 1) in Easy Apache wizard page.
     *
     * @class ListProfiles
     * @constructor
     */
    var ListProfiles = function(config) {
        // Safe exit if config is not provided.
        if(!config){
            return;
        }

        this.openSSLBug = config.openSSLBug || false;
        this.isOldProfile = config.isOldProfile || false;
        this.eaHelpUrl = config.eaHelpUrl || "http://go.cpanel.net/eaissues";
        this.warningPopupId = config.warningPopupId;
        this.showWarning = config.showWarningPopup;
        this.profileClassName = config.profileClassName || "";
        this.descLinkIdSuffix = config.descLinkIdSuffix;
        this.buildButtonId = config.buildButtonId;
        this.profileOptions = null;
        this.buildBtn = null;

        // Initializes the new instance.
        this.init();
    };

    /**
     * @class ListProfiles
     * @prototype
     */
    ListProfiles.prototype = {

        /**
         * Initializes the List profiles step in EA Wizard page.
         */
        init : function(){
            if(this.openSSLBug) {
                window.open(this.eaHelpUrl);
            }

            if(this.showWarning) {
                DOM.setStyle(this.warningPopupId, "display", "block");
                _displayPopup(this.warningPopupId, "Warning");
            }

            this.profileOptions = SELECT.query("." + this.profileClassName, document);
            this.buildBtn = SELECT.query("#" + this.buildButtonId, document, true);

            this.wireupEvents();
        },

        /**
         * Wireup events for elements in list profiles step.
         */
        wireupEvents : function(){
            var lpObj = this;
            if( this.profileOptions && this.profileOptions.length > 0 ){
                this.profileOptions.forEach(function(option){
                    var linkEl = SELECT.query("a[id^=" + lpObj.descLinkIdSuffix + "]", option, true);

                    if(lpObj.isOldProfile) {
                        var inputEl = SELECT.query("input[type=radio]", option, true);

                        EVENT.addListener([inputEl, linkEl], "click", lpObj.handleShowDetail,
                        {
                            container: option,
                            linkIdSuffix: lpObj.descLinkIdSuffix,
                            isOldProfile: lpObj.isOldProfile
                        });
                    } else {
                        EVENT.addListener(linkEl, "click", lpObj.handleShowDetail);
                    }
                });
            }
        },

        /**
         * Handles show/hide details when the radio input/link is clicked.
         * @param  {Event} e
         */
        handleShowDetail : function(e, obj){
            if(obj && obj.isOldProfile) {
                var source = _getSourceElement(e);
                if(!source){
                    return;
                }

                if(source.tagName ===  "INPUT") {
                    _toggleDetail(true, obj);
                } else if(source.tagName === "A"){
                    if(DOM.hasClass(source, showDetailClass)){
                        _toggleDetail(true, obj);
                    } else{
                        _toggleDetail(false, obj);
                    }
                }
            } else {
                var profile = DOM.getAttribute(this, "value");
                display_quickpopupbox("Profile Details",
                "<iframe class=popupFrame src=easyapache.pl?skip-cpanelsync=1&action=show_all_features&profile=" + profile + " />");                
            }
        }
    };


    /**
     * Class that provides functionality used by List profiles
     * step (Step 1) in Easy Apache wizard page.
     *
     * @class ListApache
     * @constructor
     */
    var ListApache = function(config) {
        // Safe exit if config is not provided.
        if(!config){
            return;
        }

        this.versionBlockClass = config.versionBlockClass || "";
        this.detLinkIdSuffix = config.detLinkIdSuffix;
        this.selectedVersion = config.selectedVersion;
        this.verifyOptionList = config.verifyOptions || null;
        this.optionBlocks = null;

        // Initializes the new instance.
        this.init();
    };

    /**
     * @class ListApache
     * @prototype
     */
    ListApache.prototype = {

        /**
         * Initializes the List profiles step in EA Wizard page.
         */
        init : function(){
            this.optionBlocks = SELECT.query("." + this.versionBlockClass, document);

            this.wireupEvents();
        },

        /**
         * Wireup events for elements in list profiles step.
         */
        wireupEvents : function(){
            var lapObj = this;

            if( this.optionBlocks && this.optionBlocks.length > 0 ){

                this.optionBlocks.forEach(function(option){
                    var inputEl = SELECT.query("input[type=radio]", option, true);
                    var linkEl = SELECT.query("a[id^=" + lapObj.detLinkIdSuffix + "]", option, true);

                    // For each option block, add show/hide action to the radio button &
                    // toggle link.
                    EVENT.addListener([inputEl, linkEl], "click", lapObj.handleShowDetail,
                        {
                            container: option,
                            linkIdSuffix: lapObj.detLinkIdSuffix
                        });


                    var verifyOptionIndex,
                        verifyList = lapObj.verifyOptionList;

                    // Find the options with special verify condition
                    // (present in verifyOptionList array) and apply verify action
                    // to their corresponding click events.
                    for (var i = 0, l = verifyList.length; i < l; i++){
                        if(inputEl.id === verifyList[i].id){
                            verifyOptionIndex = i;
                            break;
                        }
                    }

                    if(verifyOptionIndex >= 0 && verifyOptionIndex < verifyList.length) {

                        // Add event to input option if it exists in verify list.
                        EVENT.addListener(inputEl, "click", lapObj.handleVerifyOption,
                        {
                            lapObj : lapObj,
                            verifyOptionIndex : verifyOptionIndex
                        });
                    } else {
                        EVENT.addListener(inputEl, "click", function(){
                            lapObj.updateSelectedVersion(inputEl.value);
                        });
                    }

                });
            }
        },

        /**
         * Handles show/hide details when the radio input/link is clicked.
         * @param  {Event} e
         * @param  {HTMLElement} obj - option container
         */
        handleShowDetail : function(e, obj){
            var source = _getSourceElement(e);
            if(!source){
                return;
            }

            if(source.tagName ===  "INPUT") {
                _toggleDetail(true, obj);
            } else if(source.tagName === "A"){
                if(DOM.hasClass(source, showDetailClass)){
                    _toggleDetail(true, obj);
                } else{
                    _toggleDetail(false, obj);
                }
            }
        },

        /**
         * Handles show a confirm box to verify the select/unselect action of
         * certain apache version option.
         * @param  {Event} e
         * @param  {object} obj contains ListApache's instance and a config obj
         *         that has the data to verify.
         *         ( obj = {lapObj, verifyOptionIndex} )
         */
        handleVerifyOption : function(e, obj){
            if(obj !== null){
                var lapObj = obj.lapObj,
                    index = obj.verifyOptionIndex;

                if(lapObj !== null) {
                    lapObj.verifyOption(this,
                        lapObj.verifyOptionList[index].onObj,
                        lapObj.verifyOptionList[index].offObj
                    );
                }
            }
        },

        /**
         * verifyOption
         * @param  {HTMLElement} optionEl selected radio element
         * @param  {object} on_obj contains ( {text, url} )
         * @param  {object} off_obj contains ( {text, url} )
         */
        verifyOption : function(optionEl, on_obj, off_obj) {

            var data = {
                lapObj: this,
                element: optionEl
            };

            if (on_obj && optionEl.checked) {
                var onText = on_obj.text;

                if( on_obj.url ){
                    onText = onText + "(" + on_obj.url + ")";
                }

                _yuiDialog("Confirm Action", onText, "Ok", "Cancel", this.verifyOk, this.verifyCancel, data, data);
            }

            if (off_obj && !optionEl.checked) {
                var offText = off_obj.text;

                if( off_obj.url ){
                    offText = offText + "(" + off_obj.url + ")";
                }

                _yuiDialog("Confirm Action", offText, "Ok", "Cancel", this.verifyCancel, this.verifyOk, data, data);
            }
            return false;
        },

        /**
         * verifyOk This handler function handles
         * operations that should happen when 'OK' button is clicked in the
         * confirmation box when Apache version is updated to 2.4.
         */
        verifyOk : function(e, oData){
            // Here, yui dialog is the context of 'this'.
            this.hide();

            if(oData && oData.lapObj && oData.element){
                oData.lapObj.updateSelectedVersion(oData.element.value);
            }
        },

        /**
         * verifyCancel This handler function handles
         * operations that should happen when 'Cancel' button is clicked in the
         * confirmation box when Apache version is updated to 2.4.
         */
        verifyCancel : function(e, oData) {
            // Here, yui dialog is the context of 'this'.
            this.hide();

            if(oData && oData.lapObj && oData.element){
                var lapObj = oData.lapObj,
                    allRadioBtns = SELECT.query("form input[type=radio]", document);

                // Filter out exactly apache named radio button list.
                if(allRadioBtns){
                    var options = SELECT.filter(allRadioBtns,
                                    "[name=" + oData.element.name + "]");
                    if(options) {
                        var selectOption = SELECT.filter(options, "[value=" + lapObj.selectedVersion + "]");
                        if(selectOption && selectOption.length > 0){
                            selectOption[0].checked = true;
                        }
                    }
                }
            }

        },

        /**
         * Update the selected apache version into the hidden field
         * 'selectedOption' which is used to reset back to the right version if
         * Verify Popup is cancelled
         *
         * @param - {string} newValue New apache version selected.
         */
        updateSelectedVersion : function(newValue){
            this.selectedVersion = newValue;

            return false;
        }
    };

    /**
     * Provides functionality used by Build log Manager page.
     *
     * @class BuildProfileMgr
     * @constructor
     */
    var BuildProfileMgr = function(config) {
        // Safe exit if config is not provided.
        if(!config){
            return;
        }

        this.currNamespace = config.currNamespace;
        this.currStep = config.currStep;
        this.buildStatusId = config.buildStatusId;
        this.outputLabelId = config.outputLabelId;
        this.chkResizeId = config.chkResizeId;
        this.disableScrollId = config.disableScrollId;
        this.iframeContainerId = config.iframeContainerId;
        this.refreshUrl = config.refreshUrl;

        // Enable auto scroll of the build output by default
        // unless the user opts to disable it
        this.isAutoScroll = true;
        this.scrollTimer = -1;
        this.resizeTimer = -1;
        this.scrollPos = 2000000;

        this.buildIframeEl = null;
        this.buildIframeBody = null;
        this.buildIframeWindow = null;
        this.buildContent = null;

        // Initializes the new instance.
        this.init();
    };

    /**
     * @class BuildProfileMgr
     * @prototype
     */
    BuildProfileMgr.prototype = {

        /**
         * Initializes the Build Profile manager page js
         */
        init : function(){
            var thisObj = this;

            this.chkExpandEl = SELECT.query("#" + this.chkResizeId, document, true);
            if(this.chkExpandEl){
                EVENT.addListener(this.chkExpandEl, "click", this.handleResizeBox, this);
            }

            var refreshLinkEl = SELECT.query("#" + this.outputLabelId + " a", document, true);
            if(refreshLinkEl){
                EVENT.addListener(refreshLinkEl, "click", this.handleRefreshOutput, this);
            }

            var iframeContainerEl = SELECT.query("#" + this.iframeContainerId, document, true);
            if(iframeContainerEl){
                this.buildIframeEl = SELECT.query("iframe", iframeContainerEl, true);
                var disableScrollEl = SELECT.query("#" + this.disableScrollId + " input[type=checkbox]", document, true);

                if(this.buildIframeEl){
                    // Add disable scroll
                    EVENT.addListener([iframeContainerEl, this.buildIframeEl, disableScrollEl], "click", this.handleDisableScroll, this);
                }
            }

            EVENT.onAvailable(this.buildIframeEl.id, this.initBuildIframe, thisObj);
        },

        /**
         * initBuildIframe Initialize iframe script variables when the content
         * is available.
         */
        initBuildIframe : function(buildObj) {

            if(!buildObj){
                return;
            }

            if (buildObj.buildIframeEl.window) {
                buildObj.buildIframeWindow = buildObj.buildIframeEl.document.window;
            } else if (buildObj.buildIframeEl.contentWindow) {
                buildObj.buildIframeWindow = buildObj.buildIframeEl.contentWindow;
            }

            buildObj.buildIframeBody = buildObj.getIframeBody();

            buildObj.checkScroll();

            buildObj.scrollTimer = window.setInterval(function(){
                                        buildObj.checkScroll();
                                    },500);

            // TODO: create an Event variable and use it instead.
            YAHOO.util.Event.addListener(buildObj.buildIframeWindow, "load",  buildObj.handleDisableScroll, buildObj );

            buildObj.setOutputBoxSize(false);
        },

        /**
         * Event handler when refresh output link is clicked.
         * @param  {Event} e
         * @param  {object} buildObj BuildProfileMgr object instance
         */
        handleRefreshOutput : function(e, buildObj) {
            if(typeof e.preventDefault === "function"){
                e.preventDefault();
            } else{
                e.returnValue = false;
            }

            if(buildObj.buildIframeEl){
                if (buildObj.buildIframeEl.contentWindow) {
                    buildObj.buildIframeEl.contentWindow.location.href = buildObj.refreshUrl;
                } else {
                    buildObj.buildIframeEl.content.location.href = buildObj.refreshUrl;
                }
            }
        },

        /**
         * Event handler when disable scroll is clicked
         * @param  {Event} e
         * @param  {object} buildObj BuildProfileMgr object instance
         */
        handleDisableScroll : function(e, buildObj) {
            if(typeof e.preventDefault === "function"){
                e.preventDefault();
            } else{
                e.returnValue = false;
            }

            buildObj.removeAutoScroll();
        },

        handleResizeBox : function(e, buildObj) {
            var source = _getSourceElement(e);
            if(!source){
                return;
            }

            buildObj.setOutputBoxSize(source.checked);
        },

        /** : function
         * getIframeBody gets the current body element of the iframe.
         * return: HTML Element body object within the iframe
         */
        getIframeBody : function(){

            if (this.buildIframeEl.document) {
                return this.buildIframeEl.document.body;
            } else if (this.buildIframeEl.contentDocument) {
                return this.buildIframeEl.contentDocument.body;
            }
        },

        /**
         * setOutputBoxSize Sets the build output box's width
         * and height.
         * param: {boolean} expand true to expand and false to shrink to normal size.
         */
        setOutputBoxSize : function(expand) {
            var width = 700,    // Normal width
                height = 400;   // Normal height

            // Get iframe element if not already defined.
            if( !this.buildIframeEl ){
                this.buildIframeEl = SELECT.query("#" + this.iframeContainerId + " iframe", document, true);
            }

            // Get the 'content' div in the iframe if it is
            // not found in initialization process.
            if( !this.buildContent ) {
                var bodyEl = this.getIframeBody();
                this.buildContent = SELECT.query("#content", bodyEl, true);
            }

            if(expand) {
                var pageContainer = SELECT.query("#pageContainer", document, true);

                // Get current container's client width and apply it as
                // expanded width if it is greater than normal width.
                width = (pageContainer && pageContainer.clientWidth > width) ? pageContainer.clientWidth : width;

                // Expanded height.
                height = 700;
            }

            DOM.setStyle(this.buildContent, "display", "none");
            if(this.buildIframeEl) {
                DOM.setStyle(this.buildIframeEl, "width", width + "px");
                DOM.setStyle(this.buildIframeEl, "height",  height + "px");
            }
            var thisObj = this;
            this.resizeTimer = window.setInterval(function(){
                thisObj.showContent(thisObj);
            }, 50);
        },

        /**
         * showContent Shows the content of the build output box
         * once the iframe's resizing is done.
         */
        showContent : function(buildObj){
            if( !buildObj.buildContent ) {
                var bodyEl = buildObj.getIframeBody();
                buildObj.buildContent = SELECT.query("#content", bodyEl, true);
            }

            DOM.setStyle(buildObj.buildContent, "display", "");
            window.clearInterval(buildObj.resizeTimer);
        },

        /**
         * This function stops auto scroll and clears variables associated with it.
         */
        removeAutoScroll : function() {
            // TODO: replace getElementById with yui Selector.
            var disableScrollEl = SELECT.query("#" + this.disableScrollId, document, true);

            if(disableScrollEl){
                DOM.setStyle(disableScrollEl, "display", "none");

                window.clearInterval(this.scrollTimer);

                // Set the auto scroll to false.
                this.isAutoScroll = false;
            }
        },

        /**
         * checkScroll checks if auto scroll is active and
         * scrolls accordingly.
         */
        checkScroll : function() {
            if (!this.isAutoScroll){
                return;
            }

            this.buildIframeWindow.scroll(0, this.buildIframeBody.offsetHeight);
            this.buildIframeWindow.scroll(0, this.scrollPos++);
        },

        /**
         * Clears the variables that are used to notify
         * which software is being built (i.e Apache, PHP etc)
         * and in which step it is during that process.
         */
        clearInfoVariables : function(){
            var currNamespaceEl = SELECT.query("#" + this.currNamespace, document, true),
                currStepEl = SELECT.query("#" + this.currStep, document, true);

            if(currNamespaceEl){
                currNamespaceEl.innerHTML = "";
            }

            if(currStepEl){
                currStepEl.innerHTML = "";
            }
        },

        /**
         * Updates the status bar of the build process
         * from progress to completion.
         * @param  {string} text The success/error text displayed
         *                       after completion.
         */
        updateBuildStatus : function(text){
            var buildStatusEl = SELECT.query("#" + this.buildStatusId, document, true);

            if(buildStatusEl){
                buildStatusEl.innerHTML = text;
            }
        },

        /**
         * Updates the build output section with proper links
         * @param  {string} text
         */
        updateBuildOutput : function(text){
            var outputLableEl = SELECT.query("#" + this.outputLabelId, document, true);
            if(outputLableEl){
                outputLableEl.innerHTML = text;
            }
        }
    };

    /**
     * Provides functionality used by Build log Manager page.
     *
     * @class BuildLogMgr
     * @constructor
     */
    var BuildLogMgr = function(config) {
        this.logContainerId = config.logContainerId;
        this.checkAllClassName = config.checkAllClassName;

        // Initializes the new instance.
        this.init();
    };

    /**
     * @class BuildLogMgr
     * @prototype
     */
    BuildLogMgr.prototype = {

        /**
         * Initializes the Build log manager page js
         */
        init : function(){
            var thisObj = this;
            this.logContainer = SELECT.query("#" + this.logContainerId, document, true);

            if(this.logContainer){
                var checkAllEls = SELECT.query("." + this.checkAllClassName, this.logContainer);
                if( checkAllEls && checkAllEls.length > 0 ){
                    EVENT.addListener(checkAllEls, "click", thisObj.handleCheckAll, thisObj.logContainer);
                }
            }
        },

        /**
         * Handles check/uncheck  all
         * @param  {Event} e
         * @param  {HTMLElement} obj container of checkbox list
         */
        handleCheckAll : function(e, obj) {
            var source = _getSourceElement(e);
            if(!source){
                return;
            }

            _toggleCheckAll(source.checked, obj);
        }
    };

    /**
     * Provides functionality used by short option & exhaustive option steps.
     *
     * @class ListAllOptions
     * @constructor
     */
    var ListAllOptions = function(config) {
        this.verifyOptionList = config.verifyOptions || null;
        this.optionsTableClass = config.optionsTableClass;

        // Initializes the new instance.
        this.init();
    };

    /**
     * @class ListAllOptions
     * @prototype
     */
    ListAllOptions.prototype = {

        /**
         * Initializes the Build log manager page js
         */
        init : function(){
            var thisObj = this;

            var optionContainers = SELECT.query("." + this.optionsTableClass, document);

            if(optionContainers){
                // Initialize an array to track all options
                this.optionsList = [];

                // Iterate through each container and collect the checkbox elements.
                for(var i = 0, l = optionContainers.length; i < l; i++){
                    var chkBoxEls = SELECT.query("input[type=checkbox]", optionContainers[i]);
                    if(chkBoxEls && chkBoxEls.length > 0){
                        this.optionsList.push.apply(this.optionsList, chkBoxEls);
                    }
                }
            }

            if( this.optionsList && this.optionsList.length > 0 ){

                this.optionsList.forEach(function(option){
                    var verifyList = thisObj.verifyOptionList;

                    // Find the options with special verify condition
                    // (present in verifyOptionList array) and apply verify action
                    // to their corresponding click events.
                    for (var i = 0, l = verifyList.length; i < l; i++){
                        if(option.id === verifyList[i].id){
                            // Add event to input option if it exists in verify list.
                            EVENT.addListener(option, "click", thisObj.handleVerifyOption,
                            {
                                lopObj : thisObj,
                                verifyOptionIndex : i
                            });

                            break;
                        }
                    }
                });
            }
        },

        /**
         * Handles showing a confirm box to verify the select/unselect action of
         * certain module option.
         * @param  {Event} e
         * @param  {object} obj contains ListAllOptions' instance and the index
         *                  of the clicked option.
         *         ( obj = {lopObj, verifyOptionIndex} )
         */
        handleVerifyOption : function(e, obj){
            if(obj !== null){
                var lopObj = obj.lopObj,
                    index = obj.verifyOptionIndex;

                if(lopObj !== null) {
                    lopObj.verifyOption(this,
                        lopObj.verifyOptionList[index].onObj,
                        lopObj.verifyOptionList[index].offObj
                    );
                }
            }
        },

        /**
         * verifyOption
         * @param  {HTMLElement} optionEl selected radio element
         * @param  {object} on_obj contains ( {text, url} )
         * @param  {object} off_obj contains ( {text, url} )
         */
        verifyOption : function(optionEl, on_obj, off_obj) {
            var okFunc = function(){
                this.hide();

                optionEl.checked = true;
            },

            cancelFunc = function(){
                this.hide();

                optionEl.checked = false;
            };

            if (on_obj && optionEl.checked) {
                var onText = on_obj.text;

                if( on_obj.url ){
                    onText = onText + "(" + on_obj.url + ")";
                }

                _yuiDialog("Confirm Action", onText, "Ok", "Cancel", okFunc, cancelFunc);
            }

            if (off_obj && !optionEl.checked) {
                var offText = off_obj.text;

                if( off_obj.url ){
                    offText = offText + "(" + off_obj.url + ")";
                }

                _yuiDialog("Confirm Action", offText, "Ok", "Cancel", cancelFunc, okFunc);
            }
            return false;
        }
    };


    // Publish the public objects selectively.
    CPANEL.ea.ListProfiles = ListProfiles;
    CPANEL.ea.ListApache = ListApache;
    CPANEL.ea.BuildLogManager = BuildLogMgr;
    CPANEL.ea.BuildProfileManager = BuildProfileMgr;
    CPANEL.ea.ListAllOptions = ListAllOptions;

    CPANEL.ea.confirmBuild = confirmBuild;

}());

