MdaradMessageHandler = Class.create();
Object.extend(MdaradMessageHandler.prototype, {
    /*************************************************************************
     * Initialization methods
     *************************************************************************/
    DEFAULT_ERROR_LABEL_ID: "org.mdarad.framework.global.forward.failure.message",
    
    DEFAULT_SUCCESS_LABEL_ID: "org.mdarad.framework.global.forward.success.message",

    DEFAULT_WORKING_LABEL_ID: "org.mdarad.framework.global.forward.working.message",
    
    WORKING_STATUS: "working",
    
    ERROR_STATUS: "error",
    
    SUCCESS_STATUS: "success",

    WARNING_STATUS: "warning",
    
    MODAL_ALERT_ID: "modal_alert",

    MODAL_SUCCESS_ID: "modal_success",
    
    WINDOW_ZINDEX: null,
    
    DEFAULT_WINDOW_JS_CLASS_NAME: "vista",
            
    initialize : function () {
        this.initializeMdaradMessageHandlerPrototype ();
    },
    
    initializeMdaradMessageHandlerPrototype : function () {
        this.alerts= new Array();
        this.successes = new Array();
        
        //Default value for the window index
        document.whenReady(function() {        
            UI.Window.setOptions({
                windowManager: new UI.WindowManager({
                    zIndex: 2000
                })
            });
        });
        this._notificationCount = 0;
    },    
    
    alerts: null,
    successes: null,
     
    /*************************************************************************
     * Working Notification
     *************************************************************************/    
    _notificationCount : 0,
    _currentWorkingNotification: null,

    /**
     * This method add a modal notification window (progress bar by default).
     * @param messageContentOptions message options, the structure is the following :
     *      - resourceHandler
     * @param dialogOptions : options that will be passed to the UI.Dialog class when created.  See UI documentation.
     */
    addWorkingNotification: function(messageContentOptions, dialogOptions) {
        
        var resourceHandler = MdaradUtils.getOptionElement(messageContentOptions, "resourceHandler", null);
        if(!resourceHandler) throw "[ERROR MdradMessageHandler] The resource handler shoud be passed within the messageContentOptions";

        if(this._notificationCount == 0) {            
            var options = $H({
                buttons: [],
                theme: this.getWindowClassName(),
                width:330,
                height:170,
                resizable: false,
                draggable: false
            });

            options = options.merge(dialogOptions);

            //Create notification with dialog
            this._currentWorkingNotification = new UI.Dialog(options.toObject());
            this._currentWorkingNotification.setHeader("<div class='title'>...</div>");
            this._currentWorkingNotification.setContent("<img class='notification' src='" + resourceHandler.pathPrefix + "/static/img/progressbar.gif'/>");
            this._currentWorkingNotification.show(true);
            this._currentWorkingNotification.center();
        }
        this._notificationCount++;
    },
    removeWorkingNotification: function() {
        this._notificationCount--;
        if(this._notificationCount == 0) {
            this._currentWorkingNotification.destroy();
            this._currentWorkingNotification = null;
        }
    },

    /*************************************************************************
     * Alert messages
     *************************************************************************/
    getModalAlert: function() {
        return this.getElementFromList(this.MODAL_ALERT_ID, this.alerts);
    },

    getAlert: function(messageDomId) {
        return this.getElementFromList(messageDomId, this.alerts);
    },
    
    deleteAlert: function(element) {
        this.alerts = this.deleteElementFromList(element, this.alerts);        
    },

    /* 
     * old params  resourceHandler, messageDomId, isModal, messageKey, attributeLabel, bundle, paramResourceArray, content
     * 
     * dialogOptions : isModal, okCallback
     * 
     */
    addAlert: function(messageDomId, messageContentOptions, dialogOptions) {
        messageContentOptions = (messageContentOptions != null) ? messageContentOptions.toObject() : {}; 
        messageContentOptions.messageKey = MdaradUtils.getOptionElement(messageContentOptions, "messageKey", this.DEFAULT_ERROR_LABEL_ID);

        dialogOptions = (dialogOptions != null) ? dialogOptions.toObject() : {}; 
        dialogOptions.isModal = MdaradUtils.getOptionElement(dialogOptions, "isModal", false);

        if(dialogOptions.isModal) {
            var instance = this;
            var modalAlert = this.getModalAlert();
            if(modalAlert == null) {
                var options = $H({
                    buttons: [{
                        title: 'Ok', 
                        className: 'ok', 
                        callback: function() {
                            instance.removeAlert(messageDomId);
                            if (dialogOptions.okCallback != null) {
                                dialogOptions.okCallback.call(instance);
                            }
                        } 
                    }],
                    theme: this.getWindowClassName(),
                    width:400,
                    height:200,
                    resizable: false
                });
                options = options.merge(dialogOptions);    

                //Create notification with dialog
                var dialog = new UI.Dialog(options.toObject());
                dialog.setHeader("<div class='title'>Alert...</div>");
                dialog.setContent("<div id='alertNotification' class='messages'/>");
                dialog.show(true);
                dialog.center();
                dialog.adapt();
                dialog.activate();

                //TODO : PATCH This was added because of a bug with the window that doesn't display the buttons
                setTimeout(function() {
                    var contentElements = $$('.content');
                    for(var i = 0; i < contentElements.length; i++) {
                        var currentMatch = contentElements[i];
                        currentMatch.setStyle({height: ""});
                    }
                }, 500);

                modalAlert = {
                    messageDomId: this.MODAL_ALERT_ID,
                    dialog: dialog
                };
                this.alerts.push(modalAlert);
            } 
            if(!messageContentOptions.content) {
                //Create message                
                this.displayMessageFromResource(messageContentOptions.resourceHandler, 
                    messageContentOptions.messageKey,
                    this.ERROR_STATUS,
                    "alertNotification",
                    messageContentOptions.attributeLabel,
                    messageContentOptions.bundle,
                    messageContentOptions.paramResourceArray
                );      
            } else {
                this.displayMessage(this.ERROR_STATUS, "alertNotification", messageContentOptions.content);
            }
            //TODO: This is to correct a bug of the window not taking the buttons in account when adapt() is called.
            var notificationNode = $('alertNotification');
            var parentNode = notificationNode.parentNode.parentNode;
            var parentHeight = parentNode.style.height;
            var parentHeightAsNumber = parseInt(parentHeight.substring(0, parentHeight.length-2));
            var newHeight = parentHeightAsNumber + 15;
            parentNode.style.height = newHeight + "px";
            
        } else {
            var alertElement = this.getAlert(messageDomId);
            if(alertElement == null) {
                alertElement = {
                    messageDomId: messageDomId
                };
                this.alerts.push(alertElement);
            } 
            
            if(!(messageContentOptions.content)) {
                //Display message
                this.clearAndDisplayMessageFromResource(messageContentOptions.resourceHandler, 
                    messageContentOptions.messageKey,
                    this.ERROR_STATUS,
                    messageDomId,
                    messageContentOptions.attributeLabel,
                    messageContentOptions.bundle,
                    messageContentOptions.paramResourceArray
                );          
            } else {
                this.clearAndDisplayMessage(this.ERROR_STATUS, messageDomId, messageContentOptions.content);
            }
        } 
    },
    
    removeAlert: function(messageDomId) {
        var instance = this;
        //Look if such an alert exists (if not found it is probably a modal)
        var alertElement = instance.getAlert(messageDomId);
        
        //Modal
        if(!alertElement) {
            alertElement = instance.getModalAlert();
            if(alertElement) {
                setTimeout(function() {
                    alertElement.dialog.destroy();
                    instance.deleteAlert(alertElement);
                }, 10);
            }
        } 
        //Included message
        else {
            //Remove message
            instance.removeMessage(instance.ERROR_STATUS, messageDomId);
            instance.deleteAlert(alertElement);
        }
    },    
    
    /*************************************************************************
     * Success message
     *************************************************************************/
    /* 
     * old params messageDomId, resourceHandler, messageDomId, isModal, messageKey, attributeLabel, bundle, paramResourceArray, content
     */
    addSuccess: function(messageDomId, messageContentOptions) {
        var instance = this;

        messageContentOptions = (messageContentOptions != null) ? messageContentOptions.toObject() : {}; 
        messageContentOptions.messageKey = MdaradUtils.getOptionElement(messageContentOptions, "messageKey", this.DEFAULT_SUCCESS_LABEL_ID);

        if(!messageContentOptions.content) {
            //Display message
            this.clearAndDisplayMessageFromResource(messageContentOptions.resourceHandler, 
                messageContentOptions.messageKey,
                this.SUCCESS_STATUS,
                messageDomId,
                messageContentOptions.attributeLabel,
                messageContentOptions.bundle,
                messageContentOptions.paramResourceArray
            );          
        } else {
            instance.clearAndDisplayMessage(instance.SUCCESS_STATUS, messageDomId, messageContentOptions.content);
        }
    },

    /*************************************************************************
     * Inquiry messages
     *************************************************************************/
     
     _inquiryStack: null,
     /*
      * old params : resourceHandler, messageKey, okKey, cancelKey, okCallback
      */
    addInquiry: function(messageContentOptions, dialogOptions) {

        messageContentOptions = (messageContentOptions != null) ? messageContentOptions.toObject() : {}; 

        var parentDiv = "<div id='inquiryNotification' class='messages'/>";

        var options = $H({
             buttons: [{
                    title: 'Yes', 
                    className: 'ok', 
                    callback: MdaradUtils.getOptionElement(dialogOptions, "okCallback", null)
                }, {
                    title: 'No', 
                    className: 'cancel', 
                    callback: function(win) {win.destroy();}
                }],
            theme: this.getWindowClassName(),
            width: 400,
            height: 150,
            resizable: true
        });

        options = options.merge(dialogOptions);

        //Create Dialog
        var dialog = new UI.Dialog(options.toObject());
        dialog.setHeader("<div class='title'>Confirmation...</div>");
        dialog.setContent("<div id='inquiryNotification' class='messages'></div>");
        dialog.show(true);
        dialog.center()
        dialog.activate();
//        dialog.adapt();
                
        MdaradMessageHandler.clearAndDisplayMessageFromResource(messageContentOptions.resourceHandler, 
            messageContentOptions.messageKey,
            MdaradMessageHandler.WARNING_STATUS,
            "inquiryNotification"
        );
        
        // initialize stack of inquiries and add the first element
        if(!this._inquiryStack) this._inquiryStack = new Array();
        this._inquiryStack.push(dialog);

        //TODO: This is to correct a bug of the window not taking the buttons in account when adapt() is called.
        var notificationNode = $('inquiryNotification');
        var parentNode = notificationNode.parentNode.parentNode;
        var parentHeight = parentNode.style.height;
        var parentHeightAsNumber = parseInt(parentHeight.substring(0, parentHeight.length-2));
        var newHeight = parentHeightAsNumber + 15;
        parentNode.style.height = newHeight + "px";

    },
    
    /**
     * This method remove the first element on the stack of inquiries.
     */
    removeInquiry: function() {
        if(this._inquiryStack) {
            var dialog = this._inquiryStack.pop();
            dialog.destroy();
            dialog = null;
        }
    },
    
    /*************************************************************************
     * Methods used to open a modal window for specializations of an instance
     *************************************************************************/
    _modalSelector : null,
    
    /**
     * Method that opens a modal selector (mainly used for specializations)
     * @param contentElement dom element with the content to be displayed
     * @param cumulativeOffset cumulative offset object (from prototype)
     * @param dimensions dimensions object (from prototype)
     * @param options options to be passed to the modal control object
     */
    openModalSelector: function(contentElement, cumulativeOffset, dimensions, options) {
        var configuration = $H({
            contents : new Array(contentElement),
            position: 'relative',
            offsetTop: cumulativeOffset.top,
            offsetLeft: cumulativeOffset.left + dimensions.width,
            overlayClassName: "vista_overlay",
            fade: true
        });
        configuration = configuration.merge(options);
        
        this._modalSelector = new Control.Modal(false, configuration.toObject());
        this._modalSelector.open();
    },
    
    closeModalSelector: function() {
        if(this._modalSelector) {
            this._modalSelector.close();
            this._modalSelector = null;
        }
    },
    
    /*************************************************************************
     * Method used to display error message
     *************************************************************************/
    clearAndDisplayMessageFromResource : function(resourceHandler, resourceId, statusId, messageDomId, attributeLabel, bundle, paramResourceArray) {
        this.removeAllMessages(messageDomId);
        var messageInformation = MdaradResourceHandlerUtils.getResourceHash(resourceId, attributeLabel, bundle).merge({
            messageInfo: {
                status: statusId, 
                messageDOMElementId: messageDomId
            }        
        });
        return resourceHandler.updateResource(messageInformation, paramResourceArray);
    }, 

    displayMessageFromResource : function(resourceHandler, resourceId, statusId, messageDomId, attributeLabel, bundle, paramResourceArray) {
        var messageInformation = MdaradResourceHandlerUtils.getResourceHash(resourceId, attributeLabel, bundle).merge({
            messageInfo: {
                status: statusId, 
                messageDOMElementId: messageDomId
            }        
        });
        return resourceHandler.updateResource(messageInformation, paramResourceArray);
    },
        
    /*************************************************************************
     * Common Methods
     *************************************************************************/    
    getElementFromList: function(messageDomId, elementList) {
        for(var i=0; i < elementList.length; i++) {
            var currentElement = elementList[i];
            if(currentElement.messageDomId == messageDomId) {
                return currentElement;
            } 
        }
        return null;
    },
    
    deleteElementFromList: function(element, elementList) {
        for(var i=0; i < elementList.length; i++) {
            var currentElement = elementList[i];
            if(currentElement.messageDomId == element.messageDomId) {
                elementList[i] = null;
            } 
        }
        return elementList.compact();
    },
    
    /*************************************************************************
     * Method used to display error message
     *************************************************************************/
    clearAndDisplayMessage : function(statusId, messageDOMElementId, content) {
        this.removeAllMessages(messageDOMElementId);
        this.displayMessage(statusId, messageDOMElementId, content);
    },

    displayMessage : function(statusId, messageDOMElementId, content) {
        // status can be either : working, warning, success, error
        if(!content && statusId == "error") {
            content = 'An unexpected error occured';
        }        
        var messages = $(messageDOMElementId);

//        // Hide the div
//        Element.hide($(messageDOMElementId));

        //Create ol if not present        
        var olNode = MdaradUtils.findChild(messages, "ol");
        if(!olNode) {
            olNode = Builder.node("ol");
            messages.appendChild(olNode);
        }
        var messageLIElement = Builder.node('li', {className: statusId}, content);

//        // Repaint the div
//        if (statusId == 'success') {
//            Effect.Appear($(messageDOMElementId));
//        } else {
//            Effect.Appear($(messageDOMElementId));
//        }
        // Append to DOM
        olNode.appendChild(messageLIElement);
    },
    
    removeMessage: function(statusId, messageDomElementId) {
        var messages = $(messageDomElementId);

        var olNode = MdaradUtils.findChild(messages, "ol");
        if(olNode) {
            //Remove the messages matching the status
            document.getElementsByClassName(statusId, olNode).each(function(elementToRemove) {
                olNode.removeChild(elementToRemove);
            });

            if(olNode.childNodes.length == 0) {
                messages.removeChild(olNode);
            }
        }

    },

    removeAllMessages: function(messageDomElementId) {
        var messages = $(messageDomElementId);

        var olNode = MdaradUtils.findChild(messages, "ol");
        if(olNode) {
            //Remove the messages matching the status
            MdaradUtils.deleteAllChildren(olNode);
        }
    },
    
    /*************************************************************************
     * Util methods
     *************************************************************************/
    /**
     * Method that returns the window css class name.  The css class can
     * be defined in a global variable named WINDOW_JS_CLASS_NAME.  If not defined, the default
     * value is returned
     * @return string with the css class name
     */
    getWindowClassName : function() {
        var windowCssClass;  
        if(WINDOW_JS_CLASS_NAME && WINDOW_JS_CLASS_NAME != '') {
            windowCssClass = WINDOW_JS_CLASS_NAME;
        } else {
            windowCssClass = this.DEFAULT_WINDOW_JS_CLASS_NAME;
        }
        return windowCssClass;
    }
});
MdaradMessageHandler = new MdaradMessageHandler();
