Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
if (!window.RichFaces) {
    /**
     * Global object container for RichFaces API.
     * All classes should be defined here.
     * @class
     * @name RichFaces
     * @static
     *
     * */
    window.RichFaces = {};
}

(function(jQuery, richfaces) {

    richfaces.RICH_CONTAINER = "rf";
    
    /**
     * All input elements which can hold value, which are enabled and visible.
     */
    richfaces.EDITABLE_INPUT_SELECTOR = ":not(:submit):not(:button):not(:image):input:visible:enabled";

    //keys codes
    richfaces.KEYS = {
        BACKSPACE: 8,
        TAB: 9,
        RETURN: 13,
        ESC: 27,
        PAGEUP: 33,
        PAGEDOWN: 34,
        END: 35,
        HOME: 36,
        LEFT: 37,
        UP: 38,
        RIGHT: 39,
        DOWN: 40,
        DEL: 46
    };
    
    if (window.jsf) {
        var jsfAjaxRequest = jsf.ajax.request;
        var jsfAjaxResponse = jsf.ajax.response;
    }

    // get DOM element by id or DOM element or jQuery object
    richfaces.getDomElement = function (source) {
        var type = typeof source;
        var element;
        if (source == null) {
            element = null;
        } else if (type == "string") {
            // id
            element = document.getElementById(source);
        } else if (type == "object") {
            if (source.nodeType) {
                // DOM element
                element = source;
            } else
            if (source instanceof jQuery) {
                // jQuery object
                element = source.get(0);
            }
        }
        return element;
    };

    // get RichFaces component object by component id or DOM element or jQuery object
    richfaces.$ = function (source) {
        var element = richfaces.getDomElement(source);

        if (element) {
            return (element[richfaces.RICH_CONTAINER] || {})["component"];
        }
    };
    

    /**
     * jQuery selector ":editable" which selects only input elements which can be edited, are visible and enabled
     */
    $.extend($.expr[':'], {
        editable : function(element) {
            return $(element).is(richfaces.EDITABLE_INPUT_SELECTOR);
        }
    });

    richfaces.$$ = function(componentName, element) {
        while (element.parentNode) {
            var e = element[richfaces.RICH_CONTAINER];
            if (e && e.component && e.component.name == componentName)
                return e.component;
            else
                element = element.parentNode;
        }
    };
    richfaces.findNonVisualComponents = function (source) {
        var element = richfaces.getDomElement(source);

        if (element) {
            return (element[richfaces.RICH_CONTAINER] || {})["attachedComponents"];
        }
    };

    // find component and call his method
    richfaces.invokeMethod = function(source, method) {
        var c = richfaces.$(source);
        var f;
        if (c && typeof (f = c[method]) == "function") {
            return f.apply(c, Array.prototype.slice.call(arguments, 2));
        }
    };

    //dom cleaner
    richfaces.cleanComponent = function (source) {
        var component = richfaces.$(source);
        if (component) {
            //TODO fire destroy event
            component.destroy();
            component.detach(source);
        }
        var attachedComponents = richfaces.findNonVisualComponents(source);
        if (attachedComponents) {
            for (var i in attachedComponents) {
                if (attachedComponents[i]) {
                    attachedComponents[i].destroy();
                }
            }
        }
    };

    richfaces.cleanDom = function(source) {
        var e = (typeof source == "string") ? document.getElementById(source) : jQuery('body').get(0);
        if (source == "javax.faces.ViewRoot") {
            e = jQuery('body').get(0);
        }
        if (e) {
            // Fire a DOM cleanup event
//            $(e).trigger("beforeDomClean" + RichFaces.Event.RICH_NAMESPACE);
            $(e).trigger("beforeDomClean" + ".RICH");
            var elements = e.getElementsByTagName("*");
            if (elements.length) {
                jQuery.each(elements, function(index) {
                    richfaces.cleanComponent(this);
                });
                jQuery.cleanData(elements);
            }
            richfaces.cleanComponent(e);
            jQuery.cleanData([e]);
//            $(e).trigger("afterDomClean" + RichFaces.Event.RICH_NAMESPACE);
            $(e).trigger("afterDomClean" + ".RICH");
        }
    };

    //form.js
    richfaces.submitForm = function(form, parameters, target) {
        if (typeof form === "string") {
            form = jQuery(form)
        }
        ;
        var initialTarget = form.attr("target");
        var parameterInputs = new Array();
        try {
            form.attr("target", target);

            if (parameters) {
                for (var parameterName in parameters) {
                    var parameterValue = parameters[parameterName];

                    var input = jQuery("input[name='" + parameterName + "']", form);
                    if (input.length == 0) {
                        var newInput = jQuery("<input />").attr({type: 'hidden', name: parameterName, value: parameterValue});
                        if (parameterName === 'javax.faces.portletbridge.STATE_ID' /* fix for fileUpload in portlets */) {
                            input = newInput.prependTo(form);
                        } else {
                            input = newInput.appendTo(form);
                        }
                    } else {
                        input.val(parameterValue);
                    }

                    input.each(function() {
                        parameterInputs.push(this)
                    });
                }
            }

            //TODO: inline onsubmit handler is not triggered - http://dev.jquery.com/ticket/4930
            form.trigger("submit");
        } finally {
            if (initialTarget === undefined) {
                form.removeAttr("target");
            } else {
                form.attr("target", initialTarget);
            }
            jQuery(parameterInputs).remove();
        }
    };
    
    

    //utils.js
    jQuery.fn.toXML = function () {
        var out = '';

        if (this.length > 0) {
            if (typeof XMLSerializer == 'function' ||
                typeof XMLSerializer == 'object') {

                var xs = new XMLSerializer();
                this.each(function() {
                    out += xs.serializeToString(this);
                });
            } else if (this[0].xml !== undefined) {
                this.each(function() {
                    out += this.xml;
                });
            } else {
                this.each(function() {
                    out += this;
                });
            }
        }

        return out;
    };

    //there is the same pattern in server-side code:
    //org.ajax4jsf.javascript.ScriptUtils.escapeCSSMetachars(String)
    var CSS_METACHARS_PATTERN = /([#;&,.+*~':"!^$\[\]()=>|\/])/g;

    /**
     * Escapes CSS meta-characters in string according to
     *  <a href="http://api.jquery.com/category/selectors/">jQuery selectors</a> document.
     *
     * @param s - string to escape meta-characters in
     * @return string with meta-characters escaped
     */
    richfaces.escapeCSSMetachars = function(s) {
        //TODO nick - cache results

        return s.replace(CSS_METACHARS_PATTERN, "\\$1");
    };

    var logImpl;

    richfaces.setLog = function(newLogImpl) {
        logImpl = newLogImpl;
    };

    richfaces.log = {
        debug: function(text) {
            if (logImpl) {
                logImpl.debug(text);
            }
        },

        info: function(text) {
            if (logImpl) {
                logImpl.info(text);
            }
        },

        warn: function(text) {
            if (logImpl) {
                logImpl.warn(text);
            }
        },

        error: function(text) {
            if (logImpl) {
                logImpl.error(text);
            }
        },

        setLevel: function(level) {
            if (logImpl) {
                logImpl.setLevel(level);
            }
        },

        getLevel: function() {
            if (logImpl) {
                return logImpl.getLevel();
            }
            return 'info';
        },

        clear: function() {
            if (logImpl) {
                logImpl.clear();
            }
        }
    };

    /**
     * Evaluates chained properties for the "base" object.
     * For example, window.document.location is equivalent to
     * "propertyNamesString" = "document.location" and "base" = window
     * Evaluation is safe, so it stops on the first null or undefined object
     *
     * @param propertyNamesArray - array of strings that contains names of the properties to evaluate
     * @param base - base object to evaluate properties on
     * @return returns result of evaluation or empty string
     */
    richfaces.getValue = function(propertyNamesArray, base) {
        var result = base;
        var c = 0;
        do {
            result = result[propertyNamesArray[c++]];
        } while (result && c != propertyNamesArray.length);

        return result;
    };

    var VARIABLE_NAME_PATTERN_STRING = "[_A-Z,a-z]\\w*";
    var VARIABLES_CHAIN = new RegExp("^\\s*" + VARIABLE_NAME_PATTERN_STRING + "(?:\\s*\\.\\s*" + VARIABLE_NAME_PATTERN_STRING + ")*\\s*$");
    var DOT_SEPARATOR = /\s*\.\s*/;

    richfaces.evalMacro = function(macro, base) {
        var value = "";
        // variable evaluation
        if (VARIABLES_CHAIN.test(macro)) {
            // object's variable evaluation
            var propertyNamesArray = jQuery.trim(macro).split(DOT_SEPARATOR);
            value = richfaces.getValue(propertyNamesArray, base);
            if (!value) {
                value = richfaces.getValue(propertyNamesArray, window);
            }
        } else {
            //js string evaluation
            try {
                if (base.eval) {
                    value = base.eval(macro);
                } else with (base) {
                    value = eval(macro);
                }
            } catch (e) {
                richfaces.log.warn("Exception: " + e.message + "\n[" + macro + "]");
            }
        }

        if (typeof value == 'function') {
            value = value(base);
        }
        //TODO 0 and false are also treated as null values
        return value || "";
    };

    var ALPHA_NUMERIC_MULTI_CHAR_REGEXP = /^\w+$/;

    richfaces.interpolate = function (placeholders, context) {
        var contextVarsArray = new Array();
        for (var contextVar in context) {
            if (ALPHA_NUMERIC_MULTI_CHAR_REGEXP.test(contextVar)) {
                //guarantees that no escaping for the below RegExp is necessary
                contextVarsArray.push(contextVar);
            }
        }

        var regexp = new RegExp("\\{(" + contextVarsArray.join("|") + ")\\}", "g");
        return placeholders.replace(regexp, function(str, contextVar) {
            return context[contextVar];
        });
    };

    richfaces.clonePosition = function(element, baseElement, positioning, offset) {

    };
    //

    var jsfEventsAdapterEventNames = {
        event: {
            'begin': ['begin'],
            'complete': ['beforedomupdate'],
            'success': ['success', 'complete']
        },
        error: ['error', 'complete']
    };

    var getExtensionResponseElement = function(responseXML) {
        return jQuery("partial-response extension#org\\.richfaces\\.extension", responseXML);
    };

    var JSON_STRING_START = /^\s*(\[|\{)/;

    richfaces.parseJSON = function(dataString) {
        try {
            if (dataString) {
                if (JSON_STRING_START.test(dataString)) {
                    return jQuery.parseJSON(dataString);
                } else {
                    var parsedData = jQuery.parseJSON("{\"root\": " + dataString + "}");
                    return parsedData.root;
                }
            }
        } catch (e) {
            richfaces.log.warn("Error evaluating JSON data from element <" + elementName + ">: " + e.message);
        }

        return null;
    }

    var getJSONData = function(extensionElement, elementName) {
        var dataString = jQuery.trim(extensionElement.children(elementName).text());
        return richfaces.parseJSON(dataString);
    };

    richfaces.createJSFEventsAdapter = function(handlers) {
        //hash of handlers
        //supported are:
        // - begin
        // - beforedomupdate
        // - success
        // - error
        // - complete
        var handlers = handlers || {};
        var ignoreSuccess;

        return function(eventData) {
            var source = eventData.source;
            //that's request status, not status control data
            var status = eventData.status;
            var type = eventData.type;

            if (type == 'event' && status == 'begin') {
                ignoreSuccess = false;
            } else if (type == 'error') {
                ignoreSuccess = true;
            } else if (ignoreSuccess) {
                return;
            } else if (status == 'complete' && richfaces.ajaxContainer && richfaces.ajaxContainer.isIgnoreResponse && richfaces.ajaxContainer.isIgnoreResponse()) {
                return;
            }

            var typeHandlers = jsfEventsAdapterEventNames[type];
            var handlerNames = (typeHandlers || {})[status] || typeHandlers;

            if (handlerNames) {
                for (var i = 0; i < handlerNames.length; i++) {
                    var eventType = handlerNames[i];
                    var handler = handlers[eventType];
                    if (handler) {
                        var event = {};
                        jQuery.extend(event, eventData);
                        event.type = eventType;
                        if (type != 'error') {
                            delete event.status;

                            if (event.responseXML) {
                                var xml = getExtensionResponseElement(event.responseXML);
                                var data = getJSONData(xml, "data");
                                var componentData = getJSONData(xml, "componentData");

                                event.data = data;
                                event.componentData = componentData || {};
                            }
                        }
                        handler.call(source, event);
                    }
                }
            }
        };
    };

    richfaces.setGlobalStatusNameVariable = function(statusName) {
        //TODO: parallel requests
        if (statusName) {
            richfaces['statusName'] = statusName;
        } else {
            delete richfaces['statusName'];
        }
    }

    richfaces.setZeroRequestDelay = function(options) {
        if (typeof options.requestDelay == "undefined") {
            options.requestDelay = 0;
        }
    };

    var chain = function() {
        var functions = arguments;
        if (functions.length == 1) {
            return functions[0];
        } else {
            return function() {
                var callResult;
                for (var i = 0; i < functions.length; i++) {
                    var f = functions[i];
                    if (f) {
                        callResult = f.apply(this, arguments);
                    }
                }

                return callResult;
            };
        }
    };

    /**
     * curry (g, a) (b) -> g(a, b)
     */
    var curry = function(g, a) {
        var _g = g;
        var _a = a;

        return function(b) {
            _g(_a, b);
        };
    };

    var createEventHandler = function(handlerCode) {
        if (handlerCode) {
            return new Function("event", handlerCode);
        }

        return null;
    };

    //TODO take events just from .java code using EL-expression
    var AJAX_EVENTS = (function() {
        var serverEventHandler = function(clientHandler, event) {
            var xml = getExtensionResponseElement(event.responseXML);

            var serverHandler = createEventHandler(xml.children(event.type).text());

            if (clientHandler) {
                clientHandler.call(window, event);
            }

            if (serverHandler) {
                serverHandler.call(window, event);
            }
        };

        return {
            'error': null,
            'begin': null,
            'complete': serverEventHandler,
            'beforedomupdate': serverEventHandler
        }
    }());

    richfaces.ajax = function(source, event, options) {
        var options = options || {};
        
        var sourceId = getSourceId(source, options);
        var sourceElement = getSourceElement(source);
        
        // event source re-targeting finds a RichFaces component root
        // to setup javax.faces.source correctly - RF-12616)
        if (sourceElement) {
            source = searchForComponentRootOrReturn(sourceElement);
        }
        
        parameters = options.parameters || {}; // TODO: change "parameters" to "richfaces.ajax.params"
        parameters.execute = "@component";
        parameters.render = "@component";

        if (options.clientParameters) {
            jQuery.extend(parameters, options.clientParameters);
        }

        if (!parameters["org.richfaces.ajax.component"]) {
            parameters["org.richfaces.ajax.component"] = sourceId;
        }

        if (options.incId) {
            parameters[sourceId] = sourceId;
        }

        if (richfaces.queue) {
            parameters.queueId = options.queueId;
        }

        // propagates some options to process it in jsf.ajax.request
        parameters.rfExt = {};
        parameters.rfExt.status = options.status;
        for (var eventName in AJAX_EVENTS) {
            parameters.rfExt[eventName] = options[eventName];
        }

        jsf.ajax.request(source, event, parameters);
    };

    if (window.jsf) {
        jsf.ajax.request = function request(source, event, options) {

            // build parameters, taking options.rfExt into consideration
            var parameters = $.extend({}, options);
            parameters.rfExt = null;

            var eventHandlers;

            var sourceElement = getSourceElement(source);
            var form = getFormElement(sourceElement);

            for (var eventName in AJAX_EVENTS) {
                var handlerCode, handler;
                
                if (options.rfExt) {
                    handlerCode = options.rfExt[eventName];
                    handler = typeof handlerCode == "function" ? handlerCode : createEventHandler(handlerCode);
                }

                var serverHandler = AJAX_EVENTS[eventName];
                if (serverHandler) {
                    handler = curry(serverHandler, handler);
                }

                if (handler) {
                    eventHandlers = eventHandlers || {};
                    eventHandlers[eventName] = handler;
                }
            }

            if (options.rfExt && options.rfExt.status) {
                var namedStatusEventHandler = function() {
                    richfaces.setGlobalStatusNameVariable(options.rfExt.status);
                };

                //TODO add support for options.submit
                eventHandlers = eventHandlers || {};
                if (eventHandlers.begin) {
                    eventHandlers.begin = chain(namedStatusEventHandler, eventHandlers.begin);
                } else {
                    eventHandlers.begin = namedStatusEventHandler;
                }
            }
            
            // register handlers for form events: ajaxbegin and ajaxbeforedomupdate
            if (form) {
                eventHandlers.begin = chain(function() { jQuery(form).trigger('ajaxbegin'); }, eventHandlers.begin);
                eventHandlers.beforedomupdate = chain(function() { jQuery(form).trigger('ajaxbeforedomupdate'); }, eventHandlers.beforedomupdate);
                eventHandlers.complete = chain(function() { jQuery(form).trigger('ajaxcomplete'); }, eventHandlers.complete);
            }

            if (eventHandlers) {
                var eventsAdapter = richfaces.createJSFEventsAdapter(eventHandlers);
                parameters['onevent'] = chain(options.onevent, eventsAdapter);
                parameters['onerror'] = chain(options.onerror, eventsAdapter);
            }

            // trigger handler for form event: ajaxsubmit
            if (form) {
                jQuery(form).trigger('ajaxsubmit');
            }
            
            return jsfAjaxRequest(source, event, parameters);
        }
        
        jsf.ajax.response = function(request, context) {
            // for all RichFaces.ajax requests
            if (context.render == '@component') {
                // get list of IDs updated on the server - replaces @render option which is normally available on client
                context.render = $("extension[id='org.richfaces.extension'] render", request.responseXML).text();
            }

            return jsfAjaxResponse(request, context);
        }
    }
    
    /*
     * Returns RichFaces component root for given element in the list of ancestors of sourceElement.
     * Otherwise returns sourceElement if RichFaces component root can't be located.
     */
    var searchForComponentRootOrReturn = function(sourceElement) {
        if (sourceElement.id && !richfaces.$(sourceElement)) {
            var parentElement = false;
            jQuery(sourceElement).parents().each(function() {
                if (this.id && sourceElement.id.indexOf(this.id) == 0) { // otherwise parent element is definitely not JSF component
                    var suffix = sourceElement.id.substring(this.id.length); // extract suffix
                    if (suffix.match(/^[a-zA-Z]*$/) && richfaces.$(this)) {
                        parentElement = this;
                        return false;
                    }
                }
            });
            if (parentElement !== false) {
                return parentElement;
            }
        }
        return sourceElement;
    };
    
    var getSourceElement = function(source) {
        if (typeof source === 'string') {
            return document.getElementById(source);
        } else if (typeof source === 'object') {
            return source;
        } else {
            throw new Error("jsf.request: source must be object or string");
        }
    };
    
    var getFormElement = function(sourceElement) {
        if ($(sourceElement).is('form')) {
            return sourceElement;
        } else {
            return $('form').has(sourceElement).get(0);
        }
    };
    
    var getSourceId = function(source, options) {
        if (options.sourceId) {
            return options.sourceId;
        } else {
            return (typeof source == 'object' && (source.id || source.name)) ? (source.id ? source.id : source.name) : source;
        }
    };

    var ajaxOnComplete = function (data) {
        var type = data.type;
        var responseXML = data.responseXML;

        if (data.type == 'event' && data.status == 'complete' && responseXML) {
            var partialResponse = jQuery(responseXML).children("partial-response");
            if (partialResponse && partialResponse.length) {
                var elements = partialResponse.children('changes').children('update, delete');
                jQuery.each(elements, function () {
                    richfaces.cleanDom(jQuery(this).attr('id'));
                });
            }
        }
    };
    
    richfaces.javascriptServiceComplete = function(event) {
        jQuery(function() {
            jQuery(document).trigger("javascriptServiceComplete");
        });
    };

    var attachAjaxDOMCleaner = function() {
        // move this code to somewhere
        if (typeof jsf != 'undefined' && jsf.ajax) {
            jsf.ajax.addOnEvent(ajaxOnComplete);

            return true;
        }

        return false;
    };

    if (!attachAjaxDOMCleaner()) {
        jQuery(document).ready(attachAjaxDOMCleaner);
    }

    if (window.addEventListener) {
        window.addEventListener("unload", richfaces.cleanDom, false);
    } else {
        window.attachEvent("onunload", richfaces.cleanDom);
    }
}(jQuery, RichFaces));;/**
 * @author Pavel Yaschenko
 */

(function($, richfaces, jsf) {

    /**
     * RichFaces Ajax container
     * @class
     * @memberOf RichFaces
     * @static
     * @name ajaxContainer
     * */
    richfaces.ajaxContainer = richfaces.ajaxContainer || {};

    if (richfaces.ajaxContainer.jsfRequest) {
        return;
    }

    /**
     * JSF 2.0 original method that sends an asynchronous ajax request to the server
     * see jsf.ajax.request method for parameter's description
     * @function
     * @name RichFaces.ajaxContainer.jsfRequest
     *
     * */
    richfaces.ajaxContainer.jsfRequest = jsf.ajax.request;

    /**
     * RichFaces wrapper function of JSF 2.0 original method jsf.ajax.request
     * @function
     * @name jsf.ajax.request
     *
     * @param {string|DOMElement} source - The DOM element or an id that triggered this ajax request
     * @param {object} [event] - The DOM event that triggered this ajax request
     * @param {object} [options] - The set name/value pairs that can be sent as request parameters to control client and/or server side request processing
     * */
    jsf.ajax.request = function(source, event, options) {
        richfaces.queue.push(source, event, options);
    };

    richfaces.ajaxContainer.jsfResponse = jsf.ajax.response;

    richfaces.ajaxContainer.isIgnoreResponse = function() {
        return richfaces.queue.isIgnoreResponse();
    };


    jsf.ajax.response = function(request, context) {
        richfaces.queue.response(request, context);
    };

    var QUEUE_MODE_PULL = 'pull';
    var QUEUE_MODE_PUSH = 'push';
    var QUEUE_MODE = QUEUE_MODE_PULL;
    var DEFAULT_QUEUE_ID = "org.richfaces.queue.global";

    /**
     * RichFaces Queue API container
     * @class
     * @memberOf RichFaces
     * @static
     * @name queue
     * */
    richfaces.queue = (function() {

        var defaultQueueOptions = {};
        //defaultQueueOptions[DEFAULT_QUEUE_ID] = {requestDelay:0, ignoreDupResponse:false, timeout:0};
        var eventHandlers = {};

        var QueueEntry = function(queue, source, event, options) {
            this.queue = queue;
            this.source = source;
            this.options = $.extend({}, options || {});
            this.queueOptions = {}
            var id;

            // find default options for QueueEntry
            if (this.options.queueId) {
                if (defaultQueueOptions[this.options.queueId]) {
                    id = this.options.queueId;
                }
                delete this.options.queueId;
            } else {
                var element = richfaces.getDomElement(source);
                var form;
                if (element) {
                    element = $(element).closest("form");
                    if (element.length > 0) {
                        form = element.get(0);
                    }
                }
                if (form && form.id && defaultQueueOptions[form.id]) {
                    id = form.id;
                } else {
                    id = DEFAULT_QUEUE_ID;
                }
            }
            if (id) {
                this.queueOptions = defaultQueueOptions[id] || {};
                if (this.queueOptions.queueId) {
                    this.queueOptions = $.extend({}, (defaultQueueOptions[this.queueOptions.queueId] || {}), this.queueOptions);
                } else {
                    // TODO: clean duplicated code
                    var element = richfaces.getDomElement(source);
                    var form;
                    if (element) {
                        element = $(element).closest("form");
                        if (element.length > 0) {
                            form = element.get(0);
                        }
                    }
                    if (form && form.id && defaultQueueOptions[form.id]) {
                        id = form.id;
                    } else {
                        id = DEFAULT_QUEUE_ID;
                    }
                    if (id) {
                        this.queueOptions = $.extend({}, (defaultQueueOptions[id] || {}), this.queueOptions);
                    }
                }
            }

            if (typeof this.queueOptions.requestGroupingId == "undefined") {
                this.queueOptions.requestGroupingId = typeof this.source == "string" ? this.source : this.source.id;
            }

            // Remove the layerX and layerY events (generated in WebKit browsers)
            if (event && event instanceof Object) {
                if ('layerX' in event) delete event.layerX;
                if ('layerY' in event) delete event.layerY;
            }

            // copy of event should be created otherwise IE will fail
            this.event = $.extend({}, event);

            //requestGroupingId is mutable, thus we need special field for it
            this.requestGroupingId = this.queueOptions.requestGroupingId;
            this.eventsCount = 1;
        };

        $.extend(QueueEntry.prototype, {
                // now unused functions: ondrop, clearEntry
                isIgnoreDupResponses: function() {
                    return this.queueOptions.ignoreDupResponses;
                },

                getRequestGroupId: function() {
                    return this.requestGroupingId;
                },

                setRequestGroupId: function(id) {
                    this.requestGroupingId = id;
                },

                resetRequestGroupId: function() {
                    this.requestGroupingId = undefined;
                },

                setReadyToSubmit: function(isReady) {
                    this.readyToSubmit = isReady;
                },

                getReadyToSubmit: function() {
                    return this.readyToSubmit;
                },

                ondrop: function() {
                    var callback = this.queueOptions.onqueuerequestdrop;
                    if (callback) {
                        callback.call(this.queue, this.source, this.options, this.event);
                    }
                },

                onRequestDelayPassed: function() {
                    this.readyToSubmit = true;
                    submitFirstEntry.call(this.queue);
                },

                startTimer: function() {
                    var delay = this.queueOptions.requestDelay;
                    if (typeof delay != "number") {
                        delay = this.queueOptions.requestDelay || 0;
                    }

                    richfaces.log.debug("Queue will wait " + (delay || 0) + "ms before submit");

                    if (delay) {
                        var _this = this;
                        this.timer = window.setTimeout(function() {
                            try {
                                _this.onRequestDelayPassed();
                            } finally {
                                _this.timer = undefined;
                                _this = undefined;
                            }
                        }, delay);
                    } else {
                        this.onRequestDelayPassed();
                    }
                },

                stopTimer: function() {
                    if (this.timer) {
                        window.clearTimeout(this.timer);
                        this.timer = undefined;
                    }
                },

                clearEntry: function() { //???
                    this.stopTimer();
                    if (this.request) {
                        this.request.shouldNotifyQueue = false;
                        this.request = undefined;
                    }
                },

                getEventsCount: function() {
                    return this.eventsCount;
                },

                setEventsCount: function(newCount) {
                    this.eventsCount = newCount;
                }
            });

        // TODO: add this two variables to richfaces and report bug to jsf about constants
        var JSF_EVENT_TYPE = 'event';
        var JSF_EVENT_SUCCESS = 'success';
        var JSF_EVENT_COMPLETE = 'complete';

        var items = [];
        var lastRequestedEntry;

        //TODO: instance of this function will be created for each queue
        var onError = function (data) {
            var message = "richfaces.queue: ajax submit error";
            if (data && data.message) {
                message += ": " + data.message;
            }
            richfaces.log.warn(message);

            lastRequestedEntry = null;
            //TODO: what if somebody is going to clear queue on error?
            submitFirstEntry();
        };

        var onComplete = function (data) {
            if (data.type == JSF_EVENT_TYPE && data.status == JSF_EVENT_SUCCESS) { // or JSF_EVENT_COMPLETE will be rather
                richfaces.log.debug("richfaces.queue: ajax submit successfull");
                lastRequestedEntry = null;
                submitFirstEntry();
            }
        };

        jsf.ajax.addOnEvent(onComplete);
        jsf.ajax.addOnError(onError);

        var submitFirstEntry = function() {
            if (QUEUE_MODE == QUEUE_MODE_PULL && lastRequestedEntry) {
                richfaces.log.debug("richfaces.queue: Waiting for previous submit results");
                return;
            }
            if (isEmpty()) {
                richfaces.log.debug("richfaces.queue: Nothing to submit");
                return;
            }
            var entry;
            if (items[0].getReadyToSubmit()) {
            	try {
                    entry = lastRequestedEntry = items.shift();
                    richfaces.log.debug("richfaces.queue: will submit request NOW");
                    var o = lastRequestedEntry.options;
                    o["AJAX:EVENTS_COUNT"] = lastRequestedEntry.eventsCount;
                    richfaces.ajaxContainer.jsfRequest(lastRequestedEntry.source, lastRequestedEntry.event, o);

                    // call event handlers
                    if (o.queueonsubmit) {
                        o.queueonsubmit.call(entry);
                    }
                    callEventHandler("onrequestdequeue", entry);
            	} catch (error) {
                    onError(error);
            	}
            }
        };

        var isEmpty = function() {
            return (getSize() == 0)
        };
        var getSize = function() {
            return items.length;
        };

        var getLastEntry = function () {
            var lastIdx = items.length - 1;
            return items[lastIdx];
        };

        var updateLastEntry = function (entry) {
            var lastIdx = items.length - 1;
            items[lastIdx] = entry;
        };

        var callEventHandler = function (handlerName, entry) {
            var handler = entry.queueOptions[handlerName];
            if (handler) {
                if (typeof(handler) == "string") {
                    new Function(handler).call(null, entry);
                } else {
                    handler.call(null, entry);
                }
            }
            var opts, handler2;
            if (entry.queueOptions.queueId &&
                (opts = defaultQueueOptions[entry.queueOptions.queueId]) &&
                (handler2 = opts[handlerName])
                && handler2 != handler) {
                // the same about context
                handler2.call(null, entry);
            }
        }

        var pushEntry = function (entry) {
            items.push(entry);
            richfaces.log.debug("New request added to queue. Queue requestGroupingId changed to " + entry.getRequestGroupId());
            // call event handlers
            callEventHandler("onrequestqueue", entry);
        }

        return {
            /**
             * @constant
             * @name RichFaces.queue.DEFAULT_QUEUE_ID
             * @type string
             * */
            DEFAULT_QUEUE_ID: DEFAULT_QUEUE_ID,

            /**
             * Get current queue size
             * @function
             * @name RichFaces.queue.getSize
             *
             * @return {number} size of items in the queue
             * */
            getSize: getSize,

            /**
             * Check if queue is empty
             * @function
             * @name RichFaces.queue.isEmpty
             *
             * @return {boolean} returns true if queue is empty
             * */
            isEmpty: isEmpty,

            /**
             * Extract and submit first QueueEntry in the queue if QueueEntry is ready to submit
             * @function
             * @name RichFaces.queue.submitFirst
             * */
            submitFirst: function () {
                if (!isEmpty()) {
                    var entry = items[0];
                    entry.stopTimer();
                    entry.setReadyToSubmit(true);
                    submitFirstEntry();
                }
            },

            /**
             * Create and push QueueEntry to the queue for ajax requests
             * @function
             * @name RichFaces.queue.push
             *
             * @param {string|DOMElement} source - The DOM element or an id that triggered this ajax request
             * @param {object} [event] - The DOM event that triggered this ajax request
             * @param {object} [options] - The set name/value pairs that can be sent as request parameters to control client and/or server side request processing
             * */
            push: function (source, event, options) {
                var entry = new QueueEntry(this, source, event, options);
                var requestGroupingId = entry.getRequestGroupId();

                var lastEntry = getLastEntry();

                if (lastEntry) {
                    if (lastEntry.getRequestGroupId() == requestGroupingId) {
                        richfaces.log.debug("Similar request currently in queue");

                        richfaces.log.debug("Combine similar requests and reset timer");

                        lastEntry.stopTimer();
                        entry.setEventsCount(lastEntry.getEventsCount() + 1);

                        updateLastEntry(entry);
                        callEventHandler("onrequestqueue", entry);
                    } else {
                        richfaces.log.debug("Last queue entry is not the last anymore. Stopping requestDelay timer and marking entry as ready for submission")

                        lastEntry.stopTimer();
                        lastEntry.resetRequestGroupId();
                        lastEntry.setReadyToSubmit(true);

                        pushEntry(entry);
                        submitFirstEntry();
                    }
                } else {
                    pushEntry(entry);
                }

                // start timer
                entry.startTimer();

            },

            response: function (request, context) {
                if (this.isIgnoreResponse()) {
                    lastRequestedEntry = null;
                    submitFirstEntry();
                } else {
                    richfaces.ajaxContainer.jsfResponse(request, context);
                }
            },

            isIgnoreResponse: function () {
                var entry = items[0];
                return entry && lastRequestedEntry.isIgnoreDupResponses()
                    && lastRequestedEntry.queueOptions.requestGroupingId == entry.queueOptions.requestGroupingId;
            },

            /**
             * Remove all QueueEntry from the queue
             * @function
             * @name RichFaces.queue.clear
             * */
            clear: function () {
                var lastEntry = getLastEntry();
                if (lastEntry) {
                    lastEntry.stopTimer();
                }
                items = [];
            },

            /**
             * Set queue default options
             * @function
             * @name RichFaces.queue.setQueueOptions
             *
             * @param {string||object} [id] - Queue id for storing options or hash with options for multiple options set
             * @param {object} options - Queue options object
             * */
            setQueueOptions: function (id, options) {
                var tid = typeof id;
                if (tid == "string") {
                    // add named queue options
                    if (defaultQueueOptions[id]) {
                        throw "Queue already registered";
                    } else {
                        defaultQueueOptions[id] = options;
                    }
                } else if (tid == "object") {
                    // first parameter is hash with queue names and options
                    $.extend(defaultQueueOptions, id);
                }
                return richfaces.queue;
            },

            getQueueOptions: function (id) {
                return defaultQueueOptions[id] || {};
            }
        }
    }());
}(jQuery, RichFaces, jsf));
;(function($, rf) {

    rf.csv = rf.csv || {};

    var _messages = {};

    var RE_MESSAGE_PATTERN = /\'?\{(\d+)\}\'?/g;

    var interpolateMessage = function (message, values) {
        if (message) {
            var msgObject = message.replace(RE_MESSAGE_PATTERN, "\n$1\n").split("\n");
            var value;
            for (var i = 1; i < msgObject.length; i += 2) {
                value = values[msgObject[i]];
                msgObject[i] = typeof value == "undefined" ? "" : value;
            }
            return msgObject.join('');
        } else {
            return "";
        }
    }

    var _value_query = function(control) {
        if (null !== control.value && undefined != control.value) {
            return control.value;
        } else {
            return "";
        }
    };

    var _check_query = function(control) {
        if (control.checked) {
            return true;
        } else {
            return false;
        }
    };

    var _addOption = function(value, option) {
        if (option.selected) {
            return value[value.length] = option.value;
        }

    };

    var valueExtractors = {
        hidden : function(control) {
            return _value_query(control);
        },

        text : function(control) {
            return _value_query(control);
        },

        textarea : function(control) {
            return _value_query(control);
        },

        'select-one' : function(control) {
            if (control.selectedIndex != -1) {
                return _value_query(control);
            }
        },

        password : function(control) {
            return _value_query(control);
        },

        file : function(control) {
            return _value_query(control);
        },

        radio : function(control) {
            return _check_query(control);
        },

        checkbox : function(control) {
            return _check_query(control);
        },


        'select-multiple' : function(control) {
            var cname = control.name;
            var childs = control.childNodes;
            var value = [];
            for (var i = 0; i < childs.length; i++) {
                var child = childs[i];
                if (child.tagName === 'OPTGROUP') {
                    var options = child.childNodes;
                    for (var j = 0; j < options.length; j++) {
                        value = _addOption(value, options[j]);
                    }
                } else {
                    value = _addOption(value, child);
                }
            }
            return value;
        },

        // command inputs


        // same as link, but have additional field - control, for input
        // submit.
        input : function(control) {
            return _value_query(control);
        }
    };

    var getValue = function(element) {
        var value = "";
        if (valueExtractors[element.type]) {
            value = valueExtractors[element.type](element);
        } else if (undefined !== element.value) {
            value = element.value;
        } else {
            var component = $(element);
            // TODO: add getValue to baseComponent and change jsdocs
            if (component) {
                if (typeof rf.$(component)["getValue"] === "function") {
                    value = rf.$(component).getValue();
                } else {
                    var nestedComponents = $(":editable", component);
                    if (nestedComponents) {
                        var nestedComponent = nestedComponents[0];
                        value = valueExtractors[nestedComponent.type](nestedComponent);
                    }
                }
            }
        }
        return value;
    }

    var getLabel = function(component, id) {
        if (component.p) {
            return component.p.label || id;
        }
        return id;
    }

    $.extend(rf.csv, {
            RE_DIGITS: /^-?\d+$/,
            RE_FLOAT: /^(-?\d+)?(\.(\d+)?(e[+-]?\d+)?)?$/,
            // Messages API
            addMessage: function (messagesObject) {
                $.extend(_messages, messagesObject);
            },
            getMessage: function(customMessage, messageId, values) {
                var message = customMessage ? customMessage : _messages[messageId] || {detail:"",summary:"",severity:0};
                return {detail:interpolateMessage(message.detail, values),summary:interpolateMessage(message.summary, values),severity:message.severity};
            },
            interpolateMessage: function(message, values) {
                return {detail:interpolateMessage(message.detail, values),summary:interpolateMessage(message.summary, values),severity:message.severity};
            },
            sendMessage: function (componentId, message) {
                rf.Event.fire(window.document, rf.Event.MESSAGE_EVENT_TYPE, {'sourceId':componentId, 'message':message});
            },
            clearMessage: function(componentId) {
                rf.Event.fire(window.document, rf.Event.MESSAGE_EVENT_TYPE, {'sourceId':componentId });
            },
            validate: function (event, id, element, params) {
                var element = rf.getDomElement(element || id);
                var value = getValue(element);
                var convertedValue;
                var converter = params.c;
                rf.csv.clearMessage(id);
                if (converter) {
                    var label = getLabel(converter, id);
                    try {
                        if (converter.f)
                            convertedValue = converter.f(value, id, getLabel(converter, id), converter.m);
                    } catch (e) {
                        e.severity = 2;
                        rf.csv.sendMessage(id, e);
                        return false;
                    }
                } else {
                    convertedValue = value;
                }
                var result = true
                var validators = params.v;
                var validationErrorMessage;
                if (validators) {
                    var validatorFunction,validator;
                    for (var i = 0; i < validators.length; i++) {
                        try {
                            validator = validators[i];
                            validatorFunction = validator.f;
                            if (validatorFunction) {
                                validatorFunction(convertedValue, getLabel(validator, id), validator.p, validator.m);
                            }
                        } catch (e) {
                            validationErrorMessage = e;
                            e.severity = 2;
                            rf.csv.sendMessage(id, e);
                            result = false;
                        }
                    }
                }
                if (!result && params.oninvalid instanceof Function) {
                    params.oninvalid([validationErrorMessage]);
                }
                if (result) {
                    if (!params.da && params.a) {
                        params.a.call(element, event, id);
                    } else if (params.onvalid instanceof Function) {
                        params.onvalid();
                    }
                }
                return result;
            }
        });

    /*
     * convert all natural number formats
     *
     */
    var _convertNatural = function(value, label, msg, min, max, sample) {
        var result = null;
        if (value) {
            value = $.trim(value);
            if (!rf.csv.RE_DIGITS.test(value) || (result = parseInt(value, 10)) < min || result > max) {
                throw rf.csv.interpolateMessage(msg, sample ? [value, sample, label] : [value,label]);
            }
        }
        return result;
    }

    var _convertReal = function(value, label, msg, sample) {
        var result = null;
        if (value) {
            value = $.trim(value);
            if (!rf.csv.RE_FLOAT.test(value) || isNaN(result = parseFloat(value))) {
                // TODO - check Float limits.
                throw rf.csv.interpolateMessage(msg, sample ? [value, sample, label] : [value,label]);
            }
        }
        return result;
    }
    /*
     * Converters implementation
     */
    $.extend(rf.csv, {
            "convertBoolean": function (value, label, params, msg) {
                if (typeof value === "string") {
                    var lcvalue = $.trim(value).toLowerCase();
                    if (lcvalue === 'on' || lcvalue === 'true' || lcvalue === 'yes') {
                        return true;
                    }
                } else if (true === value) {
                    return true;
                }
                return false;
            },
            "convertDate": function (value, label, params, msg) {
                var result;
                value = $.trim(value);
                // TODO - JSF date converter options.
                result = Date.parse(value);
                return result;
            },
            "convertByte": function (value, label, params, msg) {
                return _convertNatural(value, label, msg, -128, 127, 254);
            },
            "convertNumber": function (value, label, params, msg) {
                var result;
                value = $.trim(value);
                result = parseFloat(value);
                if (isNaN(result)) {
                    throw rf.csv.interpolateMessage(msg, [value, 99, label]);
                }
                return result;
            },
            "convertFloat": function (value, label, params, msg) {
                return _convertReal(value, label, msg, 2000000000);
            },
            "convertDouble": function (value, label, params, msg) {
                return _convertReal(value, label, msg, 1999999);
            },
            "convertShort": function (value, label, params, msg) {
                return _convertNatural(value, label, msg, -32768, 32767, 32456);
            },
            "convertInteger": function (value, label, params, msg) {
                return _convertNatural(value, label, msg, -2147483648, 2147483648, 9346);
            },
            "convertCharacter": function (value, label, params, msg) {
                return _convertNatural(value, label, msg, 0, 65535);
            },
            "convertLong": function (value, label, params, msg) {
                return _convertNatural(value, label, msg, -9223372036854775808, 9223372036854775807, 98765432);
            }
        });

    var validateRange = function(value, label, params, msg) {
        var isMinSet = typeof params.min === "number";// && params.min >0;
        var isMaxSet = typeof params.max === "number";// && params.max >0;

        if (isMaxSet && value > params.max) {
            throw rf.csv.interpolateMessage(msg, isMinSet ? [params.min,params.max,label] : [params.max,label]);
        }
        if (isMinSet && value < params.min) {
            throw rf.csv.interpolateMessage(msg, isMaxSet ? [params.min,params.max,label] : [params.min,label]);
        }
    };

    var validateRegex = function(value, label, pattern, msg) {
        if (typeof pattern != "string" || pattern.length == 0) {
            throw rf.csv.getMessage(msg, 'REGEX_VALIDATOR_PATTERN_NOT_SET', []);
        }

        var matchPattern = makePatternAMatch(pattern);
        var re;
        try {
            re = new RegExp(matchPattern);
        } catch (e) {
            throw rf.csv.getMessage(msg, 'REGEX_VALIDATOR_MATCH_EXCEPTION', []);
        }
        if (!re.test(value)) {
            throw rf.csv.interpolateMessage(msg, [pattern,label]);
        }

    };

    var makePatternAMatch = function(pattern) {
        if (! (pattern.slice(0, 1) === '^') ) {
            pattern = '^' + pattern;
        }
        if (! (pattern.slice(-1) === '$') ) {
            pattern = pattern + '$';
        }
        return pattern;
    }
    /*
     * Validators implementation
     */
    $.extend(rf.csv, {
            "validateLongRange": function (value, label, params, msg) {
                var type = typeof value;
                if (type !== "number") {
                    if (type != "string") {
                        throw rf.csv.getMessage(msg, 'LONG_RANGE_VALIDATOR_TYPE', [componentId, ""]);
                    } else {
                        value = $.trim(value);
                        if (!rf.csv.RE_DIGITS.test(value) || (value = parseInt(value, 10)) == NaN) {
                            throw rf.csv.getMessage(msg, 'LONG_RANGE_VALIDATOR_TYPE', [componentId, ""]);
                        }
                    }
                }

                validateRange(value, label, params, msg);
            },
            "validateDoubleRange": function (value, label, params, msg) {
                var type = typeof value;
                if (type !== "number") {
                    if (type !== "string") {
                        throw rf.csv.getMessage(msg, 'DOUBLE_RANGE_VALIDATOR_TYPE', [componentId, ""]);
                    } else {
                        value = $.trim(value);
                        if (!rf.csv.RE_FLOAT.test(value) || (value = parseFloat(value)) == NaN) {
                            throw rf.csv.getMessage(msg, 'DOUBLE_RANGE_VALIDATOR_TYPE', [componentId, ""]);
                        }
                    }
                }

                validateRange(value, label, params, msg);
            },
            "validateLength": function (value, label, params, msg) {
                var length = value ? value.length : 0;
                validateRange(length, label, params, msg);
            },
            "validateSize": function (value, label, params, msg) {
                var length = value ? value.length : 0;
                validateRange(length, label, params, msg);
            },
            "validateRegex": function (value, label, params, msg) {
                validateRegex(value, label, params.pattern, msg);
            },
            "validatePattern": function (value, label, params, msg) {
                validateRegex(value, label, params.regexp, msg);
            },
            "validateRequired": function (value, label, params, msg) {
                if (undefined === value || null === value || "" === value) {
                    throw rf.csv.interpolateMessage(msg, [label]);
                }
            },
            "validateTrue": function (value, label, params, msg) {
                if (value !== true) {
                    throw msg;
                }
            },
            "validateFalse": function (value, label, params, msg) {
                if (value !== false) {
                    throw msg;
                }
            },
            "validateMax": function (value, label, params, msg) {
                if (value > params.value) {
                    throw msg;
                }
            },
            "validateMin": function (value, label, params, msg) {
                if (value < params.value) {
                    throw msg;
                }
            }
        });

})(jQuery, window.RichFaces || (window.RichFaces = {}));;/**
 * @author Pavel Yaschenko
 */


(function ($, richfaces, params) {

    richfaces.blankFunction = function () {
    }; //TODO: add it to global library

    /**
     * @class Base class for all components.
     * All RichFaces components should use this class as base or another RichFaces class which based on it.
     *
     <pre><code>
     //Inheritance example:
     (function ($, richfaces, params) {

     // Constructor definition
     richfaces.MyComponent = function(componentId, [options]) {
     // call constructor of parent class
     $super.constructor.call(this, componentId, [options]);

     <span style="color:red">
     // call this.attachToDom method to attach component to dom element
     // its required for the client side API calls and to clean up after ajax request or page unload:
     // destroy method will be called if component attached to dom
     this.attachToDom(componentId);
     </span>
     };

     // define private method
     var myPrivateMethod = function () {
     }

     // Extend component class and add protected methods from parent class to our container
     richfaces.BaseComponent.extend(richfaces.BaseComponent, richfaces.MyComponent);

     // define super class link
     var $super = richfaces.MyComponent.$super;

     // Add new properties and methods
     $.extend(richfaces.MyComponent.prototype, (function (params) {
     return {
     name:"MyComponent",
     f:function (){alert("hello"),
     // destroy method definition for clean up
     destroy: function () {
     // clean up code here

     // call parent's destroy method
     $super.destroy.call(this);
     }
     }
     };
     })(params));
     })(jQuery, RichFaces);
     </code></pre>
     *
     * @memberOf RichFaces
     * @name BaseComponent
     *
     * @constructor
     * @param {String} componentId - component id
     * */
    richfaces.BaseComponent = function(componentId) {
        this.id = componentId;
        this.options = this.options || {};
    };

    var $p = {};

    var extend = function (parent, child, h) {
        h = h || {};
        var F = richfaces.blankFunction;
        F.prototype = parent.prototype;
        child.prototype = new F();
        child.prototype.constructor = child;
        child.$super = parent.prototype;
        if (child.$super == richfaces.BaseComponent.prototype) {
            var r = jQuery.extend({}, $p, h || {});
        }

        var _parent = child;

        // create wrapper with protected methods and variables
        child.extend = function (_child, _h) {
            _h = _h || {};
            var _r = jQuery.extend({}, r || h || {}, _h || {});
            return extend(_parent, _child, _r);
        }
        return r || h;
    };

    /**
     * Method extends child class prototype with parent prototype
     * and return the object with parent's protected methods
     *
     * @function
     * @name RichFaces.BaseComponent.extend
     *
     * @return {object}
     * */
    richfaces.BaseComponent.extend = function(child, h) {
        return extend(richfaces.BaseComponent, child, h);
    };


    /**
     * Easy way to create a subclass.
     *
     * Example:
     *
     * RichFaces.ui.MyClass = RichFaces.BaseComponent.extendClass({
     *     // Class name
     *     name: "MyClass",
     *
     *     // Constructor
     *     init : function (...) {
     *         // ...
     *     },
     *
     *     // public api
     *     publicFunction : function () {
     *         // ...
     *     },
     *
     *     // private api
     *     // names of private methods should start with '__' (2 underscore symbols)
     *     __privateFunction : function () {
     *         // ...
     *     },
     *
     *     __overrideMethod : function () {
     *         // if you need to use method from parent class use link to parent prototype
     *         // like in previous solution with extend method
     *         $super.__overrideMethod.call(this, ...params...);
     *
     *         //...
     *     }
     *
     * });
     *
     * RichFaces.ui.MySecondClass = RichFaces.ui.MyClass({
     *     //
     *     name : "MySecondClass",
     *
     *     // Constructor
     *     init : function (...) {
     *         // ...
     *     }
     *
     * })
     *
     * */
    richfaces.BaseComponent.extendClass = function (methods) {
        var DerivedClass = methods.init || richfaces.blankFunction;
        var SupperClass = this;

        SupperClass.extend(DerivedClass);

        DerivedClass.extendClass = SupperClass.extendClass;

        $.extend(DerivedClass.prototype, methods);

        return DerivedClass;
    };

    $.extend(richfaces.BaseComponent.prototype, (function (params) {
        return {
            /**
             * Component name.
             *
             * @name RichFaces.BaseComponent#name
             * @type String
             * */
            name: "BaseComponent",

            /**
             * Method for converting object to string
             *
             * @function
             * @name RichFaces.BaseComponent#toString
             *
             * @return {String}
             * */
            toString: function() {
                var result = [];
                if (this.constructor.$super) {
                    result[result.length] = this.constructor.$super.toString();
                }
                result[result.length] = this.name;
                return result.join(', ');
            },

            /** TODO: add jsdocs and qunit tests
             *
             */
            getValue: function() {
                return;
            },

            /**
             * Method returns element's id for event handlers binding.
             * Event API calls this method when binding by component object as selector was used.
             *
             * @function
             * @name RichFaces.BaseComponent#getEventElement
             *
             * @return {String}
             * */
            getEventElement: function() {
                return this.id;
            },

            /**
             * Attach component object to DOM element by component id, DOM element or jQuery object and returns the element
             * Its required for the client side API calls and to clean up after ajax request or document unload by
             * calling destroy method
             *
             * @function
             * @name RichFaces.BaseComponent#attachToDom
             * @param {string|DOMElement|jQuery} source - component id, DOM element or DOM elements wrapped by jQuery
             *
             * @return {DOMElement}
             * */
            attachToDom: function(source) {
                source = source || this.id;
                var element = richfaces.getDomElement(source);
                if (element) {
                    var container = element[richfaces.RICH_CONTAINER] = element[richfaces.RICH_CONTAINER] || {};
                    container.component = this;
                }
                return element;
            },

            /**
             * Detach component object from DOM element by component id, DOM element or jQuery object
             *
             * @function
             * @name RichFaces.BaseComponent#detach
             * @param {string|DOMElement|jQuery} source - component id, DOM element or DOM elements wrapped by jQuery
             *
             * */
            detach: function(source) {
                source = source || this.id;
                var element = richfaces.getDomElement(source);
                element && element[richfaces.RICH_CONTAINER] && (element[richfaces.RICH_CONTAINER].component = null);
            },

            /**
             * Invokes event on on the DOM element
             * @param eventType event type, e.g. "click"
             * @param element DOM element object
             * @param event jQuery Event
             * @param data additional data used for event handler
             * @return true if an event is successfully invoked
             */
            invokeEvent: function(eventType, element, event, data) {
                var handlerResult, result;
                var eventObj = $.extend({}, event, {type: eventType});

                if (!eventObj) {
                    if (document.createEventObject) {
                        eventObj = document.createEventObject();
                        eventObj.type = eventType;
                    }
                    else if (document.createEvent) {
                        eventObj = document.createEvent('Events');
                        eventObj.initEvent(eventType, true, false);
                    }
                }
                eventObj[richfaces.RICH_CONTAINER] = {component:this, data: data};

                var eventHandler = this.options['on' + eventType];

                if (typeof eventHandler == "function") {
                    handlerResult = eventHandler.call(element, eventObj);
                }

                if (richfaces.Event) {
                    result = richfaces.Event.callHandler(this, eventType, data);
                }

                if (result != false && handlerResult != false) result = true;

                return result;
            },

            /**
             * Destroy method. Will be called before remove component from the page
             *
             * @function
             * @name RichFaces.BaseComponent#destroy
             *
             * */
            destroy: function() {
            }
        };
    })(params));

    richfaces.BaseNonVisualComponent = function(componentId) {
        this.id = componentId;
        this.options = this.options || {};
    };

    richfaces.BaseNonVisualComponent.extend = function(child, h) {
        return extend(richfaces.BaseNonVisualComponent, child, h);
    };

    richfaces.BaseNonVisualComponent.extendClass = function (methods) {
        var DerivedClass = methods.init || richfaces.blankFunction;
        var SupperClass = this;

        SupperClass.extend(DerivedClass);

        DerivedClass.extendClass = SupperClass.extendClass;

        $.extend(DerivedClass.prototype, methods);

        return DerivedClass;
    };

    $.extend(richfaces.BaseNonVisualComponent.prototype, (function (params) {
        return {
            name: "BaseNonVisualComponent",

            toString: function() {
                var result = [];
                if (this.constructor.$super) {
                    result[result.length] = this.constructor.$super.toString();
                }
                result[result.length] = this.name;
                return result.join(', ');
            },

            getValue: function() {
                return;
            },
            /**
             * Attach component object to DOM element by component id, DOM element or jQuery object and returns the element
             * Its required for the client side API calls and to clean up after ajax request or document unload by
             * calling destroy method
             *
             * @function
             * @name RichFaces.BaseNonVisualComponent#attachToDom
             * @param {string|DOMElement|jQuery} source - component id, DOM element or DOM elements wrapped by jQuery
             *
             * @return {DOMElement}
             * */
            attachToDom: function(source) {
                source = source || this.id;
                var element = richfaces.getDomElement(source);
                if (element) {
                    var container = element[richfaces.RICH_CONTAINER] = element[richfaces.RICH_CONTAINER] || {};
                    if (container.attachedComponents) {
                        container.attachedComponents[this.name] = this;
                    } else {
                        container.attachedComponents = {};
                        container.attachedComponents[this.name] = this;
                    }
                }
                return element;
            },

            /**
             * Detach component object from DOM element by component id, DOM element or jQuery object
             *
             * @function
             * @name RichFaces.BaseNonVisualComponent#detach
             * @param {string|DOMElement|jQuery} source - component id, DOM element or DOM elements wrapped by jQuery
             *
             * */
            detach: function(source) {
                source = source || this.id;
                var element = richfaces.getDomElement(source);
                element && element[richfaces.RICH_CONTAINER] && (element[richfaces.RICH_CONTAINER].attachedComponents[this.name] = null);
            },

            /**
             * Destroy method. Will be called before remove component from the page
             *
             * @function
             * @name RichFaces.BaseNonVisualComponent#destroy
             *
             * */
            destroy: function() {
            }
        };
    })(params));


})(jQuery, window.RichFaces || (window.RichFaces = {}));

// RichFaces Base class for ui components
(function($, rf) {

    rf.ui = rf.ui || {};

    // Constructor definition
    rf.ui.Base = function(componentId, options, defaultOptions) {
        this.namespace = "." + rf.Event.createNamespace(this.name, componentId);
        // call constructor of parent class
        $super.constructor.call(this, componentId);
        this.options = $.extend(this.options, defaultOptions, options);
        this.attachToDom();
        this.__bindEventHandlers();
    };

    // Extend component class and add protected methods from parent class to our container
    rf.BaseComponent.extend(rf.ui.Base);

    // define super class link
    var $super = rf.ui.Base.$super;

    $.extend(rf.ui.Base.prototype, {
            __bindEventHandlers: function () {
            },
            destroy: function () {
                rf.Event.unbindById(this.id, this.namespace);
                $super.destroy.call(this);
            }
        });

})(jQuery, window.RichFaces || (window.RichFaces = {}));;function toolbarHandlers(options) {
    if (options.id && options.events) {
        jQuery('.rf-tb-itm', document.getElementById(options.id)).bind(
            options.events);
    }
    var groups = options.groups;
    if (groups && groups.length > 0) {
        var group;
        var i;
        for (i in groups) {
            group = groups[i];
            if (group) {
                var groupIds = group.ids;
                var y;
                var groupElements = [];
                for (y in groupIds) {
                    groupElements.push(document.getElementById(groupIds[y]));
                }
                jQuery(groupElements).bind(group.events);
            }
        }
    }
}
;/**
 * @fileOverview jQuery setPosition Plugin to place elements on the page
 * @author Pavel Yaschenko, 05.2010
 * @version 0.5
 */

// draft examples of usage
// jQuery('#tooltip').setPosition('#aaa',{from:'bottom-left', to:'auto-auto'});
// jQuery('#bbb').bind("click",function(e){jQuery('#tooltip').setPosition(e);});
// TODO: clear code
// TODO: optimization

// jQuery(target).setPosition(source,[params])
// source:
//			jQuery selector
//			object {id:}
//			object {left:,top:,width:,height} // all properties are optimal
//			jQuery object
//			dom element
//			event
//
//	params:
//			type: string // position type
//			collision: string // not implemented
//			offset: array [x,y] // implemented only for noPositionType
//			from: string // place target relative of source
//			to: string // direction for target

	/**
	  * @name jQuery
	  * @namespace jQuery 
	  * */

(function($) {
	/**
     * Place DOM element relative to another element or using position parameters. Elements with style.display='none' also supported.
     * 
     * @example jQuery('#tooltip').setPosition('#myDiv',{from:'LB', to:'AA'});
     * @example jQuery('#myClickDiv').bind("click",function(e){jQuery('#tooltip').setPosition(e);});
     *
     * @function
     * @name jQuery#setPosition
     * 
     * @param {object} source - object that provides information about new position. <p>
     * accepts:
     * <ul>
     * 		<li>jQuery selector or object</li>
     * 		<li>object with id: <code>{id:'myDiv'}</code></li>
     * 		<li>object with region settings: <code>{left:0, top:0, width:100, height:100}</code></li>
     * 		<li>DOM Element</li>
     * 		<li>Event object</li>
     * </ul>
     * </p>
     * @param {object} params - position parameters:
     * <dl><dt>
     * @param {string} [params.type] - position type that defines positioning and auto positioning rules ["TOOLTIP","DROPDOWN"]</dt><dt>
     * @param {string} [params.collision] - not implemented yet</dt><dt>
     * @param {array} [params.offset] - provides array(2) with x and y for manually position definition<br/>
     * affects only if "type", "from" and "to" not defined</dt><dt>
     * @param {string} [params.from] - place target relative of source // draft definition</dt><dt>
     * @param {string} [params.to] - direction for target // draft definition</dt>
     * </blockquote>
     *
     * @return {jQuery} jQuery wrapped DOM elements
     * */
	$.fn.setPosition = function(source, params) {
		var stype = typeof source;
		if (stype == "object" || stype == "string") {
			var rect = {};
			if (stype == "string" || source.nodeType || source instanceof jQuery || typeof source.length!="undefined") {
					rect = getElementRect(source);
			} else if (source.type) {
				rect = getPointerRect(source);
			} else if (source.id) {
				rect = getElementRect(document.getElementById(source.id));
			} else {
				rect = source;
			}
			
			var params = params || {};
			var def = params.type || params.from || params.to ? $.PositionTypes[params.type || defaultType] : {noPositionType:true};
			
			var options =  $.extend({}, defaults, def, params);
			if (!options.noPositionType) {
				if (options.from.length>2) {
					options.from = positionDefinition[options.from.toLowerCase()];
				}
				if (options.to.length>2) {
					options.to = positionDefinition[options.to.toLowerCase()];
				}
			}
			return this.each(function() {
					element = $(this);
					//alert(rect.left+" "+rect.top+" "+rect.width+" "+rect.height);
					position(rect, element, options);
				});
		}
		return this;
	};
	
	var defaultType = "TOOLTIP";
	var defaults = {
		collision: "",
		offset: [0,0]
	};
	var re = /^(left|right)-(top|buttom|auto)$/i;
	
	// TODO: make it private
	var positionDefinition = {
		'top-left':'LT',
		'top-right':'RT',
		'bottom-left':'LB',
		'bottom-right':'RB',
		'top-auto':'AT',
		'bottom-auto':'AB',
		'auto-left':'LA',
		'auto-right':'RA',
		'auto-auto':'AA'
	};
	$.PositionTypes = {
		// horisontal constants: L-left, R-right, C-center, A-auto
		// vertical constants:   T-top, B-bottom, M-middle, A-auto
		// for auto: list of joinPoint-Direction pairs
		TOOLTIP: {from:"AA", to:"AA", auto:["RTRT", "RBRT", "LTRT", "RTLT", "LTLT", "LBLT", "RTRB", "RBRB", "LBRB", "RBLB"]},
		DROPDOWN:{from:"AA", to:"AA", auto:["LBRB", "LTRT", "RBLB", "RTLT"]},
        DDMENUGROUP:{from:"AA", to:"AA", auto:["RTRB", "RBRT", "LTLB", "LBLT"]}
	};
	
	/** 
	  * Add or replace position type rules for auto positioning.
	  * Does not fully determinated with parameters yet, only draft version.
	  * 
	  * @function
	  * @name jQuery.addPositionType
	  * @param {string} type - name of position rules
	  * @param {object} option - options of position rules
	  * */
	$.addPositionType = function (type, options) {
		// TODO: change [options] to [from, to, auto]
		/*var obj = {};
		if (match=from.match(re))!=null ) {
			obj.from = [ match[1]=='right' ? 'R' : 'L', match[2]=='bottom' ? 'B' : 'T'];
		}
		if (match=to.match(re))!=null ) {
			obj.to = [ match[1]=='right' ? 'R' : match[1]=='left' ? 'L' : 'A', match[2]=='bottom' ? 'B' : match[2]=='top' ? 'T' : 'A'];
		}*/
		$.PositionTypes[type] = options;
	}
    
    function getPointerRect (event) {
		var e = $.event.fix(event);
		return {width: 0, height: 0, left: e.pageX, top: e.pageY};
	};

	function getElementRect (element) {
		var jqe = $(element);
		var offset = jqe.offset();
		var rect = {width: jqe.outerWidth(), height: jqe.outerHeight(), left: Math.floor(offset.left), top: Math.floor(offset.top)};
		if (jqe.length>1) {
			var width, height, offset;
			var e;
			for (var i=1;i<jqe.length;i++) {
				e = jqe.eq(i);
				if (e.css('display')=="none") continue;
				width = e.outerWidth();
				height = e.outerHeight();
				offset = e.offset();
				var d = rect.left - offset.left;
				if (d<0) {
					if (width-d > rect.width) rect.width = width - d;
				} else {
					rect.width += d;
				}
				var d = rect.top - offset.top;
				if (d<0) {
					if (height-d > rect.height) rect.height = height -d;
				} else {
					rect.height += d;
				}
				if (offset.left < rect.left) rect.left = offset.left;
				if (offset.top < rect.top) rect.top = offset.top;
			}
		}
		
		return rect;
	};
	
	function checkCollision (elementRect, windowRect) {
		// return 0 if elementRect in windowRect without collision
		if (elementRect.left >= windowRect.left &&
			elementRect.top >= windowRect.top &&
			elementRect.right <= windowRect.right &&  
			elementRect.bottom <= windowRect.bottom)
			return 0;
		// return collision squire
		var rect = {left:   (elementRect.left>windowRect.left ? elementRect.left : windowRect.left),
					top:    (elementRect.top>windowRect.top ? elementRect.top : windowRect.top)};
		rect.right = elementRect.right<windowRect.right ? (elementRect.right==elementRect.left ? rect.left : elementRect.right) : windowRect.right;
		rect.bottom = elementRect.bottom<windowRect.bottom ? (elementRect.bottom==elementRect.top ? rect.top : elementRect.bottom) : windowRect.bottom;

		return (rect.right-rect.left) * (rect.bottom-rect.top);
	};
	
	//function fromLeft() {
	/*
	 * params: {
	 * 	left,top,width,height, //baseRect
	 * 	ox,oy, //rectoffset
	 * 	w,h // elementDim
	 * }
	 */
	/*	return this.left;
	}
	
	function fromRight(params) {
			return this.left + this.width - this.w;
	}
	
	function (params) {
		var rect = {left:fromLeft.call(params), right:fromRight.call(params), top:}
	}*/
	
	function getPositionRect(baseRect, rectOffset, elementDim, pos) {
		var rect = {};
		// TODO: add support for center and middle // may be middle rename to center too
		
		var v = pos.charAt(0);
		if (v=='L') {
			rect.left = baseRect.left;
		} else if (v=='R') {
			rect.left = baseRect.left + baseRect.width;
		}
		
		v = pos.charAt(1);
		if (v=='T') {
			rect.top = baseRect.top;
		} else if (v=='B') {
			rect.top = baseRect.top + baseRect.height;
		}
		
		v = pos.charAt(2);
		if (v=='L') {
			rect.left -= rectOffset[0];
			rect.right = rect.left;
			rect.left -= elementDim.width;
		} else if (v=='R') {
			rect.left += rectOffset[0];
			rect.right = rect.left + elementDim.width;
		}		
		
		v = pos.charAt(3);
		if (v=='T') {
			rect.top -= rectOffset[1];
			rect.bottom = rect.top;
			rect.top -= elementDim.height;
		} else if (v=='B') {
			rect.top += rectOffset[1];
			rect.bottom = rect.top + elementDim.height;
		}
		
		return rect;
	}
	
	function __mergePos(s1,s2) {
		var result = "";
		var ch;
		while (result.length < s1.length) {
			ch = s1.charAt(result.length);
			result += ch == 'A' ? s2.charAt(result.length) : ch; 
		}
		return result;
	}
	
	function calculatePosition (baseRect, rectOffset, windowRect, elementDim, options) {

		var theBest = {square:0};
		var rect;
		var s;
		var ox, oy;
		var p = options.from+options.to;
		
		if (p.indexOf('A')<0) {
			return getPositionRect(baseRect, rectOffset, elementDim, p);
		} else {
			var flag = p=="AAAA";
			var pos;
			for (var i = 0; i<options.auto.length; i++) {
				
				// TODO: draft functional
				pos = flag ? options.auto[i] : __mergePos(p, options.auto[i]);
				rect = getPositionRect(baseRect, rectOffset, elementDim, pos);
				ox = rect.left; oy = rect.top;
				s = checkCollision(rect, windowRect);
				if (s!=0) {
					if (ox>=0 && oy>=0 && theBest.square<s) theBest = {x:ox, y:oy, square:s};
				} else break;
			}
			if (s!=0 && (ox<0 || oy<0 || theBest.square>s)) {
				ox=theBest.x; oy=theBest.y
			}
		}
		
		return {left:ox, top:oy};
	}
	
	function position (rect, element, options) {
		var width = element.width();
		var height = element.height();
		
		rect.width = rect.width || 0;
		rect.height = rect.height || 0;
		
		var left = parseInt(element.css('left'),10);
		if (isNaN(left) || left==0) {
			left = 0;
			element.css('left', '0px');
		}
		if (isNaN(rect.left)) rect.left = left;
		
		var top = parseInt(element.css('top'),10);
		if (isNaN(top) || top==0) {
			top = 0;
			element.css('top', '0px');
		}
		if (isNaN(rect.top)) rect.top = top;
		
		var pos = {};
		if (options.noPositionType) {
			pos.left = rect.left + rect.width + options.offset[0];
			pos.top = rect.top + options.offset[1];
		} else {
			var jqw = $(window);
			var winRect = {left:jqw.scrollLeft(), top:jqw.scrollTop()};
			winRect.right = winRect.left + jqw.width();
			winRect.bottom = winRect.top + jqw.height();
		
			pos = calculatePosition(rect, options.offset, winRect, {width:width, height:height}, options);		
		}
		
		// jQuery does not support to get offset for hidden elements
		var hideElement=false;
		var eVisibility;
		var e;
		if (element.css("display")=="none") {
			hideElement=true;
			e = element.get(0);
			eVisibility = e.style.visibility;
			e.style.visibility = 'hidden';
			e.style.display = 'block';
		}
		
		var elementOffset = element.offset();
		
		if (hideElement) {
			e.style.visibility = eVisibility;
			e.style.display = 'none';
		}
		
		pos.left += left - Math.floor(elementOffset.left);
		pos.top += top - Math.floor(elementOffset.top);	

		if (left!=pos.left) {
			element.css('left', (pos.left + 'px'));
		}
		if (top!=pos.top) {
			element.css('top', (pos.top + 'px'));
		}
	};

})(jQuery);

;(function(jquery, richfaces) {
    var logLevels = ['debug', 'info', 'warn', 'error'];
    var logLevelsPadded = {'debug': 'debug', 'info': 'info ', 'warn': 'warn ', 'error': 'error'};
    var logLevelValues = {'debug': 1, 'info': 2, 'warn': 3, 'error': 4};

    var logClassMethods = {

        __import: function(doc, node) {
            if (doc === document) {
                return node;
            }

            var result = jquery();
            for (var i = 0; i < node.length; i++) {
                if (doc.importNode) {
                    result = result.add(doc.importNode(node[i], true));
                } else {
                    var container = doc.createElement("div");
                    container.innerHTML = node[i].outerHTML;
                    for (var child = container.firstChild; child; child = child.nextSibling) {
                        result = result.add(child);
                    }
                }
            }

            return result;
        },

        __getStyles: function() {
            var head = jQuery("head");

            if (head.length == 0) {
                return "";
            }

            try {
                //TODO - BASE element support?
                var clonedHead = head.clone();
                if (clonedHead.children().length == head.children().length) {
                    return clonedHead.children(":not(style):not(link[rel='stylesheet'])").remove().end().html();
                } else {
                    var result = new Array();
                    head.children("style, link[rel='stylesheet']").each(function() {
                        result.push(this.outerHTML);
                    });

                    return result.join('');
                }
            } catch (e) {
                return "";
            }
        },

        __openPopup: function() {
            if (!this.__popupWindow || this.__popupWindow.closed) {
                this.__popupWindow = open("", "_richfaces_logWindow", "height=400, width=600, resizable = yes, status=no, " +
                    "scrollbars = yes, statusbar=no, toolbar=no, menubar=no, location=no");

                var doc = this.__popupWindow.document;

                doc.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" +
                    "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>" + this.__getStyles() + "</head>" +
                    "<body onunload='window.close()'><div id='richfaces.log' clas='rf-log rf-log-popup'></div></body></html>");
                doc.close();
                this.__initializeControls(doc);
            } else {
                this.__popupWindow.focus();
            }
        },

        __hotkeyHandler: function(event) {
            if (event.ctrlKey && event.shiftKey) {
                if ((this.hotkey || 'l').toLowerCase() == String.fromCharCode(event.keyCode).toLowerCase()) {
                    this.__openPopup();
                }
            }
        },

        __getTimeAsString: function() {
            var date = new Date();

            var timeString = this.__lzpad(date.getHours(), 2) + ':' + this.__lzpad(date.getMinutes(), 2) + ':' +
                this.__lzpad(date.getSeconds(), 2) + '.' + this.__lzpad(date.getMilliseconds(), 3);

            return timeString;
        },

        __lzpad: function(s, length) {
            s = s.toString();
            var a = new Array();
            for (var i = 0; i < length - s.length; i++) {
                a.push('0');
            }
            a.push(s);
            return a.join('');
        },

        __getMessagePrefix: function(level) {
            return logLevelsPadded[level] + '[' + this.__getTimeAsString() + ']: ';
        },

        __setLevelFromSelect: function(event) {
            this.setLevel(event.target.value);
        },

        __initializeControls : function(doc) {
            var console = jquery("#richfaces\\.log", doc);

            var clearBtn = console.children("button.rf-log-element");
            if (clearBtn.length == 0) {
                clearBtn = jquery("<button type='button' name='clear' class='rf-log-element'>Clear</button>", doc).appendTo(console);
            }

            clearBtn.click(jquery.proxy(this.clear, this));

            var levelSelect = console.children("select.rf-log-element");
            if (levelSelect.length == 0) {
                levelSelect = jquery("<select class='rf-log-element' name='richfaces.log' />", doc).appendTo(console);
            }

            if (levelSelect.children().length == 0) {
                for (var l = 0; l < logLevels.length; l++) {
                    jquery("<option value='" + logLevels[l] + "'>" + logLevels[l] + "</option>", doc).appendTo(levelSelect);
                }
            }

            levelSelect.val(this.getLevel());
            levelSelect.change(jquery.proxy(this.__setLevelFromSelect, this));

            var consoleEntries = console.children(".rf-log-contents");
            if (consoleEntries.length == 0) {
                consoleEntries = jquery("<div class='rf-log-contents'></div>", doc).appendTo(console);
            }
            this.__contentsElement = consoleEntries;
        },

        __append: function(element) {
            var target = this.__contentsElement;
            if (this.mode == "popup") {
                var doc = this.__popupWindow.document;
                jquery(doc.createElement("div")).appendTo(target).append(this.__import(doc, element));
            } else {
                jquery(document.createElement("div")).appendTo(target).append(element);
            }
        },

        __log: function(level, message) {
            //TODO scroll to the added message
            //TODO check popup is opened
            if (this.mode == 'console') {
                var logMsg = 'RichFaces: ' + message;
                if (console[level]) {
                    console[level](logMsg);
                } else if (console.log) {
                    console.log(logMsg);
                }
                return;
            }
            
            if (!this.__contentsElement) {
                return;
            }

            if (logLevelValues[level] >= logLevelValues[this.getLevel()]) {
                var newEntry = jquery();
                newEntry = newEntry.add(jquery("<span class='rf-log-entry-lbl rf-log-entry-lbl-" + level + "'></span>").text(this.__getMessagePrefix(level)));

                var entrySpan = jquery("<span class='rf-log-entry-msg rf-log-entry-msg-" + level + "'></span>");
                if (typeof message != 'object' || !message.appendTo) {
                    entrySpan.text(message);
                } else {
                    message.appendTo(entrySpan);
                }

                newEntry = newEntry.add(entrySpan);

                this.__append(newEntry);
            }
        },

        init: function(options) {
            $super.constructor.call(this, 'richfaces.log');
            this.attachToDom();
            richfaces.setLog(this);

            options = options || {};

            this.level = options.level;
            this.hotkey = options.hotkey;
            this.mode = (options.mode || 'inline');

            if (this.mode == 'console') {
                // do nothing
            } else if (this.mode == 'popup') {
                this.__boundHotkeyHandler = jquery.proxy(this.__hotkeyHandler, this);
                jquery(document).bind('keydown', this.__boundHotkeyHandler);
            } else {
                this.__initializeControls(document);
            }
        },

        destroy: function() {
            richfaces.setLog(null);

            //TODO test this method
            if (this.__popupWindow) {
                this.__popupWindow.close();
            }
            this.__popupWindow = null;

            if (this.__boundHotkeyHandler) {
                jquery(document).unbind('keydown', this.__boundHotkeyHandler);
                this.__boundHotkeyHandler = null;
            }

            this.__contentsElement = null;
            $super.destroy.call(this);
        },

        setLevel: function(level) {
            this.level = level;
            this.clear();
        },

        getLevel: function() {
            return this.level || 'info';
        },

        clear: function() {
            if (this.__contentsElement) {
                this.__contentsElement.children().remove();
            }
        }
    };

    for (var i = 0; i < logLevels.length; i++) {
        logClassMethods[logLevels[i]] = (function() {
            var level = logLevels[i];
            return function(message) {
                this.__log(level, message);
            }
        }());
    }

    richfaces.HtmlLog = richfaces.BaseComponent.extendClass(logClassMethods);
    // define super class link
    var $super = richfaces.HtmlLog.$super;

    jQuery(document).ready(function() {
        if (typeof jsf != 'undefined') {
            (function(jQuery, richfaces, jsf) {

                //JSF log adapter
                var identifyElement = function(elt) {
                    var identifier = '<' + elt.tagName.toLowerCase();
                    var e = jQuery(elt);
                    if (e.attr('id')) {
                        identifier += (' id=' + e.attr('id'));
                    }
                    if (e.attr('class')) {
                        identifier += (' class=' + e.attr('class'));
                    }

                    identifier += ' ...>';

                    return identifier;
                }

                var formatPartialResponseElement = function(logElement, responseElement) {
                    var change = jQuery(responseElement);

                    logElement.append("Element <b>" + responseElement.nodeName + "</b>");
                    if (change.attr("id")) {
                        logElement.append(document.createTextNode(" for id=" + change.attr("id")));
                    }

                    jQuery(document.createElement("br")).appendTo(logElement);
                    jQuery("<span class='rf-log-entry-msg-xml'></span>").appendTo(logElement).text(change.toXML());
                    jQuery(document.createElement("br")).appendTo(logElement);
                }

                var formatPartialResponse = function(partialResponse) {
                    var logElement = jQuery(document.createElement("span"));

                    partialResponse.children().each(function() {
                        var responseElement = jQuery(this);
                        if (responseElement.is('changes')) {
                            logElement.append("Listing content of response <b>changes</b> element:<br />");
                            responseElement.children().each(function() {
                                formatPartialResponseElement(logElement, this);
                            });
                        } else {
                            formatPartialResponseElement(logElement, this);
                        }
                    });

                    return logElement;
                }

                var jsfAjaxLogAdapter = function(data) {
                    try {
                        var log = richfaces.log;

                        var source = data.source;
                        var type = data.type;

                        var responseCode = data.responseCode;
                        var responseXML = data.responseXML;
                        var responseText = data.responseText;

                        if (type != 'error') {
                            log.info("Received '" + type + "' event from " + identifyElement(source));

                            if (type == 'beforedomupdate') {
                                var partialResponse;

                                if (responseXML) {
                                    partialResponse = jQuery(responseXML).children("partial-response");
                                }

                                var responseTextEntry = jQuery("<span>Server returned responseText: </span><span class='rf-log-entry-msg-xml'></span>").eq(1).text(responseText).end();

                                if (partialResponse && partialResponse.length) {
                                    log.debug(responseTextEntry);
                                    log.info(formatPartialResponse(partialResponse));
                                } else {
                                    log.info(responseTextEntry);
                                }
                            }
                        } else {
                            var status = data.status;
                            log.error("Received '" + type + '@' + status + "' event from " + identifyElement(source));
                            log.error("[" + data.responseCode + "] " + data.errorName + ": " + data.errorMessage);
                        }
                    } catch (e) {
                        //ignore logging errors
                    }
                };

                var eventsListener = richfaces.createJSFEventsAdapter({
                        begin: jsfAjaxLogAdapter,
                        beforedomupdate: jsfAjaxLogAdapter,
                        success: jsfAjaxLogAdapter,
                        complete: jsfAjaxLogAdapter,
                        error: jsfAjaxLogAdapter
                    });

                jsf.ajax.addOnEvent(eventsListener);
                jsf.ajax.addOnError(eventsListener);
                //
            }(jQuery, RichFaces, jsf));
        }
        ;
    });

}(jQuery, RichFaces));;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
(function(richfaces, jQuery) {

    var getGlobalStatusNameVariable = function() {
        return richfaces.statusName;
    }

    var RICHFACES_AJAX_STATUS = "richfaces:ajaxStatus";

    var getStatusDataAttributeName = function(statusName) {
        return statusName ? (RICHFACES_AJAX_STATUS + "@" + statusName) : RICHFACES_AJAX_STATUS;
    };

    var statusAjaxEventHandler = function(data, methodName) {
        if (methodName) {
            //global status name
            var statusName = getGlobalStatusNameVariable();
            var source = data.source;

            var statusApplied = false;
            var statusDataAttribute = getStatusDataAttributeName(statusName);

            var statusContainers;
            if (statusName) {
                statusContainers = [jQuery(document)];
            } else {
                statusContainers = [jQuery(source).parents('form'), jQuery(document)];
            }

            for (var containerIdx = 0; containerIdx < statusContainers.length && !statusApplied;
                 containerIdx++) {

                var statusContainer = statusContainers[containerIdx];
                var statuses = statusContainer.data(statusDataAttribute);
                if (statuses) {
                    for (var statusId in statuses) {
                        var status = statuses[statusId];
                        var result = status[methodName].apply(status, arguments);
                        if (result) {
                            statusApplied = true;
                        } else {
                            delete statuses[statusId];
                        }
                    }

                    if (!statusApplied) {
                        statusContainer.removeData(statusDataAttribute);
                    }
                }
            }
        }
    };

    var initializeStatuses = function() {
        var thisFunction = arguments.callee;
        if (!thisFunction.initialized) {
            thisFunction.initialized = true;

            var jsfEventsListener = richfaces.createJSFEventsAdapter({
                    begin: function(event) {
                        statusAjaxEventHandler(event, 'start');
                    },
                    error: function(event) {
                        statusAjaxEventHandler(event, 'error');
                    },
                    success: function(event) {
                        statusAjaxEventHandler(event, 'success');
                    },
                    complete: function() {
                        richfaces.setGlobalStatusNameVariable(null);
                    }
                });

            jsf.ajax.addOnEvent(jsfEventsListener);
            //TODO blocks default alert error handler
            jsf.ajax.addOnError(jsfEventsListener);
        }
    };

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.Status = richfaces.BaseComponent.extendClass({

            name: "Status",

            //TODO - support for parallel requests
            init: function(id, options) {
                this.id = id;
                this.attachToDom();
                this.options = options || {};
                this.register();
            },

            register: function() {
                initializeStatuses();

                var statusName = this.options.statusName;
                var dataStatusAttribute = getStatusDataAttributeName(statusName);

                var container;
                if (statusName) {
                    container = jQuery(document);
                } else {
                    container = jQuery(richfaces.getDomElement(this.id)).parents('form');
                    if (container.length == 0) {
                        container = jQuery(document);
                    }
                    ;
                }

                var statuses = container.data(dataStatusAttribute);
                if (!statuses) {
                    statuses = {};
                    container.data(dataStatusAttribute, statuses);
                }

                statuses[this.id] = this;
            },

            start: function() {
                if (this.options.onstart) {
                    this.options.onstart.apply(this, arguments);
                }

                return this.__showHide('.rf-st-start');
            },

            stop: function() {
                this.__stop();
                return this.__showHide('.rf-st-stop');
            },

            success: function() {
                if (this.options.onsuccess) {
                    this.options.onsuccess.apply(this, arguments);
                }
                return this.stop();
            },

            error: function() {
                if (this.options.onerror) {
                    this.options.onerror.apply(this, arguments);
                }
                this.__stop();

                return this.__showHide(':not(.rf-st-error) + .rf-st-stop, .rf-st-error');
            },

            __showHide: function(selector) {
                var element = jQuery(richfaces.getDomElement(this.id));
                if (element) {
                    var statusElts = element.children();
                    statusElts.each(function() {
                        var t = jQuery(this);
                        t.css('display', t.is(selector) ? '' : 'none');
                    });

                    return true;
                }
                return false;
            },

            __stop: function () {
                if (this.options.onstop) {
                    this.options.onstop.apply(this, arguments);
                }
            }
        });
}(window.RichFaces, jQuery));
;/*
 * code review by Pavel Yaschenko
 * 
 * 1. No need to save DOM element (this.indicator). We can use id to get dom element. It helps to avoid memory leaks :)
 * 
 * 2. Name refactoring: change names acceptClass, rejectClass, draggingClass 
 * 						to more readable names: getAcceptClass, getRejectClass, getDragClass
 * 
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.DragIndicator = function(id, options) {
        $super.constructor.call(this, id);
        this.attachToDom(id);

        this.indicator = $(document.getElementById(id));
        this.options = options;
    };

    var defaultOptions = {
    };

    rf.BaseComponent.extend(rf.ui.DragIndicator);
    var $super = rf.ui.DragIndicator.$super;

    $.extend(rf.ui.DragIndicator.prototype, ( function () {
        return {
            show : function() {
                this.indicator.show();
            },

            hide: function() {
                this.indicator.hide();
            },

            getAcceptClass: function() {
                return this.options.acceptClass;
            },

            getRejectClass: function() {
                return this.options.rejectClass;
            },

            getDraggingClass: function() {
                return this.options.draggingClass;
            },

            getElement: function() {
                return this.indicator;
            }
        }
    })());

})(jQuery, window.RichFaces);

;(function($, rf) {
    rf.ui = rf.ui || {};
    var defaultOptions = {
    };
    rf.ui.Poll = function(componentId, options) {
        $super.constructor.call(this, componentId, options);
        this.id = componentId;
        this.attachToDom();
        this.interval = options.interval || 1000;
        this.ontimer = options.ontimer;

        this.pollElement = rf.getDomElement(this.id);

        rf.ui.pollTracker = rf.ui.pollTracker || {};

        if (options.enabled) {
            this.startPoll();
        }
    }

    rf.BaseComponent.extend(rf.ui.Poll);
    var $super = rf.ui.Poll.$super;
    $.extend(rf.ui.Poll.prototype, (function() {
        return {
            name: "Poll",

            startPoll: function() {
                this.stopPoll();
                var poll = this;
                rf.ui.pollTracker[poll.id] = window.setTimeout(function() {
                    try {
                        poll.ontimer.call(poll.pollElement || window);
                        poll.startPoll();
                    } catch (e) {
                        // TODO: handle exception
                    }
                }, poll.interval);
            },

            stopPoll : function() {
                if (rf.ui.pollTracker && rf.ui.pollTracker[this.id]) {
                    window.clearTimeout(rf.ui.pollTracker[this.id]);
                    delete rf.ui.pollTracker[this.id];
                }
            },

            setZeroRequestDelay : function(options) {
                if (typeof options.requestDelay == "undefined") {
                    options.requestDelay = 0;
                }
            },

            destroy : function() {
                this.stopPoll();
                this.detach(this.id);
                // call parent's destroy method
                $super.destroy.call(this);
            }

        };
    })());

})(jQuery, RichFaces);;(function ($, richfaces) {

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.DataTable = function(id, options) {
        $super.constructor.call(this, id);
        this.options = $.extend(this.options, options || {});
        this.attachToDom();

    };

    richfaces.BaseComponent.extend(richfaces.ui.DataTable);
    var $super = richfaces.ui.DataTable.$super;

    $.extend(richfaces.ui.DataTable, {
            SORTING: "rich:sorting",
            FILTERING: "rich:filtering",
            SUBTABLE_SELECTOR:".rf-cst"
        });

    $.extend(richfaces.ui.DataTable.prototype, ( function () {

        var invoke = function(event, attributes) {
            richfaces.ajax(this.id, event, {"parameters" : attributes});
        };

        var createParameters = function(type, id, arg1, arg2) {
            var parameters = {};
            var key = this.id + type;
            parameters[key] = (id + ":" + (arg1 || "") + ":" + arg2);

            var eventOptions = this.options.ajaxEventOption;
            for (key in eventOptions) {
                if (!parameters[key]) {
                    parameters[key] = eventOptions[key];
                }
            }
            return parameters;
        };


        return {

            name : "RichFaces.ui.DataTable",

            sort: function(columnId, direction, isClear) {
                invoke.call(this, null, createParameters.call(this, richfaces.ui.DataTable.SORTING, columnId, direction, isClear));
            },

            clearSorting: function() {
                this.sort("", "", true);
            },

            filter: function(columnId, filterValue, isClear) {
                invoke.call(this, null, createParameters.call(this, richfaces.ui.DataTable.FILTERING, columnId, filterValue, isClear));
            },

            clearFiltering: function() {
                this.filter("", "", true);
            },

            expandAllSubTables: function() {
                this.invokeOnSubTables('expand');
            },

            collapseAllSubTables: function() {
                this.invokeOnSubTables('collapse');
            },

            switchSubTable: function(id) {
                this.getSubTable(id).switchState();
            },

            getSubTable: function(id) {
                return richfaces.$(id);
            },

            invokeOnSubTables: function(funcName) {
                var elements = $(document.getElementById(this.id)).children(richfaces.ui.DataTable.SUBTABLE_SELECTOR);
                var invokeOnComponent = this.invokeOnComponent;
                elements.each(
                    function() {
                        if (this.firstChild && this.firstChild[richfaces.RICH_CONTAINER] && this.firstChild[richfaces.RICH_CONTAINER].component) {
                            var component = this.firstChild[richfaces.RICH_CONTAINER].component;
                            if (component instanceof RichFaces.ui.CollapsibleSubTable) {
                                invokeOnComponent(component, funcName);
                            }
                        }
                    }
                );
            },

            invokeOnSubTable: function(id, funcName) {
                var subtable = this.getSubTable(id);
                this.invokeOnComponent(subtable, funcName);
            },

            invokeOnComponent: function(component, funcName) {
                if (component) {
                    var func = component[funcName];
                    if (typeof func == 'function') {
                        func.call(component);
                    }
                }
            },
            destroy: function() {
                $super.destroy.call(this);
            }
        }

    })());

})(jQuery, window.RichFaces);

;(function ($, richfaces) {

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.CollapsibleSubTable = function(id, f, options) {
        this.id = id;
        this.stateInput = options.stateInput;
        this.optionsInput = options.optionsInput;
        this.expandMode = options.expandMode || richfaces.ui.CollapsibleSubTable.MODE_CLNT;
        this.eventOptions = options.eventOptions;
        this.formId = f;

        this.attachToDom();
    };

    $.extend(richfaces.ui.CollapsibleSubTable, {
            MODE_AJAX: "ajax",
            MODE_SRV: "server",
            MODE_CLNT: "client",
            collapse: 0,
            expand: 1
        });

    richfaces.BaseComponent.extend(richfaces.ui.CollapsibleSubTable);
    var $super = richfaces.ui.CollapsibleSubTable.$super;

    $.extend(richfaces.ui.CollapsibleSubTable.prototype, (function () {

        var element = function() {
            //use parent tbody as parent dom elem
            return $(document.getElementById(this.id)).parent();
        };

        var stateInputElem = function() {
            return $(document.getElementById(this.stateInput));
        };

        var optionsInputElem = function() {
            return $(document.getElementById(this.optionsInput));
        };

        var ajax = function(e, options) {
            this.__switchState();
            richfaces.ajax(this.id, e, options);
        };

        var server = function(options) {
            this.__switchState();
            $(document.getElementById(this.formId)).submit();
        };

        var client = function(options) {
            if (this.isExpanded()) {
                this.collapse(options);
            } else {
                this.expand(options);
            }
        };


        return {

            name: "CollapsibleSubTable",

            switchState: function(e, options) {
                if (this.expandMode == richfaces.ui.CollapsibleSubTable.MODE_AJAX) {
                    ajax.call(this, e, this.eventOptions, options);
                } else if (this.expandMode == richfaces.ui.CollapsibleSubTable.MODE_SRV) {
                    server.call(this, options);
                } else if (this.expandMode == richfaces.ui.CollapsibleSubTable.MODE_CLNT) {
                    client.call(this, options);
                }
            },

            collapse: function(options) {
                this.setState(richfaces.ui.CollapsibleSubTable.collapse);
                element.call(this).hide();
            },

            expand: function(options) {
                this.setState(richfaces.ui.CollapsibleSubTable.expand);
                element.call(this).show();
            },

            isExpanded: function() {
                return (parseInt(this.getState()) == richfaces.ui.CollapsibleSubTable.expand);
            },

            __switchState: function(options) {
                var state = this.isExpanded() ? richfaces.ui.CollapsibleSubTable.collapse : richfaces.ui.CollapsibleSubTable.expand;
                this.setState(state);
            },

            getState: function() {
                return stateInputElem.call(this).val();
            },

            setState: function(state) {
                stateInputElem.call(this).val(state)
            },

            setOption: function(option) {
                optionsInputElem.call(this).val(option);
            },

            getMode: function() {
                return this.expandMode;
            },
            destroy: function() {
                $super.destroy.call(this);
            }
        };

    })());

})(jQuery, window.RichFaces);;/*	
 Watermark plugin for jQuery
 Version: 3.0.6
 http://jquery-watermark.googlecode.com/

 Copyright (c) 2009-2010 Todd Northrop
 http://www.speednet.biz/

 June 21, 2010

 Requires:  jQuery 1.2.3+

 Dual licensed under the MIT or GPL Version 2 licenses.
 See mit-license.txt and gpl2-license.txt in the project root for details.
 ------------------------------------------------------*/

(function ($) {

    var
    // Will speed up references to undefined
            undefined,

    // String constants for data names
            dataFlag = "watermark",
            dataClass = "watermarkClass",
            dataFocus = "watermarkFocus",
            dataFormSubmit = "watermarkSubmit",
            dataMaxLen = "watermarkMaxLength",
            dataPassword = "watermarkPassword",
            dataText = "watermarkText",

    // Includes only elements with watermark defined
            selWatermarkDefined = ":data(" + dataFlag + ")",

    // Includes only elements capable of having watermark
            selWatermarkAble = ":text,:password,:search,textarea",

    // triggerFns:
    // Array of function names to look for in the global namespace.
    // Any such functions found will be hijacked to trigger a call to
    // hideAll() any time they are called.  The default value is the
    // ASP.NET function that validates the controls on the page
    // prior to a postback.
    //
    // Am I missing other important trigger function(s) to look for?
    // Please leave me feedback:
    // http://code.google.com/p/jquery-watermark/issues/list
            triggerFns = [
                "Page_ClientValidate"
            ],

    // Holds a value of true if a watermark was displayed since the last
    // hideAll() was executed. Avoids repeatedly calling hideAll().
            pageDirty = false;

// Extends jQuery with a custom selector - ":data(...)"
// :data(<name>)  Includes elements that have a specific name defined in the jQuery data collection. (Only the existence of the name is checked; the value is ignored.)
// :data(<name>=<value>)  Includes elements that have a specific jQuery data name defined, with a specific value associated with it.
// :data(<name>!=<value>)  Includes elements that have a specific jQuery data name defined, with a value that is not equal to the value specified.
// :data(<name>^=<value>)  Includes elements that have a specific jQuery data name defined, with a value that starts with the value specified.
// :data(<name>$=<value>)  Includes elements that have a specific jQuery data name defined, with a value that ends with the value specified.
// :data(<name>*=<value>)  Includes elements that have a specific jQuery data name defined, with a value that contains the value specified.
    $.extend($.expr[":"], {
        "search":function (elem) {
            return "search" === (elem.type || "");
        },

        "data":function (element, index, matches, set) {
            var data, parts = /^((?:[^=!^$*]|[!^$*](?!=))+)(?:([!^$*]?=)(.*))?$/.exec(matches[3]);

            if (parts) {
                data = $(element).data(parts[1]);

                if (data !== undefined) {

                    if (parts[2]) {
                        data = "" + data;

                        switch (parts[2]) {
                            case "=":
                                return (data == parts[3]);
                            case "!=":
                                return (data != parts[3]);
                            case "^=":
                                return (data.slice(0, parts[3].length) == parts[3]);
                            case "$=":
                                return (data.slice(-parts[3].length) == parts[3]);
                            case "*=":
                                return (data.indexOf(parts[3]) !== -1);
                        }
                    }

                    return true;
                }
            }

            return false;
        }
    });

    $.watermark = {

        // Current version number of the plugin
        version:"3.0.6",

        // Default options used when watermarks are instantiated.
        // Can be changed to affect the default behavior for all
        // new or updated watermarks.
        // BREAKING CHANGE:  The $.watermark.className
        // property that was present prior to version 3.0.2 must
        // be changed to $.watermark.options.className
        options:{

            // Default class name for all watermarks
            className:"watermark",

            // If true, plugin will detect and use native browser support for
            // watermarks, if available. (e.g., WebKit's placeholder attribute.)
            useNative:true
        },

        // Hide one or more watermarks by specifying any selector type
        // i.e., DOM element, string selector, jQuery matched set, etc.
        hide:function (selector) {
            $(selector).filter(selWatermarkDefined).each(
                    function () {
                        $.watermark._hide($(this));
                    }
            );
        },

        // Internal use only.
        _hide:function ($input, focus) {
            var inputVal = $input.val() || "",
                    inputWm = $input.data(dataText) || "",
                    maxLen = $input.data(dataMaxLen) || 0,
                    className = $input.data(dataClass);

            if ((inputWm.length) && (inputVal == inputWm)) {
                $input.val("");

                // Password type?
                if ($input.data(dataPassword)) {

                    if (($input.attr("type") || "") === "text") {
                        var $pwd = $input.data(dataPassword) || [],
                                $wrap = $input.parent() || [];

                        if (($pwd.length) && ($wrap.length)) {
                            $wrap[0].removeChild($input[0]); // Can't use jQuery methods, because they destroy data
                            $wrap[0].appendChild($pwd[0]);
                            $input = $pwd;
                        }
                    }
                }

                if (maxLen) {
                    $input.attr("maxLength", maxLen);
                    $input.removeData(dataMaxLen);
                }

                if (focus) {
                    $input.attr("autocomplete", "off");  // Avoid NS_ERROR_XPC_JS_THREW_STRING error in Firefox

                    window.setTimeout(
                            function () {
                                $input.select();  // Fix missing cursor in IE
                            }
                            , 1);
                }
            }

            className && $input.removeClass(className);
        },

        // Display one or more watermarks by specifying any selector type
        // i.e., DOM element, string selector, jQuery matched set, etc.
        // If conditions are not right for displaying a watermark, ensures that watermark is not shown.
        show:function (selector) {
            $(selector).filter(selWatermarkDefined).each(
                    function () {
                        $.watermark._show($(this));
                    }
            );
        },

        // Internal use only.
        _show:function ($input) {
            var val = $input.val() || "",
                    text = $input.data(dataText) || "",
                    type = $input.attr("type") || "",
                    className = $input.data(dataClass);

            if (((val.length == 0) || (val == text)) && (!$input.data(dataFocus))) {
                pageDirty = true;

                // Password type?
                if ($input.data(dataPassword)) {

                    if (type === "password") {
                        var $pwd = $input.data(dataPassword) || [],
                                $wrap = $input.parent() || [];

                        if (($pwd.length) && ($wrap.length)) {
                            $wrap[0].removeChild($input[0]); // Can't use jQuery methods, because they destroy data
                            $wrap[0].appendChild($pwd[0]);
                            $input = $pwd;
                            $input.attr("maxLength", text.length);
                        }
                    }
                }

                // Ensure maxLength big enough to hold watermark (input of type="text" or type="search" only)
                if ((type === "text") || (type === "search")) {
                    var maxLen = $input.attr("maxLength") || 0;

                    if ((maxLen > 0) && (text.length > maxLen)) {
                        $input.data(dataMaxLen, maxLen);
                        $input.attr("maxLength", text.length);
                    }
                }

                className && $input.addClass(className);
                $input.val(text);
            }
            else {
                $.watermark._hide($input);
            }
        },

        // Hides all watermarks on the current page.
        hideAll:function () {
            if (pageDirty) {
                $.watermark.hide(selWatermarkAble);
                pageDirty = false;
            }
        },

        // Displays all watermarks on the current page.
        showAll:function () {
            $.watermark.show(selWatermarkAble);
        }
    };

    $.fn.watermark = function (text, options) {
        ///	<summary>
        ///		Set watermark text and class name on all input elements of type="text/password/search" and
        /// 	textareas within the matched set. If className is not specified in options, the default is
        /// 	"watermark". Within the matched set, only input elements with type="text/password/search"
        /// 	and textareas are affected; all other elements are ignored.
        ///	</summary>
        ///	<returns type="jQuery">
        ///		Returns the original jQuery matched set (not just the input and texarea elements).
        /// </returns>
        ///	<param name="text" type="String">
        ///		Text to display as a watermark when the input or textarea element has an empty value and does not
        /// 	have focus. The first time watermark() is called on an element, if this argument is empty (or not
        /// 	a String type), then the watermark will have the net effect of only changing the class name when
        /// 	the input or textarea element's value is empty and it does not have focus.
        ///	</param>
        ///	<param name="options" type="Object" optional="true">
        ///		Provides the ability to override the default watermark options ($.watermark.options). For backward
        /// 	compatibility, if a string value is supplied, it is used as the class name that overrides the class
        /// 	name in $.watermark.options.className. Properties include:
        /// 		className: When the watermark is visible, the element will be styled using this class name.
        /// 		useNative (Boolean or Function): Specifies if native browser support for watermarks will supersede
        /// 			plugin functionality. If useNative is a function, the return value from the function will
        /// 			determine if native support is used. The function is passed one argument -- a jQuery object
        /// 			containing the element being tested as the only element in its matched set -- and the DOM
        /// 			element being tested is the object on which the function is invoked (the value of "this").
        ///	</param>
        /// <remarks>
        ///		The effect of changing the text and class name on an input element is called a watermark because
        ///		typically light gray text is used to provide a hint as to what type of input is required. However,
        ///		the appearance of the watermark can be something completely different: simply change the CSS style
        ///		pertaining to the supplied class name.
        ///
        ///		The first time watermark() is called on an element, the watermark text and class name are initialized,
        ///		and the focus and blur events are hooked in order to control the display of the watermark.  Also, as
        /// 	of version 3.0, drag and drop events are hooked to guard against dropped text being appended to the
        /// 	watermark.  If native watermark support is provided by the browser, it is detected and used, unless
        /// 	the useNative option is set to false.
        ///
        ///		Subsequently, watermark() can be called again on an element in order to change the watermark text
        ///		and/or class name, and it can also be called without any arguments in order to refresh the display.
        ///
        ///		For example, after changing the value of the input or textarea element programmatically, watermark()
        /// 	should be called without any arguments to refresh the display, because the change event is only
        /// 	triggered by user actions, not by programmatic changes to an input or textarea element's value.
        ///
        /// 	The one exception to programmatic updates is for password input elements:  you are strongly cautioned
        /// 	against changing the value of a password input element programmatically (after the page loads).
        /// 	The reason is that some fairly hairy code is required behind the scenes to make the watermarks bypass
        /// 	IE security and switch back and forth between clear text (for watermarks) and obscured text (for
        /// 	passwords).  It is *possible* to make programmatic changes, but it must be done in a certain way, and
        /// 	overall it is not recommended.
        /// </remarks>

        if (!this.length) {
            return this;
        }

        var hasClass = false,
                hasText = (typeof(text) === "string");

        if (typeof(options) === "object") {
            hasClass = (typeof(options.className) === "string");
            options = $.extend({}, $.watermark.options, options);
        }
        else if (typeof(options) === "string") {
            hasClass = true;
            options = $.extend({}, $.watermark.options, {className:options});
        }
        else {
            options = $.watermark.options;
        }

        if (typeof(options.useNative) !== "function") {
            options.useNative = options.useNative ? function () {
                return true;
            } : function () {
                return false;
            };
        }

        return this.each(
                function () {
                    var $input = $(this);

                    if (!$input.is(selWatermarkAble)) {
                        return;
                    }

                    // Watermark already initialized?
                    if ($input.data(dataFlag)) {

                        // If re-defining text or class, first remove existing watermark, then make changes
                        if (hasText || hasClass) {
                            $.watermark._hide($input);

                            if (hasText) {
                                $input.data(dataText, text);
                            }

                            if (hasClass) {
                                $input.data(dataClass, options.className);
                            }
                        }
                    }
                    else {

                        // Detect and use native browser support, if enabled in options
                        if (options.useNative.call(this, $input)) {

                            // Placeholder attribute (WebKit)
                            // Big thanks to Opera for the wacky test required

                            if ((("" + $input.css("-webkit-appearance")).replace("undefined", "") !== "") && ((($input.attr("tagName") || "") !== "TEXTAREA")) && $input.size() > 0 && $input[0].tagName !== "TEXTAREA") {

                                // className is not set because WebKit doesn't appear to have
                                // a separate class name property for placeholders (watermarks).
                                if (hasText) {
                                    $input.attr("placeholder", text);
                                }

                                // Only set data flag for non-native watermarks (purposely commented-out)
                                // $input.data(dataFlag, 1);
                                return;
                            }
                        }

                        $input.data(dataText, hasText ? text : "");
                        $input.data(dataClass, options.className);
                        $input.data(dataFlag, 1); // Flag indicates watermark was initialized

                        // Special processing for password type
                        if (($input.attr("type") || "") === "password") {
                            var $wrap = $input.wrap("<span>").parent(),
                                    $wm = $($wrap.html().replace(/type=["']?password["']?/i, 'type="text"'));

                            $wm.data(dataText, $input.data(dataText));
                            $wm.data(dataClass, $input.data(dataClass));
                            $wm.data(dataFlag, 1);
                            $wm.attr("maxLength", text.length);

                            $wm.focus(
                                    function () {
                                        $.watermark._hide($wm, true);
                                    }
                            ).bind("dragenter",
                                    function () {
                                        $.watermark._hide($wm);
                                    }
                            ).bind("dragend",
                                    function () {
                                        window.setTimeout(function () {
                                            $wm.blur();
                                        }, 1);
                                    }
                            );
                            $input.blur(
                                    function () {
                                        $.watermark._show($input);
                                    }
                            ).bind("dragleave",
                                    function () {
                                        $.watermark._show($input);
                                    }
                            );

                            $wm.data(dataPassword, $input);
                            $input.data(dataPassword, $wm);
                        }
                        else {

                            $input.focus(
                                    function () {
                                        $input.data(dataFocus, 1);
                                        $.watermark._hide($input, true);
                                    }
                            ).blur(
                                    function () {
                                        $input.data(dataFocus, 0);
                                        $.watermark._show($input);
                                    }
                            ).bind("dragenter",
                                    function () {
                                        $.watermark._hide($input);
                                    }
                            ).bind("dragleave",
                                    function () {
                                        $.watermark._show($input);
                                    }
                            ).bind("dragend",
                                    function () {
                                        window.setTimeout(function () {
                                            $.watermark._show($input);
                                        }, 1);
                                    }
                            ).bind("drop",
                                    // Firefox makes this lovely function necessary because the dropped text
                                    // is merged with the watermark before the drop event is called.
                                    function (evt) {
                                        var dropText = evt.originalEvent.dataTransfer.getData("Text");

                                        if ($input.val().replace(dropText, "") === $input.data(dataText)) {
                                            $input.val(dropText);
                                        }

                                        $input.focus();
                                    }
                            );
                        }

                        // In order to reliably clear all watermarks before form submission,
                        // we need to replace the form's submit function with our own
                        // function.  Otherwise watermarks won't be cleared when the form
                        // is submitted programmatically.
                        if (this.form) {
                            var form = this.form,
                                    $form = $(form);

                            if (!$form.data(dataFormSubmit)) {
                                $form.submit($.watermark.hideAll);

                                // form.submit exists for all browsers except Google Chrome
                                // (see "else" below for explanation)
                                if (form.submit) {
                                    $form.data(dataFormSubmit, form.onsubmit || 1);

                                    form.onsubmit = (function (f, $f) {
                                        return function () {
                                            var nativeSubmit = $f.data(dataFormSubmit);
                                            $.watermark.hideAll();
                                            if (nativeSubmit instanceof Function) {
                                                nativeSubmit();
                                            } else {
                                                eval(nativeSubmit);
                                            }
                                        };
                                    })(form, $form);
                                } else {
                                    $form.data(dataFormSubmit, 1);

                                    // This strangeness is due to the fact that Google Chrome's
                                    // form.submit function is not visible to JavaScript (identifies
                                    // as "undefined").  I had to invent a solution here because hours
                                    // of Googling (ironically) for an answer did not turn up anything
                                    // useful.  Within my own form.submit function I delete the form's
                                    // submit function, and then call the non-existent function --
                                    // which, in the world of Google Chrome, still exists.
                                    form.submit = (function (f) {
                                        return function () {
                                            $.watermark.hideAll();
                                            delete f.submit;
                                            f.submit();
                                        };
                                    })(form);
                                }
                            }
                        }
                    }

                    $.watermark._show($input);
                }
        );
    };

// Hijack any functions found in the triggerFns list
    if (triggerFns.length) {

        // Wait until DOM is ready before searching
        $(function () {
            var i, name, fn;

            for (i = triggerFns.length - 1; i >= 0; i--) {
                name = triggerFns[i];
                fn = window[name];

                if (typeof(fn) === "function") {
                    window[name] = (function (origFn) {
                        return function () {
                            $.watermark.hideAll();
                            return origFn.apply(null, Array.prototype.slice.call(arguments));
                        };
                    })(fn);
                }
            }
        });
    }

})(jQuery);
;if (!window.RichFaces) {
    window.RichFaces = {};
}

(function(jquery, richfaces) {

    var evaluate = function(selector) {
        var result = selector;
        try {
            result = eval(selector);
        } catch (e) {
            //do nothing
        }
        return result;
    };

    var evaluateJQuery = function(element, selector) {
        var result = element || evaluate(selector);
        if (!(result instanceof jquery)) {
            result = jquery(result || "");
        }

        return result;
    };

    var createEventHandlerFunction = function(opts) {
        return function() {
            var selector = evaluateJQuery(null, opts.selector);
            selector[opts.attachType || "bind"](opts.event, null, new Function("event", opts.query));
        };
    };

    var createDirectQueryFunction = function(opts) {
        var queryFunction = new Function("options", "arguments[1]." + opts.query);

        return function() {
            var element;
            var options;

            if (arguments.length == 1) {
                //function(options) { ...query()... }
                options = arguments[0];
            } else {
                //function(element, options) { ...query()... }
                element = arguments[0];
                options = arguments[1];
            }

            var selector = evaluateJQuery(element, opts.selector);
            queryFunction.call(this, options, selector);
        };
    };

    var createQueryFunction = function(options) {
        if (options.event) {
            return createEventHandlerFunction(options);
        } else {
            return createDirectQueryFunction(options);
        }
    };

    var query = function(options) {
        if (options.timing == 'immediate') {
            createQueryFunction(options).call(this);
        } else {
            jquery(document).ready(createQueryFunction(options));
        }
    };

    richfaces.jQuery = {

        createFunction: createQueryFunction,

        query: query

    };

}(jQuery, RichFaces));
;/**
 * @author Pavel Yaschenko
 */

// TODO: add support to bind multiple events using type param as an object with eventType,function pairs // see bindById method
// TODO: update js docs 

(function($, richfaces) {

    /**
     * RichFaces Event API container
     * @class
     * @memberOf RichFaces
     * @static
     * @name Event
     * */
    richfaces.Event = richfaces.Event || {};

    var getEventElement = function (selector) {
        if (!selector) {
            throw "RichFaces.Event: empty selector";
        }
        var element;
        if (RichFaces.BaseComponent && selector instanceof RichFaces.BaseComponent) {
            element = $(richfaces.getDomElement(selector.getEventElement()));
        } else {
            element = $(selector);
        }

        return element;
    }

    var getHandlerWrapper = function (component, fn) {
        return function (e, d) {
            if (!e[richfaces.RICH_CONTAINER]) {
                e[richfaces.RICH_CONTAINER] = {data: d};
            }
            return fn.call(component || this, e, this, d);
        };
    }

    var getMultipleHandlerWrapper = function (object, component) {
        var result = {};
        for (var type in object) {
            result[type] = getHandlerWrapper(component, object[type]);
        }
        return result;
    }

    $.extend(richfaces.Event, {
            /**
             * @constant
             * @name RichFaces.Event.RICH_NAMESPACE
             * @type string
             * */
            RICH_NAMESPACE : "RICH",

            /**
             * @constant
             * @name RichFaces.Event.EVENT_NAMESPACE_SEPARATOR
             * @type string
             * */
            EVENT_NAMESPACE_SEPARATOR : ".",

            MESSAGE_EVENT_TYPE: "onmessage",

            /**
             * Attach an event handler to execute when the DOM is fully loaded.
             *
             * @function
             * @name RichFaces.Event.ready
             * @param {function} fn - event handler
             * @return {jQuery} document element wrapped by jQuery
             * */
            ready : function(fn) {
                // TODO: not completed yet
                return $(document).ready(fn);
                /*
                 function callback(jQueryReference) {
                 this; // document
                 }
                 */
            },

            /**
             * Attach a handler to an event for the elements.
             * @function
             * @name RichFaces.Event.bind
             *
             * @param {string|DOMElement|jQuery} selector - jQuery elements selector
             * @param {string} eventType - one or more JavaScript event types, such as "click" or "submit," or custom event names
             * @param {function} fn - event handler
             * @param {Object} [data] - component or object with additional data
             * It is a context for an event handler
             * @return {function} function that binded to the element's event
             * */
            bind : function(selector, eventType, fn, component, data) {
                // eventType: namespace can be used, like onclick.rf.conponentName
                if (typeof eventType == "object") {
                    // in this case fn == component object
                    getEventElement(selector).bind(getMultipleHandlerWrapper(eventType, fn), data);
                } else {
                    var f = getHandlerWrapper(component, fn);
                    getEventElement(selector).bind(eventType, data, f);
                    return f;
                }
            },

            /**
             * Attach a handler to an event for the element by element id.
             * @function
             * @name RichFaces.Event.bindById
             *
             * @param {string} id - DOM element id
             * @param {string} eventType - one or more JavaScript event types, such as "click" or "submit," or custom event names
             * @param {function} fn - event handler
             * @param {Object} [data] - component or object with additional data
             * It is a context for an event handler
             * @return {function} function that binded to the element's event
             * */
            bindById : function(id, eventType, fn, component, data) {
                // eventType: namespace can be used, like onclick.rf.conponentName
                if (typeof eventType == "object") {
                    // in this case fn == component object
                    $(document.getElementById(id)).bind(getMultipleHandlerWrapper(eventType, fn), data);
                } else {
                    var f = getHandlerWrapper(component, fn);
                    $(document.getElementById(id)).bind(eventType, data, f);
                }
                return f;
            },

            /**
             * Attach a handler to an event for the elements.
             * The handler will be called only once when event happened.
             * @function
             * @name RichFaces.Event.bindOne
             *
             * @param {string|DOMElement|jQuery} selector - jQuery elements selector
             * @param {string} eventType - one or more JavaScript event types, such as "click" or "submit," or custom event names
             * @param {function} fn - event handler
             * @param {Object} [data] - component or object with additional data
             * It is a context for an event handler
             * @return {function} function that binded to the element's event
             * */
            bindOne: function(selector, eventType, fn, component, data) {
                // eventType: namespace can be used, like onclick.rf.conponentName
                var f = getHandlerWrapper(component, fn);
                getEventElement(selector).one(eventType, data, f);
                return f;
            },

            /**
             * Attach a handler to an event for the element by element id.
             * The handler will be called only once when event happened.
             * @function
             * @name RichFaces.Event.bindOneById
             *
             * @param {string} id - DOM element id
             * @param {string} eventType - one or more JavaScript event types, such as "click" or "submit," or custom event names
             * @param {function} fn - event handler
             * @param {Object} [data] - component or object with additional data
             * It is a context for an event handler
             * @return {function} function that binded to the element's event
             * */
            bindOneById: function(id, eventType, fn, component, data) {
                // eventType: namespace can be used, like onclick.rf.conponentName
                var f = getHandlerWrapper(component, fn);
                $(document.getElementById(id)).one(eventType, data, f);
                return f;
            },

            /**
             * Remove a previously-attached event handler from the elements.
             * @function
             * @name RichFaces.Event.unbind
             *
             * @param {string|DOMElement|jQuery} selector - jQuery elements selector
             * @param {string} [eventType] - one or more JavaScript event types, such as "click" or "submit," or custom event names
             * @param {function} [fn] - event handler
             * @return {jQuery} element wrapped by jQuery
             * */
            unbind : function(selector, eventType, fn) {
                // eventType: namespace can be used, like onclick.rf.conponentName
                return getEventElement(selector).unbind(eventType, fn);
            },

            /**
             * Remove a previously-attached event handler from the elements by element id.
             * The handler will be called only once when event happened.
             * @function
             * @name RichFaces.Event.unbindById
             *
             * @param {string} id - DOM element id
             * @param {string} [eventType] - one or more JavaScript event types, such as "click" or "submit," or custom event names
             * @param {function} [fn] - event handler
             * @return {jQuery} element wrapped by jQuery
             * */
            unbindById : function(id, eventType, fn) {
                // eventType: namespace can be used, like onclick.rf.conponentName
                return $(document.getElementById(id)).unbind(eventType, fn);
            },

            // TODO add jsdocs and qunits
            bindScrollEventHandlers: function(element, handler, component) {
                var elements = [];
                element = richfaces.getDomElement(element).parentNode;
                while (element && element != window.document.body) {
                    if (element.offsetWidth != element.scrollWidth || element.offsetHeight != element.scrollHeight) {
                        elements.push(element);
                        richfaces.Event.bind(element, "scroll" + component.getNamespace(), handler, component);
                    }
                    element = element.parentNode;
                }
                return elements;
            },
            unbindScrollEventHandlers: function(elements, component) {
                richfaces.Event.unbind(elements, "scroll" + component.getNamespace());
            },

            /**
             * Execute all handlers and behaviors attached to the matched elements for the given event type.
             * @function
             * @name RichFaces.Event.fire
             *
             * @param {string|DOMElement|jQuery} selector - jQuery elements selector
             * @param {string} eventType - event type
             * @param {Object} [data] - a object of additional parameters to pass to the event handler
             * @return {jQuery} element wrapped by jQuery
             * */
            fire : function(selector, eventType, data) {
                var event = $.Event(eventType);
                getEventElement(selector).trigger(event, [data]);
                return !event.isDefaultPrevented();
            },

            /**
             * The same as the fire method, but selects element by id.
             * @function
             * @name RichFaces.Event.fireById
             *
             * @param {string} id - DOM element id
             * @param {string} eventType - event type
             * @param {Object} [data] - a object of additional parameters to pass to the event handler
             * @return {jQuery} element wrapped by jQuery
             * */
            fireById : function(id, eventType, data) {
                var event = $.Event(eventType);
                $(document.getElementById(id)).trigger(event, [data]);
                return !event.isDefaultPrevented();
            },

            /**
             * The same as the fire method, but:
             *  - does not cause the default behavior of an event to occur
             *  - does not bubble up event
             *  - call handler only for the first founded element
             *  - returns whatever value that was returned by the handler
             * @function
             * @name RichFaces.Event.callHandler
             *
             * @param {string|DOMElement|jQuery} selector - jQuery elements selector
             * @param {string} eventType - event type
             * @param {Object} [data] - a object of additional parameters to pass to the event handler
             * @return value that was returned by the handler
             * */
            callHandler : function(selector, eventType, data) {
                return getEventElement(selector).triggerHandler(eventType, [data]);
            },

            /**
             * The same as the callHandler method, but selects element by id.
             * @function
             * @name RichFaces.Event.callHandlerById
             *
             * @param {string} id - DOM element id
             * @param {string} eventType - event type
             * @param {Object} [data] - a object of additional parameters to pass to the event handler
             * @return value that was returned by the handler
             *  */
            callHandlerById : function(id, eventType, data) {
                return $(document.getElementById(id)).triggerHandler(eventType, [data]);
            },

            /**
             * Create an event namespace for the components.
             * @function
             * @name RichFaces.Event.createNamespace
             *
             * @param {string} [componentName] - component name
             * @param {string} [id] - element id
             * @param {string} [prefix=RichFaces.Event.RICH_NAMESPACE] - namespace prefix
             * @return {string} namespace string
             *  */
                // TODO: rename argument names
            createNamespace : function(componentName, id, prefix) {
                var a = [];
                a.push(prefix || richfaces.Event.RICH_NAMESPACE);
                if (componentName) {
                    a.push(componentName);
                }
                if (id) {
                    a.push(id);
                }
                return a.join(richfaces.Event.EVENT_NAMESPACE_SEPARATOR);
            }
        });

})(jQuery, window.RichFaces || (window.RichFaces = {}));

/*
 fn : function (eventObject, element) {
 this; // object passed as data to bind function or dom element if no data
 element; // dom element

 }
 */

// 	API usage example:
// 		RichFaces.Event.bind(selector, type, fn, data);
;/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
 * Licensed under the MIT License (LICENSE.txt).
 *
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 * Thanks to: Seamus Leahy for adding deltaX and deltaY
 *
 * Version: 3.0.4
 * 
 * Requires: 1.2.2+
 */

(function($) {

var types = ['DOMMouseScroll', 'mousewheel'];

$.event.special.mousewheel = {
    setup: function() {
        if ( this.addEventListener ) {
            for ( var i=types.length; i; ) {
                this.addEventListener( types[--i], handler, false );
            }
        } else {
            this.onmousewheel = handler;
        }
    },
    
    teardown: function() {
        if ( this.removeEventListener ) {
            for ( var i=types.length; i; ) {
                this.removeEventListener( types[--i], handler, false );
            }
        } else {
            this.onmousewheel = null;
        }
    }
};

$.fn.extend({
    mousewheel: function(fn) {
        return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
    },
    
    unmousewheel: function(fn) {
        return this.unbind("mousewheel", fn);
    }
});


function handler(event) {
    var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
    event = $.event.fix(orgEvent);
    event.type = "mousewheel";
    
    // Old school scrollwheel delta
    if ( event.wheelDelta ) { delta = event.wheelDelta/120; }
    if ( event.detail     ) { delta = -event.detail/3; }
    
    // New school multidimensional scroll (touchpads) deltas
    deltaY = delta;
    
    // Gecko
    if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
        deltaY = 0;
        deltaX = -1*delta;
    }
    
    // Webkit
    if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
    if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
    
    // Add event and delta to the front of the arguments
    args.unshift(event, delta, deltaX, deltaY);
    
    return $.event.handle.apply(this, args);
}

})(jQuery);;(function ($, rf) {

    rf.ui = rf.ui || {};

    var defaultOptions = {
        useNative: false
    };

    rf.ui.Placeholder = rf.BaseComponent.extendClass({

        name:"Placeholder",

        init: function (componentId, options) {
            $super.constructor.call(this, componentId);
            options = $.extend({}, defaultOptions, options);
            this.attachToDom(this.id);
            $(function() {
                options.className = 'rf-plhdr ' + ((options.styleClass) ? options.styleClass : '');
                var elements = (options.selector) ? $(options.selector) : $(document.getElementById(options.targetId));
                // finds all inputs within the subtree of target elements
                var inputs = elements.find(':editable').andSelf().filter(':editable');
                inputs.watermark(options.text, options);
            });
        },
        // destructor definition
        destroy: function () {
            // define destructor if additional cleaning is needed but
            // in most cases its not nessesary.
            // call parent’s destructor
            $super.destroy.call(this);
        }
    });
    
    // once per all placeholders on a page
    $(function() {
        $(document).on('ajaxsubmit', 'form', $.watermark.hideAll);
        $(document).on('ajaxbegin', 'form', $.watermark.showAll);
    });
    
    // define super class reference - reference to the parent prototype
    var $super = rf.ui.Placeholder.$super;
})(jQuery, RichFaces);;// RichFaces.utils
// RichFaces.utils.cache
(function ($, rf) {
    rf.utils = rf.utils || {};

    rf.utils.Cache = function (key, items, values, useCache) {
        this.key = key.toLowerCase();
        this.cache = {};
        this.cache[this.key] = items || [];
        this.originalValues = typeof values == "function" ? values(items) : values || this.cache[this.key];
        this.values = processValues(this.originalValues);
        this.useCache = useCache || checkValuesPrefix.call(this);
    };

    var processValues = function (values) {
        var processedValues = [];
        for (var i = 0; i < values.length; i++) {
            processedValues.push(values[i].toLowerCase());
        }
        return processedValues;
    };

    var checkValuesPrefix = function () {
        var result = true;
        for (var i = 0; i < this.values.length; i++) {
            if (this.values[i].indexOf(this.key) != 0) {
                result = false;
                break;
            }
        }
        return result;
    };

    var getItems = function (key, filterFunction) {
        key = key.toLowerCase();
        var newCache = [];

        if (key.length < this.key.length) {
            return newCache;
        }

        if (this.cache[key]) {
            newCache = this.cache[key];
        } else {
            var useCustomFilterFunction = typeof filterFunction == "function";
            var itemsCache = this.cache[this.key];
            for (var i = 0; i < this.values.length; i++) {
                var value = this.values[i];
                if (useCustomFilterFunction && filterFunction(key, value)) {
                    newCache.push(itemsCache[i]);
                } else {
                    var p = value.indexOf(key);
                    if (p == 0) {
                        newCache.push(itemsCache[i]);
                    }
                }
            }

            if ((!this.lastKey || key.indexOf(this.lastKey) != 0) && newCache.length > 0) {
                this.cache[key] = newCache;
                if (newCache.length == 1) {
                    this.lastKey = key;
                }
            }
        }

        return newCache;
    };

    var getItemValue = function (item) {
        return this.originalValues[this.cache[this.key].index(item)];
    };

    var isCached = function (key) {
        key = key.toLowerCase();
        return this.cache[key] || this.useCache && key.indexOf(this.key) == 0;
    };

    $.extend(rf.utils.Cache.prototype, (function () {
        return  {
            getItems: getItems,
            getItemValue: getItemValue,
            isCached: isCached
        };
    })());

})(jQuery, RichFaces);;// AJAX-JSF AJAX-like library, for communicate with view Tree on server side.
// In case of XMLHttpRequest don't worked, use :
// JSHttpRequest v1.12. (C) Dmitry Koterov, 2005-01-27. 
// http://forum.dklab.ru/users/DmitryKoterov/
//
// Do not remove this comment if you want to use script!
// ?? ???????? ?????? ???????????, ???? ?? ?????? ???????????? ??????!
//
// Modified by Alexander J. Smirnov to use as JSF AJAX-like components. 

// DOM - like elements for JSRequest. JS serialiser encode
// XML sax events to creation of corresponding objects.  
JSNode =  function() {
};

// Base node  
JSNode.prototype = {
	tag : null,
	attrs : {},
	childs : [],
	value : "",
	_symbols : {
			'&':"&amp;",
			'<':"&lt;",
			'>':"&gt;",
			'"':"&quot;",
			'\'':"&apos;",
			'\u00A0':"&nbsp;"
	},

	// Public functions
	getInnerHTML : function(context) {
		var children = [];
		for (var i = 0; i < this.childs.length; i++)
		{
			children.push(this.childs[i].getContent(context)); 
		}
		return children.join('');
	},
	// Escape XML symbols - < > & ' ...
	xmlEscape : function(value) {
		return jQuery("<div></div>").text(value).html();
	}
};

// Element node
E = function(tagname,attributes,childnodes) {
	this.tag = tagname;
	if (attributes) this.attrs = attributes;
	if(childnodes) this.childs = childnodes;
};

E.prototype = new JSNode();
E.prototype.getContent = function(context) {
	var html = "<"+this.tag;
	var inner = this.getInnerHTML(context);
	if (inner=='') this.isEmpty = true; else this.isEmpty=false;
	for(var i in this.attrs) {
		if (!this.attrs.hasOwnProperty(i)) {
			continue ;
		}

		var attrValue = this.attrs[i];
		
		if (typeof attrValue == "function")
			attrValue = attrValue.call(this, context);
		
		if (attrValue) 
			html += " "+(i=='className'?'class':i)+'="'+this.xmlEscape(attrValue)+'"';
	}
	html+= ">"+inner+"</"+this.tag+">";
	return html;
};

// Escaped Text node
ET = function(text) {
	this.value = text;
};


//ET.prototype = new JSNode();
ET.prototype.getContent = function(context) {
  	var value = this.value;
  	if (typeof value=="function") value=value(context);
  	if (value && value.getContent) {
		value = value.getContent(context);
	}
	
	if (value) return value;
  
	return "";
};

// Text node
T = function(text) {
	this.value = text;
};

T.prototype = new JSNode();
T.prototype.getContent = function(context) {
  	var value = this.value;
  	if (typeof value=="function") value=value(context);
  		
	if (value) return this.xmlEscape(value);

	return "";
};

// Comment node
C = function(text) {
	this.value = text;
};

//C.prototype = new JSNode();
C.prototype.getContent = function(context) {
	return "<!--"+this.value+"-->";
};
  
// CDATA Section node.
D = function(text) {
	this.value = text;
};
  
//D.prototype = new JSNode();
D.prototype.getContent = function(context) {
	return "<![CDATA["+this.value+"]]>";
};


;(function($, rf) {

    // Constructor definition
    rf.ui.NotifyMessage = function(componentId, options, notifyOptions) {
        // call constructor of parent class
        $super.constructor.call(this, componentId, options, defaultOptions);
        this.notifyOptions = notifyOptions;
    };

    // Extend component class and add protected methods from parent class to our container
    rf.ui.Base.extend(rf.ui.NotifyMessage);

    // define super class link
    var $super = rf.ui.NotifyMessage.$super;

    var defaultOptions = {
        showSummary:true,
        level:0,
        isMessages: false,
        globalOnly: false
    };


    var onMessage = function (event, element, data) {
        var sourceId = data.sourceId;
        var message = data.message;
        if (!this.options.forComponentId) {
            if (!this.options.globalOnly && message) {
                renderMessage.call(this, sourceId, message);
            }
        } else if (this.options.forComponentId === sourceId) {
            renderMessage.call(this, sourceId, message);
        }
    }

    var renderMessage = function(index, message) {
        if (message && message.severity >= this.options.level) {
            showNotification.call(this, message);
        }
    }
    
    var showNotification = function(message) {
        RichFaces.ui.Notify($.extend({}, this.notifyOptions, {
            'summary': this.options.showSummary ? message.summary : undefined,
            'detail': this.options.showDetail ? message.detail : undefined,
            'severity': message.severity
        }));
    }

    var bindEventHandlers = function () {
        rf.Event.bind(window.document, rf.Event.MESSAGE_EVENT_TYPE + this.namespace, onMessage, this);
    };

    $.extend(rf.ui.NotifyMessage.prototype, {
            name: "NotifyMessage",
            __bindEventHandlers: bindEventHandlers,
            
            destroy : function() {
                rf.Event.unbind(window.document, rf.Event.MESSAGE_EVENT_TYPE + this.namespace);
                $super.destroy.call(this);
            }
        });

})(jQuery, window.RichFaces || (window.RichFaces = {}));;(function ($, richfaces) {

    richfaces.ui = richfaces.ui || {};

    var initButtons = function(buttons, css, component) {
        var id;

        var fn = function(e) {
            e.data.fn.call(e.data.component, e);
        };

        var data = {};
        data.component = component;

        for (id in buttons) {
            var element = $(document.getElementById(id));

            data.id = id;
            data.page = buttons[id];
            data.element = element;
            data.fn = component.processClick;

            element.bind('click', copy(data), fn);
        }
    };

    var copy = function(data) {
        var key;
        var eventData = {};

        for (key in data) {
            eventData[key] = data[key];
        }

        return eventData;
    };

    var togglePressClass = function(el, event) {
        if (event.type == 'mousedown') {
            el.addClass('rf-ds-press');
        } else if (event.type == 'mouseup' || event.type == 'mouseout') {
            el.removeClass('rf-ds-press');
        }
    };

    richfaces.ui.DataScroller = function(id, submit, options) {

        $super.constructor.call(this, id);

        var dataScrollerElement = this.attachToDom();

        this.options = options;
        this.currentPage = options.currentPage;

        if (submit && typeof submit == 'function') {
            RichFaces.Event.bindById(id, this.getScrollEventName(), submit);
        }

        var css = {};

        if (options.buttons) {

            $(dataScrollerElement).delegate('.rf-ds-btn', 'mouseup mousedown mouseout', function(event) {
                if ($(this).hasClass('rf-ds-dis')) {
                    $(this).removeClass('rf-ds-press');
                } else {
                    togglePressClass($(this), event);
                }
            });

            initButtons(options.buttons.left, css, this);
            initButtons(options.buttons.right, css, this);
        }

        if (options.digitals) {

            $(dataScrollerElement).delegate('.rf-ds-nmb-btn', 'mouseup mousedown mouseout', function(event) {
                togglePressClass($(this), event);
            });

            initButtons(options.digitals, css, this);
        }
    };

    richfaces.BaseComponent.extend(richfaces.ui.DataScroller);
    var $super = richfaces.ui.DataScroller.$super;

    $.extend(richfaces.ui.DataScroller.prototype, (function () {

        var scrollEventName = "rich:datascroller:onscroll";

        return {

            name: "RichFaces.ui.DataScroller",

            processClick: function(event) {
                var data = event.data;
                if (data) {
                    var page = data.page;
                    if (page) {
                        this.switchToPage(page);
                    }
                }
            },

            switchToPage: function(page) {
                if (typeof page != 'undefined' && page != null) {
                    RichFaces.Event.fireById(this.id, this.getScrollEventName(), {'page' : page});
                }
            },

            fastForward: function() {
                this.switchToPage("fastforward");
            },

            fastRewind: function() {
                this.switchToPage("fastrewind");
            },

            next: function() {
                this.switchToPage("next");
            },

            previous: function() {
                this.switchToPage("previous");
            },

            first: function() {
                this.switchToPage("first");
            },

            last: function() {
                this.switchToPage("last");
            },

            getScrollEventName: function() {
                return scrollEventName;
            },
            destroy: function() {
                $super.destroy.call(this);
            }
        }

    })());

})(jQuery, window.RichFaces);;(function($, rf) {

    // Constructor definition
    rf.ui.Message = function(componentId, options) {
        // call constructor of parent class
        $super.constructor.call(this, componentId, options, defaultOptions);
        if (this.options.isMessages) {
            this.severityClasses = ["rf-msgs-inf", "rf-msgs-wrn", "rf-msgs-err", "rf-msgs-ftl"];
            this.summaryClass = "rf-msgs-sum";
            this.detailClass = "rf-msgs-det";
        } else {
            this.severityClasses = ["rf-msg-inf", "rf-msg-wrn", "rf-msg-err", "rf-msg-ftl"];
            this.summaryClass = "rf-msg-sum";
            this.detailClass = "rf-msg-det";
        }
    };

    // Extend component class and add protected methods from parent class to our container
    rf.ui.Base.extend(rf.ui.Message);

    // define super class link
    var $super = rf.ui.Message.$super;

    var defaultOptions = {
        showSummary:true,
        level:0,
        isMessages: false,
        globalOnly: false
    };


    var onMessage = function (event, element, data) {
        var content = $(rf.getDomElement(this.id));
        var sourceId = data.sourceId;
        var message = data.message;
        if (!this.options.forComponentId) {
            if (!message || this.options.globalOnly) {
                // rf.csv.clearMessage
                var element;
                while (element = rf.getDomElement(this.id + ':' + sourceId)) {
                    $(element).remove();
                }
            } else {
                renderMessage.call(this, sourceId, message);
            }
        } else if (this.options.forComponentId === sourceId) {
            content.empty();
            renderMessage.call(this, sourceId, message);
        }
    }

    var renderMessage = function(index, message) {
        if (message && message.severity >= this.options.level) {

            var content = $(rf.getDomElement(this.id));
            var msgContent = $("<span/>", {'class':(this.severityClasses)[message.severity],"id":this.id + ':' + index});
            if (message.summary) {
                if (this.options.tooltip) {
                    msgContent.attr("title", message.summary);
                } else if (this.options.showSummary) {
                    msgContent.append($("<span/>", {"class":(this.summaryClass)}).text(message.summary));
                }
            }
            if (this.options.showDetail && message.detail) {
                msgContent.append($("<span/>", {"class":(this.detailClass)}).text(message.detail));
            }
            content.append(msgContent);
        }
    }

    var bindEventHandlers = function () {
        rf.Event.bind(window.document, rf.Event.MESSAGE_EVENT_TYPE + this.namespace, onMessage, this);
    };

    $.extend(rf.ui.Message.prototype, {
            name: "Message",
            __bindEventHandlers: bindEventHandlers,
            
            destroy : function() {
                rf.Event.unbind(window.document, rf.Event.MESSAGE_EVENT_TYPE + this.namespace);
                $super.destroy.call(this);
            }
        });

})(jQuery, window.RichFaces || (window.RichFaces = {}));
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 * 
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */


(function ($, rf) {

    rf.ui = rf.ui || {};

    var __DEFAULT_OPTIONS = {
        expandSingle : true,
        bubbleSelection : true
    };

    rf.ui.PanelMenu = rf.BaseComponent.extendClass({
            // class name
            name:"PanelMenu",

            /**
             * @class PanelMenu
             * @name PanelMenu
             *
             * @constructor
             * @param {String} componentId - component id
             * @param {Hash} options - params
             * */
            init : function (componentId, options) {
                $super.constructor.call(this, componentId);
                this.items = {};
                this.attachToDom();

                this.options = $.extend(this.options, __DEFAULT_OPTIONS, options || {});
                this.activeItem = this.__getValueInput().value;
                this.nestingLevel = 0;

                this.__addUserEventHandler("collapse");
                this.__addUserEventHandler("expand");
            },

            addItem: function(item) {
                this.items[item.itemName] = item;
            },

            deleteItem: function(item) {
                delete this.items[item.itemName];
            },

            getSelectedItem: function() {
                return this.getItem(this.selectedItem());
            },

            getItem: function (name) {
                return this.items[name];
            },

            /***************************** Public Methods  ****************************************************************/
            /**
             * @methodOf
             * @name PanelMenu#selectItem
             *
             * TODO ...
             *
             * @param {String} name
             * @return {void} TODO ...
             */
            selectItem: function (name) {
                // TODO implement
            },

            /**
             * @methodOf
             * @name PanelMenu#selectedItem
             *
             * TODO ...
             *
             * @return {String} TODO ...
             */
            selectedItem: function (id) {
                if (typeof id != "undefined") {
                    var valueInput = this.__getValueInput();
                    var prevActiveItem = valueInput.value;

                    this.activeItem = id;
                    valueInput.value = id;

                    for (var itemName in this.items) {
                        var item = this.items[itemName];
                        if (item.__isSelected()) {
                            item.__unselect();
                        }
                    }

                    return prevActiveItem;
                } else {
                    return this.activeItem;
                }
            },

            __getValueInput : function() {
                return document.getElementById(this.id + "-value");
            },

            /**
             * @methodOf
             * @name PanelMenu#expandAll
             *
             * TODO ...
             *
             * @return {void} TODO ...
             */
            expandAll: function () {
                // TODO implement
            },

            /**
             * @methodOf
             * @name PanelMenu#collapseAll
             *
             * TODO ...
             *
             * @return {void} TODO ...
             */
            collapseAll: function () {
                // TODO implement
            },

            /**
             * @methodOf
             * @name PanelMenu#expandGroup
             *
             * TODO ...
             *
             * @param {String} groupName
             * @return {void} TODO ...
             */
            expandGroup: function (groupName) {
                // TODO implement
            },

            /**
             * @methodOf
             * @name PanelMenu#collapseGroup
             *
             * TODO ...
             *
             * @param {String} groupName
             * @return {void} TODO ...
             */
            collapseGroup: function (groupName) {
                // TODO implement
            },


            /***************************** Private Methods ****************************************************************/


            __panelMenu  : function () {
                return $(rf.getDomElement(this.id));
            },

            __childGroups : function () {
                return this.__panelMenu().children(".rf-pm-top-gr")
            },

            /**
             * @private
             * */
            __addUserEventHandler : function (name) {
                var handler = this.options["on" + name];
                if (handler) {
                    //TODO nick - this will cause slowdowns in IE
                    rf.Event.bindById(this.id, name, handler);
                }
            },

            __isActiveItem: function(item) {
                return item.itemName == this.activeItem;
            },

            __collapseGroups : function (source) {
                var topGroup = source.__rfTopGroup();
                this.__childGroups().each(function (index, group) {
                    if (group.id != source.getEventElement() && (!topGroup || group.id != topGroup.id)) {
                        rf.$(group).__collapse();
                    }
                });

            },

            destroy: function () {
                rf.Event.unbindById(this.id, "." + this.namespace);
                $super.destroy.call(this);
            }
        });

    // define super class link
    var $super = rf.ui.PanelMenu.$super;

})(jQuery, RichFaces);
;(function ($, rf) {

    rf.ui = rf.ui || {};

    var defaultOptions = {
        interval: 1000,
        minValue: 0,
        maxValue: 100
    };

    var stateSelectors = {
        initial: '> .rf-pb-init',
        progress: '> .rf-pb-rmng',
        finish: '> .rf-pb-fin'
    };

    // Constructor definition
    rf.ui.ProgressBar = function(componentId, options) {
        // call constructor of parent class
        $super.constructor.call(this, componentId);
        this.__elt = this.attachToDom();
        this.options = $.extend(this.options, defaultOptions, options || {});
        this.enabled = this.options.enabled;
        this.minValue = this.options.minValue;
        this.maxValue = this.options.maxValue;

        this.__setValue(this.options.value || this.options.minValue /* TODO - check with Ilya */);

        if (this.options.resource) {
            this.__poll();
        } else if (this.options.submitFunction) {
            this.submitFunction = new Function("beforeUpdateHandler", "afterUpdateHandler", "params", "event", this.options.submitFunction);
            this.__poll();
        }

        if (this.options.onfinish) {
            rf.Event.bind(this.__elt, "finish", new Function("event", this.options.onfinish));
        }
    };

    // Extend component class and add protected methods from parent class to our container
    rf.BaseComponent.extend(rf.ui.ProgressBar);

    // define super class link
    var $super = rf.ui.ProgressBar.$super;

    $.extend(rf.ui.ProgressBar.prototype, (function() {
        return {
            name: "ProgressBar",

            __isInitialState: function() {
                return parseFloat(this.value) < parseFloat(this.getMinValue());
            },

            __isProgressState: function() {
                return !this.__isInitialState() && !this.__isFinishState();
            },

            __isFinishState: function() {
                return parseFloat(this.value) >= parseFloat(this.getMaxValue());
            },

            __beforeUpdate: function(event) {
                if (event.componentData && typeof event.componentData[this.id] != 'undefined') {
                    this.setValue(event.componentData[this.id]);
                }
            },

            __afterUpdate: function(event) {
                this.__poll();
            },

            __onResourceDataAvailable: function(data) {
                var parsedData = rf.parseJSON(data);
                if (parsedData instanceof Number || typeof parsedData == 'number') {
                    this.setValue(parsedData);
                }

                this.__poll();
            },

            __submit: function() {
                if (this.submitFunction) {
                    this.submitFunction.call(this, $.proxy(this.__beforeUpdate, this), $.proxy(this.__afterUpdate, this),
                        this.__params || {});
                } else {
                    $.get(this.options.resource, this.__params || {}, $.proxy(this.__onResourceDataAvailable, this), 'text');
                }
            },

            __poll: function(immediate) {
                if (this.enabled) {
                    if (immediate) {
                        this.__submit();
                    } else {
                        this.__pollTimer = setTimeout($.proxy(this.__submit, this), this.options.interval);
                    }
                }
            },

            __calculatePercent: function(v) {
                var min = parseFloat(this.getMinValue());
                var max = parseFloat(this.getMaxValue());
                var value = parseFloat(v);
                if (min < value && value < max) {
                    return (100 * (value - min)) / (max - min);
                } else if (value <= min) {
                    return 0;
                } else if (value >= max) {
                    return 100;
                }
            },

            __getPropertyOrObject: function(obj, propName) {
                if ($.isPlainObject(obj) && obj.propName) {
                    return obj.propName;
                }

                return obj;
            },

            getValue: function() {
                return this.value;
            },

            __showState: function (state) {
                var stateElt = $(stateSelectors[state], this.__elt);

                if (stateElt.length == 0 && (state == 'initial' || state == 'finish')) {
                    stateElt = $(stateSelectors['progress'], this.__elt)
                }

                stateElt.show().siblings().hide();
            },

            __setValue: function(val, initialStateSetup) {
                this.value = parseFloat(this.__getPropertyOrObject(val, "value"));

                if (this.__isFinishState() || this.__isInitialState()) {
                    this.disable();
                }
            },

            __updateVisualState: function() {
                if (this.__isInitialState()) {
                    this.__showState("initial");
                } else if (this.__isFinishState()) {
                    this.__showState("finish");
                } else {
                    this.__showState("progress");
                }

                var p = this.__calculatePercent(this.value);
                $(".rf-pb-prgs", this.__elt).css('width', p + "%");
            },

            setValue: function(val) {
                var wasInFinishState = this.__isFinishState();

                this.__setValue(val);
                this.__updateVisualState();

                if (!wasInFinishState && this.__isFinishState()) {
                    rf.Event.callHandler(this.__elt, "finish");
                }
            },

            getMaxValue: function() {
                return this.maxValue;
            },

            getMinValue: function() {
                return this.minValue;
            },

            isAjaxMode: function () {
                return !!this.submitFunction || !!this.options.resource;
            },

            disable: function () {
                this.__params = null;
                if (this.__pollTimer) {
                    clearTimeout(this.__pollTimer);
                    this.__pollTimer = null;
                }

                this.enabled = false;
            },

            enable: function (params) {
                if (this.isEnabled()) {
                    return;
                }

                this.__params = params;
                this.enabled = true;

                if (this.isAjaxMode()) {
                    this.__poll(true);
                }

            },

            isEnabled: function() {
                return this.enabled;
            },

            destroy: function() {
                this.disable();
                this.__elt = null;
                $super.destroy.call(this);
            }
        }
    }()));

})(jQuery, RichFaces);
;(function ($, richfaces) {

    richfaces.ui = richfaces.ui || {};
    var selectionEventHandler = function(event) {
        event.stopPropagation();
        event.preventDefault();
    };

    var disableSelection = function (element) {
        if (typeof element.onselectstart != "undefined") //IE
        {
            $(richfaces.getDomElement(element)).bind('selectstart', selectionEventHandler);
        }
        else //All other (ie: Opera)
        {
            $(richfaces.getDomElement(element)).bind('mousedown', selectionEventHandler);
        }
    };

    var enableSelection = function (element) {
        if (typeof element.onselectstart != "undefined") //IE
        {
            $(richfaces.getDomElement(element)).unbind('selectstart', selectionEventHandler);
        }
        else //All other (ie: Opera)
        {
            $(richfaces.getDomElement(element)).unbind('mousedown', selectionEventHandler);
        }
    };

    var defaultOptions = {
        width:-1,
        height:-1,
        minWidth:-1,
        minHeight:-1,
        modal:true,
        moveable:true,
        resizeable: false,
        autosized: false,
        left: "auto",
        top : "auto",
        zindex:100,
        shadowDepth : 5,
        shadowOpacity: 0.1,
        attachToBody:true
    };


    richfaces.ui.PopupPanel = function(id, options) {

        $super.constructor.call(this, id);
        this.markerId = id;
        this.attachToDom(this.markerId);
        this.options = $.extend(this.options, defaultOptions, options || {});

        this.minWidth = this.getMinimumSize(this.options.minWidth);
        this.minHeight = this.getMinimumSize(this.options.minHeight);
        this.maxWidth = this.options.maxWidth;
        this.maxHeight = this.options.maxHeight;

        this.baseZIndex = this.options.zindex;

        this.div = $(richfaces.getDomElement(id));
        this.cdiv = $(richfaces.getDomElement(id + "_container"));
        this.contentDiv = $(richfaces.getDomElement(id + "_content"));
        this.shadowDiv = $(richfaces.getDomElement(id + "_shadow"));
        this.shadeDiv = $(richfaces.getDomElement(id + "_shade"));
        this.scrollerDiv = $(richfaces.getDomElement(id + "_content_scroller"));

        $(this.shadowDiv).css("opacity", this.options.shadowOpacity);
        this.shadowDepth = parseInt(this.options.shadowDepth);

        this.borders = new Array();
        this.firstHref = $(richfaces.getDomElement(id + "FirstHref"));
        if (this.options.resizeable) {
            this.borders.push(new richfaces.ui.PopupPanel.Border(id + "ResizerN", this, "N-resize", richfaces.ui.PopupPanel.Sizer.N));
            this.borders.push(new richfaces.ui.PopupPanel.Border(id + "ResizerE", this, "E-resize", richfaces.ui.PopupPanel.Sizer.E));
            this.borders.push(new richfaces.ui.PopupPanel.Border(id + "ResizerS", this, "S-resize", richfaces.ui.PopupPanel.Sizer.S));
            this.borders.push(new richfaces.ui.PopupPanel.Border(id + "ResizerW", this, "W-resize", richfaces.ui.PopupPanel.Sizer.W));

            this.borders.push(new richfaces.ui.PopupPanel.Border(id + "ResizerNW", this, "NW-resize", richfaces.ui.PopupPanel.Sizer.NW));
            this.borders.push(new richfaces.ui.PopupPanel.Border(id + "ResizerNE", this, "NE-resize", richfaces.ui.PopupPanel.Sizer.NE));
            this.borders.push(new richfaces.ui.PopupPanel.Border(id + "ResizerSE", this, "SE-resize", richfaces.ui.PopupPanel.Sizer.SE));
            this.borders.push(new richfaces.ui.PopupPanel.Border(id + "ResizerSW", this, "SW-resize", richfaces.ui.PopupPanel.Sizer.SW));
        }

        if (this.options.moveable && richfaces.getDomElement(id + "_header")) {
            this.header = new richfaces.ui.PopupPanel.Border(id + "_header", this, "move", richfaces.ui.PopupPanel.Sizer.Header);
        } else {
            $(richfaces.getDomElement(id + "_header")).css('cursor', 'default');
        }

    };

    richfaces.BaseComponent.extend(richfaces.ui.PopupPanel);
    var $super = richfaces.ui.PopupPanel.$super;
    $.extend(richfaces.ui.PopupPanel.prototype, (function (options) {

        return {

            name: "PopupPanel",
            saveInputValues: function(element) {
                /* Fix for RF-3856 - Checkboxes in modal panel does not hold their states after modal was closed and opened again */
                if ($.browser.msie /* reproducible for checkbox/radio in IE6, radio in IE 7/8 beta 2 */) {
                    $('input[type=checkbox], input[type=radio]', element).each(function(index) {
                        $(this).defaultChecked = $(this).checked;
                    });
                }
            },

            width: function() {
                return this.getContentElement()[0].clientWidth;//TODO
            },

            height: function() {
                return this.getContentElement()[0].clientHeight;//TODO
            },

            getLeft : function () {
                return this.cdiv.css('left');
            },

            getTop : function () {
                return this.cdiv.css('top');
            },

            getInitialSize : function() {
                if (this.options.autosized) {
                    return 15;
                } else {
                    return $(richfaces.getDomElement(this.markerId + "_header_content")).height();
                }
            },

            getContentElement: function() {
                if (!this._contentElement) {
                    this._contentElement = this.cdiv;
                }

                return this._contentElement;
            },
            getSizeElement : function() {
                return document.body;
            },

            getMinimumSize : function(size) {
                return Math.max(size, 2 * this.getInitialSize() + 2);
            },

            __getParsedOption: function(options, name) {
                var value = parseInt(options[name], 10);

                if (value < 0 || isNaN(value)) {
                    value = this[name];
                }

                return value;
            },

            destroy: function() {

                this._contentElement = null;
                this.firstOutside = null;
                this.lastOutside = null;
                this.firstHref = null;
                this.parent = null;
                if (this.header) {
                    this.header.destroy();
                    this.header = null;
                }

                for (var k = 0; k < this.borders.length; k++) {
                    this.borders[k].destroy();
                }
                this.borders = null;

                if (this.domReattached) {
                    this.div.remove();
                }

                this.markerId = null;
                this.options = null;

                this.div = null;
                this.cdiv = null;
                this.contentDiv = null;
                this.shadowDiv = null;
                this.scrollerDiv = null;
                this.userOptions = null;
                this.eIframe = null;

                $super.destroy.call(this);

            },

            initIframe : function() {
                if (this.contentWindow) {
                    $(this.contentWindow.document.body).css("margin", "0px 0px 0px 0px");
                } else {
                    //TODO opera etc.

                }

                if ("transparent" == $(document.body).css("background-color")) {
                    $(this).css('filter', "alpha(opacity=0)");
                    $(this).css('opacity', "0");
                }
            },

            setLeft: function(pos) {
                if (!isNaN(pos)) {
                    this.cdiv.css('left', pos + "px");
                }
            },

            setTop: function(pos) {
                if (!isNaN(pos)) {
                    this.cdiv.css('top', pos + "px");
                }
            },

            show: function(event, opts) {
                var element = this.cdiv;
                if (!this.shown && this.invokeEvent("beforeshow", event, null, element)) {
                    this.preventFocus();


                    if (!this.domReattached) {
                        this.parent = this.div.parent();

                        var domElementAttachment;
                        if (opts) {
                            domElementAttachment = opts.domElementAttachment;
                        }

                        if (!domElementAttachment) {
                            domElementAttachment = this.options.domElementAttachment;
                        }

                        var newParent;
                        if ('parent' == domElementAttachment) {
                            newParent = this.parent;
                        } else if ('form' == domElementAttachment) {
                            newParent = this.findForm(element)[0] || document.body;
                        } else {
                            //default - body
                            newParent = document.body;
                        }

                        if (newParent != this.parent) {
                            this.saveInputValues(element);
                            this.shadeDiv.length && newParent.appendChild(this.shadeDiv.get(0));
                            newParent.appendChild(this.cdiv.get(0));
                            this.domReattached = true;
                        } else {
                            this.parent.show();
                        }
                    }

                    var forms = $("form", element);

                    if (this.options.keepVisualState && forms) {
                        for (var i = 0; i < forms.length; i++) {
                            var popup = this;
                            $(forms[i]).bind("submit", {popup:popup}, this.setStateInput);
                        }
                    }


                    var options = {};
                    this.userOptions = {};
                    $.extend(options, this.options);

                    if (opts) {
                        $.extend(options, opts);
                        $.extend(this.userOptions, opts);
                    }

                    this.currentMinHeight = this.getMinimumSize(this.__getParsedOption(options, 'minHeight'));
                    this.currentMinWidth = this.getMinimumSize(this.__getParsedOption(options, 'minWidth'));

                    var eContentElt = this.getContentElement();

                    if (!this.options.autosized) {
                        if (options.width && options.width == -1)
                            options.width = 300;
                        if (options.height && options.height == -1)
                            options.height = 200;
                    }

                    if (options.width && options.width != -1) {
                        if (this.currentMinWidth > options.width) {
                            options.width = this.currentMinWidth;
                        }
                        if (options.width > this.maxWidth) {
                            options.width = this.maxWidth;
                        }
                        $(richfaces.getDomElement(eContentElt)).css('width', options.width + (/px/.test(options.width) ? '' : 'px'));
                        this.shadowDiv.css('width', options.width + (/px/.test(options.width) ? '' : 'px'));
                        this.scrollerDiv.css('width', options.width + (/px/.test(options.width) ? '' : 'px'));
                    }

                    if (options.height && options.height != -1) {
                        if (this.currentMinHeight > options.height) {
                            options.height = this.currentMinHeight;
                        }
                        if (options.height > this.maxHeight) {
                            options.height = this.maxHeight;
                        }
                        $(richfaces.getDomElement(eContentElt)).css('height', options.height + (/px/.test(options.height) ? '' : 'px'));
                        var headerHeight = $(richfaces.getDomElement(this.markerId + "_header")) ? $(richfaces.getDomElement(this.markerId + "_header")).innerHeight() : 0;
                        this.scrollerDiv.css('height', options.height - headerHeight + (/px/.test(options.height) ? '' : 'px'));
                    }

                    var eIframe;
                    if (this.options.overlapEmbedObjects && !this.iframe) {
                        this.iframe = this.markerId + "IFrame";
                        $("<iframe src=\"javascript:''\" frameborder=\"0\" scrolling=\"no\" id=\"" + this.iframe + "\" " +
                            "class=\"rf-pp-ifr\" style=\"width:" + this.options.width + "px; height:" + this.options.height + "px;\">" +
                            "</iframe>").insertBefore($(':first-child', this.cdiv)[0]);

                        eIframe = $(richfaces.getDomElement(this.iframe));

                        eIframe.bind('load', this.initIframe);
                        this.eIframe = eIframe;
                    }

                    if (options.left) {
                        var _left;
                        if (options.left != "auto") {
                            _left = parseInt(options.left, 10);
                        } else {
                            var cw = this.__calculateWindowWidth();
                            var _width = this.width();
                            if (cw >= _width) {
                                _left = (cw - _width) / 2;
                            } else {
                                _left = 0;
                            }
                        }

                        this.setLeft(Math.round(_left));
                        $(this.shadowDiv).css("left", this.shadowDepth);
                    }

                    if (options.top) {
                        var _top;
                        if (options.top != "auto") {
                            _top = parseInt(options.top, 10);
                        } else {
                            var ch = this.__calculateWindowHeight();
                            var _height = this.height();
                            if (ch >= _height) {
                                _top = (ch - _height) / 2;
                            } else {
                                _top = 0;
                            }
                        }

                        this.setTop(Math.round(_top));
                        $(this.shadowDiv).css("top", this.shadowDepth);
                        $(this.shadowDiv).css("bottom", -this.shadowDepth);
                    }


                    this.div.css('visibility', '');
                    $(this.cdiv).find('*').each(function() {
                        // Force a CSS "touch" of all popupPanel children to ensure visibility in IE 9/10
                        var $this = $(this);
                        var visibility = $this.css('visibility');
                        $this.css('visibility', visibility);
                    })
                    this.div.css('display', 'block');
                    if (this.options.autosized) {
                        this.shadowDiv.css('width', this.cdiv[0].clientWidth);

                    }

                    var showEvent = {};
                    showEvent.parameters = opts || {};
                    this.shown = true;
                    this.invokeEvent("show", showEvent, null, element);
                }
            },

            __calculateWindowHeight: function() {
                var documentElement = document.documentElement;
                return self.innerHeight || (documentElement && documentElement.clientHeight) || document.body.clientHeight;
            },

            __calculateWindowWidth: function() {
                var documentElement = document.documentElement;
                return self.innerWidth || (documentElement && documentElement.clientWidth) || document.body.clientWidth;
            },

            startDrag: function(border) {
                disableSelection(document.body);
            },
            firstOnfocus: function(event) {
                var e = $(event.data.popup.firstHref);
                if (e) {
                    e.focus();
                }
            },

            processAllFocusElements: function(root, callback) {
                var idx = -1;
                var tagName;
                var formElements = "|a|input|select|button|textarea|";

                if (root.focus && root.nodeType == 1 && (tagName = root.tagName) &&
                    // Many not visible elements have focus method, we is had to avoid processing them.
                    (idx = formElements.indexOf(tagName.toLowerCase())) != -1 &&
                    formElements.charAt(idx - 1) === '|' &&
                    formElements.charAt(idx + tagName.length) === '|' &&
                    !root.disabled && root.type != "hidden") {
                    callback.call(this, root);
                } else {
                    if (root != this.cdiv.get(0)) {
                        var child = root.firstChild;
                        while (child) {
                            if (!child.style || child.style.display != 'none') {
                                this.processAllFocusElements(child, callback);
                            }
                            child = child.nextSibling;
                        }
                    }
                }
            },

            processTabindexes:    function(input) {
                if (!this.firstOutside) {
                    this.firstOutside = input;
                }
                if (!input.prevTabIndex) {
                    input.prevTabIndex = input.tabIndex;
                    input.tabIndex = -1;
                }

                if (!input.prevAccessKey) {
                    input.prevAccessKey = input.accessKey;
                    input.accessKey = "";
                }
            },

            restoreTabindexes:    function(input) {
                if (input.prevTabIndex != undefined) {
                    if (input.prevTabIndex == 0) {
                        $(input).removeAttr('tabindex');
                    } else {
                        input.tabIndex = input.prevTabIndex;
                    }
                    input.prevTabIndex = undefined;
                }
                if (input.prevAccessKey != undefined) {
                    if (input.prevAccessKey == "") {
                        $(input).removeAttr('accesskey');
                    } else {
                        input.accessKey = input.prevAccessKey;
                    }
                    input.prevAccessKey = undefined;
                }
            },

            preventFocus:    function() {
                if (this.options.modal) {
                    this.processAllFocusElements(document, this.processTabindexes);
                    var popup = this;
                    if (this.firstOutside) {

                        $(richfaces.getDomElement(this.firstOutside)).bind("focus", {popup: popup}, this.firstOnfocus);
                    }
                }
            },

            restoreFocus: function() {
                if (this.options.modal) {
                    this.processAllFocusElements(document, this.restoreTabindexes);

                    if (this.firstOutside) {
                        $(richfaces.getDomElement(this.firstOutside)).unbind("focus", this.firstOnfocus);
                        this.firstOutside = null;
                    }
                }
            },

            endDrag: function(border) {
                for (var k = 0; k < this.borders.length; k++) {
                    this.borders[k].show();
                    this.borders[k].doPosition();
                }
                enableSelection(document.body);
            },

            hide: function(event, opts) {
                var element = this.cdiv;
                this.restoreFocus();
                if (this.shown && this.invokeEvent("beforehide", event, null, element)) {

                    this.currentMinHeight = undefined;
                    this.currentMinWidth = undefined;

                    this.div.hide();

                    if (this.parent) {
                        if (this.domReattached) {
                            this.saveInputValues(element);
                            var div = this.div.get(0);
                            this.shadeDiv.length && div.appendChild(this.shadeDiv.get(0));
                            div.appendChild(element.get(0));

                            this.domReattached = false;
                        }
                    }

                    var hideEvent = {};
                    hideEvent.parameters = opts || {};

                    var forms = $("form", element);
                    if (this.options.keepVisualState && forms) {
                        for (var i = 0; i < forms.length; i++) {
                            $(forms[i]).unbind("submit", this.setStateInput);
                        }
                    }

                    this.shown = false;
                    this.invokeEvent("hide", hideEvent, null, element)
                }
            },

            getStyle: function(elt, name) {
                return parseInt($(richfaces.getDomElement(elt)).css(name).replace("px", ""), 10);
            },

            doResizeOrMove: function(diff) {
                var vetoes = {};
                var shadowHash = {};
                var cssHash = {};
                var cssHashWH = {};
                var shadowHashWH = {};
                var contentHashWH = {};
                var scrollerHashWH = {};
                var newSize;
                var scrollerHeight = 22;
                var scrollerWidth = 0;
                var eContentElt = this.getContentElement();

                newSize = this.getStyle(eContentElt, "width");

                var oldWidthSize = newSize;
                newSize += diff.deltaWidth || 0;


                if (newSize >= this.currentMinWidth || this.options.autosized) {
                    cssHashWH.width = newSize + 'px';
                    shadowHashWH.width = newSize + 'px';
                    contentHashWH.width = newSize - scrollerWidth + 'px';
                    scrollerHashWH.width = newSize - scrollerWidth + 'px';
                } else {
                    cssHashWH.width = this.currentMinWidth + 'px';
                    shadowHashWH.width = this.currentMinWidth + 'px';
                    contentHashWH.width = this.currentMinWidth - scrollerWidth + 'px';
                    scrollerHashWH.width = this.currentMinWidth - scrollerWidth + 'px';
                    vetoes.vx = oldWidthSize - this.currentMinWidth;

                    vetoes.x = true;
                }

                if (newSize > this.options.maxWidth) {
                    if (diff.deltaWidth) {
                        cssHashWH.width = this.currentMaxWidth + 'px';
                        shadowHashWH.width = this.currentMaxWidth + 'px';
                        contentHashWH.width = this.currentMaxWidth - scrollerWidth + 'px';
                        scrollerHashWH.width = this.currentMaxWidth - scrollerWidth + 'px';
                        vetoes.vx = oldWidthSize - this.currentMaxWidth;
                    }

                    vetoes.x = true;
                }

                if (vetoes.vx && diff.deltaX) {
                    diff.deltaX = -vetoes.vx;
                }

                var eCdiv = $(this.cdiv);

                if (diff.deltaX && (vetoes.vx || !vetoes.x)) {
                    if (vetoes.vx) {
                        diff.deltaX = vetoes.vx;
                    }

                    var newLeftPos = this.getStyle(eCdiv, "left");
                    newLeftPos += diff.deltaX;
                    cssHash.left = newLeftPos + 'px';

                }

                newSize = this.getStyle(eContentElt, "height");

                var oldHeightSize = newSize;
                newSize += diff.deltaHeight || 0;

                if (newSize >= this.currentMinHeight || this.options.autosized) {
                    if (diff.deltaHeight) {
                        cssHashWH.height = newSize + 'px';
                        shadowHashWH.height = newSize + 'px';
                        scrollerHashWH.height = newSize - scrollerHeight + 'px';
                    }
                } else {
                    if (diff.deltaHeight) {
                        cssHashWH.height = this.currentMinHeight + 'px';
                        shadowHashWH.height = this.currentMinHeight + 'px';
                        scrollerHashWH.height = this.currentMinHeight - scrollerHeight + 'px';
                        vetoes.vy = oldHeightSize - this.currentMinHeight;
                    }

                    vetoes.y = true;
                }

                if (newSize > this.options.maxHeight) {
                    if (diff.deltaHeight) {
                        cssHashWH.height = this.currentMaxHeight + 'px';
                        shadowHashWH.height = this.currentMaxHeight + 'px';
                        scrollerHashWH.height = this.currentMaxHeight - scrollerHeight + 'px';
                        vetoes.vy = oldHeightSize - this.currentMaxHeight;
                    }

                    vetoes.y = true;
                }

                if (vetoes.vy && diff.deltaY) {
                    diff.deltaY = -vetoes.vy;
                }

                if (diff.deltaY && (vetoes.vy || !vetoes.y)) {
                    if (vetoes.vy) {
                        diff.deltaY = vetoes.vy;
                    }

                }
                if (diff.deltaY && (vetoes.vy || !vetoes.y)) {
                    if (vetoes.vy) {
                        diff.deltaY = vetoes.vy;
                    }

                    var newTopPos = this.getStyle(eCdiv, "top");
                    newTopPos += diff.deltaY;
                    cssHash.top = newTopPos + 'px';
                }
                eContentElt.css(cssHashWH);
                this.scrollerDiv.css(scrollerHashWH);
                if (this.eIframe) {
                    this.eIframe.css(scrollerHashWH);
                }
                this.shadowDiv.css(shadowHashWH);

                eCdiv.css(cssHash);
                this.shadowDiv.css(shadowHash);

                $.extend(this.userOptions, cssHash);
                $.extend(this.userOptions, cssHashWH);
                var w = this.width();
                var h = this.height();

                this.reductionData = null;

                if (w <= 2 * this.getInitialSize()) {
                    this.reductionData = {};
                    this.reductionData.w = w;
                }

                if (h <= 2 * this.getInitialSize()) {
                    if (!this.reductionData) {
                        this.reductionData = {};
                    }

                    this.reductionData.h = h;
                }

                if (this.header) {
                    this.header.doPosition();
                }

                return vetoes;
            },

            setSize : function (width, height) {
                var w = width - this.width();
                var h = height - this.height();
                var diff = new richfaces.ui.PopupPanel.Sizer.Diff(0, 0, w, h);
                this.doResizeOrMove(diff);
            },

            moveTo : function (top, left) {
                this.cdiv.css('top', top);
                this.cdiv.css('left', left);
            },

            move : function (dx, dy) {
                var diff = new richfaces.ui.PopupPanel.Sizer.Diff(dx, dy, 0, 0);
                this.doResizeOrMove(diff);
            },

            resize : function (dx, dy) {
                var diff = new richfaces.ui.PopupPanel.Sizer.Diff(0, 0, dx, dy);
                this.doResizeOrMove(diff);
            },

            findForm: function(elt) {
                var target = elt;
                while (target) {
                    if (target[0] && (!target[0].tagName /* document node doesn't have tagName */
                        || target[0].tagName.toLowerCase() != "form")) {

                        target = $(target).parent();
                    } else {
                        break;
                    }
                }

                return target;
            },

            setStateInput: function(event) {
                // Concret input but not entire form is a target element for onsubmit in FF
                var popup = event.data.popup;
                target = $(popup.findForm(event.currentTarget));

                var input = document.createElement("input");
                input.type = "hidden";
                input.id = popup.markerId + "OpenedState";
                input.name = popup.markerId + "OpenedState";
                input.value = popup.shown ? "true" : "false";
                target.append(input);

                $.each(popup.userOptions, function(key, value) {
                    input = document.createElement("input");
                    input.type = "hidden";
                    input.id = popup.markerId + "StateOption_" + key;
                    input.name = popup.markerId + "StateOption_" + key;
                    input.value = value;
                    target.append(input);
                });

                return true;
            }


        }

    })());
    $.extend(richfaces.ui.PopupPanel, {

            showPopupPanel : function (id, opts, event) {
                richfaces.Event.ready(function() {
                    richfaces.$(id).show()
                });
            },

            hidePopupPanel : function (id, opts, event) {
                richfaces.Event.ready(function() {
                    richfaces.$(id).hide()
                });
            }
        });

})(jQuery, window.RichFaces);
;/*!
 * jQuery UI Core 1.9.2
 * http://jqueryui.com
 *
 * Copyright 2012 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/category/ui-core/
 */
(function( $, undefined ) {

var uuid = 0,
	runiqueId = /^ui-id-\d+$/;

// prevent duplicate loading
// this is only a problem because we proxy existing functions
// and we don't want to double proxy them
$.ui = $.ui || {};
if ( $.ui.version ) {
	return;
}

$.extend( $.ui, {
	version: "1.9.2",

	keyCode: {
		BACKSPACE: 8,
		COMMA: 188,
		DELETE: 46,
		DOWN: 40,
		END: 35,
		ENTER: 13,
		ESCAPE: 27,
		HOME: 36,
		LEFT: 37,
		NUMPAD_ADD: 107,
		NUMPAD_DECIMAL: 110,
		NUMPAD_DIVIDE: 111,
		NUMPAD_ENTER: 108,
		NUMPAD_MULTIPLY: 106,
		NUMPAD_SUBTRACT: 109,
		PAGE_DOWN: 34,
		PAGE_UP: 33,
		PERIOD: 190,
		RIGHT: 39,
		SPACE: 32,
		TAB: 9,
		UP: 38
	}
});

// plugins
$.fn.extend({
	_focus: $.fn.focus,
	focus: function( delay, fn ) {
		return typeof delay === "number" ?
			this.each(function() {
				var elem = this;
				setTimeout(function() {
					$( elem ).focus();
					if ( fn ) {
						fn.call( elem );
					}
				}, delay );
			}) :
			this._focus.apply( this, arguments );
	},

	scrollParent: function() {
		var scrollParent;
		if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
			scrollParent = this.parents().filter(function() {
				return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
			}).eq(0);
		} else {
			scrollParent = this.parents().filter(function() {
				return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
			}).eq(0);
		}

		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
	},

	zIndex: function( zIndex ) {
		if ( zIndex !== undefined ) {
			return this.css( "zIndex", zIndex );
		}

		if ( this.length ) {
			var elem = $( this[ 0 ] ), position, value;
			while ( elem.length && elem[ 0 ] !== document ) {
				// Ignore z-index if position is set to a value where z-index is ignored by the browser
				// This makes behavior of this function consistent across browsers
				// WebKit always returns auto if the element is positioned
				position = elem.css( "position" );
				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
					// IE returns 0 when zIndex is not specified
					// other browsers return a string
					// we ignore the case of nested elements with an explicit value of 0
					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
					value = parseInt( elem.css( "zIndex" ), 10 );
					if ( !isNaN( value ) && value !== 0 ) {
						return value;
					}
				}
				elem = elem.parent();
			}
		}

		return 0;
	},

	uniqueId: function() {
		return this.each(function() {
			if ( !this.id ) {
				this.id = "ui-id-" + (++uuid);
			}
		});
	},

	removeUniqueId: function() {
		return this.each(function() {
			if ( runiqueId.test( this.id ) ) {
				$( this ).removeAttr( "id" );
			}
		});
	}
});

// selectors
function focusable( element, isTabIndexNotNaN ) {
	var map, mapName, img,
		nodeName = element.nodeName.toLowerCase();
	if ( "area" === nodeName ) {
		map = element.parentNode;
		mapName = map.name;
		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
			return false;
		}
		img = $( "img[usemap=#" + mapName + "]" )[0];
		return !!img && visible( img );
	}
	return ( /input|select|textarea|button|object/.test( nodeName ) ?
		!element.disabled :
		"a" === nodeName ?
			element.href || isTabIndexNotNaN :
			isTabIndexNotNaN) &&
		// the element and all of its ancestors must be visible
		visible( element );
}

function visible( element ) {
	return $.expr.filters.visible( element ) &&
		!$( element ).parents().andSelf().filter(function() {
			return $.css( this, "visibility" ) === "hidden";
		}).length;
}

$.extend( $.expr[ ":" ], {
	data: $.expr.createPseudo ?
		$.expr.createPseudo(function( dataName ) {
			return function( elem ) {
				return !!$.data( elem, dataName );
			};
		}) :
		// support: jQuery <1.8
		function( elem, i, match ) {
			return !!$.data( elem, match[ 3 ] );
		},

	focusable: function( element ) {
		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
	},

	tabbable: function( element ) {
		var tabIndex = $.attr( element, "tabindex" ),
			isTabIndexNaN = isNaN( tabIndex );
		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
	}
});

// support
$(function() {
	var body = document.body,
		div = body.appendChild( div = document.createElement( "div" ) );

	// access offsetHeight before setting the style to prevent a layout bug
	// in IE 9 which causes the element to continue to take up space even
	// after it is removed from the DOM (#8026)
	div.offsetHeight;

	$.extend( div.style, {
		minHeight: "100px",
		height: "auto",
		padding: 0,
		borderWidth: 0
	});

	$.support.minHeight = div.offsetHeight === 100;
	$.support.selectstart = "onselectstart" in div;

	// set display to none to avoid a layout bug in IE
	// http://dev.jquery.com/ticket/4014
	body.removeChild( div ).style.display = "none";
});

// support: jQuery <1.8
if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
	$.each( [ "Width", "Height" ], function( i, name ) {
		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
			type = name.toLowerCase(),
			orig = {
				innerWidth: $.fn.innerWidth,
				innerHeight: $.fn.innerHeight,
				outerWidth: $.fn.outerWidth,
				outerHeight: $.fn.outerHeight
			};

		function reduce( elem, size, border, margin ) {
			$.each( side, function() {
				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
				if ( border ) {
					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
				}
				if ( margin ) {
					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
				}
			});
			return size;
		}

		$.fn[ "inner" + name ] = function( size ) {
			if ( size === undefined ) {
				return orig[ "inner" + name ].call( this );
			}

			return this.each(function() {
				$( this ).css( type, reduce( this, size ) + "px" );
			});
		};

		$.fn[ "outer" + name] = function( size, margin ) {
			if ( typeof size !== "number" ) {
				return orig[ "outer" + name ].call( this, size );
			}

			return this.each(function() {
				$( this).css( type, reduce( this, size, true, margin ) + "px" );
			});
		};
	});
}

// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
	$.fn.removeData = (function( removeData ) {
		return function( key ) {
			if ( arguments.length ) {
				return removeData.call( this, $.camelCase( key ) );
			} else {
				return removeData.call( this );
			}
		};
	})( $.fn.removeData );
}





// deprecated

(function() {
	var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
	$.ui.ie = uaMatch.length ? true : false;
	$.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
})();

$.fn.extend({
	disableSelection: function() {
		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
			".ui-disableSelection", function( event ) {
				event.preventDefault();
			});
	},

	enableSelection: function() {
		return this.unbind( ".ui-disableSelection" );
	}
});

$.extend( $.ui, {
	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
	plugin: {
		add: function( module, option, set ) {
			var i,
				proto = $.ui[ module ].prototype;
			for ( i in set ) {
				proto.plugins[ i ] = proto.plugins[ i ] || [];
				proto.plugins[ i ].push( [ option, set[ i ] ] );
			}
		},
		call: function( instance, name, args ) {
			var i,
				set = instance.plugins[ name ];
			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
				return;
			}

			for ( i = 0; i < set.length; i++ ) {
				if ( instance.options[ set[ i ][ 0 ] ] ) {
					set[ i ][ 1 ].apply( instance.element, args );
				}
			}
		}
	},

	contains: $.contains,

	// only used by resizable
	hasScroll: function( el, a ) {

		//If overflow is hidden, the element might have extra content, but the user wants to hide it
		if ( $( el ).css( "overflow" ) === "hidden") {
			return false;
		}

		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
			has = false;

		if ( el[ scroll ] > 0 ) {
			return true;
		}

		// TODO: determine which cases actually cause this to happen
		// if the element doesn't have the scroll set, see if it's possible to
		// set the scroll
		el[ scroll ] = 1;
		has = ( el[ scroll ] > 0 );
		el[ scroll ] = 0;
		return has;
	},

	// these are odd functions, fix the API or move into individual plugins
	isOverAxis: function( x, reference, size ) {
		//Determines when x coordinate is over "b" element axis
		return ( x > reference ) && ( x < ( reference + size ) );
	},
	isOver: function( y, x, top, left, height, width ) {
		//Determines when x, y coordinates is over "b" element
		return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
	}
});

})( jQuery );
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
(function($, richfaces) {

    var NEW_NODE_TOGGLE_STATE = "__NEW_NODE_TOGGLE_STATE";

    var TRIGGER_NODE_AJAX_UPDATE = "__TRIGGER_NODE_AJAX_UPDATE";

    var SELECTION_STATE = "__SELECTION_STATE";

    var TREE_CLASSES = ["rf-tr-nd-colps", "rf-tr-nd-exp"];

    var TREE_HANDLE_CLASSES = ["rf-trn-hnd-colps", "rf-trn-hnd-exp"];

    var TREE_ICON_CLASSES = ["rf-trn-ico-colps", "rf-trn-ico-exp"];

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.TreeNode = richfaces.BaseComponent.extendClass({

            name: "TreeNode",

            init: function (id, commonOptions) {
                $superTreeNode.constructor.call(this, id);
                this.__rootElt = $(this.attachToDom());

                this.__children = new Array();

                this.__initializeChildren(commonOptions);

                var handlers = (commonOptions.clientEventHandlers || {})[this.getId().substring(commonOptions.treeId.length)] || {};

                if (handlers.bth) {
                    richfaces.Event.bind(this.__rootElt, "beforetoggle", new Function("event", handlers.bth));
                }

                if (handlers.th) {
                    richfaces.Event.bind(this.__rootElt, "toggle", new Function("event", handlers.th));
                }

                this.__addLastNodeClass();
            },

            destroy: function() {

                if (this.parent) {
                    this.parent.removeChild(this);
                    this.parent = null;
                }

                this.__clientToggleStateInput = null;

                this.__clearChildren();

                this.__rootElt = null;

                $superTreeNode.destroy.call(this);
            },

            __initializeChildren: function(commonOptions) {
                var _this = this;
                this.__rootElt.children(".rf-tr-nd").each(function() {
                    _this.addChild(new richfaces.ui.TreeNode(this, commonOptions));
                });
            },

            __addLastNodeClass: function() {
                if (this.__rootElt.next("div").length == 0) {
                    this.__rootElt.addClass("rf-tr-nd-last");
                }
            },

            __getNodeContainer: function() {
                return this.__rootElt.find(" > .rf-trn:first");
            },

            __getHandle: function() {
                return this.__getNodeContainer().find(" > .rf-trn-hnd:first");
            },

            __getContent: function() {
                return this.__getNodeContainer().find(" > .rf-trn-cnt:first");
            },

            __getIcons: function() {
                return this.__getContent().find(" > .rf-trn-ico");
            },

            getParent: function() {
                return this.__parent;
            },

            setParent: function(newParent) {
                this.__parent = newParent;
            },

            addChild: function(child, idx) {
                var start;
                if (typeof idx != 'undefined') {
                    start = idx;
                } else {
                    start = this.__children.length;
                }

                this.__children.splice(start, 0, child);
                child.setParent(this);
            },

            removeChild: function(child) {
                if (this.__children.length) {
                    var idx = this.__children.indexOf(child);
                    if (idx != -1) {
                        var removedChildren = this.__children.splice(idx, 1);
                        if (removedChildren) {
                            for (var i = 0; i < removedChildren.length; i++) {
                                removedChildren[i].setParent(undefined);
                            }
                        }
                    }
                }
            },

            __clearChildren: function() {
                for (var i = 0; i < this.__children.length; i++) {
                    this.__children[i].setParent(undefined);
                }

                this.__children = new Array();
            },

            isExpanded: function() {
                return !this.isLeaf() && this.__rootElt.hasClass("rf-tr-nd-exp");
            },

            isCollapsed: function() {
                return !this.isLeaf() && this.__rootElt.hasClass("rf-tr-nd-colps");
            },

            isLeaf: function() {
                return this.__rootElt.hasClass("rf-tr-nd-lf");
            },

            __canBeToggled: function() {
                return !this.isLeaf() && !this.__rootElt.hasClass("rf-tr-nd-exp-nc") && !this.__loading;
            },

            toggle: function() {
                if (!this.__canBeToggled()) {
                    return;
                }

                if (this.isCollapsed()) {
                    this.expand();
                } else {
                    this.collapse();
                }
            },

            __updateClientToggleStateInput: function(newState) {
                if (!this.__clientToggleStateInput) {
                    this.__clientToggleStateInput = $("<input type='hidden' />").appendTo(this.__rootElt)
                        .attr({name: this.getId() + NEW_NODE_TOGGLE_STATE});
                }

                this.__clientToggleStateInput.val(newState.toString());

            },

            __fireBeforeToggleEvent: function() {
                return richfaces.Event.callHandler(this.__rootElt, "beforetoggle");
            },

            __fireToggleEvent: function() {
                richfaces.Event.callHandler(this.__rootElt, "toggle");
            },

            __makeLoading: function() {
                this.__loading = true;
                this.__getNodeContainer().addClass("rf-trn-ldn");
            },

            __resetLoading: function() {
                this.__loading = false;
                this.__getNodeContainer().removeClass("rf-trn-ldn");
            },

            __changeToggleState: function(newState) {
                if (!this.isLeaf()) {
                    if (newState ^ this.isExpanded()) {

                        if (this.__fireBeforeToggleEvent() === false) {
                            return;
                        }

                        var tree = this.getTree();

                        switch (tree.getToggleType()) {
                            case 'client':
                                this.__rootElt.addClass(TREE_CLASSES[newState ? 1 : 0]).removeClass(TREE_CLASSES[!newState ? 1 : 0]);
                                this.__getHandle().addClass(TREE_HANDLE_CLASSES[newState ? 1 : 0]).removeClass(TREE_HANDLE_CLASSES[!newState ? 1 : 0]);

                                var icons = this.__getIcons();
                                if (icons.length == 1) {
                                    icons.addClass(TREE_ICON_CLASSES[newState ? 1 : 0]).removeClass(TREE_ICON_CLASSES[!newState ? 1 : 0]);
                                }

                                this.__updateClientToggleStateInput(newState);
                                this.__fireToggleEvent();
                                break;

                            case 'ajax':
                            case 'server':
                                //TODO - event?
                                tree.__sendToggleRequest(null, this, newState);
                                break;
                        }
                    }
                }
            },

            collapse: function() {
                this.__changeToggleState(false);
            },

            expand: function() {
                this.__changeToggleState(true);
            },

            __setSelected: function(value) {
                var content = this.__getContent();
                if (value) {
                    content.addClass("rf-trn-sel");
                } else {
                    content.removeClass("rf-trn-sel");
                }

                this.__selected = value;
            },

            isSelected: function() {
                return this.__selected;
            },

            getTree: function() {
                return this.getParent().getTree();
            },

            getId: function() {
                return this.__rootElt.attr('id');
            }

        });

    // define super class link for TreeNode
    var $superTreeNode = richfaces.ui.TreeNode.$super;

    richfaces.ui.TreeNode.initNodeByAjax = function(nodeId, commonOptions) {
        var node = $(document.getElementById(nodeId));

        var opts = commonOptions || {};

        var parent = node.parent(".rf-tr-nd, .rf-tr");

        var idx = node.prevAll(".rf-tr-nd").length;

        var parentNode = richfaces.$(parent[0]);
        opts.treeId = parentNode.getTree().getId();

        var newChild = new richfaces.ui.TreeNode(node[0], opts);
        parentNode.addChild(newChild, idx);

        var tree = parentNode.getTree();

        if (tree.getSelection().contains(newChild.getId())) {
            newChild.__setSelected(true);
        }
    };

    richfaces.ui.TreeNode.emitToggleEvent = function(nodeId) {
        var node = document.getElementById(nodeId);
        if (!node) {
            return;
        }

        richfaces.$(node).__fireToggleEvent();
    };

    var findTree = function(elt) {
        return richfaces.$($(elt).closest(".rf-tr"));
    };

    var findTreeNode = function(elt) {
        return richfaces.$($(elt).closest(".rf-tr-nd"));
    };

    var isEventForAnotherTree = function(tree, elt) {
        return tree != findTree(elt);
    };

    richfaces.ui.Tree = richfaces.ui.TreeNode.extendClass({

            name: "Tree",

            init: function (id, options) {
                this.__treeRootElt = $(richfaces.getDomElement(id));

                var commonOptions = {};
                commonOptions.clientEventHandlers = options.clientEventHandlers || {};
                commonOptions.treeId = id;

                $superTree.constructor.call(this, this.__treeRootElt, commonOptions);

                this.__toggleType = options.toggleType || 'ajax';
                this.__selectionType = options.selectionType || 'client';

                if (options.ajaxSubmitFunction) {
                    this.__ajaxSubmitFunction = new Function("event", "source", "params", "complete", options.ajaxSubmitFunction);
                }

                if (options.onbeforeselectionchange) {
                    richfaces.Event.bind(this.__treeRootElt, "beforeselectionchange", new Function("event", options.onbeforeselectionchange));
                }

                if (options.onselectionchange) {
                    richfaces.Event.bind(this.__treeRootElt, "selectionchange", new Function("event", options.onselectionchange));
                }

                this.__toggleNodeEvent = options.toggleNodeEvent;
                if (this.__toggleNodeEvent) {
                    this.__treeRootElt.delegate(".rf-trn", this.__toggleNodeEvent, this, this.__nodeToggleActivated);
                }
                if (!this.__toggleNodeEvent || this.__toggleNodeEvent != 'click') {
                    this.__treeRootElt.delegate(".rf-trn-hnd", "click", this, this.__nodeToggleActivated);
                }

                this.__treeRootElt.delegate(".rf-trn-cnt", "mousedown", this, this.__nodeSelectionActivated);

                this.__findSelectionInput();
                this.__selection = new richfaces.ui.TreeNodeSet(this.__selectionInput.val());

                $(document).ready($.proxy(this.__updateSelectionFromInput, this));
            },

            __findSelectionInput: function () {
                this.__selectionInput = $(" > .rf-tr-sel-inp", this.__treeRootElt);
            },

            __addLastNodeClass: function() {
                //stub function overriding parent class method
            },

            destroy: function() {
                if (this.__toggleNodeEvent) {
                    this.__treeRootElt.undelegate(".rf-trn", this.__toggleNodeEvent, this, this.__nodeToggleActivated);
                }
                if (!this.__toggleNodeEvent || this.__toggleNodeEvent != 'click') {
                    this.__treeRootElt.undelegate(".rf-trn-hnd", "click", this, this.__nodeToggleActivated);
                }

                this.__treeRootElt.undelegate(".rf-trn-cnt", "mousedown", this.__nodeSelectionActivated);
                this.__treeRootElt = null;

                this.__selectionInput = null;
                this.__ajaxSubmitFunction = null;
                $superTree.destroy.call(this);
            },

            __nodeToggleActivated: function(event) {
                var theTree = event.data;
                if (isEventForAnotherTree(theTree, this)) {
                    return;
                }

                var treeNode = findTreeNode(this);
                treeNode.toggle();
            },

            __nodeSelectionActivated: function(event) {
                var theTree = event.data;
                if (isEventForAnotherTree(theTree, this)) {
                    return;
                }

                var treeNode = findTreeNode(this);

                if (event.ctrlKey) {
                    theTree.__toggleSelection(treeNode);
                } else {
                    theTree.__addToSelection(treeNode);
                }
            },

            __sendToggleRequest: function(event, toggleSource, newNodeState) {
                var toggleSourceId = toggleSource.getId();

                var clientParams = {};
                clientParams[toggleSourceId + NEW_NODE_TOGGLE_STATE] = newNodeState;

                if (this.getToggleType() == 'server') {
                    var form = this.__treeRootElt.closest('form');
                    richfaces.submitForm(form, clientParams);
                } else {
                    toggleSource.__makeLoading();
                    clientParams[toggleSourceId + TRIGGER_NODE_AJAX_UPDATE] = newNodeState;
                    this.__ajaxSubmitFunction(event, toggleSourceId, clientParams, function() {
                        var treeNode = richfaces.$(toggleSourceId);
                        if (treeNode) {
                            treeNode.__resetLoading();
                        }
                    });
                }
            },

            getToggleType: function() {
                return this.__toggleType;
            },

            getSelectionType: function() {
                return this.__selectionType;
            },

            getTree: function() {
                return this;
            },

            __handleSelectionChange: function(newSelection) {
                var eventData = {
                    oldSelection: this.getSelection().getNodes(),
                    newSelection: newSelection.getNodes()
                };

                if (richfaces.Event.callHandler(this.__treeRootElt, "beforeselectionchange", eventData) === false) {
                    return;
                }

                this.__selectionInput.val(newSelection.getNodeString());

                if (this.getSelectionType() == 'client') {
                    this.__updateSelection(newSelection);
                } else {
                    this.__ajaxSubmitFunction(null, this.getId());
                }
            },

            __toggleSelection: function(node) {
                var newSelection = this.getSelection().cloneAndToggle(node);
                this.__handleSelectionChange(newSelection);
            },

            __addToSelection: function(node) {
                var newSelection = this.getSelection().cloneAndAdd(node);
                this.__handleSelectionChange(newSelection);
            },

            __updateSelectionFromInput: function() {
                this.__findSelectionInput();
                this.__updateSelection(new richfaces.ui.TreeNodeSet(this.__selectionInput.val()));
            },

            __updateSelection: function(newSelection) {

                var oldSelection = this.getSelection();

                oldSelection.each(function() {
                    this.__setSelected(false)
                });
                newSelection.each(function() {
                    this.__setSelected(true)
                });

                if (oldSelection.getNodeString() != newSelection.getNodeString()) {
                    richfaces.Event.callHandler(this.__treeRootElt, "selectionchange", {
                            oldSelection: oldSelection.getNodes(),
                            newSelection: newSelection.getNodes()
                        });
                }

                this.__selection = newSelection;
            },

            getSelection: function() {
                return this.__selection;
            },

            contextMenuAttach: function (menu) {
                var selector = "[id='" + this.id[0].id + "'] ";
                selector += (typeof menu.options.targetSelector === 'undefined')
                    ?  ".rf-trn-cnt" : menu.options.targetSelector;
                selector = jQuery.trim(selector);
                richfaces.Event.bind(selector, menu.options.showEvent, $.proxy(menu.__showHandler, menu), menu);
            }

        });

    // define super class link for Tree
    var $superTree = richfaces.ui.Tree.$super;

    richfaces.ui.TreeNodeSet = function() {
        this.init.apply(this, arguments);
    };

    //TODO - that's a single-node set, implement multi-node support!
    $.extend(richfaces.ui.TreeNodeSet.prototype, {

            init: function(nodeId) {
                this.__nodeId = nodeId;
            },

            contains: function(node) {
                if (node.getId) {
                    return this.__nodeId == node.getId();
                } else {
                    return this.__nodeId == node;
                }
            },

            getNodeString: function() {
                return this.__nodeId;
            },

            toString: function() {
                return this.getNodeString();
            },

            getNodes: function() {
                if (this.__nodeId) {
                    var node = richfaces.$(this.__nodeId);
                    if (node) {
                        return [node];
                    } else {
                        return null;
                    }
                }

                return [];
            },

            cloneAndAdd: function(node) {
                return new richfaces.ui.TreeNodeSet(node.getId());
            },

            cloneAndToggle: function(node) {
                var nodeId;
                if (this.contains(node)) {
                    nodeId = "";
                } else {
                    nodeId = node.getId();
                }

                return new richfaces.ui.TreeNodeSet(nodeId);
            },

            each: function(callback) {
                $.each(this.getNodes() || [], callback);
            }
        });

}(jQuery, RichFaces));;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    /* SIMPLE INNER CLASS for handle switch operation*/
    function SwitchItems(comp) {
        this.comp = comp;
    }

    SwitchItems.prototype = {

        /**
         * @param {TogglePanelItem} oldPanel
         * @param {TogglePanelItem} newPanel
         *
         * @return {void}
         * */
        exec : function (oldPanel, newPanel) {
            if (newPanel.switchMode == "server") {
                return this.execServer(oldPanel, newPanel);
            } else if (newPanel.switchMode == "ajax") {
                return this.execAjax(oldPanel, newPanel);
            } else if (newPanel.switchMode == "client") {
                return this.execClient(oldPanel, newPanel);
            } else {
                rf.log.error("SwitchItems.exec : unknown switchMode (" + this.comp.switchMode + ")");
            }
        },

        /**
         * @protected
         * @param {TogglePanelItem} oldPanel
         * @param {TogglePanelItem} newPanel
         *
         * @return {Boolean} false
         * */
        execServer : function (oldPanel, newPanel) {
            if (oldPanel) {
                var continueProcess = oldPanel.__leave();
                if (!continueProcess) {
                    return false;
                }
            }

            this.__setActiveItem(newPanel.getName());

            rf.submitForm(this.__getParentForm());

            return false;
        },

        /**
         * @protected
         * @param {TogglePanelItem} oldPanel
         * @param {TogglePanelItem} newPanel
         *
         * @return {Boolean} false
         * */
        execAjax : function (oldPanel, newPanel) {
            var options = $.extend({}, this.comp.options["ajax"], {}/*this.getParameters(newPanel)*/);

            this.__setActiveItem(newPanel.getName());
            rf.ajax(this.comp.id, null, options);

            if (oldPanel) {
                this.__setActiveItem(oldPanel.getName());
            }

            return false;
        },

        /**
         * @protected
         * @param {TogglePanelItem} oldPanel
         * @param {TogglePanelItem} newPanel
         *
         * @return {undefined}
         *             - false - if process has been terminated
         *             - true  - in other cases
         * */
        execClient : function (oldPanel, newPanel) {
            if (oldPanel) {
                var continueProcess = oldPanel.__leave();
                if (!continueProcess) {
                    return false;
                }
            }

            this.__setActiveItem(newPanel.getName());

            newPanel.__enter();
            this.comp.__fireItemChange(oldPanel, newPanel);

            return true;
        },

        /**
         * @private
         * */
        __getParentForm : function () {
            return $(rf.getDomElement(this.comp.id)).parents('form:first');
        },

        /**
         * @private
         * */
        __setActiveItem : function (name) {
            rf.getDomElement(this.__getValueInputId()).value = name;
            this.comp.activeItem = name;
        },

        /**
         * @private
         * */
        __getValueInputId: function () {
            return this.comp.id + "-value"
        }
    };

    /**
     * @class TogglePanel
     * @name TogglePanel
     *
     * @constructor
     * @param {String} componentId - component id
     * @param {Hash} options - params
     * */
    rf.ui.TogglePanel = rf.BaseComponent.extendClass({

            // class name
            name:"TogglePanel",

            init : function (componentId, options) {
                $super.constructor.call(this, componentId);
                this.attachToDom();

                this.items = [];

                this.options = $.extend(this.options, options || {});
                this.activeItem = this.options.activeItem;

                this.__addUserEventHandler("itemchange");
                this.__addUserEventHandler("beforeitemchange");
            },

            /***************************** Public Methods  ****************************************************************/

            /**
             * @methodOf
             *
             * @name TogglePanel#getSelectItem
             *
             * @return {String} name of current selected panel item
             */
            getSelectItem: function () {
                return this.activeItem;
            },

            /**
             * @methodOf
             * @name TogglePanel#switchToItem
             *
             * @param {String} name - panel item name to switch
             *           we can use meta names @first, @prev, @next and @last
             * @return {Boolean} - false if something wrong and true if all is ok
             */
            switchToItem: function (name) {
                var newPanel = this.getNextItem(name);
                if (newPanel == null) {
                    rf.log.warn("TogglePanel.switchToItems(" + name + "): item with name '" + name + "' not found");
                    return false;
                }

                var oldPanel = this.__getItemByName(this.getSelectItem());

                var continueProcess = this.__fireBeforeItemChange(oldPanel, newPanel);
                if (!continueProcess) {
                    rf.log.warn("TogglePanel.switchToItems(" + name + "): switch has been canceled by beforeItemChange event");
                    return false
                }

                return this.__itemsSwitcher().exec(oldPanel, newPanel);
            },

            /**
             * @methodOf
             * @name TogglePanel#getNextItem
             *
             * @param {String} name of TogglePanelItem or meta name (@first | @prev | @next | @last)
             * @return {TogglePanelItem} null if item not found
             */
            getNextItem : function (name) {
                if (name) {
                    var newItemIndex = this.__ITEMS_META_NAMES[name];
                    if (newItemIndex) {
                        return this.__getItem(newItemIndex(this));
                    } else {
                        return this.__getItemByName(name);
                    }
                } else {
                    return this.__getItemByName(this.nextItem());
                }
            },

            /**
             * please, remove this method when client side ajax events will be added
             *
             * */
            onCompleteHandler : function (newItemName) {
                var oldItem = this.__getItemByName(this.activeItem);
                var newItem = this.__getItemByName(newItemName);

                // Don't do like this and remove it ASAP
                this.__itemsSwitcher().execClient(oldItem, newItem);
            },

            /**
             * @methodOf
             * @name TogglePanel#getItems
             *
             * @return {TogglePanelItem[]} all defined panel items
             */
            getItems : function () {
                return this.items;
            },

            /**
             * @methodOf
             * @name TogglePanel#getItemsNames
             *
             * @return {String[]} names of all defined items
             */
            getItemsNames: function () {
                var res = [];
                for (var i = 0; i < this.items.length; i++) {
                    res.push(this.items[i].getName());
                }

                return res;
            },

            /**
             * @methodOf
             * @name TogglePanel#nextItem
             *
             * @param {String} [itemName = activeItem]
             * @return {String} name of next panel item
             */
            nextItem: function (itemName) {
                var itemIndex = this.__getItemIndex(itemName || this.activeItem);
                if (itemIndex == -1) {
                    return null;
                }

                return this.__getItemName(itemIndex + 1);
            },

            /**
             * @methodOf
             * @name TogglePanel#firstItem
             *
             * @return {String} name of first panel item
             */
            firstItem: function () {
                return this.__getItemName(0);
            },

            /**
             * @methodOf
             * @name TogglePanel#lastItem
             *
             * @return {String} name of last panel item
             */
            lastItem: function () {
                return this.__getItemName(this.items.length - 1);
            },

            /**
             * @methodOf
             * @name TogglePanel#prevItem
             *
             * @param {String} itemName
             * @return {String} name of prev panel item
             *                  null if it is first item
             */
            prevItem: function (itemName) {
                var itemIndex = this.__getItemIndex(itemName || this.activeItem);
                if (!this.options.cycledSwitching && itemIndex < 1) {
                    return null;
                }

                return this.__getItemName(itemIndex - 1);
            },

            /////////////////////////////////////////////////////////////////////////////////
            //// Private
            /////////////////////////////////////////////////////////////////////////////////

            /********************* Methods *************************/

            __itemsSwitcher : function () {
                return new SwitchItems(this);
            },

            __ITEMS_META_NAMES : (function () {
                function goFrom(comp, ind, step) {
                    var res = ind;
                    while ((!comp.items[res] || comp.items[res].disabled) && res < comp.items.length && res > 0) {
                        res += step;
                    }
                    return res;
                }


                return {
                    "@first" : function (comp) {
                        return goFrom(comp, 0, 1);
                    },

                    "@prev"  : function (comp) {
                        return goFrom(comp, parseInt(comp.__getItemIndex(comp.activeItem)) - 1, -1);
                    },

                    "@next"  : function (comp) {
                        return goFrom(comp, parseInt(comp.__getItemIndex(comp.activeItem)) + 1, 1);
                    },

                    "@last"  : function (comp) {
                        return goFrom(comp, comp.items.length - 1, -1);
                    }
                }
            })(),

            /**
             * @private
             * */
            __getItemIndex : function (itemName) {
                var item;
                for (var i = 0; i < this.items.length; i++) {
                    item = this.items[i];
                    if (!item.disabled && item.getName() === itemName) {
                        return i;
                    }
                }

                rf.log.info("TogglePanel.getItemIndex: item with name '" + itemName + "' not found");
                return -1;
            },

            /**
             * @private
             * */
            __addUserEventHandler : function (name) {
                var handler = this.options["on" + name];
                if (handler) {
                    rf.Event.bindById(this.id, name, handler);
                }
            },

            /**
             * @private
             * @param {Number} index - array index
             *
             * @return {TogglePanelItem}
             *    null - if item not found
             * */
            __getItem : function (index) {
                if (this.options.cycledSwitching) {
                    var size = this.items.length;
                    return this.items[(size + index) % size]
                } else if (index >= 0 && index < this.items.length) {
                    return this.items[index]
                } else {
                    return null;
                }
            },

            __getItemByName : function (name) {
                return this.__getItem(this.__getItemIndex(name));
            },

            __getItemName : function (index) {
                var item = this.__getItem(index);
                if (item == null) {
                    return null;
                }

                return item.getName();
            },

            /**
             * Fire Concealable Event
             * */

            __fireItemChange : function (oldItem, newItem) {
                return new rf.Event.fireById(this.id, "itemchange", {
                        id: this.id,
                        oldItem : oldItem,
                        newItem : newItem
                    });
            },

            __fireBeforeItemChange : function (oldItem, newItem) {
                return rf.Event.fireById(this.id, "beforeitemchange", {
                        id: this.id,
                        oldItem : oldItem,
                        newItem : newItem
                    });
            }
        });

    // define super class link
    var $super = rf.ui.TogglePanel.$super;
})(jQuery, RichFaces);
;/**
 * Copyright 2012 Jeanfrancois Arcand
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * IE streaming/XDR supports is copied/highly inspired by http://code.google.com/p/jquery-stream/
 *
 * Copyright 2011, Donghwan Kim
 * Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * LocalStorage supports is copied/highly inspired by https://github.com/flowersinthesand/jquery-socket
 * Copyright 2011, Donghwan Kim
 * Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 * */
/**
 * Official documentation of this library: https://github.com/Atmosphere/atmosphere/wiki/jQuery.atmosphere.js-API
 */
jQuery.atmosphere = function() {
    jQuery(window).bind("unload.atmosphere", function() {
        jQuery.atmosphere.unsubscribe();
    });

    // Prevent ESC to kill the connection from Firefox.
    jQuery(window).keypress(function(e){
        if(e.keyCode == 27){
            e.preventDefault();
        }
    });

    var parseHeaders = function(headerString) {
        var match, rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, headers = {};
        while (match = rheaders.exec(headerString)) {
            headers[match[1]] = match[2];
        }
        return headers;
    };

    return {
        version : "1.0.10",
        requests : [],
        callbacks : [],

        onError : function(response) {
        },
        onClose : function(response) {
        },
        onOpen : function(response) {
        },
        onMessage : function(response) {
        },
        onReconnect : function(request, response) {
        },
        onMessagePublished : function(response) {
        },
        onTransportFailure : function (reason, request) {
        },
        onLocalMessage : function (response) {
        },

        AtmosphereRequest : function(options) {

            /**
             * {Object} Request parameters.
             * @private
             */
            var _request = {
                timeout: 300000,
                method: 'GET',
                headers: {},
                contentType : '',
                callback: null,
                url : '',
                data : '',
                suspend : true,
                maxRequest : -1,
                reconnect : true,
                maxStreamingLength : 10000000,
                lastIndex : 0,
                logLevel : 'info',
                requestCount : 0,
                fallbackMethod: 'GET',
                fallbackTransport : 'streaming',
                transport : 'long-polling',
                webSocketImpl: null,
                webSocketUrl: null,
                webSocketPathDelimiter: "@@",
                enableXDR : false,
                rewriteURL : false,
                attachHeadersAsQueryString : true,
                executeCallbackBeforeReconnect : false,
                readyState : 0,
                lastTimestamp : 0,
                withCredentials : false,
                trackMessageLength : false ,
                messageDelimiter : '|',
                connectTimeout : -1,
                reconnectInterval : 0,
                dropAtmosphereHeaders : true,
                uuid : 0,
                shared : false,
                readResponsesHeaders : true,
                maxReconnectOnClose: 5,
                enableProtocol: false,
                onError : function(response) {
                },
                onClose : function(response) {
                },
                onOpen : function(response) {
                },
                onMessage : function(response) {
                },
                onReconnect : function(request, response) {
                },
                onMessagePublished : function(response) {
                },
                onTransportFailure : function (reason, request) {
                },
                onLocalMessage : function (request) {
                }
            };

            /**
             * {Object} Request's last response.
             * @private
             */
            var _response = {
                status: 200,
                responseBody : '',
                headers : [],
                state : "messageReceived",
                transport : "polling",
                error: null,
                request : null,
                partialMessage : "",
                id : 0
            };

            /**
             * {websocket} Opened web socket.
             *
             * @private
             */
            var _websocket = null;

            /**
             * {SSE} Opened SSE.
             *
             * @private
             */
            var _sse = null;

            /**
             * {XMLHttpRequest, ActiveXObject} Opened ajax request (in case of
             * http-streaming or long-polling)
             *
             * @private
             */
            var _activeRequest = null;

            /**
             * {Object} Object use for streaming with IE.
             *
             * @private
             */
            var _ieStream = null;

            /**
             * {Object} Object use for jsonp transport.
             *
             * @private
             */
            var _jqxhr = null;

            /**
             * {boolean} If request has been subscribed or not.
             *
             * @private
             */
            var _subscribed = true;

            /**
             * {number} Number of test reconnection.
             *
             * @private
             */
            var _requestCount = 0;

            /**
             * {boolean} If request is currently aborded.
             *
             * @private
             */
            var _abordingConnection = false;

            /**
             * A local "channel' of communication.
             * @private
             */
            var _localSocketF = null;

            /**
             * The storage used.
             * @private
             */
            var _storageService;

            /**
             * Local communication
             * @private
             */
            var _localStorageService = null;

            /**
             * A Unique ID
             * @private
             */
            var guid = jQuery.now();

            /** Trace time */
            var _traceTimer;

            // Automatic call to subscribe
            _subscribe(options);

            /**
             * Initialize atmosphere request object.
             *
             * @private
             */
            function _init() {
                _subscribed = true;
                _abordingConnection = false;
                _requestCount = 0;

                _websocket = null;
                _sse = null;
                _activeRequest = null;
                _ieStream = null;
            }

            /**
             * Re-initialize atmosphere object.
             * @private
             */
            function _reinit() {
                _clearState();
                _init();
            }

            /**
             * Subscribe request using request transport. <br>
             * If request is currently opened, this one will be closed.
             *
             * @param {Object}
                *            Request parameters.
             * @private
             */
            function _subscribe(options) {
                _reinit();

                _request = jQuery.extend(_request, options);
                // Allow at least 1 request
                _request.mrequest = _request.reconnect;
                if (!_request.reconnect) {
                    _request.reconnect = true;
                }
            }

            /**
             * Check if web socket is supported (check for custom implementation
             * provided by request object or browser implementation).
             *
             * @returns {boolean} True if web socket is supported, false
             *          otherwise.
             * @private
             */
            function _supportWebsocket() {
                return _request.webSocketImpl != null || window.WebSocket || window.MozWebSocket;
            }

            /**
             * Check if server side events (SSE) is supported (check for custom implementation
             * provided by request object or browser implementation).
             *
             * @returns {boolean} True if web socket is supported, false
             *          otherwise.
             * @private
             */
            function _supportSSE() {
                return window.EventSource;
            }

            /**
             * Open request using request transport. <br>
             * If request transport is 'websocket' but websocket can't be
             * opened, request will automatically reconnect using fallback
             * transport.
             *
             * @private
             */
            function _execute() {
                // Shared across multiple tabs/windows.
                if (_request.shared) {
                    _localStorageService = _local(_request);
                    if (_localStorageService != null) {
                        if (_request.logLevel == 'debug') {
                            jQuery.atmosphere.debug("Storage service available. All communication will be local");
                        }

                        if (_localStorageService.open(_request)) {
                            // Local connection.
                            return;
                        }
                    }

                    if (_request.logLevel == 'debug') {
                        jQuery.atmosphere.debug("No Storage service available.");
                    }
                    // Wasn't local or an error occurred
                    _localStorageService = null;
                }

                // Protocol
                _request.firstMessage= true;
                _request.ctime = jQuery.now();

                if (_request.transport != 'websocket' && _request.transport != 'sse') {
                    // Gives a chance to the connection to be established before calling the callback
                    setTimeout(function() {
                        _open('opening', _request.transport, _request);
                    }, 500);
                    _executeRequest();

                } else if (_request.transport == 'websocket') {
                    if (!_supportWebsocket()) {
                        _reconnectWithFallbackTransport("Websocket is not supported, using request.fallbackTransport (" + _request.fallbackTransport + ")");
                    } else {
                        _executeWebSocket(false);
                    }
                } else if (_request.transport == 'sse') {
                    if (!_supportSSE()) {
                        _reconnectWithFallbackTransport("Server Side Events(SSE) is not supported, using request.fallbackTransport (" + _request.fallbackTransport + ")");
                    } else {
                        _executeSSE(false);
                    }
                }
            }

            function _local(request) {
                var trace, connector, orphan, name = "atmosphere-" + request.url, connectors = {
                    storage: function() {
                        if (!jQuery.atmosphere.supportStorage()) {
                            return;
                        }

                        var storage = window.localStorage,
                            get = function(key) {
                                return jQuery.parseJSON(storage.getItem(name + "-" + key));
                            },
                            set = function(key, value) {
                                storage.setItem(name + "-" + key, jQuery.stringifyJSON(value));
                            };

                        return {
                            init: function() {
                                set("children", get("children").concat([guid]));
                                jQuery(window).on("storage.socket", function(event) {
                                    event = event.originalEvent;
                                    if (event.key === name && event.newValue) {
                                        listener(event.newValue);
                                    }
                                });
                                return get("opened");
                            },
                            signal: function(type, data) {
                                storage.setItem(name, jQuery.stringifyJSON({target: "p", type: type, data: data}));
                            },
                            close: function() {
                                var index, children = get("children");

                                jQuery(window).off("storage.socket");
                                if (children) {
                                    index = jQuery.inArray(request.id, children);
                                    if (index > -1) {
                                        children.splice(index, 1);
                                        set("children", children);
                                    }
                                }
                            }
                        };
                    },
                    windowref: function() {
                        var win = window.open("", name.replace(/\W/g, ""));

                        if (!win || win.closed || !win.callbacks) {
                            return;
                        }

                        return {
                            init: function() {
                                win.callbacks.push(listener);
                                win.children.push(guid);
                                return win.opened;
                            },
                            signal: function(type, data) {
                                if (!win.closed && win.fire) {
                                    win.fire(jQuery.stringifyJSON({target: "p", type: type, data: data}));
                                }
                            },
                            close : function() {
                                function remove(array, e) {
                                    var index = jQuery.inArray(e, array);
                                    if (index > -1) {
                                        array.splice(index, 1);
                                    }
                                }

                                // Removes traces only if the parent is alive
                                if (!orphan) {
                                    remove(win.callbacks, listener);
                                    remove(win.children, guid);
                                }
                            }

                        };
                    }
                };

                // Receives open, close and message command from the parent
                function listener(string) {
                    var command = jQuery.parseJSON(string), data = command.data;

                    if (command.target === "c") {
                        switch (command.type) {
                            case "open":
                                _open("opening", 'local', _request)
                                break;
                            case "close":
                                if (!orphan) {
                                    orphan = true;
                                    if (data.reason === "aborted") {
                                        _close();
                                    } else {
                                        // Gives the heir some time to reconnect
                                        if (data.heir === guid) {
                                            _execute();
                                        } else {
                                            setTimeout(function() {
                                                _execute();
                                            }, 100);
                                        }
                                    }
                                }
                                break;
                            case "message":
                                _prepareCallback(data, "messageReceived", 200, request.transport);
                                break;
                            case "localMessage":
                                _localMessage(data);
                                break;
                        }
                    }
                }

                function findTrace() {
                    var matcher = new RegExp("(?:^|; )(" + encodeURIComponent(name) + ")=([^;]*)").exec(document.cookie);
                    if (matcher) {
                        return jQuery.parseJSON(decodeURIComponent(matcher[2]));
                    }
                }

                // Finds and validates the parent socket's trace from the cookie
                trace = findTrace();
                if (!trace || jQuery.now() - trace.ts > 1000) {
                    return;
                }

                // Chooses a connector
                connector = connectors.storage() || connectors.windowref();
                if (!connector) {
                    return;
                }

                return {
                    open: function() {
                        var parentOpened;

                        // Checks the shared one is alive
                        _traceTimer = setInterval(function() {
                            var oldTrace = trace;
                            trace = findTrace();
                            if (!trace || oldTrace.ts === trace.ts) {
                                // Simulates a close signal
                                listener(jQuery.stringifyJSON({target: "c", type: "close", data: {reason: "error", heir: oldTrace.heir}}));
                            }
                        }, 1000);

                        parentOpened = connector.init();
                        if (parentOpened) {
                            // Firing the open event without delay robs the user of the opportunity to bind connecting event handlers
                            setTimeout(function() {
                                _open("opening", 'local', request)
                            }, 50);
                        }
                        return parentOpened;
                    },
                    send: function(event) {
                        connector.signal("send", event);
                    },
                    localSend: function(event) {
                        connector.signal("localSend", jQuery.stringifyJSON({id: guid , event: event}));
                    },
                    close: function() {
                        // Do not signal the parent if this method is executed by the unload event handler
                        if (!_abordingConnection) {
                            clearInterval(_traceTimer);
                            connector.signal("close");
                            connector.close();
                        }
                    }
                };
            };

            function share() {
                var storageService, name = "atmosphere-" + _request.url, servers = {
                    // Powered by the storage event and the localStorage
                    // http://www.w3.org/TR/webstorage/#event-storage
                    storage: function() {
                        if (!jQuery.atmosphere.supportStorage()) {
                            return;
                        }

                        var storage = window.localStorage;

                        return {
                            init: function() {
                                // Handles the storage event
                                jQuery(window).on("storage.socket", function(event) {
                                    event = event.originalEvent;
                                    // When a deletion, newValue initialized to null
                                    if (event.key === name && event.newValue) {
                                        listener(event.newValue);
                                    }
                                });
                            },
                            signal: function(type, data) {
                                storage.setItem(name, jQuery.stringifyJSON({target: "c", type: type, data: data}));
                            },
                            get: function(key) {
                                return jQuery.parseJSON(storage.getItem(name + "-" + key));
                            },
                            set: function(key, value) {
                                storage.setItem(name + "-" + key, jQuery.stringifyJSON(value));
                            },
                            close : function() {
                                jQuery(window).off("storage.socket");
                                storage.removeItem(name);
                                storage.removeItem(name + "-opened");
                                storage.removeItem(name + "-children");
                            }

                        };
                    },
                    // Powered by the window.open method
                    // https://developer.mozilla.org/en/DOM/window.open
                    windowref: function() {
                        // Internet Explorer raises an invalid argument error
                        // when calling the window.open method with the name containing non-word characters
                        var neim = name.replace(/\W/g, ""), win = (jQuery('iframe[name="' + neim + '"]')[0]
                            || jQuery('<iframe name="' + neim + '" />').hide().appendTo("body")[0]).contentWindow;

                        return {
                            init: function() {
                                // Callbacks from different windows
                                win.callbacks = [listener];
                                // In IE 8 and less, only string argument can be safely passed to the function in other window
                                win.fire = function(string) {
                                    var i;

                                    for (i = 0; i < win.callbacks.length; i++) {
                                        win.callbacks[i](string);
                                    }
                                };
                            },
                            signal: function(type, data) {
                                if (!win.closed && win.fire) {
                                    win.fire(jQuery.stringifyJSON({target: "c", type: type, data: data}));
                                }
                            },
                            get: function(key) {
                                return !win.closed ? win[key] : null;
                            },
                            set: function(key, value) {
                                if (!win.closed) {
                                    win[key] = value;
                                }
                            },
                            close : function() {}
                        };
                    }
                };


                // Receives send and close command from the children
                function listener(string) {
                    var command = jQuery.parseJSON(string), data = command.data;

                    if (command.target === "p") {
                        switch (command.type) {
                            case "send":
                                _push(data);
                                break;
                            case "localSend":
                                _localMessage(data);
                                break;
                            case "close":
                                _close();
                                break;
                        }
                    }
                }

                _localSocketF = function propagateMessageEvent(context) {
                    storageService.signal("message", context);
                }

                function leaveTrace() {
                    document.cookie = encodeURIComponent(name) + "=" +
                        // Opera's JSON implementation ignores a number whose a last digit of 0 strangely
                        // but has no problem with a number whose a last digit of 9 + 1
                        encodeURIComponent(jQuery.stringifyJSON({ts: jQuery.now() + 1, heir: (storageService.get("children") || [])[0]}));
                }

                // Chooses a storageService
                storageService = servers.storage() || servers.windowref();
                storageService.init();

                if (_request.logLevel == 'debug') {
                    jQuery.atmosphere.debug("Installed StorageService " + storageService);
                }

                // List of children sockets
                storageService.set("children", []);

                if (storageService.get("opened") != null && !storageService.get("opened")) {
                    // Flag indicating the parent socket is opened
                    storageService.set("opened", false);
                }
                // Leaves traces
                leaveTrace();
                _traceTimer = setInterval(leaveTrace, 1000);

                _storageService = storageService;
            }

            /**
             * @private
             */
            function _open(state, transport, request) {
                if (_request.shared && transport != 'local') {
                    share();
                }

                if (_storageService != null) {
                    _storageService.set("opened", true);
                }

                request.close = function() {
                    _close();
                    request.reconnect = false;
                }

                _response.request = request;
                var prevState = _response.state;
                _response.state = state;
                _response.status = 200;
                var prevTransport = _response.transport;
                _response.transport = transport;

                var _body = _response.responseBody;
                _invokeCallback();
                _response.responseBody = _body;

                _response.state = prevState;
                _response.transport = prevTransport;
            }

            /**
             * Execute request using jsonp transport.
             *
             * @param request
             *            {Object} request Request parameters, if
             *            undefined _request object will be used.
             * @private
             */
            function _jsonp(request) {
                // When CORS is enabled, make sure we force the proper transport.
                request.transport="jsonp";

                var rq = _request;
                if ((request != null) && (typeof(request) != 'undefined')) {
                    rq = request;
                }

                var url = rq.url;
                var data = rq.data;
                if (rq.attachHeadersAsQueryString) {
                    url = _attachHeaders(rq);
                    if (data != '') {
                        url += "&X-Atmosphere-Post-Body=" + encodeURIComponent(data);
                    }
                    data = '';
                }

                _jqxhr = jQuery.ajax({
                    url : url,
                    type : rq.method,
                    dataType: "jsonp",
                    error : function(jqXHR, textStatus, errorThrown) {
                        if (jqXHR.status < 300) {
                            _reconnect(_jqxhr, rq);
                        } else {
                            _prepareCallback(textStatus, "error", jqXHR.status, rq.transport);
                        }
                    },
                    jsonp : "jsonpTransport",
                    success: function(json) {

                        if (rq.reconnect && (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) {
                            _readHeaders(_jqxhr, rq);

                            if (!rq.executeCallbackBeforeReconnect) {
                                _reconnect(_jqxhr, rq);
                            }

                            var msg = json.message;
                            if (msg != null && typeof msg != 'string') {
                                try {
                                    msg = jQuery.stringifyJSON(msg);
                                } catch (err) {
                                    // The message was partial
                                }
                            }

                            if (_handleProtocol(rq, msg)) {
                                _prepareCallback(msg, "messageReceived", 200, rq.transport);
                            }

                            if (rq.executeCallbackBeforeReconnect) {
                                _reconnect(_jqxhr, rq);
                            }
                        } else {
                            jQuery.atmosphere.log(_request.logLevel, ["JSONP reconnect maximum try reached " + _request.requestCount]);
                            _onError();
                        }
                    },
                    data : rq.data,
                    beforeSend : function(jqXHR) {
                        _doRequest(jqXHR, rq, false);
                    }
                });
            }

            /**
             * Execute request using ajax transport.
             *
             * @param request
             *            {Object} request Request parameters, if
             *            undefined _request object will be used.
             * @private
             */
            function _ajax(request) {
                var rq = _request;
                if ((request != null) && (typeof(request) != 'undefined')) {
                    rq = request;
                }

                var url = rq.url;
                var data = rq.data;
                if (rq.attachHeadersAsQueryString) {
                    url = _attachHeaders(rq);
                    if (data != '') {
                        url += "&X-Atmosphere-Post-Body=" + encodeURIComponent(data);
                    }
                    data = '';
                }

                _jqxhr = jQuery.ajax({
                    url : url,
                    type : rq.method,
                    error : function(jqXHR, textStatus, errorThrown) {
                        if (jqXHR.status < 300) {
                            _reconnect(_jqxhr, rq);
                        } else {
                            _prepareCallback(textStatus, "error", jqXHR.status, rq.transport);
                        }
                    },
                    success: function(data, textStatus, jqXHR) {

                        if (rq.reconnect && (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) {
                            if (!rq.executeCallbackBeforeReconnect) {
                                _reconnect(_jqxhr, rq);
                            }

                            if (_handleProtocol(rq, data)) {
                                _prepareCallback(data, "messageReceived", 200, rq.transport);
                            }

                            if (rq.executeCallbackBeforeReconnect) {
                                _reconnect(_jqxhr, rq);
                            }
                        } else {
                            jQuery.atmosphere.log(_request.logLevel, ["AJAX reconnect maximum try reached " + _request.requestCount]);
                            _onError();
                        }
                    },
                    data : rq.data,
                    beforeSend : function(jqXHR) {
                        _doRequest(jqXHR, rq, false);
                    }
                });
            }

            /**
             * Build websocket object.
             *
             * @param location
             *            {string} Web socket url.
             * @returns {websocket} Web socket object.
             * @private
             */
            function _getWebSocket(location) {
                if (_request.webSocketImpl != null) {
                    return _request.webSocketImpl;
                } else {
                    if (window.WebSocket) {
                        return new WebSocket(location);
                    } else {
                        return new MozWebSocket(location);
                    }
                }
            }

            /**
             * Build web socket url from request url.
             *
             * @return {string} Web socket url (start with "ws" or "wss" for
             *         secure web socket).
             * @private
             */
            function _buildWebSocketUrl() {
                var url = _attachHeaders(_request);

                return decodeURI(jQuery('<a href="' + url + '"/>')[0].href.replace(/^http/, "ws"));
            }

            /**
             * Build SSE url from request url.
             *
             * @return a url with Atmosphere's headers
             * @private
             */
            function _buildSSEUrl() {
                var url = _attachHeaders(_request);
                return url;
            }

            /**
             * Open SSE. <br>
             * Automatically use fallback transport if SSE can't be
             * opened.
             *
             * @private
             */
            function _executeSSE(sseOpened) {

                _response.transport = "sse";

                var location = _buildSSEUrl(_request.url);

                if (_request.logLevel == 'debug') {
                    jQuery.atmosphere.debug("Invoking executeSSE");
                    jQuery.atmosphere.debug("Using URL: " + location);
                }

                if (sseOpened) {
                    _open('re-opening', "sse", _request);
                }

                if (_request.enableProtocol && sseOpened) {
                    var time = jQuery.now() - _request.ctime;
                    _request.lastTimestamp = Number(_request.stime) + Number(time);
                }

                if (sseOpened && !_request.reconnect) {
                    if (_sse != null) {
                        _clearState();
                    }
                    return;
                }
                _sse = new EventSource(location, {withCredentials: _request.withCredentials});

                if (_request.connectTimeout > 0) {
                    _request.id = setTimeout(function() {
                        if (!sseOpened) {
                            _clearState();
                        }
                    }, _request.connectTimeout);
                }

                _sse.onopen = function(event) {
                    if (_request.logLevel == 'debug') {
                        jQuery.atmosphere.debug("SSE successfully opened");
                    }

                    if (!sseOpened) {
                        _open('opening', "sse", _request);
                    }
                    sseOpened = true;

                    if (_request.method == 'POST') {
                        _response.state = "messageReceived";
                        _sse.send(_request.data);
                    }
                };

                _sse.onmessage = function(message) {
                    if (message.origin != window.location.protocol + "//" + window.location.host) {
                        jQuery.atmosphere.log(_request.logLevel, ["Origin was not " + window.location.protocol + "//" + window.location.host]);
                        return;
                    }

                    if (!_handleProtocol(_request, message.data)) return;

                    _response.state = 'messageReceived';
                    _response.status = 200;

                    var message = message.data;
                    var skipCallbackInvocation = _trackMessageSize(message, _request, _response);

                    if (jQuery.trim(message).length == 0) {
                        skipCallbackInvocation = true;
                    }

                    if (!skipCallbackInvocation) {
                        _invokeCallback();
                        _response.responseBody = '';
                    }
                };

                _sse.onerror = function(message) {

                    clearTimeout(_request.id);
                    _response.state = 'closed';
                    _response.responseBody = "";
                    _response.status = !sseOpened ? 501 : 200;
                    _invokeCallback();
                    _clearState();

                    if (_abordingConnection) {
                        jQuery.atmosphere.log(_request.logLevel, ["SSE closed normally"]);
                    } else if (!sseOpened) {
                        _reconnectWithFallbackTransport("SSE failed. Downgrading to fallback transport and resending");
                    } else if (_request.reconnect && (_response.transport == 'sse')) {
                        if (_requestCount++ < _request.maxReconnectOnClose) {
                            _request.id = setTimeout(function() {
                                _executeSSE(true);
                            }, _request.reconnectInterval);
                            _response.responseBody = "";
                        } else {
                            jQuery.atmosphere.log(_request.logLevel, ["SSE reconnect maximum try reached " + _requestCount]);
                            _onError();
                        }
                    }
                };
            }

            /**
             * Open web socket. <br>
             * Automatically use fallback transport if web socket can't be
             * opened.
             *
             * @private
             */
            function _executeWebSocket(webSocketOpened) {

                _response.transport = "websocket";

                if (_request.enableProtocol && webSocketOpened) {
                    var time = jQuery.now() - _request.ctime;
                    _request.lastTimestamp = Number(_request.stime) + Number(time);
                }

                var location = _buildWebSocketUrl(_request.url);
                var closed = false;

                if (_request.logLevel == 'debug') {
                    jQuery.atmosphere.debug("Invoking executeWebSocket");
                    jQuery.atmosphere.debug("Using URL: " + location);
                }

                if (webSocketOpened) {
                    _open('re-opening', "websocket", _request);
                }

                if (webSocketOpened && !_request.reconnect) {
                    if (_websocket != null) {
                        _clearState();
                    }
                    return;
                }

                _websocket = _getWebSocket(location);

                if (_request.connectTimeout > 0) {
                    _request.id = setTimeout(function() {
                        if (!webSocketOpened) {
                            var _message = {
                                code : 1002,
                                reason : "",
                                wasClean : false
                            };
                            _websocket.onclose(_message);
                            // Close it anyway
                            try {
                                _clearState();
                            } catch (e) {
                            }
                            return;
                        }

                        _request.id = setTimeout(function() {
                            setTimeout(function () {
                                _clearState();
                            }, _request.reconnectInterval)
                        }, _request.timeout);

                    }, _request.connectTimeout);
                }

                _websocket.onopen = function(message) {
                    if (_request.logLevel == 'debug') {
                        jQuery.atmosphere.debug("Websocket successfully opened");
                    }

                    if (!webSocketOpened) {
                        _open('opening', "websocket", _request);
                    }

                    webSocketOpened = true;

                    if (_request.method == 'POST') {
                        _response.state = "messageReceived";
                        _websocket.send(_request.data);
                    }
                };

                _websocket.onmessage = function(message) {

                    clearTimeout(_request.id);
                    _request.id = setTimeout(function() {
                        setTimeout(function () {
                            _clearState();
                        }, _request.reconnectInterval)
                    }, _request.timeout);

                    if (!_handleProtocol(_request, message.data)) return;

                    _response.state = 'messageReceived';
                    _response.status = 200;

                    var message = message.data;
                    var skipCallbackInvocation = _trackMessageSize(message, _request, _response);

                    if (!skipCallbackInvocation) {
                        _invokeCallback();
                        _response.responseBody = '';
                    }
                };

                _websocket.onerror = function(message) {
                    clearTimeout(_request.id)
                };

                _websocket.onclose = function(message) {
                    if (closed) return

                    var reason = message.reason;
                    if (reason === "") {
                        switch (message.code) {
                            case 1000:
                                reason = "Normal closure; the connection successfully completed whatever purpose for which " +
                                    "it was created.";
                                break;
                            case 1001:
                                reason = "The endpoint is going away, either because of a server failure or because the " +
                                    "browser is navigating away from the page that opened the connection.";
                                break;
                            case 1002:
                                reason = "The endpoint is terminating the connection due to a protocol error.";
                                break;
                            case 1003:
                                reason = "The connection is being terminated because the endpoint received data of a type it " +
                                    "cannot accept (for example, a text-only endpoint received binary data).";
                                break;
                            case 1004:
                                reason = "The endpoint is terminating the connection because a data frame was received that " +
                                    "is too large.";
                                break;
                            case 1005:
                                reason = "Unknown: no status code was provided even though one was expected.";
                                break;
                            case 1006:
                                reason = "Connection was closed abnormally (that is, with no close frame being sent).";
                                break;
                        }
                    }

                    jQuery.atmosphere.warn("Websocket closed, reason: " + reason);
                    jQuery.atmosphere.warn("Websocket closed, wasClean: " + message.wasClean);

                    _response.state = 'closed';
                    _response.responseBody = "";
                    _response.status = !webSocketOpened ? 501 : 200;
                    _invokeCallback();
                    clearTimeout(_request.id);

                    closed = true;

                    if (_abordingConnection) {
                        jQuery.atmosphere.log(_request.logLevel, ["Websocket closed normally"]);
                    } else if (!webSocketOpened) {
                        _reconnectWithFallbackTransport("Websocket failed. Downgrading to Comet and resending");

                    } else if (_request.reconnect && _response.transport == 'websocket') {
                        _clearState();
                        if (_request.reconnect && _requestCount++ < _request.maxReconnectOnClose) {
                            _request.id = setTimeout(function() {
                                _response.responseBody = "";
                                _executeWebSocket(true);
                            }, _request.reconnectInterval);
                        } else {
                            jQuery.atmosphere.log(_request.logLevel, ["Websocket reconnect maximum try reached " + _requestCount]);
                            jQuery.atmosphere.warn("Websocket error, reason: " + message.reason);
                            _onError();
                        }
                    }
                };
            }

            function _handleProtocol(request, message) {
                // The first messages is always the uuid.
                if (request.enableProtocol && request.firstMessage) {
                    request.firstMessage  = false;
                    var messages =  message.split(request.messageDelimiter);
                    request.uuid = messages[0];
                    request.stime = messages[1];
                    return false;
                }
                return true;
            }

            function _onError() {
                _clearState();

                _response.state = 'error';
                _response.responseBody = "";
                _response.status = 500;
                _invokeCallback();
            }

            /**
             * Track received message and make sure callbacks/functions are only invoked when the complete message
             * has been received.
             *
             * @param message
             * @param request
             * @param response
             */
            function _trackMessageSize(message, request, response) {
                if (request.trackMessageLength) {

                    // If we have found partial message, prepend them.
                    if (response.partialMessage.length != 0) {
                        message = response.partialMessage + message;
                    }

                    var messages = [];
                    var messageLength = 0;
                    var messageStart = message.indexOf(request.messageDelimiter);
                    while (messageStart != -1) {
                        messageLength = message.substring(messageLength, messageStart);
                        message = message.substring(messageStart + request.messageDelimiter.length, message.length);

                        if (message.length == 0 || message.length < messageLength) break;

                        messageStart = message.indexOf(request.messageDelimiter);
                        messages.push(message.substring(0, messageLength));
                    }

                    if (messages.length == 0 || (messageStart != -1 && message.length != 0 && messageLength != message.length)){
                        response.partialMessage = messageLength + request.messageDelimiter + message ;
                    } else {
                        response.partialMessage = "";
                    }

                    if (messages.length != 0) {
                        response.responseBody = messages.join(request.messageDelimiter);
                        return false;
                    } else {
                        return true;
                    }
                } else {
                    response.responseBody = message;
                }
                return false;
            }

            /**
             * Reconnect request with fallback transport. <br>
             * Used in case websocket can't be opened.
             *
             * @private
             */
            function _reconnectWithFallbackTransport(errorMessage) {
                jQuery.atmosphere.log(_request.logLevel, [errorMessage]);

                if (typeof(_request.onTransportFailure) != 'undefined') {
                    _request.onTransportFailure(errorMessage, _request);
                } else if (typeof(jQuery.atmosphere.onTransportFailure) != 'undefined') {
                    jQuery.atmosphere.onTransportFailure(errorMessage, _request);
                }

                _request.transport = _request.fallbackTransport;
                var reconnect = _request.reconnect && _requestCount++ < _request.maxReconnectOnClose;
                if (reconnect && _request.transport != 'none' || _request.transport == null) {
                    _request.method = _request.fallbackMethod;
                    _response.transport = _request.fallbackTransport;
                    _request.id = setTimeout(function() {
                        _execute();
                    }, _request.reconnectInterval);
                } else if (!reconnect) {
                    _onError();
                }
            }

            /**
             * Get url from request and attach headers to it.
             *
             * @param request
             *            {Object} request Request parameters, if
             *            undefined _request object will be used.
             *
             * @returns {Object} Request object, if undefined,
             *          _request object will be used.
             * @private
             */
            function _attachHeaders(request) {
                var rq = _request;
                if ((request != null) && (typeof(request) != 'undefined')) {
                    rq = request;
                }

                var url = rq.url;

                // If not enabled
                if (!rq.attachHeadersAsQueryString) return url;

                // If already added
                if (url.indexOf("X-Atmosphere-Framework") != -1) {
                    return url;
                }

                url += (url.indexOf('?') != -1) ? '&' : '?';
                url += "X-Atmosphere-tracking-id=" + rq.uuid;
                url += "&X-Atmosphere-Framework=" + jQuery.atmosphere.version;
                url += "&X-Atmosphere-Transport=" + rq.transport;

                if (rq.trackMessageLength) {
                    url += "&X-Atmosphere-TrackMessageSize=" + "true";
                }

                if (rq.lastTimestamp != undefined) {
                    url += "&X-Cache-Date=" + rq.lastTimestamp;
                } else {
                    url += "&X-Cache-Date=" + 0;
                }

                if (rq.contentType != '') {
                    url += "&Content-Type=" + rq.contentType;
                }

                if (rq.enableProtocol) {
                   url += "&X-atmo-protocol=true";
                }

                jQuery.each(rq.headers, function(name, value) {
                    var h = jQuery.isFunction(value) ? value.call(this, rq, request, _response) : value;
                    if (h != null) {
                        url += "&" + encodeURIComponent(name) + "=" + encodeURIComponent(h);
                    }
                });

                return url;
            }

            /**
             * Build ajax request. <br>
             * Ajax Request is an XMLHttpRequest object, except for IE6 where
             * ajax request is an ActiveXObject.
             *
             * @return {XMLHttpRequest, ActiveXObject} Ajax request.
             * @private
             */
            function _buildAjaxRequest() {
                if (jQuery.browser.msie) {
                    if (typeof XMLHttpRequest == "undefined")
                      XMLHttpRequest = function () {
                        try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
                          catch (e) {}
                        try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
                          catch (e) {}
                        try { return new ActiveXObject("Microsoft.XMLHTTP"); }
                          catch (e) {}
                        //Microsoft.XMLHTTP points to Msxml2.XMLHTTP and is redundant
                        throw new Error("This browser does not support XMLHttpRequest.");
                      };
                }
                return new XMLHttpRequest();
            }

            /**
             * Execute ajax request. <br>
             *
             * @param request
             *            {Object} request Request parameters, if
             *            undefined _request object will be used.
             * @private
             */
            function _executeRequest(request) {
                var rq = _request;
                if ((request != null) || (typeof(request) != 'undefined')) {
                    rq = request;
                }

                // CORS fake using JSONP
                if ((rq.transport == 'jsonp') || ((rq.enableXDR) && (jQuery.atmosphere.checkCORSSupport()))) {
                    _jsonp(rq);
                    return;
                }

                if (rq.transport == 'ajax') {
                    _ajax(request);
                    return;
                }

                if (jQuery.browser.msie && jQuery.browser.version < 10) {
                    if ((rq.transport == 'streaming')) {
                        rq.enableXDR && window.XDomainRequest ? _ieXDR(rq) : _ieStreaming(rq);
                        return;
                    }

                    if ((rq.enableXDR) && (window.XDomainRequest)) {
                        _ieXDR(rq);
                        return;
                    }
                }

                if (rq.reconnect && ( rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) {
                    var ajaxRequest = _buildAjaxRequest();
                    _doRequest(ajaxRequest, rq, true);

                    if (rq.suspend) {
                        _activeRequest = ajaxRequest;
                    }

                    if (rq.transport != 'polling') {
                        _response.transport = rq.transport;
                    }

                    if (!jQuery.browser.msie) {
                        ajaxRequest.onerror = function() {
                            try {
                                _response.status = XMLHttpRequest.status;
                            } catch(e) {
                                _response.status = 500;
                            }

                            if (!_response.status) {
                                _response.status = 500;
                            }
                            _clearState();

                            if (rq.reconnect) {
                                _reconnect(ajaxRequest, rq, true);
                            } else {
                                _onError();
                            }
                        };
                    }

                    ajaxRequest.onreadystatechange = function() {
                        if (_abordingConnection) {
                            return;
                        }

                        var skipCallbackInvocation = false;
                        var update = false;

                        // Remote server disconnected us, reconnect.
                        if (rq.transport == 'streaming'
                            && rq.readyState > 2
                            && ajaxRequest.readyState == 4) {

                            rq.readyState = 0;
                            rq.lastIndex = 0;

                            _reconnect(ajaxRequest, rq, true);
                            return;
                        }

                        rq.readyState = ajaxRequest.readyState;

                        if (ajaxRequest.readyState == 4) {
                            if (jQuery.browser.msie) {
                                update = true;
                            } else if (rq.transport == 'streaming') {
                                update = true;
                            } else if (rq.transport == 'long-polling') {
                                update = true;
                                clearTimeout(rq.id);
                            }
                        } else if (rq.transport == 'streaming' && jQuery.browser.msie && ajaxRequest.readyState >= 3) {
                            update = true;
                        } else if (!jQuery.browser.msie && ajaxRequest.readyState == 3 && ajaxRequest.status == 200 && rq.transport != 'long-polling') {
                            update = true;
                        } else {
                            clearTimeout(rq.id);
                        }

                        if (update) {
                            var responseText = ajaxRequest.responseText;

                            // MSIE status can be higher than 1000, Chrome can be 0
                            if (ajaxRequest.status >= 500 || ajaxRequest.status == 0) {
                                if (rq.reconnect) {
                                    _reconnect(ajaxRequest, rq, true);
                                } else {
                                    _onError();
                                }
                                return;
                            }

                            _readHeaders(ajaxRequest, _request);

                            if (rq.transport == 'streaming') {
                                var text = responseText.substring(rq.lastIndex, responseText.length);
                                _response.isJunkEnded = true;

                                //fix junk is comming in parts
                                if (!_response.junkFull && (text.indexOf("<!-- Welcome to the Atmosphere Framework.") == -1 || text.indexOf("<!-- EOD -->") == -1)) {
                                    return;
                                }
                                _response.junkFull = true;

                                //if it's the start and we see the junk start
                                //fix for reconnecting on chrome - junk is comming in parts
                                if (rq.lastIndex == 0 && text.indexOf("<!-- Welcome to the Atmosphere Framework.") != -1 && text.indexOf("<!-- EOD -->") != -1) {
                                    _response.isJunkEnded = false;
                                }

                                if (!_response.isJunkEnded) {
                                    var endOfJunk = "<!-- EOD -->";
                                    var endOfJunkLength = endOfJunk.length;
                                    var junkEnd = text.indexOf(endOfJunk) + endOfJunkLength;

                                    if (junkEnd > endOfJunkLength && junkEnd != text.length) {
                                        _response.responseBody = text.substring(junkEnd);
                                        //fix cached messages
                                        skipCallbackInvocation = _trackMessageSize(_response.responseBody, rq, _response);
                                    } else {
                                        skipCallbackInvocation = true;
                                    }
                                } else {
                                    var message = responseText.substring(rq.lastIndex, responseText.length);
                                    rq.lastIndex = responseText.length;
                                    if (!_handleProtocol( _request, message)) {
                                        _reconnect(ajaxRequest, rq, false);
                                        return;
                                    }
                                    skipCallbackInvocation = _trackMessageSize(message, rq, _response);
                                }
                                rq.lastIndex = responseText.length;

                                if (jQuery.browser.opera) {
                                    jQuery.atmosphere.iterate(function() {
                                        if (ajaxRequest.responseText.length > rq.lastIndex) {
                                            try {
                                                _response.status = ajaxRequest.status;
                                                _response.headers = parseHeaders(ajaxRequest.getAllResponseHeaders());

                                                _readHeaders(ajaxRequest, _request);
                                            }
                                            catch(e) {
                                                _response.status = 404;
                                            }
                                            _response.state = "messageReceived";
                                            _response.responseBody = ajaxRequest.responseText.substring(rq.lastIndex);
                                            rq.lastIndex = ajaxRequest.responseText.length;

                                            if (!_handleProtocol( _request, _response.responseBody)) {
                                                _reconnect(ajaxRequest, rq, false);
                                                return;
                                            }
                                            _invokeCallback();
                                            if ((rq.transport == 'streaming') && (ajaxRequest.responseText.length > rq.maxStreamingLength)) {
                                                // Close and reopen connection on large data received
                                                _clearState();
                                                _doRequest(_buildAjaxRequest(), rq, true);
                                            }
                                        }
                                    }, 0);
                                }

                                if (skipCallbackInvocation) {
                                    return;
                                }
                            } else {
                                if (!_handleProtocol( _request, responseText)) {
                                    _reconnect(ajaxRequest, rq, false);
                                    return;
                                }

                                _trackMessageSize(responseText, rq, _response);
                                rq.lastIndex = responseText.length;
                            }

                            try {
                                _response.status = ajaxRequest.status;
                                _response.headers = parseHeaders(ajaxRequest.getAllResponseHeaders());

                                _readHeaders(ajaxRequest, rq);
                            } catch(e) {
                                _response.status = 404;
                            }

                            if (rq.suspend) {
                                _response.state = _response.status == 0 ? "closed" : "messageReceived";
                            } else {
                                _response.state = "messagePublished";
                            }

                            if (!rq.executeCallbackBeforeReconnect) {
                                _reconnect(ajaxRequest, rq, false);
                            }

                            // For backward compatibility with Atmosphere < 0.8
                            if (_response.responseBody.indexOf("parent.callback") != -1) {
                                jQuery.atmosphere.log(rq.logLevel, ["parent.callback no longer supported with 0.8 version and up. Please upgrade"]);
                            }

                            _invokeCallback();

                            if (rq.executeCallbackBeforeReconnect) {
                                _reconnect(ajaxRequest, rq, false);
                            }

                            if ((rq.transport == 'streaming') && (responseText.length > rq.maxStreamingLength)) {
                                // Close and reopen connection on large data received
                                _clearState();
                                _doRequest(_buildAjaxRequest(), rq, true);
                            }
                        }
                    };
                    ajaxRequest.send(rq.data);

                    if (rq.suspend) {
                        rq.id = setTimeout(function() {
                            if (_subscribed) {
                                setTimeout(function () {
                                    _clearState();
                                    _execute();
                                }, rq.reconnectInterval)
                            }
                        }, rq.timeout);
                    }
                    _subscribed = true;

                } else {
                    if (rq.logLevel == 'debug') {
                        jQuery.atmosphere.log(rq.logLevel, ["Max re-connection reached."]);
                    }
                    _onError();
                }
            }

            /**
             * Do ajax request.
             * @param ajaxRequest Ajax request.
             * @param request Request parameters.
             * @param create If ajax request has to be open.
             */
            function _doRequest(ajaxRequest, request, create) {
                // Prevent Android to cache request
                var url = _attachHeaders(request);
                url = jQuery.atmosphere.prepareURL(url);

                if (create) {
                    ajaxRequest.open(request.method, url, true);
                    if (request.connectTimeout > -1) {
                        request.id = setTimeout(function() {
                            if (request.requestCount == 0) {
                                _clearState();
                                _prepareCallback("Connect timeout", "closed", 200, request.transport);
                            }
                        }, request.connectTimeout);
                    }
                }

                if (_request.withCredentials) {
                    if ("withCredentials" in ajaxRequest) {
                        ajaxRequest.withCredentials = true;
                    }
                }

                if (!_request.dropAtmosphereHeaders) {
                    ajaxRequest.setRequestHeader("X-Atmosphere-Framework", jQuery.atmosphere.version);
                    ajaxRequest.setRequestHeader("X-Atmosphere-Transport", request.transport);
                    if (request.lastTimestamp != undefined) {
                        ajaxRequest.setRequestHeader("X-Cache-Date", request.lastTimestamp);
                    } else {
                        ajaxRequest.setRequestHeader("X-Cache-Date", 0);
                    }

                    if (request.trackMessageLength) {
                        ajaxRequest.setRequestHeader("X-Atmosphere-TrackMessageSize", "true")
                    }

                    if (request.contentType != '') {
                        ajaxRequest.setRequestHeader("Content-Type", request.contentType);
                    }
                    ajaxRequest.setRequestHeader("X-Atmosphere-tracking-id", request.uuid);
                }

                jQuery.each(request.headers, function(name, value) {
                    var h = jQuery.isFunction(value) ? value.call(this, ajaxRequest, request, create, _response) : value;
                    if (h != null) {
                        ajaxRequest.setRequestHeader(name, h);
                    }
                });
            }

            function _reconnect(ajaxRequest, request, force) {
                var reconnect = request.reconnect && _requestCount++ < request.maxReconnectOnClose;

                if (reconnect && force || (request.suspend && ajaxRequest.status == 200 && request.transport != 'streaming' && _subscribed)) {
                    if (request.reconnect) {
                        _open('re-opening', request.transport, request);
                        request.id = setTimeout(function() {
                            _executeRequest();
                        }, request.reconnectInterval);
                    }
                } else if (!reconnect) {
                    _onError();
                }
            }

            // From jquery-stream, which is APL2 licensed as well.
            function _ieXDR(request) {
                if (request.transport != "polling") {
                    _ieStream = _configureXDR(request);
                    _ieStream.open();
                } else {
                    _configureXDR(request).open();
                }
            }

            // From jquery-stream
            function _configureXDR(request) {
                var rq = _request;
                if ((request != null) && (typeof(request) != 'undefined')) {
                    rq = request;
                }

                var transport = rq.transport;
                var lastIndex = 0;
                var xdrCallback = function (xdr) {
                    var responseBody = xdr.responseText;
                    var isJunkEnded = false;

                    if (responseBody.indexOf("<!-- Welcome to the Atmosphere Framework.") != -1) {
                        isJunkEnded = true;
                    }

                    if (isJunkEnded) {
                        var endOfJunk = "<!-- EOD -->";
                        var endOfJunkLenght = endOfJunk.length;
                        var junkEnd = responseBody.indexOf(endOfJunk);
                        if (junkEnd !== -1) {
                            responseBody = responseBody.substring(junkEnd + endOfJunkLenght + lastIndex);
                            lastIndex += responseBody.length;
                        }
                    }

                    if (!_handleProtocol(request, responseBody)) return;

                    _prepareCallback(responseBody, "messageReceived", 200, transport);
                };

                var xdr = new window.XDomainRequest();
                var rewriteURL = rq.rewriteURL || function(url) {
                    // Maintaining session by rewriting URL
                    // http://stackoverflow.com/questions/6453779/maintaining-session-by-rewriting-url
                    var match = /(?:^|;\s*)(JSESSIONID|PHPSESSID)=([^;]*)/.exec(document.cookie);

                    switch (match && match[1]) {
                        case "JSESSIONID":
                            return url.replace(/;jsessionid=[^\?]*|(\?)|$/, ";jsessionid=" + match[2] + "$1");
                        case "PHPSESSID":
                            return url.replace(/\?PHPSESSID=[^&]*&?|\?|$/, "?PHPSESSID=" + match[2] + "&").replace(/&$/, "");
                    }
                    return url;
                };

                // Handles open and message event
                xdr.onprogress = function() {
                    handle(xdr);
                };

                // Handles error event
                xdr.onerror = function() {
                    // If the server doesn't send anything back to XDR will fail with polling
                    if (rq.transport != 'polling') {
                        _prepareCallback(xdr.responseText, "error", 500, transport);
                    }

                    _reconnect(xdr, rq, false);
                };

                // Handles close event
                xdr.onload = function() {
                    handle(xdr);
                };

               var handle = function (xdr) {
                    // XDomain loop forever on itself without this.
                    // TODO: Clearly I need to come with something better than that solution
                    if (rq.lastMessage == xdr.responseText) return;

                    if (rq.executeCallbackBeforeReconnect) {
                        xdrCallback(xdr);
                    }

                    if (rq.transport == "long-polling" && (rq.reconnect && (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest))) {
                        xdr.status = 200;
                        _reconnect(xdr, rq, false);
                    }

                    if (!rq.executeCallbackBeforeReconnect) {
                        xdrCallback(xdr);
                    }
                    rq.lastMessage = xdr.responseText;
                };

                return {
                    open: function() {
                        if (rq.method == 'POST') {
                            rq.attachHeadersAsQueryString = true;
                        }
                        var url = _attachHeaders(rq);
                        if (rq.method == 'POST') {
                            url += "&X-Atmosphere-Post-Body=" + encodeURIComponent(rq.data);
                        }
                        xdr.open(rq.method, rewriteURL(url));
                        xdr.send();
                        if (rq.connectTimeout > -1) {
                            rq.id = setTimeout(function() {
                                if (rq.requestCount == 0) {
                                    _clearState();
                                    _prepareCallback("Connect timeout", "closed", 200, rq.transport);
                                }
                            }, rq.connectTimeout);
                        }
                    },
                    close: function() {
                        xdr.abort();
                        _prepareCallback(xdr.responseText, "closed", 200, transport);
                    }
                };
            }

            // From jquery-stream, which is APL2 licensed as well.
            function _ieStreaming(request) {
                _ieStream = _configureIE(request);
                _ieStream.open();
            }

            function _configureIE(request) {
                var rq = _request;
                if ((request != null) && (typeof(request) != 'undefined')) {
                    rq = request;
                }

                var stop;
                var doc = new window.ActiveXObject("htmlfile");

                doc.open();
                doc.close();

                var url = rq.url;

                if (rq.transport != 'polling') {
                    _response.transport = rq.transport;
                }

                return {
                    open: function() {
                        var iframe = doc.createElement("iframe");

                        url = _attachHeaders(rq);
                        if (rq.data != '') {
                            url += "&X-Atmosphere-Post-Body=" + encodeURIComponent(rq.data);
                        }

                        // Finally attach a timestamp to prevent Android and IE caching.
                        url = jQuery.atmosphere.prepareURL(url);

                        iframe.src = url;
                        doc.body.appendChild(iframe);

                        // For the server to respond in a consistent format regardless of user agent, we polls response text
                        var cdoc = iframe.contentDocument || iframe.contentWindow.document;

                        stop = jQuery.atmosphere.iterate(function() {
                            try {
                                if (!cdoc.firstChild) {
                                    return;
                                }

                                // Detects connection failure
                                if (cdoc.readyState === "complete") {
                                    try {
                                        jQuery.noop(cdoc.fileSize);
                                    } catch(e) {
                                        _prepareCallback("Connection Failure", "error", 500, rq.transport);
                                        return false;
                                    }
                                }

                                var res = cdoc.body ? cdoc.body.lastChild : cdoc;
                                var readResponse = function() {
                                    // Clones the element not to disturb the original one
                                    var clone = res.cloneNode(true);

                                    // If the last character is a carriage return or a line feed, IE ignores it in the innerText property
                                    // therefore, we add another non-newline character to preserve it
                                    clone.appendChild(cdoc.createTextNode("."));

                                    var text = clone.innerText;
                                    var isJunkEnded = true;

                                    if (text.indexOf("<!-- Welcome to the Atmosphere Framework.") == -1) {
                                        isJunkEnded = false;
                                    }

                                    if (isJunkEnded) {
                                        var endOfJunk = "<!-- EOD -->";
                                        var endOfJunkLength = endOfJunk.length;
                                        var junkEnd = text.indexOf(endOfJunk) + endOfJunkLength;

                                        text = text.substring(junkEnd);
                                    }

                                    text = text.substring(0, text.length - 1);

                                    _handleProtocol(rq, text);
                                    return text;

                                };

                                //To support text/html content type
                                if (!jQuery.nodeName(res, "pre")) {
                                    // Injects a plaintext element which renders text without interpreting the HTML and cannot be stopped
                                    // it is deprecated in HTML5, but still works
                                    var head = cdoc.head || cdoc.getElementsByTagName("head")[0] || cdoc.documentElement || cdoc;
                                    var script = cdoc.createElement("script");

                                    script.text = "document.write('<plaintext>')";

                                    head.insertBefore(script, head.firstChild);
                                    head.removeChild(script);

                                    // The plaintext element will be the response container
                                    res = cdoc.body.lastChild;
                                }

                                // Handles open event
                                _prepareCallback(readResponse(), "opening", 200, rq.transport);

                                // Handles message and close event
                                stop = jQuery.atmosphere.iterate(function() {
                                    var text = readResponse();
                                    if (text.length > rq.lastIndex) {
                                        _response.status = 200;

                                        // Empties response every time that it is handled
                                        res.innerText = "";
                                        _prepareCallback(text, "messageReceived", 200, rq.transport);

                                        rq.lastIndex = 0;
                                    }

                                    if (cdoc.readyState === "complete") {
                                        _prepareCallback("", "closed", 200, rq.transport);
                                        _prepareCallback("", "re-opening", 200, rq.transport);
                                        rq.id = setTimeout(function() {
                                            _ieStreaming(rq);
                                        }, rq.reconnectInterval);
                                        return false;
                                    }
                                }, null);

                                return false;
                            } catch (err) {
                                if (_requestCount++ < rq.maxReconnectOnClose) {
                                    rq.id = setTimeout(function() {
                                        _ieStreaming(rq);
                                    }, rq.reconnectInterval);
                                } else {
                                    _onError();
                                }
                                doc.execCommand("Stop");
                                doc.close();
                                return false;
                            }
                        });
                    },

                    close: function() {
                        if (stop) {
                            stop();
                        }

                        doc.execCommand("Stop");
                        _prepareCallback("", "closed", 200, rq.transport);
                    }
                };
            }

            /*
             * Send message. <br>
             * Will be automatically dispatch to other connected.
             *
             * @param {Object,string} Message to send.
             * @private
             */
            function _push(message) {

                if (_localStorageService != null) {
                    _pushLocal(message);
                } else if (_activeRequest != null || _sse != null) {
                    _pushAjaxMessage(message);
                } else if (_ieStream != null) {
                    _pushIE(message);
                } else if (_jqxhr != null) {
                    _pushJsonp(message);
                } else if (_websocket != null) {
                    _pushWebSocket(message);
                }
            }

            function _pushLocal(message) {
                _localStorageService.send(message);
            }

            function _intraPush(message) {
                // IE 9 will crash if not.
                if (message.length == 0) return;

                try {
                    if (_localStorageService) {
                        _localStorageService.localSend(message);
                    } else {
                        _storageService.signal("localMessage",  jQuery.stringifyJSON({id: guid , event: message}));
                    }
                } catch (err) {
                    jQuery.atmosphere.error(err);
                }
            }

            /**
             * Send a message using currently opened ajax request (using
             * http-streaming or long-polling). <br>
             *
             * @param {string, Object} Message to send. This is an object, string
             *            message is saved in data member.
             * @private
             */
            function _pushAjaxMessage(message) {
                var rq = _getPushRequest(message);
                _executeRequest(rq);
            }

            /**
             * Send a message using currently opened ie streaming (using
             * http-streaming or long-polling). <br>
             *
             * @param {string, Object} Message to send. This is an object, string
             *            message is saved in data member.
             * @private
             */
            function _pushIE(message) {
                if (_request.enableXDR && jQuery.atmosphere.checkCORSSupport()) {
                    var rq = _getPushRequest(message);
                    // Do not reconnect since we are pushing.
                    rq.reconnect = false;
                    _jsonp(rq);
                } else {
                    _pushAjaxMessage(message);
                }
            }

            /**
             * Send a message using jsonp transport. <br>
             *
             * @param {string, Object} Message to send. This is an object, string
             *            message is saved in data member.
             * @private
             */
            function _pushJsonp(message) {
                _pushAjaxMessage(message);
            }

            function _getStringMessage(message) {
                var msg = message;
                if (typeof(msg) == 'object') {
                    msg = message.data;
                }
                return msg;
            }

            /**
             * Build request use to push message using method 'POST' <br>.
             * Transport is defined as 'polling' and 'suspend' is set to false.
             *
             * @return {Object} Request object use to push message.
             * @private
             */
            function _getPushRequest(message) {
                var msg = _getStringMessage(message);

                var rq = {
                    connected: false,
                    timeout: 60000,
                    method: 'POST',
                    url: _request.url,
                    contentType : _request.contentType,
                    headers: {},
                    reconnect : true,
                    callback: null,
                    data : msg,
                    suspend : false,
                    maxRequest : -1,
                    logLevel : 'info',
                    requestCount : 0,
                    withCredentials : _request.withCredentials,
                    transport: 'polling',
                    attachHeadersAsQueryString: true,
                    enableXDR: _request.enableXDR,
                    uuid : _request.uuid,
                    enableProtocol : false,
                    maxReconnectOnClose : _request.maxReconnectOnClose
                };

                if (typeof(message) == 'object') {
                    rq = jQuery.extend(rq, message);
                }

                return rq;
            }

            /**
             * Send a message using currently opened websocket. <br>
             *
             * @param {string, Object}
                *            Message to send. This is an object, string message is
             *            saved in data member.
             */
            function _pushWebSocket(message) {
                var msg = _getStringMessage(message);
                var data;
                try {
                    if (_request.webSocketUrl != null) {
                        data = _request.webSocketPathDelimiter
                            + _request.webSocketUrl
                            + _request.webSocketPathDelimiter
                            + msg;
                    } else {
                        data = msg;
                    }

                    _websocket.send(data);

                } catch (e) {
                    _websocket.onclose = function(message) {
                    };
                    _clearState();

                    _reconnectWithFallbackTransport("Websocket failed. Downgrading to Comet and resending " + data);
                    _pushAjaxMessage(message);
                }
            }

            function _localMessage(message) {
                var m = jQuery.parseJSON(message);
                if (m.id != guid) {
                    if (typeof(_request.onLocalMessage) != 'undefined') {
                        _request.onLocalMessage(m.event);
                    } else if (typeof(jQuery.atmosphere.onLocalMessage) != 'undefined') {
                        jQuery.atmosphere.onLocalMessage(m.event);
                    }
                }
            }

            function _prepareCallback(messageBody, state, errorCode, transport) {

                if (state == "messageReceived") {
                    if (_trackMessageSize(messageBody, _request, _response)) return;
                }

                _response.transport = transport;
                _response.status = errorCode;
                _response.state = state;
                _response.responseBody = messageBody;

                _invokeCallback();
            }

            function _readHeaders(xdr, request) {
                if (!request.readResponsesHeaders) {
                    request.lastTimestamp = jQuery.now();
                    request.uuid = jQuery.atmosphere.guid();
                    return;
                }

                try {
                    var tempDate = xdr.getResponseHeader('X-Cache-Date');
                    if (tempDate && tempDate != null && tempDate.length > 0 ) {
                        request.lastTimestamp = tempDate.split(" ").pop();
                    }

                    var tempUUID = xdr.getResponseHeader('X-Atmosphere-tracking-id');
                    if (tempUUID && tempUUID != null) {
                        request.uuid = tempUUID.split(" ").pop();
                    }

                    // HOTFIX for firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=608735
                    if (request.headers) {
                        jQuery.each(_request.headers, function (name) {
                            var v = xdr.getResponseHeader(name);
                            if (v) {
                                _response.headers[name] = v;
                            }
                        });
                    }
                } catch (e) {
                }
            }

            function _invokeFunction(response) {
                _f(response, _request);
                // Global
                _f(response, jQuery.atmosphere);
            }

            function _f(response, f) {
                switch (response.state) {
                    case "messageReceived" :
                        _requestCount = 0;
                        if (typeof(f.onMessage) != 'undefined') f.onMessage(response);
                        break;
                    case "error" :
                        if (typeof(f.onError) != 'undefined') f.onError(response);
                        break;
                    case "opening" :
                        if (typeof(f.onOpen) != 'undefined') f.onOpen(response);
                        break;
                    case "messagePublished" :
                        if (typeof(f.onMessagePublished) != 'undefined') f.onMessagePublished(response);
                        break;
                    case "re-opening" :
                        if (typeof(f.onReconnect) != 'undefined') f.onReconnect(_request, response);
                        break;
                    case "unsubscribe" :
                    case "closed" :
                        if (typeof(f.onClose) != 'undefined') f.onClose(response);
                        break;
                }
            }

            /**
             * Invoke request callbacks.
             *
             * @private
             */
            function _invokeCallback() {
                var call = function (index, func) {
                    func(_response);
                };

                if (_localStorageService == null && _localSocketF != null) {
                    _localSocketF(_response.responseBody);
                }

                _request.reconnect = _request.mrequest;

                var messages = (typeof(_response.responseBody) == 'string' && _request.trackMessageLength) ?
                    _response.responseBody.split(_request.messageDelimiter) : new Array(_response.responseBody);
                for (var i = 0; i < messages.length; i++) {

                    if (messages.length > 1 && messages[i].length == 0) {
                        continue;
                    }
                    _response.responseBody = jQuery.trim(messages[i]);

                    // Ugly see issue 400.
                    if (_response.responseBody.length == 0 && _response.transport == 'streaming' && _response.state == "messageReceived") {
                        var ua = navigator.userAgent.toLowerCase();
                        var isAndroid = ua.indexOf("android") > -1;
                        if (isAndroid) {
                            continue;
                        }
                    }

                    _invokeFunction(_response);

                    // Invoke global callbacks
                    if (jQuery.atmosphere.callbacks.length > 0) {
                        if (_request.logLevel == 'debug') {
                            jQuery.atmosphere.debug("Invoking " + jQuery.atmosphere.callbacks.length + " global callbacks: " + _response.state);
                        }
                        try {
                            jQuery.each(jQuery.atmosphere.callbacks, call);
                        } catch (e) {
                            jQuery.atmosphere.log(_request.logLevel, ["Callback exception" + e]);
                        }
                    }

                    // Invoke request callback
                    if (typeof(_request.callback) == 'function') {
                        if (_request.logLevel == 'debug') {
                            jQuery.atmosphere.debug("Invoking request callbacks");
                        }
                        try {
                            _request.callback(_response);
                        } catch (e) {
                            jQuery.atmosphere.log(_request.logLevel, ["Callback exception" + e]);
                        }
                    }
                }

            }

            /**
             * Close request.
             *
             * @private
             */
            function _close() {
                _request.reconnect = false;
                _response.request = _request;
                _subscribed = false;
                _abordingConnection = true;
                _response.state = 'unsubscribe';
                _response.responseBody = "";
                _response.status = 408;
                _invokeCallback();

                _clearState();
            }

            function _clearState() {
                if (_ieStream != null) {
                    _ieStream.close();
                    _ieStream = null;
                }
                if (_jqxhr != null) {
                    _jqxhr.abort();
                    _jqxhr = null;
                }
                if (_activeRequest != null) {
                    _activeRequest.abort();
                    _activeRequest = null;
                }
                if (_websocket != null) {
                    _websocket.close();
                    _websocket = null;
                }
                if (_sse != null) {
                    _sse.close();
                    _sse = null;
                }
                _clearStorage();
            }

            function _clearStorage() {
                // Stop sharing a connection
                if (_storageService != null) {
                    // Clears trace timer
                    clearInterval(_traceTimer);
                    // Removes the trace
                    document.cookie = encodeURIComponent("atmosphere-" + _request.url) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
                    // The heir is the parent unless unloading
                    _storageService.signal("close", {reason: "", heir: !_abordingConnection ? guid : (_storageService.get("children") || [])[0]});
                    _storageService.close();
                }
                if (_localStorageService != null) {
                    _localStorageService.close();
                }
            }

            this.subscribe = function(options) {
                _subscribe(options);
                _execute();
            };

            this.execute = function() {
                _execute();
            };

            this.invokeCallback = function() {
                _invokeCallback();
            };

            this.close = function() {
                _close();
            };

            this.getUrl = function() {
                return _request.url;
            };

            this.uuid = function() {
                return _request.uuid;
            }

            this.push = function(message) {
                _push(message);
            };

            this.pushLocal = function(message) {
                _intraPush(message);
            };

            this.enableProtocol = function(message) {
                return _request.enableProtocol;
            };

            this.response = _response;
        },

        subscribe: function(url, callback, request) {
            if (typeof(callback) == 'function') {
                jQuery.atmosphere.addCallback(callback);
            }

            if (typeof(url) != "string") {
                request = url;
            } else {
                request.url = url;
            }

            var rq = new jQuery.atmosphere.AtmosphereRequest(request);
            rq.execute();

            jQuery.atmosphere.requests[jQuery.atmosphere.requests.length] = rq;
            return rq;
        },

        addCallback: function(func) {
            if (jQuery.inArray(func, jQuery.atmosphere.callbacks) == -1) {
                jQuery.atmosphere.callbacks.push(func);
            }
        },

        removeCallback: function(func) {
            var index = jQuery.inArray(func, jQuery.atmosphere.callbacks);
            if (index != -1) {
                jQuery.atmosphere.callbacks.splice(index, 1);
            }
        },

        unsubscribe : function() {
            if (jQuery.atmosphere.requests.length > 0) {
              var requestsClone = [].concat(jQuery.atmosphere.requests);
              for (var i = 0; i < requestsClone.length; i++) {
                    var rq = requestsClone[i];
                    if (rq.enableProtocol()) {
                        jQuery.ajax({url: rq.getUrl() + "?X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=" + rq.uuid(), async:false});
                    }
                    rq.close();
                    clearTimeout(rq.id);
                }
            }
            jQuery.atmosphere.requests = [];
            jQuery.atmosphere.callbacks = [];
        },

        unsubscribeUrl: function(url) {
            var idx = -1;
            if (jQuery.atmosphere.requests.length > 0) {
                for (var i = 0; i < jQuery.atmosphere.requests.length; i++) {
                    var rq = jQuery.atmosphere.requests[i];

                    // Suppose you can subscribe once to an url
                    if (rq.getUrl() == url) {
                        rq.close();
                        clearTimeout(rq.id);
                        idx = i;
                        break;
                    }
                }
            }
            if (idx >= 0) {
                jQuery.atmosphere.requests.splice(idx, 1);
            }
        },

        publish: function(request) {
            if (typeof(request.callback) == 'function') {
                jQuery.atmosphere.addCallback(callback);
            }
            request.transport = "polling";

            var rq = new jQuery.atmosphere.AtmosphereRequest(request);
            jQuery.atmosphere.requests[jQuery.atmosphere.requests.length] = rq;
            return rq;
        },

        checkCORSSupport : function() {
            if (jQuery.browser.msie && !window.XDomainRequest) {
                return true;
            } else if (jQuery.browser.opera && jQuery.browser.version < 12.0) {
                return true;
            }

            // Force Android to use CORS as some version like 2.2.3 fail otherwise
            var ua = navigator.userAgent.toLowerCase();
            var isAndroid = ua.indexOf("android") > -1;
            if (isAndroid) {
                return true;
            }
            return false;
        },

        S4 : function() {
            return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
        },

        guid : function() {
            return (jQuery.atmosphere.S4() + jQuery.atmosphere.S4() + "-" + jQuery.atmosphere.S4() + "-" + jQuery.atmosphere.S4() + "-" + jQuery.atmosphere.S4() + "-" + jQuery.atmosphere.S4() + jQuery.atmosphere.S4() + jQuery.atmosphere.S4());
        },

        // From jQuery-Stream
        prepareURL: function(url) {
            // Attaches a time stamp to prevent caching
            var ts = jQuery.now();
            var ret = url.replace(/([?&])_=[^&]*/, "$1_=" + ts);

            return ret + (ret === url ? (/\?/.test(url) ? "&" : "?") + "_=" + ts : "");
        },

        // From jQuery-Stream
        param : function(data) {
            return jQuery.param(data, jQuery.ajaxSettings.traditional);
        },

        supportStorage : function() {
            var storage = window.localStorage;
            if (storage) {
                try {
                    storage.setItem("t", "t");
                    storage.removeItem("t");
                    // The storage event of Internet Explorer and Firefox 3 works strangely
                    return window.StorageEvent && !jQuery.browser.msie && !(jQuery.browser.mozilla && jQuery.browser.version.split(".")[0] === "1");
                } catch (e) {
                }
            }

            return false;
        },

        iterate : function (fn, interval) {
            var timeoutId;

            // Though the interval is 0 for real-time application, there is a delay between setTimeout calls
            // For detail, see https://developer.mozilla.org/en/window.setTimeout#Minimum_delay_and_timeout_nesting
            interval = interval || 0;

            (function loop() {
                timeoutId = setTimeout(function() {
                    if (fn() === false) {
                        return;
                    }

                    loop();
                }, interval);
            })();

            return function() {
                clearTimeout(timeoutId);
            };
        },

        log: function (level, args) {
            if (window.console) {
                var logger = window.console[level];
                if (typeof logger == 'function') {
                    logger.apply(window.console, args);
                }
            }
        },

        warn: function() {
            jQuery.atmosphere.log('warn', arguments);
        },

        info :function() {
            jQuery.atmosphere.log('info', arguments);
        },

        debug: function() {
            jQuery.atmosphere.log('debug', arguments);
        },

        error: function() {
            jQuery.atmosphere.log('error', arguments);
        }
    };
}();

// http://stackoverflow.com/questions/9645803/whats-the-replacement-for-browser
// Limit scope pollution from any deprecated API
(function () {

    var matched, browser;

// Use of jQuery.browser is frowned upon.
// More details: http://api.jquery.com/jQuery.browser
// jQuery.uaMatch maintained for back-compat
    jQuery.uaMatch = function (ua) {
        ua = ua.toLowerCase();

        var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
            /(webkit)[ \/]([\w.]+)/.exec(ua) ||
            /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
            /(msie) ([\w.]+)/.exec(ua) ||
            ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
            [];

        return {
            browser: match[ 1 ] || "",
            version: match[ 2 ] || "0"
        };
    };

    matched = jQuery.uaMatch(navigator.userAgent);
    browser = {};

    if (matched.browser) {
        browser[ matched.browser ] = true;
        browser.version = matched.version;
    }

// Chrome is Webkit, but Webkit is also Safari.
    if (browser.chrome) {
        browser.webkit = true;
    } else if (browser.webkit) {
        browser.safari = true;
    }

    jQuery.browser = browser;

    jQuery.sub = function () {
        function jQuerySub(selector, context) {
            return new jQuerySub.fn.init(selector, context);
        }

        jQuery.extend(true, jQuerySub, this);
        jQuerySub.superclass = this;
        jQuerySub.fn = jQuerySub.prototype = this();
        jQuerySub.fn.constructor = jQuerySub;
        jQuerySub.sub = this.sub;
        jQuerySub.fn.init = function init(selector, context) {
            if (context && context instanceof jQuery && !(context instanceof jQuerySub)) {
                context = jQuerySub(context);
            }

            return jQuery.fn.init.call(this, selector, context, rootjQuerySub);
        };
        jQuerySub.fn.init.prototype = jQuerySub.fn;
        var rootjQuerySub = jQuerySub(document);
        return jQuerySub;
    };

})();

/*
 * jQuery stringifyJSON
 * http://github.com/flowersinthesand/jquery-stringifyJSON
 * 
 * Copyright 2011, Donghwan Kim 
 * Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 */
// This plugin is heavily based on Douglas Crockford's reference implementation
(function(jQuery) {

    var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, meta = {
        '\b' : '\\b',
        '\t' : '\\t',
        '\n' : '\\n',
        '\f' : '\\f',
        '\r' : '\\r',
        '"' : '\\"',
        '\\' : '\\\\'
    };

    function quote(string) {
        return '"' + string.replace(escapable, function(a) {
            var c = meta[a];
            return typeof c === "string" ? c : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
        }) + '"';
    }

    function f(n) {
        return n < 10 ? "0" + n : n;
    }

    function str(key, holder) {
        var i, v, len, partial, value = holder[key], type = typeof value;

        if (value && typeof value === "object" && typeof value.toJSON === "function") {
            value = value.toJSON(key);
            type = typeof value;
        }

        switch (type) {
            case "string":
                return quote(value);
            case "number":
                return isFinite(value) ? String(value) : "null";
            case "boolean":
                return String(value);
            case "object":
                if (!value) {
                    return "null";
                }

                switch (Object.prototype.toString.call(value)) {
                    case "[object Date]":
                        return isFinite(value.valueOf()) ? '"' + value.getUTCFullYear() + "-" + f(value.getUTCMonth() + 1) + "-" + f(value.getUTCDate()) + "T" +
                            f(value.getUTCHours()) + ":" + f(value.getUTCMinutes()) + ":" + f(value.getUTCSeconds()) + "Z" + '"' : "null";
                    case "[object Array]":
                        len = value.length;
                        partial = [];
                        for (i = 0; i < len; i++) {
                            partial.push(str(i, value) || "null");
                        }

                        return "[" + partial.join(",") + "]";
                    default:
                        partial = [];
                        for (i in value) {
                            if (Object.prototype.hasOwnProperty.call(value, i)) {
                                v = str(i, value);
                                if (v) {
                                    partial.push(quote(i) + ":" + v);
                                }
                            }
                        }

                        return "{" + partial.join(",") + "}";
                }
        }
    }

    jQuery.stringifyJSON = function(value) {
        if (window.JSON && window.JSON.stringify) {
            return window.JSON.stringify(value);
        }

        return str("", {"": value});
    };

}(jQuery));;(function($, rf) {
    rf.ui = rf.ui || {};

    var defaultOptions = {
        mode : "server",
        cssRoot : "ddm",
        cssClasses : {}
    }

    // constructor definition

    rf.ui.MenuItem = function(componentId, options) {
        this.options = {};
        $.extend(this.options, defaultOptions, options || {});
        $super.constructor.call(this, componentId);
        $.extend(this.options.cssClasses, buildCssClasses.call(this, this.options.cssRoot));
        this.attachToDom(componentId);
        this.element = $(rf.getDomElement(componentId));
        rf.Event.bindById(this.id, 'click', this.__clickHandler, this);
        rf.Event.bindById(this.id, 'mouseenter', this.select, this);
        rf.Event.bindById(this.id, 'mouseleave', this.unselect, this);
        this.selected = false;
    };

    var buildCssClasses = function(cssRoot) {
        var cssClasses = {
            itemCss : "rf-" +cssRoot+ "-itm",
            selectItemCss : "rf-" +cssRoot+ "-itm-sel",
            unselectItemCss : "rf-" +cssRoot+ "-itm-unsel",
            labelCss: "rf-" +cssRoot+ "-lbl"
        }
        return cssClasses;
    }

    rf.BaseComponent.extend(rf.ui.MenuItem);

    // define super class link
    var $super = rf.ui.MenuItem.$super;

    $.extend(rf.ui.MenuItem.prototype, (function() {

        return {
            name : "MenuItem",
            select : function() {
                this.element.removeClass(this.options.cssClasses.unselectItemCss);
                this.element.addClass(this.options.cssClasses.selectItemCss);
                this.selected = true;
            },
            unselect : function() {
                this.element.removeClass(this.options.cssClasses.selectItemCss);
                this.element.addClass(this.options.cssClasses.unselectItemCss);
                this.selected = false;
            },
            activate : function() {
                this.invokeEvent('click', rf.getDomElement(this.id));
            },

            isSelected : function() {
                return this.selected;
            },

            __clickHandler : function(e) {
                if ($(e.target).is(":input:not(:button):not(:reset):not(:submit)")) {
                    return;
                }

                var parentMenu = this.__getParentMenu();
                if (parentMenu) {
                    parentMenu.processItem(this.element);
                }
                
                var item = rf.getDomElement(this.id);
                var params = this.options.params;
                var form = this.__getParentForm(item);
                var itemId = {};
                itemId[item.id] = item.id;
                $.extend(itemId, params || {});
                e.form = form;
                e.itemId = itemId;
                this.options.onClickHandler.call(this, e);
            },

            __getParentForm : function(item) {
                return $($(item).parents("form").get(0));
            },

            __getParentMenu : function() {
                var menu = this.element.parents('div.' + this.options.cssClasses.labelCss);
                if (menu && menu.length > 0)
                    return rf.$(menu);
                else
                    return null;
            }
        };
    })());

})(jQuery, RichFaces);;/*
 * jQuery Hotkeys Plugin
 * Copyright 2010, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *
 * Based upon the plugin by Tzury Bar Yochay:
 * http://github.com/tzuryby/hotkeys
 *
 * Original idea by:
 * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
*/

(function(jQuery){

	jQuery.hotkeys = {
		version: "0.8",

		specialKeys: {
			8: "backspace", 9: "tab", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
			20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
			37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del", 
			96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
			104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/", 
			112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8", 
			120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 191: "/", 224: "meta"
		},

		shiftNums: {
			"`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&", 
			"8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<", 
			".": ">",  "/": "?",  "\\": "|"
		}
	};
	
	var defaultOptions = {
        key : '',
        enabledInInput : false
    };

	function keyHandler( handleObj ) {
		var options = ( typeof handleObj.data == "string" ) ? {key: handleObj.data} : handleObj.data;
		options = jQuery.extend({}, defaultOptions, options);

		var origHandler = handleObj.handler,
			keys = options.key.toLowerCase().split(" ");
		
		// when no key binding is defined
		if (keys.length === 1 && keys[0] === '') {
		    return;
		}
		
		handleObj.handler = function( event ) {
			var character = String.fromCharCode( event.which ).toLowerCase(),
					isTextInput = (/textarea|select/i.test( event.target.nodeName ) || event.target.type === "text");
			// Don't fire in text-accepting inputs that we didn't directly bind to
			if ( this !== event.target && isTextInput && !options.enabledInInput ) {
				return;
			}

			// Keypress represents characters, not special keys
			var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ],
				key, modif = "", possible = {};

			// check combinations (alt|ctrl|shift+anything)
			if ( event.altKey && special !== "alt" ) {
				modif += "alt+";
			}

			if ( event.ctrlKey && special !== "ctrl" ) {
				modif += "ctrl+";
			}

			// TODO: Need to make sure this works consistently across platforms
			if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
				modif += "meta+";
			}

			if ( event.shiftKey && special !== "shift" ) {
				modif += "shift+";
			}

			if ( special ) {
				possible[ modif + special ] = true;

			} else {
				possible[ modif + character ] = true;
				possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;

				// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
				if ( modif === "shift+" ) {
					possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
				}
			}
			for ( var i = 0, l = keys.length; i < l; i++ ) {
				if ( possible[ keys[i] ] ) {
					return origHandler.apply( this, arguments );
				}
			}
		};
	}

	jQuery.each([ "keydown", "keyup", "keypress" ], function() {
		jQuery.event.special[ this ] = { add: keyHandler };
	});

})( jQuery );
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
(function(richfaces, jQuery) {
    richfaces.ui = richfaces.ui || {};

    richfaces.ui.InputNumberSlider = richfaces.BaseComponent.extendClass({

            name: "InputNumberSlider",

            delay: 200,
            maxValue: 100,
            minValue: 0,
            step: 1,
            tabIndex: 0,

            decreaseSelectedClass: "rf-insl-dec-sel",
            handleSelectedClass: "rf-insl-hnd-sel",
            increaseSelectedClass: "rf-insl-inc-sel",

            init: function (id, options, selectedClasses) {
                $superInputNumberSlider.constructor.call(this, id);
                jQuery.extend(this, options);
                this.range = this.maxValue - this.minValue;
                this.id = id;
                this.element = jQuery(this.attachToDom());
                this.input = this.element.children(".rf-insl-inp-cntr").children(".rf-insl-inp");
                this.track = this.element.children(".rf-insl-trc-cntr").children(".rf-insl-trc");
                this.handleContainer = this.track.children("span");
                this.handle = this.handleContainer.children(".rf-insl-hnd, .rf-insl-hnd-dis");
                this.tooltip = this.element.children(".rf-insl-tt");

                var value = Number(this.input.val());
                if (isNaN(value)) {
                    value = this.minValue;
                }
                this.handleContainer.css("display", "block");
                this.track.css("padding-right", this.handle.width() + "px");
                this.__setValue(value, null, true);

                if (!this.disabled) {
                    this.decreaseButton = this.element.children(".rf-insl-dec");
                    this.increaseButton = this.element.children(".rf-insl-inc");

                    this.track[0].tabIndex = this.tabIndex;

                    for (var i in selectedClasses) {
                        this[i] += " " + selectedClasses[i];
                    }
                    var proxy = jQuery.proxy(this.__inputHandler, this);
                    this.input.change(proxy);
                    this.input.submit(proxy);
                    this.element.mousewheel(jQuery.proxy(this.__mousewheelHandler, this));
                    this.track.keydown(jQuery.proxy(this.__keydownHandler, this));
                    this.decreaseButton.mousedown(jQuery.proxy(this.__decreaseHandler, this));
                    this.increaseButton.mousedown(jQuery.proxy(this.__increaseHandler, this));
                    this.track.mousedown(jQuery.proxy(this.__mousedownHandler, this));
                }
            },

            decrease: function (event) {
                var value = this.value - this.step;
                value = this.roundFloat(value);
                this.setValue(value, event);
            },

            increase: function (event) {
                var value = this.value + this.step;
                value = this.roundFloat(value);
                this.setValue(value, event);
            },

            getValue: function () {
                return this.value;
            },

            setValue: function (value, event) {
                if (!this.disabled) {
                    this.__setValue(value, event);
                }
            },

            roundFloat: function(x){
                var str = this.step.toString();
                var power = 0;
                if (!/\./.test(str)) {
                    if (this.step >= 1) {
                        return x;
                    }
                    if (/e/.test(str)) {
                        power = str.split("-")[1];
                    }
                } else {
                    power = str.length - str.indexOf(".") - 1;
                }
                var ret = x.toFixed(power);
                return parseFloat(ret);
            },

            __setValue: function (value, event, skipOnchange) {
                if (!isNaN(value)) {
                    var changed = false;
                    if (this.input.val() == "") {
                        // value already changed from "" to 0, compare to real value to track changes
                        changed = true;
                    }

                    if (value > this.maxValue) {
                        value = this.maxValue;
                        this.input.val(value);
                        changed = true;
                    } else if (value < this.minValue) {
                        value = this.minValue;
                        this.input.val(value);
                        changed = true;
                    }
                    if (value != this.value || changed) {
                        this.input.val(value);
                        var left = 100 * (value - this.minValue) / this.range;
                        if(this.handleType=='bar') {
                            this.handleContainer.css("width", left + "%");
                        } else {
                            this.handleContainer.css("padding-left", left + "%");
                        }
                        this.tooltip.text(value);
                        this.tooltip.setPosition(this.handle, {from: 'LT', offset: [0, 5]}); //TODO Seems offset doesn't work now.
                        this.value = value;
                        if (this.onchange && !skipOnchange) {
                            this.onchange.call(this.element[0], event);
                        }
                    }
                }
            },

            __inputHandler: function (event) {
                var value = Number(this.input.val());
                if (isNaN(value)) {
                    this.input.val(this.value);
                } else {
                    this.__setValue(value, event);
                }
            },

            __mousewheelHandler: function (event, delta, deltaX, deltaY) {
                delta = deltaX || deltaY;
                if (delta > 0) {
                    this.increase(event);
                } else if (delta < 0) {
                    this.decrease(event);
                }
                return false;
            },

            __keydownHandler: function (event) {
                if (event.keyCode == 37) { //LEFT
                    var value = Number(this.input.val()) - this.step;
                    value = this.roundFloat(value);
                    this.__setValue(value, event);
                    event.preventDefault();
                } else if (event.keyCode == 39) { //RIGHT
                    var value = Number(this.input.val()) + this.step;
                    value = this.roundFloat(value);
                    this.__setValue(value, event);
                    event.preventDefault();
                }
            },

            __decreaseHandler: function (event) {
                var component = this;
                component.decrease(event);
                this.intervalId = window.setInterval(function() {
                    component.decrease(event);
                }, this.delay);
                jQuery(document).one("mouseup", true, jQuery.proxy(this.__clearInterval, this));
                this.decreaseButton.addClass(this.decreaseSelectedClass);
                event.preventDefault();
            },

            __increaseHandler: function (event) {
                var component = this;
                component.increase(event);
                this.intervalId = window.setInterval(function() {
                    component.increase(event);
                }, this.delay);
                jQuery(document).one("mouseup", jQuery.proxy(this.__clearInterval, this));
                this.increaseButton.addClass(this.increaseSelectedClass);
                event.preventDefault();
            },

            __clearInterval: function (event) {
                window.clearInterval(this.intervalId);
                if (event.data) { // decreaseButton
                    this.decreaseButton.removeClass(this.decreaseSelectedClass);
                } else {
                    this.increaseButton.removeClass(this.increaseSelectedClass);
                }
            },

            __mousedownHandler: function (event) {
                this.__mousemoveHandler(event);
                this.track.focus();
                var jQueryDocument = jQuery(document);
                jQueryDocument.mousemove(jQuery.proxy(this.__mousemoveHandler, this));
                jQueryDocument.one("mouseup", jQuery.proxy(this.__mouseupHandler, this));
                this.handle.addClass(this.handleSelectedClass);
                this.tooltip.show();
            },

            __mousemoveHandler: function (event) {
                var value = this.range * (event.pageX - this.track.offset().left - this.handle.width() / 2) / (this.track.width()
                    - this.handle.width()) + this.minValue;
                value = Math.round(value / this.step) * this.step;
                value = this.roundFloat(value);
                this.__setValue(value, event);
                event.preventDefault();
            },

            __mouseupHandler: function () {
                this.handle.removeClass(this.handleSelectedClass);
                this.tooltip.hide();
                jQuery(document).unbind("mousemove", this.__mousemoveHandler);
            },

            destroy: function (event) {
                jQuery(document).unbind("mousemove", this.__mousemoveHandler);
                $superInputNumberSlider.destroy.call(this);
            }
        });
    $superInputNumberSlider = richfaces.ui.InputNumberSlider.$super;
}(window.RichFaces, jQuery));
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
(function(richfaces, jQuery) {
    richfaces.utils = richfaces.utils || {};

    richfaces.utils.addCSSText = function(cssText, elementId) {
        var style = jQuery("<style></style>").attr({type: 'text/css', id: elementId}).appendTo("head");
        try {
            style.html(cssText);
        } catch (e) {
            //IE
            style[0].styleSheet.cssText = cssText;
        }
    };
    
    richfaces.utils.getCSSRule = function (className) {
        return richfaces.utils.findCSSRule(function(selectorText) {
            return selectorText.toLowerCase() == className.toLowerCase();
        });
    };

    richfaces.utils.findCSSRule = function (selectFunction) {
        var rule = null;
        var sheets = document.styleSheets;
        for (var j = 0; !rule && j < sheets.length; j++) {
            try {
                var sheet = sheets[j];
                var rules = sheet.cssRules ? sheet.cssRules : sheet.rules;
                for (var i = 0; !rule && i < rules.length; i++) {
                    if (rules[i].selectorText && selectFunction(rules[i].selectorText)) {
                        rule = rules[i];
                    }
                }
            } catch (e) {
                richfaces.log.debug("Cannot obtain CSS rule for " + (sheet.href || sheet) + ": " + e);
            }
        }
        return rule;
    };

    richfaces.utils.Ranges = function() {
        this.ranges = [];
    };

    richfaces.utils.Ranges.prototype = {

        add: function(index) {
            var i = 0;
            while (i < this.ranges.length && index >= this.ranges[i++][1]);
            i--;
            if (this.ranges[i - 1] && index == (this.ranges[i - 1][1] + 1)) {
                if (index == (this.ranges[i][0] - 1)) {
                    this.ranges[i - 1][1] = this.ranges[i][1];
                    this.ranges.splice(i, 1);
                } else {
                    this.ranges[i - 1][1]++;
                }
            } else {
                if (this.ranges[i]) {
                    if (this.ranges[i] && index == (this.ranges[i][0] - 1)) {
                        this.ranges[i][0]--;
                    } else {
                        if (index == (this.ranges[i][1] + 1)) {
                            this.ranges[i][1]++;
                        } else {
                            if (index < this.ranges[i][1]) {
                                this.ranges.splice(i, 0, [index, index]);
                            } else {
                                this.ranges.splice(i + 1, 0, [index, index]);
                            }
                        }
                    }
                } else {
                    this.ranges.splice(i, 0, [index, index]);
                }
            }
        },

        remove: function(index) {
            var i = 0;
            while (i < this.ranges.length && index > this.ranges[i++][1]);
            i--;
            if (this.ranges[i]) {
                if (index == (this.ranges[i][1])) {
                    if (index == (this.ranges[i][0])) {
                        this.ranges.splice(i, 1);
                    } else {
                        this.ranges[i][1]--;
                    }
                } else {
                    if (index == (this.ranges[i][0])) {
                        this.ranges[i][0]++;
                    } else {
                        this.ranges.splice(i + 1, 0, [index + 1, this.ranges[i][1]]);
                        this.ranges[i][1] = index - 1;
                    }
                }
            }
        },

        clear: function() {
            this.ranges = [];
        },

        contains: function(index) {
            var i = 0;
            while (i < this.ranges.length && index >= this.ranges[i][0]) {
                if (index >= this.ranges[i][0] && index <= this.ranges[i][1]) {
                    return true;
                } else {
                    i++;
                }
            }
            return false;
        },

        toString: function() {
            var ret = new Array(this.ranges.length);
            for (var i = 0; i < this.ranges.length; i++) {
                ret[i] = this.ranges[i].join();
            }
            return ret.join(";");
        }
    };

    var WIDTH_CLASS_NAME_BASE = "rf-edt-c-";
    var MIN_WIDTH = 20;

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.ExtendedDataTable = richfaces.BaseComponent.extendClass({

            name: "ExtendedDataTable",

            init: function (id, rowCount, ajaxFunction, options) {
                $super.constructor.call(this, id);
                this.ranges = new richfaces.utils.Ranges();
                this.rowCount = rowCount;
                this.ajaxFunction = ajaxFunction;
                this.options = options || {};
                this.element = this.attachToDom();
                this.newWidths = {};
                this.storeDomReferences();
                if (this.options['onready'] && typeof this.options['onready'] == 'function') {
                    richfaces.Event.bind(this.element, "rich:ready", this.options['onready']);
                }
                jQuery(document).ready(jQuery.proxy(this.initialize, this));
                this.resizeEventName = "resize.rf.edt." + this.id;
                this.activateResizeListener();
                jQuery(this.scrollElement).bind("scroll", jQuery.proxy(this.updateScrollPosition, this));
                this.bindHeaderHandlers();
                jQuery(this.element).bind("rich:onajaxcomplete", jQuery.proxy(this.ajaxComplete, this));
                
                this.resizeData = {};
                this.idOfReorderingColumn = "";
                this.timeoutId = null;
            },

            storeDomReferences: function() {
                this.dragElement = document.getElementById(this.id + ":d");
                this.reorderElement = document.getElementById(this.id + ":r");
                this.reorderMarkerElement = document.getElementById(this.id + ":rm");
                this.widthInput = document.getElementById(this.id + ":wi");
                this.selectionInput = document.getElementById(this.id + ":si");


                this.header = jQuery(this.element).children(".rf-edt-hdr");
                this.headerCells = this.header.find(".rf-edt-hdr-c");
                this.footerCells = jQuery(this.element).children(".rf-edt-ftr").find(".rf-edt-ftr-c");
                this.resizerHolders = this.header.find(".rf-edt-rsz-cntr");

                this.frozenHeaderPartElement = document.getElementById(this.id + ":frozenHeader");
                this.frozenColumnCount = this.frozenHeaderPartElement ? this.frozenHeaderPartElement.firstChild.rows[0].cells.length : 0;//TODO Richfaces.firstDescendant;

                this.headerElement = document.getElementById(this.id + ":header");
                this.footerElement = document.getElementById(this.id + ":footer");
                this.scrollElement = document.getElementById(this.id + ":scrl");
                this.scrollContentElement = document.getElementById(this.id + ":scrl-cnt");

            },

            getColumnPosition: function(id) {
                var position;
                for (var i = 0; i < this.headerCells.length; i++) {
                    if (id == this.headerCells[i].className.match(new RegExp(WIDTH_CLASS_NAME_BASE + "([^\\W]*)"))[1]) {
                        position = i;
                    }
                }
                return position;
            },

            setColumnPosition: function(id, position) {
                var colunmsOrder = "";
                var before;
                for (var i = 0; i < this.headerCells.length; i++) {
                    var current = this.headerCells[i].className.match(new RegExp(WIDTH_CLASS_NAME_BASE + "([^\\W]*)"))[1];
                    if (i == position) {
                        if (before) {
                            colunmsOrder += current + "," + id + ",";
                        } else {
                            colunmsOrder += id + "," + current + ",";
                        }
                    } else {
                        if (id != current) {
                            colunmsOrder += current + ",";
                        } else {
                            before = true;
                        }
                    }
                }
                this.ajaxFunction(null, {"rich:columnsOrder" : colunmsOrder}); // TODO Maybe, event model should be used here.
            },

            setColumnWidth: function(columnId, width) {
                width = width + "px";
                this.getColumnStyle(columnId).width = width;
                this.newWidths[columnId] = width;
                var widthsArray = new Array();
                for (var id in this.newWidths) {
                    widthsArray.push(id + ":" + this.newWidths[id]);
                }
                this.widthInput.value = widthsArray.toString();
                this.updateLayout();
                this.adjustResizers();
                this.ajaxFunction(); // TODO Maybe, event model should be used here.
            },
            
            getColumnStyle: function(columnId) {
                var tableId = this.element.id;
                var columnClass = WIDTH_CLASS_NAME_BASE + columnId;
                var stylesheet = richfaces.utils.findCSSRule(function(selector) {
                    return selector.indexOf(columnClass) !== -1 && selector.indexOf(tableId) !== -1;
                });
                if (!stylesheet) {
                    throw new Error("Cannot find the stylesheet for column '" + columnId + "'");
                }
                return stylesheet.style;
            },

            filter: function(colunmId, filterValue, isClear) {
                if (typeof(filterValue) == "undefined" || filterValue == null) {
                    filterValue = "";
                }
                var map = {};
                map[this.id + "rich:filtering"] = colunmId + ":" + filterValue + ":" + isClear;
                this.ajaxFunction(null, map); // TODO Maybe, event model should be used here.
            },

            clearFiltering: function() {
                this.filter("", "", true);
            },

            sortHandler: function(event) {
                var sortHandle = $(event.data.sortHandle);
                var button = sortHandle.find('.rf-edt-srt-btn');
                var columnId = button.data('columnid');
                var sortOrder = button.hasClass('rf-edt-srt-asc') ? 'descending' : 'ascending';
                this.sort(columnId, sortOrder, false);
            },

            filterHandler: function(event) {
                var filterHandle = $(event.data.filterHandle);
                var columnId = filterHandle.data('columnid');
                var filterValue = filterHandle.val();
                this.filter(columnId, filterValue, false);
            },


            sort: function(colunmId, sortOrder, isClear) {
                if (typeof(sortOrder) == "string") {
                    sortOrder = sortOrder.toLowerCase();
                }
                var map = {}
                map[this.id + "rich:sorting"] = colunmId + ":" + sortOrder + ":" + isClear;
                this.ajaxFunction(null, map); // TODO Maybe, event model should be used here.
            },

            clearSorting: function() {
                this.sort("", "", true);
            },

            destroy: function() {
                jQuery(window).unbind("resize", this.updateLayout);
                jQuery(richfaces.getDomElement(this.id + ':st')).remove();
                $super.destroy.call(this);
            },

            bindHeaderHandlers: function() {
                this.header.find(".rf-edt-rsz").bind("mousedown", jQuery.proxy(this.beginResize, this));
                this.headerCells.bind("mousedown", jQuery.proxy(this.beginReorder, this));
                var self = this;
                this.header.find(".rf-edt-c-srt").each(function() {
                    $(this).bind("click", {sortHandle: this}, jQuery.proxy(self.sortHandler, self));
                });
                this.header.find(".rf-edt-flt-i").each(function() {
                    $(this).bind("blur", {filterHandle: this}, jQuery.proxy(self.filterHandler, self));
                });
            },

            updateLayout: function() {
                this.deActivateResizeListener();
                this.headerCells.height("auto");
                var headerCellHeight = 0;
                this.headerCells.each(function() {
                    if (this.clientHeight > headerCellHeight) {
                        headerCellHeight = this.clientHeight;
                    }
                });
                this.headerCells.height(headerCellHeight + "px");
                this.footerCells.height("auto");
                var footerCellHeight = 0;
                this.footerCells.each(function() {
                    if (this.clientHeight > footerCellHeight) {
                        footerCellHeight = this.clientHeight;
                    }
                });
                this.footerCells.height(footerCellHeight + "px");
                this.normalPartStyle.width = "auto";
                var offsetWidth = this.frozenHeaderPartElement ? this.frozenHeaderPartElement.offsetWidth : 0;
                var width = Math.max(0, this.element.clientWidth - offsetWidth);
                if (width) {
                    this.parts.each(function() {
                        this.style.width = "auto";
                    });
                    var contentWidth = this.parts.width();
                    if (contentWidth > width) {
                        this.normalPartStyle.width = width + "px";
                    }
                    this.normalPartStyle.display = "block";
                    // update scroller and scroll-content
                    if (contentWidth > width) {
                        this.parts.each(function() {
                            this.style.width = width + "px";
                        });
                        this.scrollElement.style.display = "block";
                        this.scrollElement.style.overflowX = "scroll";
                        this.scrollElement.style.width = width + "px";
                        this.scrollContentElement.style.width = contentWidth + "px";
                        this.updateScrollPosition();
                    } else {
                        this.parts.each(function() {
                            this.style.width = "";
                        });
                        this.scrollElement.style.display = "none";
                    }
                } else {
                    this.normalPartStyle.display = "none";
                }
                var height = this.element.clientHeight;
                var el = this.element.firstChild;
                while (el && (!el.nodeName || el.nodeName.toUpperCase() != "TABLE")) {
                    if (el.nodeName && el.nodeName.toUpperCase() == "DIV" && el != this.bodyElement) {
                        height -= el.offsetHeight;
                    }
                    el = el.nextSibling;
                }
                if (this.bodyElement.offsetHeight > height || !this.contentElement) {
                    this.bodyElement.style.height = height + "px";
                }
                this.activateResizeListener();
            },

            adjustResizers: function() { //For IE7 only.
                var scrollLeft = this.scrollElement ? this.scrollElement.scrollLeft : 0;
                var clientWidth = this.element.clientWidth - 3;
                var i = 0;
                for (; i < this.frozenColumnCount; i++) {
                    if (clientWidth > 0) {
                        this.resizerHolders[i].style.display = "none";
                        this.resizerHolders[i].style.display = "";
                        clientWidth -= this.resizerHolders[i].offsetWidth;
                    }
                    if (clientWidth <= 0) {
                        this.resizerHolders[i].style.display = "none";
                    }
                }
                scrollLeft -= 3;
                for (; i < this.resizerHolders.length; i++) {
                    if (clientWidth > 0) {
                        this.resizerHolders[i].style.display = "none";
                        if (scrollLeft > 0) {
                            this.resizerHolders[i].style.display = "";
                            scrollLeft -= this.resizerHolders[i].offsetWidth;
                            if (scrollLeft > 0) {
                                this.resizerHolders[i].style.display = "none";
                            } else {
                                clientWidth += scrollLeft;
                            }
                        } else {
                            this.resizerHolders[i].style.display = "";
                            clientWidth -= this.resizerHolders[i].offsetWidth;
                        }
                    }
                    if (clientWidth <= 0) {
                        this.resizerHolders[i].style.display = "none";
                    }
                }
            },

            updateScrollPosition: function() {
                if (this.scrollElement) {
                    var scrollLeft = this.scrollElement.scrollLeft;
                    this.parts.each(function() {
                        this.scrollLeft = scrollLeft;
                    });
                }
                this.adjustResizers();
            },

            initialize: function() {
                this.deActivateResizeListener();
                if (! $(this.element).is(":visible")) {
                    this.showOffscreen(this.element);
                }
                this.bodyElement = document.getElementById(this.id + ":b");
                this.bodyElement.tabIndex = -1; //TODO don't use tabIndex.
                this.normalPartStyle = richfaces.utils.getCSSRule("div.rf-edt-cnt").style;
                var bodyJQuery = jQuery(this.bodyElement);
                this.contentElement = bodyJQuery.children("div:not(.rf-edt-ndt):first")[0];
                if (this.contentElement) {
                    this.spacerElement = this.contentElement.firstChild;//TODO this.marginElement = Richfaces.firstDescendant(this.contentElement);
                    this.dataTableElement = this.contentElement.lastChild;//TODO this.dataTableElement = Richfaces.lastDescendant(this.contentElement);
                    this.tbodies = jQuery(document.getElementById(this.id + ":tbf")).add(document.getElementById(this.id + ":tbn"));
                    this.rows = this.tbodies[0].rows.length;
                    this.rowHeight = this.dataTableElement.offsetHeight / this.rows;
                    if (this.rowCount != this.rows) {
                        this.contentElement.style.height = (this.rowCount * this.rowHeight) + "px";
                    }
                    bodyJQuery.bind("scroll", jQuery.proxy(this.bodyScrollListener, this));
                    if (this.options.selectionMode != "none") {
                        this.tbodies.bind("click", jQuery.proxy(this.selectionClickListener, this));
                        bodyJQuery.bind(window.opera ? "keypress" : "keydown", jQuery.proxy(this.selectionKeyDownListener, this));
                        this.initializeSelection();
                    }
                } else {
                    this.spacerElement = null;
                    this.dataTableElement = null;
                }
                this.parts = jQuery(this.element).find(".rf-edt-cnt, .rf-edt-ftr-cnt");
                this.updateLayout();
                this.updateScrollPosition(); //TODO Restore horizontal scroll position
                if ($(this.element).data('offscreenElements')) {
                    this.hideOffscreen(this.element);
                }
                this.activateResizeListener();
                jQuery(this.element).triggerHandler("rich:ready", this);
            },

            showOffscreen: function(element) {
                var $element = $(element);
                var offscreenElements = $element.parents(":not(:visible)").addBack().toArray().reverse();
                var that = this;
                $.each(offscreenElements, function() {
                    $this = $(this);
                    if ($this.css('display') === 'none') {
                        that.showOffscreenElement($(this));
                    }
                })
                $element.data('offscreenElements', offscreenElements);
            },

            hideOffscreen: function(element) {
                var $element = $(element);
                var offscreenElements = $element.data('offscreenElements');
                var that = this;
                $.each(offscreenElements, function() {
                    $this = $(this);
                    if ($this.data('offscreenOldValues')) {
                        that.hideOffscreenElement($(this));
                    }
                })
                $element.removeData('offscreenElements');
            },

            showOffscreenElement: function($element) {
                var offscreenOldValues = {};
                offscreenOldValues.oldPosition = $element.css('position');
                offscreenOldValues.oldLeft = $element.css('left');
                offscreenOldValues.oldDisplay = $element.css('display');
                $element.css('position', 'absolute');
                $element.css('left', '-10000');
                $element.css('display', 'block');
                $element.data('offscreenOldValues', offscreenOldValues);
            },

            hideOffscreenElement: function($element) {
                var offscreenOldValues = $element.data('offscreenOldValues');
                $element.css('display', offscreenOldValues.oldDisplay);
                $element.css('left', offscreenOldValues.oldLeft);
                $element.css('position', offscreenOldValues.oldPosition);
                $element.removeData('offscreenOldValues');
            },

            drag: function(event) {
                jQuery(this.dragElement).setPosition({left:Math.max(this.resizeData.left + MIN_WIDTH, event.pageX)});
                return false;
            },

            beginResize: function(event) {
                var id = event.currentTarget.parentNode.className.match(new RegExp(WIDTH_CLASS_NAME_BASE + "([^\\W]*)"))[1];
                this.resizeData = {
                    id : id,
                    left : jQuery(event.currentTarget).parent().offset().left
                };
                this.dragElement.style.height = this.element.offsetHeight + "px";
                jQuery(this.dragElement).setPosition({top:jQuery(this.element).offset().top, left:event.pageX});
                this.dragElement.style.display = "block";
                jQuery(document).bind("mousemove", jQuery.proxy(this.drag, this));
                jQuery(document).one("mouseup", jQuery.proxy(this.endResize, this));
                return false;
            },

            endResize: function(event) {
                jQuery(document).unbind("mousemove", this.drag);
                this.dragElement.style.display = "none";
                var width = Math.max(MIN_WIDTH, event.pageX - this.resizeData.left);
                this.setColumnWidth(this.resizeData.id, width);
            },

            reorder: function(event) {
                jQuery(this.reorderElement).setPosition(event, {offset:[5,5]});
                this.reorderElement.style.display = "block";
                return false;
            },

            beginReorder: function(event) {
                if (!jQuery(event.target).is("a, img, :input")) {
                    this.idOfReorderingColumn = event.currentTarget.className.match(new RegExp(WIDTH_CLASS_NAME_BASE + "([^\\W]*)"))[1];
                    jQuery(document).bind("mousemove", jQuery.proxy(this.reorder, this));
                    this.headerCells.bind("mouseover", jQuery.proxy(this.overReorder, this));
                    jQuery(document).one("mouseup", jQuery.proxy(this.cancelReorder, this));
                    return false;
                }
            },

            overReorder: function(event) {
                if (this.idOfReorderingColumn != event.currentTarget.className.match(new RegExp(WIDTH_CLASS_NAME_BASE + "([^\\W]*)"))[1]) {
                    var eventElement = jQuery(event.currentTarget);
                    var offset = eventElement.offset();
                    jQuery(this.reorderMarkerElement).setPosition({top:offset.top + eventElement.height(), left:offset.left - 5});
                    this.reorderMarkerElement.style.display = "block";
                    eventElement.one("mouseout", jQuery.proxy(this.outReorder, this));
                    eventElement.one("mouseup", jQuery.proxy(this.endReorder, this));
                }
            },

            outReorder: function(event) {
                this.reorderMarkerElement.style.display = "";
                jQuery(event.currentTarget).unbind("mouseup", this.endReorder);
            },

            endReorder: function(event) {
                this.reorderMarkerElement.style.display = "";
                jQuery(event.currentTarget).unbind("mouseout", this.outReorder);
                var id = event.currentTarget.className.match(new RegExp(WIDTH_CLASS_NAME_BASE + "([^\\W]*)"))[1];
                var colunmsOrder = "";
                var _this = this;
                this.headerCells.each(function() {
                    var i = this.className.match(new RegExp(WIDTH_CLASS_NAME_BASE + "([^\\W]*)"))[1];
                    if (i == id) {
                        colunmsOrder += _this.idOfReorderingColumn + "," + id + ",";
                    } else if (i != _this.idOfReorderingColumn) {
                        colunmsOrder += i + ",";
                    }
                });
                this.ajaxFunction(event, {"rich:columnsOrder" : colunmsOrder}); // TODO Maybe, event model should be used here.
            },

            cancelReorder: function(event) {
                jQuery(document).unbind("mousemove", this.reorder);
                this.headerCells.unbind("mouseover", this.overReorder);
                this.reorderElement.style.display = "none";
            },

            loadData: function(event) {
                var clientFirst = Math.round((this.bodyElement.scrollTop + this.bodyElement.clientHeight / 2) / this.rowHeight - this.rows / 2);
                if (clientFirst <= 0) {
                    clientFirst = 0;
                } else {
                    clientFirst = Math.min(this.rowCount - this.rows, clientFirst);
                }
                this.ajaxFunction(event, {"rich:clientFirst" : clientFirst});// TODO Maybe, event model should be used here.
            },

            bodyScrollListener: function(event) {
                if (this.timeoutId) {
                    window.clearTimeout(this.timeoutId);
                    this.timeoutId = null;
                }
                if (Math.max(event.currentTarget.scrollTop - this.rowHeight, 0) < this.spacerElement.offsetHeight
                    || Math.min(event.currentTarget.scrollTop + this.rowHeight + event.currentTarget.clientHeight, event.currentTarget.scrollHeight) > this.spacerElement.offsetHeight + this.dataTableElement.offsetHeight) {
                    var _this = this;
                    this.timeoutId = window.setTimeout(function (event) {
                        _this.loadData(event)
                    }, 1000);
                }
            },

            showActiveRow: function() {
                if (this.bodyElement.scrollTop > this.activeIndex * this.rowHeight + this.spacerElement.offsetHeight) { //UP
                    this.bodyElement.scrollTop = Math.max(this.bodyElement.scrollTop - this.rowHeight, 0);
                } else if (this.bodyElement.scrollTop + this.bodyElement.clientHeight
                    < (this.activeIndex + 1) * this.rowHeight + this.spacerElement.offsetHeight) { //DOWN
                    this.bodyElement.scrollTop = Math.min(this.bodyElement.scrollTop + this.rowHeight, this.bodyElement.scrollHeight - this.bodyElement.clientHeight);
                }
            },

            selectRow: function(index) {
                this.ranges.add(index);
                for (var i = 0; i < this.tbodies.length; i++) {
                    jQuery(this.tbodies[i].rows[index]).addClass("rf-edt-r-sel");
                }
            },

            deselectRow: function (index) {
                this.ranges.remove(index);
                for (var i = 0; i < this.tbodies.length; i++) {
                    jQuery(this.tbodies[i].rows[index]).removeClass("rf-edt-r-sel");
                }
            },

            setActiveRow: function (index) {
                if (typeof this.activeIndex == "number") {
                    for (var i = 0; i < this.tbodies.length; i++) {
                        jQuery(this.tbodies[i].rows[this.activeIndex]).removeClass("rf-edt-r-act");
                    }

                }
                this.activeIndex = index;
                for (var i = 0; i < this.tbodies.length; i++) {
                    jQuery(this.tbodies[i].rows[this.activeIndex]).addClass("rf-edt-r-act");
                }
            },

            resetShiftRow: function () {
                if (typeof this.shiftIndex == "number") {
                    for (var i = 0; i < this.tbodies.length; i++) {
                        jQuery(this.tbodies[i].rows[this.shiftIndex]).removeClass("rf-edt-r-sht");
                    }

                }
                this.shiftIndex = null;
            },

            setShiftRow: function (index) {
                this.resetShiftRow();
                this.shiftIndex = index;
                if (typeof index == "number") {
                    for (var i = 0; i < this.tbodies.length; i++) {
                        jQuery(this.tbodies[i].rows[this.shiftIndex]).addClass("rf-edt-r-sht");
                    }
                }
            },

            initializeSelection: function() {
                this.ranges.clear();
                var strings = this.selectionInput.value.split("|");
                this.activeIndex = strings[1] || null;
                this.shiftIndex = strings[2] || null;
                this.selectionFlag = null;
                var rows = this.tbodies[0].rows;
                for (var i = 0; i < rows.length; i++) {
                    var row = jQuery(rows[i]);
                    if (row.hasClass("rf-edt-r-sel")) {
                        this.ranges.add(row[0].rowIndex)
                    }
                    if (row.hasClass("rf-edt-r-act")) {
                        this.activeIndex = row[0].rowIndex;
                    }
                    if (row.hasClass("rf-edt-r-sht")) {
                        this.shiftIndex = row[0].rowIndex;
                    }
                }
                this.writeSelection();
            },

            writeSelection: function() {
                this.selectionInput.value = [this.ranges, this.activeIndex, this.shiftIndex, this.selectionFlag].join("|");
            },

            selectRows: function(range) {
                if (typeof range == "number") {
                    range = [range, range];
                }
                var changed;
                var i = 0;
                for (; i < range[0]; i++) {
                    if (this.ranges.contains(i)) {
                        this.deselectRow(i);
                        changed = true;
                    }
                }
                for (; i <= range[1]; i++) {
                    if (!this.ranges.contains(i)) {
                        this.selectRow(i);
                        changed = true;
                    }
                }
                for (; i < this.rows; i++) {
                    if (this.ranges.contains(i)) {
                        this.deselectRow(i);
                        changed = true;
                    }
                }
                this.selectionFlag = typeof this.shiftIndex == "string" ? this.shiftIndex : "x";
                return changed;
            },

            processSlectionWithShiftKey: function(index) {
                if (this.shiftIndex == null) {
                    this.setShiftRow(this.activeIndex != null ? this.activeIndex : index);
                }
                var range;
                if ("u" == this.shiftIndex) {
                    range = [0, index];
                } else if ("d" == this.shiftIndex) {
                    range = [index, this.rows - 1];
                } else if (index >= this.shiftIndex) {
                    range = [this.shiftIndex, index];
                } else {
                    range = [index, this.shiftIndex];
                }
                return this.selectRows(range);
            },

            onbeforeselectionchange: function (event) {
                return !this.options.onbeforeselectionchange || this.options.onbeforeselectionchange.call(this.element, event) != false;
            },

            onselectionchange: function (event, index, changed) {
                if (!event.shiftKey) {
                    this.resetShiftRow();
                }
                if (this.activeIndex != index) {
                    this.setActiveRow(index);
                    this.showActiveRow();
                }
                if (changed) {
                    this.writeSelection();
                    if (this.options.onselectionchange) {
                        this.options.onselectionchange.call(this.element, event);
                    }
                }
            },

            selectionClickListener: function (event) {
                if (!this.onbeforeselectionchange(event)) {
                    return;
                }
                var changed;
                if (event.shiftKey || event.ctrlKey) {
                    if (window.getSelection) { //TODO Try to find other way.
                        window.getSelection().removeAllRanges();
                    } else if (document.selection) {
                        document.selection.empty();
                    }
                }
                var tr = event.target;
                while (this.tbodies.index(tr.parentNode) == -1) {
                    tr = tr.parentNode;
                }
                var index = tr.rowIndex;
                if (this.options.selectionMode == "single" || (this.options.selectionMode != "multipleKeyboardFree"
                    && !event.shiftKey && !event.ctrlKey)) {
                    changed = this.selectRows(index);
                } else if (this.options.selectionMode == "multipleKeyboardFree" || (!event.shiftKey && event.ctrlKey)) {
                    if (this.ranges.contains(index)) {
                        this.deselectRow(index);
                    } else {
                        this.selectRow(index);
                    }
                    changed = true;
                } else {
                    changed = this.processSlectionWithShiftKey(index);
                }
                this.onselectionchange(event, index, changed);
            },

            selectionKeyDownListener: function(event) {
                if (event.ctrlKey && this.options.selectionMode != "single" && (event.keyCode == 65 || event.keyCode == 97) //Ctrl-A
                    && this.onbeforeselectionchange(event)) {
                    this.selectRows([0, rows]);
                    this.selectionFlag = "a";
                    this.onselectionchange(event, this.activeIndex, true); //TODO Is there a way to know that selection haven't changed?
                    event.preventDefault();
                } else {
                    var index;
                    if (event.keyCode == 38) { //UP
                        index = -1;
                    } else if (event.keyCode == 40) { //DOWN
                        index = 1;
                    }
                    if (index != null && this.onbeforeselectionchange(event)) {
                        if (typeof this.activeIndex == "number") {
                            index += this.activeIndex;
                            if (index >= 0 && index < this.rows) {
                                var changed;
                                if (this.options.selectionMode == "single" || (!event.shiftKey && !event.ctrlKey)) {
                                    changed = this.selectRows(index);
                                } else if (event.shiftKey) {
                                    changed = this.processSlectionWithShiftKey(index);
                                }
                                this.onselectionchange(event, index, changed);
                            }
                        }
                        event.preventDefault();
                    }
                }
            },

            ajaxComplete: function (event, data) {
                this.storeDomReferences();
                if (data.reinitializeHeader) {
                    this.bindHeaderHandlers();
                    this.updateLayout();
                } else {
                    this.selectionInput = document.getElementById(this.id + ":si");
                    if (data.reinitializeBody) {
                        this.rowCount = data.rowCount;
                        this.initialize();
                    } else if (this.options.selectionMode != "none") {
                        this.initializeSelection();
                    }
                    if (this.spacerElement) {
                        this.spacerElement.style.height = (data.first * this.rowHeight) + "px";
                    }
                }
            },

            activateResizeListener: function() {
                $(window).on(this.resizeEventName, jQuery.proxy(this.updateLayout, this));
            },

            deActivateResizeListener: function() {
                $(window).off(this.resizeEventName);
            },

            contextMenuAttach: function (menu) {
                var selector = "[id='" + this.element.id + "'] ";
                selector += (typeof menu.options.targetSelector === 'undefined')
                    ?  ".rf-edt-b td" : menu.options.targetSelector;
                selector = jQuery.trim(selector);
                richfaces.Event.bind(selector, menu.options.showEvent, $.proxy(menu.__showHandler, menu), menu);
            },

            contextMenuShow: function (menu, event) {
                var tr = event.target;
                while (this.tbodies.index(tr.parentNode) == -1) {
                    tr = tr.parentNode;
                }
                var index = tr.rowIndex;
                if (! this.ranges.contains(index) ) {
                    this.selectionClickListener(event);
                }
            }
        });

    var $super = richfaces.ui.ExtendedDataTable.$super;
}(window.RichFaces, jQuery));;(function ($, richfaces) {

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.CollapsibleSubTableToggler = function(id, options) {
        this.id = id;
        this.eventName = options.eventName;
        this.expandedControl = options.expandedControl;
        this.collapsedControl = options.collapsedControl;
        this.forId = options.forId;
        this.element = $(document.getElementById(this.id));

        if (this.element && this.eventName) {
            this.element.bind(this.eventName, $.proxy(this.switchState, this));
        }
    };

    $.extend(richfaces.ui.CollapsibleSubTableToggler.prototype, (function () {

        var getElementById = function(id) {
            return $(document.getElementById(id))
        }

        return {

            switchState: function(e) {
                var subtable = richfaces.$(this.forId);
                if (subtable) {
                    var mode = subtable.getMode();

                    if (richfaces.ui.CollapsibleSubTable.MODE_CLNT == mode) {
                        this.toggleControl(subtable.isExpanded());
                    }

                    subtable.setOption(this.id);
                    subtable.switchState(e);
                }
            },

            toggleControl: function(collapse) {
                var expandedControl = getElementById(this.expandedControl);
                var collapsedControl = getElementById(this.collapsedControl);

                if (collapse) {
                    expandedControl.hide();
                    collapsedControl.show();
                } else {
                    collapsedControl.hide();
                    expandedControl.show();
                }
            }
        };
    })());

})(jQuery, window.RichFaces);;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
(function(richfaces, jQuery) {

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.FileUpload = function(id, options) {
        this.id = id;
        this.items = [];
        this.submitedItems = [];

        jQuery.extend(this, options);
        if (this.acceptedTypes) {
            this.acceptedTypes = jQuery.trim(this.acceptedTypes).toUpperCase().split(/\s*,\s*/);
        }
        if (this.maxFilesQuantity) {
            this.maxFilesQuantity = parseInt(jQuery.trim(this.maxFilesQuantity));
        }
        this.element = jQuery(this.attachToDom());
        this.form = this.element.parents("form:first");
        var header = this.element.children(".rf-fu-hdr:first");
        var leftButtons = header.children(".rf-fu-btns-lft:first");
        this.addButton = leftButtons.children(".rf-fu-btn-add:first");
        this.uploadButton = this.addButton.next();
        this.clearButton = leftButtons.next().children(".rf-fu-btn-clr:first");
        this.inputContainer = this.addButton.find(".rf-fu-inp-cntr:first");
        this.input = this.inputContainer.children("input");
        this.list = header.next();
        this.hiddenContainer = this.list.next();
        this.iframe = this.hiddenContainer.children("iframe:first");
        this.progressBarElement = this.iframe.next();
        this.progressBar = richfaces.$(this.progressBarElement);
        this.cleanInput = this.input.clone();
        this.addProxy = jQuery.proxy(this.__addItem, this);
        this.input.change(this.addProxy);
        this.addButton.mousedown(pressButton).mouseup(unpressButton).mouseout(unpressButton);
        this.uploadButton.click(jQuery.proxy(this.__startUpload, this)).mousedown(pressButton)
            .mouseup(unpressButton).mouseout(unpressButton);
        this.clearButton.click(jQuery.proxy(this.__removeAllItems, this)).mousedown(pressButton)
            .mouseup(unpressButton).mouseout(unpressButton);
        this.iframe.load(jQuery.proxy(this.__load, this));
        if (this.onfilesubmit) {
            richfaces.Event.bind(this.element, "onfilesubmit", new Function("event", this.onfilesubmit));
        }
        if (this.ontyperejected) {
            richfaces.Event.bind(this.element, "ontyperejected", new Function("event", this.ontyperejected));
        }
        if (this.onuploadcomplete) {
            richfaces.Event.bind(this.element, "onuploadcomplete", new Function("event", this.onuploadcomplete));
        }
        if (this.onclear) {
            richfaces.Event.bind(this.element, "onclear", new Function("event", this.onclear));
        }
        if (this.onfileselect) {
            richfaces.Event.bind(this.element, "onfileselect", new Function("event", this.onfileselect));
        }
    }

    var UID = "rf_fu_uid";
    var UID_ALT = "rf_fu_uid_alt";
    var FAKE_PATH = "C:\\fakepath\\";
    var ITEM_HTML = '<div class="rf-fu-itm">'
        + '<span class="rf-fu-itm-lft"><span class="rf-fu-itm-lbl"/><span class="rf-fu-itm-st"/></span>'
        + '<span class="rf-fu-itm-rgh"><a href="javascript:void(0)" class="rf-fu-itm-lnk"/></span></div>';

    var ITEM_STATE = {
        NEW: "new",
        UPLOADING: "uploading",
        DONE: "done",
        SIZE_EXCEEDED: "sizeExceeded",
        STOPPED: "stopped",
        SERVER_ERROR: "serverError"
    };

    var pressButton = function(event) {
        jQuery(this).children(":first").css("background-position", "3px 3px").css("padding", "4px 4px 2px 22px");
    };

    var unpressButton = function(event) {
        jQuery(this).children(":first").css("background-position", "2px 2px").css("padding", "3px 5px 3px 21px");
    };

    richfaces.BaseComponent.extend(richfaces.ui.FileUpload);

    $.extend(richfaces.ui.FileUpload.prototype, (function () {

        return {
            name: "FileUpload",

            doneLabel: "Done",
            sizeExceededLabel: "File size is exceeded",
            stoppedLabel: "",
            serverErrorLabel: "Server error",
            clearLabel: "Clear",
            deleteLabel: "Delete",

            __addItem: function() {
                var fileName = this.input.val();
                if (!navigator.platform.indexOf("Win")) {
                    fileName = fileName.match(/[^\\]*$/)[0];
                } else {
                    if (!fileName.indexOf(FAKE_PATH)) {
                        fileName = fileName.substr(FAKE_PATH.length);
                    } else {
                        fileName = fileName.match(/[^\/]*$/)[0];
                    }
                }
                if (this.__accept(fileName) && (!this.noDuplicate || !this.__isFileAlreadyAdded(fileName))) {
                    this.input.hide();
                    this.input.unbind("change", this.addProxy);
                    var item = new Item(this, fileName);
                    this.list.append(item.getJQuery());
                    this.items.push(item);
                    this.input = this.cleanInput.clone();
                    this.inputContainer.append(this.input);
                    this.input.change(this.addProxy);
                    this.__updateButtons();
                    richfaces.Event.fire(this.element, "onfileselect", fileName);
                    if (this.immediateUpload) {
                        this.__startUpload();
                    }
                }
            },

            __removeItem: function(item) {
                this.items.splice(jQuery.inArray(item, this.items), 1);
                this.submitedItems.splice(jQuery.inArray(item, this.submitedItems), 1);
                this.__updateButtons();
                richfaces.Event.fire(this.element, "onclear", [item.model]);
            },

            __removeAllItems: function(item) {
                var itemsRemoved = [];
                for (var i in this.submitedItems) {
                    itemsRemoved.push(this.submitedItems[i].model);
                }
                for (var i in this.items) {
                    itemsRemoved.push(this.items[i].model);
                }
                this.list.empty();
                this.items.splice(0, this.items.length);
                this.submitedItems.splice(0, this.submitedItems.length);
                this.__updateButtons();
                richfaces.Event.fire(this.element, "onclear", itemsRemoved);
            },

            __updateButtons: function() {
                if (!this.loadableItem && this.list.children(".rf-fu-itm").size()) {
                    if (this.items.length) {
                        this.uploadButton.css("display", "inline-block");
                    } else {
                        this.uploadButton.hide();
                    }
                    this.clearButton.css("display", "inline-block");
                } else {
                    this.uploadButton.hide();
                    this.clearButton.hide();
                }
                if (this.maxFilesQuantity && this.__getTotalItemCount() >= this.maxFilesQuantity) {
                    this.addButton.hide();
                } else {
                    this.addButton.css("display", "inline-block");
                }
            },

            __startUpload: function() {
                this.loadableItem = this.items.shift();
                this.__updateButtons();
                this.loadableItem.startUploading();
            },

            __submit: function() {
                var encodedURLInputs = this.form.children("input[name='javax.faces.encodedURL']");
                var originalAction = encodedURLInputs.length > 0 ? encodedURLInputs.val() : this.form.attr("action");
                var originalEncoding = this.form.attr("encoding");
                var originalEnctype = this.form.attr("enctype");
                try {
                    var delimiter = originalAction.indexOf("?") == -1 ? "?" : "&";
                    this.form.attr("action", originalAction + delimiter + UID + "=" + this.loadableItem.uid);
                    this.form.attr("encoding", "multipart/form-data");
                    this.form.attr("enctype", "multipart/form-data");
                    richfaces.submitForm(this.form, {"org.richfaces.ajax.component": this.id}, this.id);
                    richfaces.Event.fire(this.element, "onfilesubmit", this.loadableItem.model);
                } finally {
                    this.form.attr("action", originalAction);
                    this.form.attr("encoding", originalEncoding);
                    this.form.attr("enctype", originalEnctype);
                    this.loadableItem.input.removeAttr("name");
                }
            },

            __load: function(event) {
                if (this.loadableItem) {
                    var contentDocument = event.target.contentWindow.document;
                    contentDocument = contentDocument.XMLDocument || contentDocument;
                    var documentElement = contentDocument.documentElement;
                    var responseStatus, id;
                    if (documentElement.tagName.toUpperCase() == "PARTIAL-RESPONSE") {
                        var errors = jQuery(documentElement).children("error");
                        responseStatus = errors.length > 0 ? ITEM_STATE.SERVER_ERROR : ITEM_STATE.DONE;
                    } else if ((id = documentElement.id) && id.indexOf(UID + this.loadableItem.uid + ":") == 0) {
                        responseStatus = id.split(":")[1];
                    }
                    if (responseStatus) {
                        var responseContext = {
                            source: this.element[0],
                            /* hack for MyFaces */
                            _mfInternal: {
                                _mfSourceControlId: this.element.attr('id')
                            }
                        };

                        responseStatus == ITEM_STATE.DONE && jsf.ajax.response({responseXML: contentDocument}, responseContext);
                        this.loadableItem.finishUploading(responseStatus);
                        this.submitedItems.push(this.loadableItem);
                        if (responseStatus == ITEM_STATE.DONE && this.items.length) {
                            this.__startUpload();
                        } else {
                            this.loadableItem = null;
                            this.__updateButtons();
                            var items = [];
                            for (var i in this.submitedItems) {
                                items.push(this.submitedItems[i].model);
                            }
                            for (var i in this.items) {
                                items.push(this.items[i].model);
                            }
                            richfaces.Event.fire(this.element, "onuploadcomplete", items);
                        }
                    }
                }
            },

            __accept: function(fileName) {
                fileName = fileName.toUpperCase();
                var result = !this.acceptedTypes;
                for (var i = 0; !result && i < this.acceptedTypes.length; i++) {
                    var extension = this.acceptedTypes[i];
                    result = fileName.indexOf(extension, fileName.length - extension.length) !== -1;
                }
                if (!result) {
                    richfaces.Event.fire(this.element, "ontyperejected", fileName);
                }
                return result;
            },

            __isFileAlreadyAdded: function(fileName) {
                var result = false;
                for (var i = 0; !result && i < this.items.length; i++) {
                    result = this.items[i].model.name == fileName;
                }
                result = result || (this.loadableItem && this.loadableItem.model.name == fileName);
                for (var i = 0; !result && i < this.submitedItems.length; i++) {
                    result = this.submitedItems[i].model.name == fileName;
                }
                return result;
            },


            __getTotalItemCount : function() {
                return this.__getItemCountByState(this.items, ITEM_STATE.NEW)
                    + this.__getItemCountByState(this.submitedItems, ITEM_STATE.DONE)
            },

            __getItemCountByState : function(items) {
                var statuses = {}
                var s = 0;
                for ( var i = 1; i < arguments.length; i++) {
                    statuses[arguments[i]] = true;
                }
                for ( var i = 0; i < items.length; i++) {
                    if (statuses[items[i].model.state]) {
                        s++;
                    }
                }
                return s;
            }
        };
    })());


    var Item = function(fileUpload, fileName) {
        this.fileUpload = fileUpload;
        this.input = fileUpload.input;
        this.model = {name: fileName, state: ITEM_STATE.NEW};
    };

    jQuery.extend(Item.prototype, {
            getJQuery: function() {
                this.element = jQuery(ITEM_HTML);
                var leftArea = this.element.children(".rf-fu-itm-lft:first");
                this.label = leftArea.children(".rf-fu-itm-lbl:first");
                this.state = this.label.nextAll(".rf-fu-itm-st:first");
                this.link = leftArea.next().children("a");
                this.label.html(this.model.name);
                this.link.html(this.fileUpload["deleteLabel"]);
                this.link.click(jQuery.proxy(this.removeOrStop, this));
                return this.element;
            },

            removeOrStop: function() {
                this.input.remove();
                this.element.remove();
                this.fileUpload.__removeItem(this);
            },

            startUploading: function() {
                this.state.css("display", "block");
                this.link.html("");
                this.input.attr("name", this.fileUpload.id);
                this.model.state = ITEM_STATE.UPLOADING;
                this.uid = Math.random();
                this.fileUpload.__submit();
                if (this.fileUpload.progressBar) {
                    this.fileUpload.progressBar.setValue(0);
                    this.state.html(this.fileUpload.progressBarElement.detach());

                    var params = {};
                    params[UID_ALT] = this.uid;
                    this.fileUpload.progressBar.enable(params);
                }
            },

            finishUploading: function(state) {
                if (this.fileUpload.progressBar) {
                    this.fileUpload.progressBar.disable();
                    this.fileUpload.hiddenContainer.append(this.fileUpload.progressBarElement.detach());
                }
                this.input.remove();
                this.state.html(this.fileUpload[state + "Label"]);
                this.link.html(this.fileUpload["clearLabel"]);
                this.model.state = state;
            }
        });
}(window.RichFaces, jQuery));
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
(function(richfaces, jQuery) {
    richfaces.ui = richfaces.ui || {};

    richfaces.ui.InputNumberSpinner = richfaces.BaseComponent.extendClass({

            name: "InputNumberSpinner",

            cycled: true,
            delay: 200,
            maxValue: 100,
            minValue: 0,
            step: 1,

            init: function (id, options) {
                $super.constructor.call(this, id);
                jQuery.extend(this, options);
                this.element = jQuery(this.attachToDom());
                this.input = this.element.children(".rf-insp-inp");

                var value = Number(this.input.val());
                if (isNaN(value)) {
                    value = this.minValue;
                }
                this.__setValue(value, null, true);

                if (!this.input.attr("disabled")) {
                    var buttonsArea = this.element.children(".rf-insp-btns");
                    this.decreaseButton = buttonsArea.children(".rf-insp-dec");
                    this.increaseButton = buttonsArea.children(".rf-insp-inc");

                    var proxy = jQuery.proxy(this.__inputHandler, this)
                    this.input.change(proxy);
                    this.input.submit(proxy);
                    this.input.submit(proxy);
                    this.input.mousewheel(jQuery.proxy(this.__mousewheelHandler, this));
                    this.input.keydown(jQuery.proxy(this.__keydownHandler, this));
                    this.decreaseButton.mousedown(jQuery.proxy(this.__decreaseHandler, this));
                    this.increaseButton.mousedown(jQuery.proxy(this.__increaseHandler, this));
                }
            },

            decrease: function (event) {
                var value = this.value - this.step;
                value = this.roundFloat(value);
                if (value < this.minValue && this.cycled) {
                    value = this.maxValue;
                }
                this.__setValue(value, event);
            },

            increase: function (event) {
                var value = this.value + this.step;
                value = this.roundFloat(value);

                if (value > this.maxValue && this.cycled) {
                    value = this.minValue;
                }
                this.__setValue(value, event);
            },

            getValue: function () {
                return this.value;
            },

            setValue: function (value, event) {
                if (!this.input.attr("disabled")) {
                    this.__setValue(value);
                }
            },

            roundFloat: function(x){
                var str = this.step.toString();
                var power = 0;
                if (!/\./.test(str)) {
                    if (this.step >= 1) {
                        return x;
                    }
                    if (/e/.test(str)) {
                        power = str.split("-")[1];
                    }
                } else {
                    power = str.length - str.indexOf(".") - 1;
                }
                var ret = x.toFixed(power);
                return parseFloat(ret);
            },

            destroy: function (event) {
                if (this.intervalId) {
                    window.clearInterval(this.intervalId);
                    this.decreaseButton.css("backgroundPosition", " 50% 40%").unbind("mouseout", this.destroy)
                        .unbind("mouseup", this.destroy);
                    this.increaseButton.css("backgroundPosition", " 50% 40%").unbind("mouseout", this.destroy)
                        .unbind("mouseup", this.destroy);
                    this.intervalId = null;
                }
                $super.destroy.call(this);
            },

            __setValue: function (value, event, skipOnchange) {
                if (!isNaN(value)) {
                    if (value > this.maxValue) {
                        value = this.maxValue;
                        this.input.val(value);
                    } else if (value < this.minValue) {
                        value = this.minValue;
                        this.input.val(value);
                    }
                    if (value != this.value) {
                        this.input.val(value);
                        this.value = value;
                        if (this.onchange && !skipOnchange) {
                            this.onchange.call(this.element[0], event);
                        }
                    }
                }
            },

            __inputHandler: function (event) {
                var value = Number(this.input.val());
                if (isNaN(value)) {
                    this.input.val(this.value);
                } else {
                    this.__setValue(value, event);
                }
            },

            __mousewheelHandler: function (event, delta, deltaX, deltaY) {
                delta = deltaX || deltaY;
                if (delta > 0) {
                    this.increase(event);
                } else if (delta < 0) {
                    this.decrease(event);
                }
                return false;
            },

            __keydownHandler: function (event) {
                if (event.keyCode == 40) { //DOWN
                    this.decrease(event);
                    event.preventDefault();
                } else if (event.keyCode == 38) { //UP
                    this.increase(event);
                    event.preventDefault();
                }
            },

            __decreaseHandler: function (event) {
                var component = this;
                component.decrease(event);
                this.intervalId = window.setInterval(function() {
                    component.decrease(event);
                }, this.delay);
                var proxy = jQuery.proxy(this.destroy, this);
                this.decreaseButton.bind("mouseup", proxy).bind("mouseout", proxy)
                    .css("backgroundPosition", "60% 60%");
                event.preventDefault();
            },

            __increaseHandler: function (event) {
                var component = this;
                component.increase(event);
                this.intervalId = window.setInterval(function() {
                    component.increase(event);
                }, this.delay);
                var proxy = jQuery.proxy(this.destroy, this);
                this.increaseButton.bind("mouseup", proxy).bind("mouseout", proxy)
                    .css("backgroundPosition", "60% 60%");
                event.preventDefault();
            }
        });

    // define super class link
    var $super = richfaces.ui.InputNumberSpinner.$super;
}(window.RichFaces, jQuery));;(function ($, richfaces) {

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.ComponentControl = richfaces.ui.ComponentControl || {};

    $.extend(richfaces.ui.ComponentControl, {

            execute: function(event, parameters) {
                var targetList = parameters.target;
                var selector = parameters.selector;
                var callback = parameters.callback;

                if (parameters.onbeforeoperation && typeof parameters.onbeforeoperation == "function") {
                    var result = parameters.onbeforeoperation(event);
                    if (result == "false" || result == 0) return;
                }

                if (targetList) {
                    for (var i = 0; i < targetList.length; i++) {
                        var component = document.getElementById(targetList[i]);
                        if (component) {
                            richfaces.ui.ComponentControl.invokeOnComponent(event, component, callback);
                        }
                    }
                }

                if (selector) {
                    richfaces.ui.ComponentControl.invokeOnComponent(event, selector, callback);
                }
            },

            invokeOnComponent : function(event, target, callback) {
                if (callback && typeof callback == 'function') {
                    $(target).each(function() {
                        var component = richfaces.$(this);
                        if (component) {
                            callback(event, component);
                        }
                    });
                }
            }
        });

})(jQuery, window.RichFaces);;(function (richfaces) {

    richfaces.Selection = richfaces.Selection || {};

    richfaces.Selection.set = function (field, start, end) {
        if (field.setSelectionRange) {
            field.focus();
            field.setSelectionRange(start, end);
        } else if (field.createTextRange) {
            var range = field.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', start);
            range.select();
        }
    }

    richfaces.Selection.getStart = function(field) {
        if (field.setSelectionRange) {
            return field.selectionStart;
        } else if (document.selection && document.selection.createRange) {
            var r = document.selection.createRange().duplicate();
            r.moveEnd('character', field.value.length);
            if (r.text == '') return field.value.length;
            return field.value.lastIndexOf(r.text);
        }
    }

    richfaces.Selection.getEnd = function(field) {
        if (field.setSelectionRange) {
            return field.selectionEnd;
        } else if (document.selection && document.selection.createRange) {
            var r = document.selection.createRange().duplicate();
            r.moveStart('character', -field.value.length);
            return r.text.length;
        }
    }

    richfaces.Selection.setCaretTo = function (field, pos) {
        if (!pos) pos = field.value.length;
        richfaces.Selection.set(field, pos, pos);
    }
})(window.RichFaces || (window.RichFaces = {}));;/*
 * jQuery UI Effects 1.8.5
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/
 */
;jQuery.effects || (function($, undefined) {

$.effects = {};



/******************************************************************************/
/****************************** COLOR ANIMATIONS ******************************/
/******************************************************************************/

// override the animation for color styles
$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
	'borderRightColor', 'borderTopColor', 'color', 'outlineColor'],
function(i, attr) {
	$.fx.step[attr] = function(fx) {
		if (!fx.colorInit) {
			fx.start = getColor(fx.elem, attr);
			fx.end = getRGB(fx.end);
			fx.colorInit = true;
		}

		fx.elem.style[attr] = 'rgb(' +
			Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
			Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
			Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
	};
});

// Color Conversion functions from highlightFade
// By Blair Mitchelmore
// http://jquery.offput.ca/highlightFade/

// Parse strings looking for color tuples [255,255,255]
function getRGB(color) {
		var result;

		// Check if we're already dealing with an array of colors
		if ( color && color.constructor == Array && color.length == 3 )
				return color;

		// Look for rgb(num,num,num)
		if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
				return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];

		// Look for rgb(num%,num%,num%)
		if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
				return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];

		// Look for #a0b1c2
		if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
				return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];

		// Look for #fff
		if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
				return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];

		// Look for rgba(0, 0, 0, 0) == transparent in Safari 3
		if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
				return colors['transparent'];

		// Otherwise, we're most likely dealing with a named color
		return colors[$.trim(color).toLowerCase()];
}

function getColor(elem, attr) {
		var color;

		do {
				color = $.curCSS(elem, attr);

				// Keep going until we find an element that has color, or we hit the body
				if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
						break;

				attr = "backgroundColor";
		} while ( elem = elem.parentNode );

		return getRGB(color);
};

// Some named colors to work with
// From Interface by Stefan Petre
// http://interface.eyecon.ro/

var colors = {
	aqua:[0,255,255],
	azure:[240,255,255],
	beige:[245,245,220],
	black:[0,0,0],
	blue:[0,0,255],
	brown:[165,42,42],
	cyan:[0,255,255],
	darkblue:[0,0,139],
	darkcyan:[0,139,139],
	darkgrey:[169,169,169],
	darkgreen:[0,100,0],
	darkkhaki:[189,183,107],
	darkmagenta:[139,0,139],
	darkolivegreen:[85,107,47],
	darkorange:[255,140,0],
	darkorchid:[153,50,204],
	darkred:[139,0,0],
	darksalmon:[233,150,122],
	darkviolet:[148,0,211],
	fuchsia:[255,0,255],
	gold:[255,215,0],
	green:[0,128,0],
	indigo:[75,0,130],
	khaki:[240,230,140],
	lightblue:[173,216,230],
	lightcyan:[224,255,255],
	lightgreen:[144,238,144],
	lightgrey:[211,211,211],
	lightpink:[255,182,193],
	lightyellow:[255,255,224],
	lime:[0,255,0],
	magenta:[255,0,255],
	maroon:[128,0,0],
	navy:[0,0,128],
	olive:[128,128,0],
	orange:[255,165,0],
	pink:[255,192,203],
	purple:[128,0,128],
	violet:[128,0,128],
	red:[255,0,0],
	silver:[192,192,192],
	white:[255,255,255],
	yellow:[255,255,0],
	transparent: [255,255,255]
};



/******************************************************************************/
/****************************** CLASS ANIMATIONS ******************************/
/******************************************************************************/

var classAnimationActions = ['add', 'remove', 'toggle'],
	shorthandStyles = {
		border: 1,
		borderBottom: 1,
		borderColor: 1,
		borderLeft: 1,
		borderRight: 1,
		borderTop: 1,
		borderWidth: 1,
		margin: 1,
		padding: 1
	};

function getElementStyles() {
	var style = document.defaultView
			? document.defaultView.getComputedStyle(this, null)
			: this.currentStyle,
		newStyle = {},
		key,
		camelCase;

	// webkit enumerates style porperties
	if (style && style.length && style[0] && style[style[0]]) {
		var len = style.length;
		while (len--) {
			key = style[len];
			if (typeof style[key] == 'string') {
				camelCase = key.replace(/\-(\w)/g, function(all, letter){
					return letter.toUpperCase();
				});
				newStyle[camelCase] = style[key];
			}
		}
	} else {
		for (key in style) {
			if (typeof style[key] === 'string') {
				newStyle[key] = style[key];
			}
		}
	}
	
	return newStyle;
}

function filterStyles(styles) {
	var name, value;
	for (name in styles) {
		value = styles[name];
		if (
			// ignore null and undefined values
			value == null ||
			// ignore functions (when does this occur?)
			$.isFunction(value) ||
			// shorthand styles that need to be expanded
			name in shorthandStyles ||
			// ignore scrollbars (break in IE)
			(/scrollbar/).test(name) ||

			// only colors or values that can be converted to numbers
			(!(/color/i).test(name) && isNaN(parseFloat(value)))
		) {
			delete styles[name];
		}
	}
	
	return styles;
}

function styleDifference(oldStyle, newStyle) {
	var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
		name;

	for (name in newStyle) {
		if (oldStyle[name] != newStyle[name]) {
			diff[name] = newStyle[name];
		}
	}

	return diff;
}

$.effects.animateClass = function(value, duration, easing, callback) {
	if ($.isFunction(easing)) {
		callback = easing;
		easing = null;
	}

	return this.each(function() {

		var that = $(this),
			originalStyleAttr = that.attr('style') || ' ',
			originalStyle = filterStyles(getElementStyles.call(this)),
			newStyle,
			className = that.attr('className');

		$.each(classAnimationActions, function(i, action) {
			if (value[action]) {
				that[action + 'Class'](value[action]);
			}
		});
		newStyle = filterStyles(getElementStyles.call(this));
		that.attr('className', className);

		that.animate(styleDifference(originalStyle, newStyle), duration, easing, function() {
			$.each(classAnimationActions, function(i, action) {
				if (value[action]) { that[action + 'Class'](value[action]); }
			});
			// work around bug in IE by clearing the cssText before setting it
			if (typeof that.attr('style') == 'object') {
				that.attr('style').cssText = '';
				that.attr('style').cssText = originalStyleAttr;
			} else {
				that.attr('style', originalStyleAttr);
			}
			if (callback) { callback.apply(this, arguments); }
		});
	});
};

$.fn.extend({
	_addClass: $.fn.addClass,
	addClass: function(classNames, speed, easing, callback) {
		return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
	},

	_removeClass: $.fn.removeClass,
	removeClass: function(classNames,speed,easing,callback) {
		return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
	},

	_toggleClass: $.fn.toggleClass,
	toggleClass: function(classNames, force, speed, easing, callback) {
		if ( typeof force == "boolean" || force === undefined ) {
			if ( !speed ) {
				// without speed parameter;
				return this._toggleClass(classNames, force);
			} else {
				return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
			}
		} else {
			// without switch parameter;
			return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
		}
	},

	switchClass: function(remove,add,speed,easing,callback) {
		return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
	}
});



/******************************************************************************/
/*********************************** EFFECTS **********************************/
/******************************************************************************/

$.extend($.effects, {
	version: "1.8.5",

	// Saves a set of properties in a data storage
	save: function(element, set) {
		for(var i=0; i < set.length; i++) {
			if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
		}
	},

	// Restores a set of previously saved properties from a data storage
	restore: function(element, set) {
		for(var i=0; i < set.length; i++) {
			if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
		}
	},

	setMode: function(el, mode) {
		if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
		return mode;
	},

	getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
		// this should be a little more flexible in the future to handle a string & hash
		var y, x;
		switch (origin[0]) {
			case 'top': y = 0; break;
			case 'middle': y = 0.5; break;
			case 'bottom': y = 1; break;
			default: y = origin[0] / original.height;
		};
		switch (origin[1]) {
			case 'left': x = 0; break;
			case 'center': x = 0.5; break;
			case 'right': x = 1; break;
			default: x = origin[1] / original.width;
		};
		return {x: x, y: y};
	},

	// Wraps the element around a wrapper that copies position properties
	createWrapper: function(element) {

		// if the element is already wrapped, return it
		if (element.parent().is('.ui-effects-wrapper')) {
			return element.parent();
		}

		// wrap the element
		var props = {
				width: element.outerWidth(true),
				height: element.outerHeight(true),
				'float': element.css('float')
			},
			wrapper = $('<div></div>')
				.addClass('ui-effects-wrapper')
				.css({
					fontSize: '100%',
					background: 'transparent',
					border: 'none',
					margin: 0,
					padding: 0
				});

		element.wrap(wrapper);
		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element

		// transfer positioning properties to the wrapper
		if (element.css('position') == 'static') {
			wrapper.css({ position: 'relative' });
			element.css({ position: 'relative' });
		} else {
			$.extend(props, {
				position: element.css('position'),
				zIndex: element.css('z-index')
			});
			$.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
				props[pos] = element.css(pos);
				if (isNaN(parseInt(props[pos], 10))) {
					props[pos] = 'auto';
				}
			});
			element.css({position: 'relative', top: 0, left: 0 });
		}

		return wrapper.css(props).show();
	},

	removeWrapper: function(element) {
		if (element.parent().is('.ui-effects-wrapper'))
			return element.parent().replaceWith(element);
		return element;
	},

	setTransition: function(element, list, factor, value) {
		value = value || {};
		$.each(list, function(i, x){
			unit = element.cssUnit(x);
			if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
		});
		return value;
	}
});


function _normalizeArguments(effect, options, speed, callback) {
	// shift params for method overloading
	if (typeof effect == 'object') {
		callback = options;
		speed = null;
		options = effect;
		effect = options.effect;
	}
	if ($.isFunction(options)) {
		callback = options;
		speed = null;
		options = {};
	}
        if (typeof options == 'number' || $.fx.speeds[options]) {
		callback = speed;
		speed = options;
		options = {};
	}
	if ($.isFunction(speed)) {
		callback = speed;
		speed = null;
	}

	options = options || {};

	speed = speed || options.duration;
	speed = $.fx.off ? 0 : typeof speed == 'number'
		? speed : $.fx.speeds[speed] || $.fx.speeds._default;

	callback = callback || options.complete;

	return [effect, options, speed, callback];
}

$.fn.extend({
	effect: function(effect, options, speed, callback) {
		var args = _normalizeArguments.apply(this, arguments),
			// TODO: make effects takes actual parameters instead of a hash
			args2 = {
				options: args[1],
				duration: args[2],
				callback: args[3]
			},
			effectMethod = $.effects[effect];
		
		return effectMethod && !$.fx.off ? effectMethod.call(this, args2) : this;
	},

	_show: $.fn.show,
	show: function(speed) {
		if (!speed || typeof speed == 'number' || $.fx.speeds[speed] || !$.effects[speed] ) {
			return this._show.apply(this, arguments);
		} else {
			var args = _normalizeArguments.apply(this, arguments);
			args[1].mode = 'show';
			return this.effect.apply(this, args);
		}
	},

	_hide: $.fn.hide,
	hide: function(speed) {
		if (!speed || typeof speed == 'number' || $.fx.speeds[speed] || !$.effects[speed] ) {
			return this._hide.apply(this, arguments);
		} else {
			var args = _normalizeArguments.apply(this, arguments);
			args[1].mode = 'hide';
			return this.effect.apply(this, args);
		}
	},

	// jQuery core overloads toggle and creates _toggle
	__toggle: $.fn.toggle,
	toggle: function(speed) {
		if (!speed || typeof speed == 'number' || $.fx.speeds[speed] || !$.effects[speed]  ||
			typeof speed == 'boolean' || $.isFunction(speed)) {
			return this.__toggle.apply(this, arguments);
		} else {
			var args = _normalizeArguments.apply(this, arguments);
			args[1].mode = 'toggle';
			return this.effect.apply(this, args);
		}
	},

	// helper functions
	cssUnit: function(key) {
		var style = this.css(key), val = [];
		$.each( ['em','px','%','pt'], function(i, unit){
			if(style.indexOf(unit) > 0)
				val = [parseFloat(style), unit];
		});
		return val;
	}
});



/******************************************************************************/
/*********************************** EASING ***********************************/
/******************************************************************************/

/*
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - jQuery Easing
 *
 * Open source under the BSD License.
 *
 * Copyright 2008 George McGinley Smith
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 *
 * Neither the name of the author nor the names of contributors may be used to endorse
 * or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
$.easing.jswing = $.easing.swing;

$.extend($.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		//alert($.easing.default);
		return $.easing[$.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});

/*
 *
 * TERMS OF USE - EASING EQUATIONS
 *
 * Open source under the BSD License.
 *
 * Copyright 2001 Robert Penner
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 *
 * Neither the name of the author nor the names of contributors may be used to endorse
 * or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

})(jQuery);
;/*
 * jQuery Pines Notify (pnotify) Plugin 1.0.2-richfaces
 *
 * Copyright (c) 2009-2011 Hunter Perrin
 *
 * Triple license under the GPL, LGPL, and MPL:
 *    http://www.gnu.org/licenses/gpl.html
 *    http://www.gnu.org/licenses/lgpl.html
 *    http://www.mozilla.org/MPL/MPL-1.1.html
 *    
 * Modified by: RichFaces team
 */

(function($) {
    var history_handle_top, timer;
    var body;
    var jwindow;
    $.extend({
        pnotify_remove_all: function () {
            var body_data = body.data("pnotify");
            /* POA: Added null-check */
            if (body_data && body_data.length) {
                $.each(body_data, function() {
                    if (this.pnotify_remove)
                        this.pnotify_remove();
                });
            }
        },
        pnotify_position_all: function () {
            if (timer)
                clearTimeout(timer);
            timer = null;
            var body_data = body.data("pnotify");
            if (!body_data || !body_data.length)
                return;
            $.each(body_data, function() {
                var s = this.opts.pnotify_stack;
                if (!s) return;
                if (!s.nextpos1)
                    s.nextpos1 = s.firstpos1;
                if (!s.nextpos2)
                    s.nextpos2 = s.firstpos2;
                if (!s.addpos2)
                    s.addpos2 = 0;
                if (this.css("display") != "none") {
                    var curpos1, curpos2;
                    var animate = {};
                    // Calculate the current pos1 value.
                    var csspos1;
                    switch (s.dir1) {
                        case "down":
                            csspos1 = "top";
                            break;
                        case "up":
                            csspos1 = "bottom";
                            break;
                        case "left":
                            csspos1 = "right";
                            break;
                        case "right":
                            csspos1 = "left";
                            break;
                    }
                    curpos1 = parseInt(this.css(csspos1));
                    if (isNaN(curpos1))
                        curpos1 = 0;
                    // Remember the first pos1, so the first visible notice goes there.
                    if (typeof s.firstpos1 == "undefined") {
                        s.firstpos1 = curpos1;
                        s.nextpos1 = s.firstpos1;
                    }
                    // Calculate the current pos2 value.
                    var csspos2;
                    switch (s.dir2) {
                        case "down":
                            csspos2 = "top";
                            break;
                        case "up":
                            csspos2 = "bottom";
                            break;
                        case "left":
                            csspos2 = "right";
                            break;
                        case "right":
                            csspos2 = "left";
                            break;
                    }
                    curpos2 = parseInt(this.css(csspos2));
                    if (isNaN(curpos2))
                        curpos2 = 0;
                    // Remember the first pos2, so the first visible notice goes there.
                    if (typeof s.firstpos2 == "undefined") {
                        s.firstpos2 = curpos2;
                        s.nextpos2 = s.firstpos2;
                    }
                    // Check that it's not beyond the viewport edge.
                    if ((s.dir1 == "down" && s.nextpos1 + this.height() > jwindow.height()) ||
                            (s.dir1 == "up" && s.nextpos1 + this.height() > jwindow.height()) ||
                            (s.dir1 == "left" && s.nextpos1 + this.width() > jwindow.width()) ||
                            (s.dir1 == "right" && s.nextpos1 + this.width() > jwindow.width())) {
                        // If it is, it needs to go back to the first pos1, and over on pos2.
                        s.nextpos1 = s.firstpos1;
                        s.nextpos2 += s.addpos2 + 10;
                        s.addpos2 = 0;
                    }
                    // Animate if we're moving on dir2.
                    if (s.animation && s.nextpos2 < curpos2) {
                        switch (s.dir2) {
                            case "down":
                                animate.top = s.nextpos2 + "px";
                                break;
                            case "up":
                                animate.bottom = s.nextpos2 + "px";
                                break;
                            case "left":
                                animate.right = s.nextpos2 + "px";
                                break;
                            case "right":
                                animate.left = s.nextpos2 + "px";
                                break;
                        }
                    } else
                        this.css(csspos2, s.nextpos2 + "px");
                    // Keep track of the widest/tallest notice in the column/row, so we can push the next column/row.
                    switch (s.dir2) {
                        case "down":
                        case "up":
                            if (this.outerHeight(true) > s.addpos2)
                                s.addpos2 = this.height();
                            break;
                        case "left":
                        case "right":
                            if (this.outerWidth(true) > s.addpos2)
                                s.addpos2 = this.width();
                            break;
                    }
                    // Move the notice on dir1.
                    if (s.nextpos1) {
                        // Animate if we're moving toward the first pos.
                        if (s.animation && (curpos1 > s.nextpos1 || animate.top || animate.bottom || animate.right || animate.left)) {
                            switch (s.dir1) {
                                case "down":
                                    animate.top = s.nextpos1 + "px";
                                    break;
                                case "up":
                                    animate.bottom = s.nextpos1 + "px";
                                    break;
                                case "left":
                                    animate.right = s.nextpos1 + "px";
                                    break;
                                case "right":
                                    animate.left = s.nextpos1 + "px";
                                    break;
                            }
                        } else
                            this.css(csspos1, s.nextpos1 + "px");
                    }
                    if (animate.top || animate.bottom || animate.right || animate.left)
                        this.animate(animate, {duration: 500, queue: false});
                    // Calculate the next dir1 position.
                    switch (s.dir1) {
                        case "down":
                        case "up":
                            s.nextpos1 += this.height() + 10;
                            break;
                        case "left":
                        case "right":
                            s.nextpos1 += this.width() + 10;
                            break;
                    }
                }
            });
            // Reset the next position data.
            $.each(body_data, function() {
                var s = this.opts.pnotify_stack;
                if (!s) return;
                s.nextpos1 = s.firstpos1;
                s.nextpos2 = s.firstpos2;
                s.addpos2 = 0;
                s.animation = true;
            });
        },
        pnotify: function(options) {
            if (!body)
                body = $("body");
            if (!jwindow)
                jwindow = $(window);

            var animating;

            // Build main options.
            var opts;
            if (typeof options != "object") {
                opts = $.extend({}, $.pnotify.defaults);
                opts.pnotify_text = options;
            } else {
                opts = $.extend({}, $.pnotify.defaults, options);
                if (opts['pnotify_animation'] instanceof Object) {
                    opts['pnotify_animation'] = $.extend({
                        effect_in:$.pnotify.defaults.pnotify_animation,
                        effect_out:$.pnotify.defaults.pnotify_animation
                    }, opts['pnotify_animation']);
                }
            }

            if (opts.pnotify_before_init) {
                if (opts.pnotify_before_init(opts) === false)
                    return null;
            }

            // This keeps track of the last element the mouse was over, so
            // mouseleave, mouseenter, etc can be called.
            var nonblock_last_elem;
            // This is used to pass events through the notice if it is non-blocking.
            var nonblock_pass = function(e, e_name) {
                pnotify.css("display", "none");
                var element_below = document.elementFromPoint(e.clientX, e.clientY);
                pnotify.css("display", "block");
                var jelement_below = $(element_below);
                var cursor_style = jelement_below.css("cursor");
                pnotify.css("cursor", cursor_style != "auto" ? cursor_style : "default");
                // If the element changed, call mouseenter, mouseleave, etc.
                if (!nonblock_last_elem || nonblock_last_elem.get(0) != element_below) {
                    if (nonblock_last_elem) {
                        dom_event.call(nonblock_last_elem.get(0), "mouseleave", e.originalEvent);
                        dom_event.call(nonblock_last_elem.get(0), "mouseout", e.originalEvent);
                    }
                    dom_event.call(element_below, "mouseenter", e.originalEvent);
                    dom_event.call(element_below, "mouseover", e.originalEvent);
                }
                dom_event.call(element_below, e_name, e.originalEvent);
                // Remember the latest element the mouse was over.
                nonblock_last_elem = jelement_below;
            };

            // Create our widget.
            // Stop animation, reset the removal timer, and show the close
            // button when the user mouses over.
            var pnotify = $("<div />", {
                "class": "rf-ntf " + opts.pnotify_addclass,
                "css": {"display": "none"},
                "mouseenter": function(e) {
                    if (opts.pnotify_nonblock) e.stopPropagation();
                    if (opts.pnotify_mouse_reset && animating == "out") {
                        // If it's animating out, animate back in really quick.
                        pnotify.stop(true);
                        animating = "in";
                        pnotify.css("height", "auto").animate({"width": opts.pnotify_width, "opacity": opts.pnotify_nonblock ? opts.pnotify_nonblock_opacity : opts.pnotify_opacity}, "fast");
                    }
                    if (opts.pnotify_nonblock) {
                        // If it's non-blocking, animate to the other opacity.
                        pnotify.animate({"opacity": opts.pnotify_nonblock_opacity}, "fast");
                    }
                    if (opts.pnotify_hide && opts.pnotify_mouse_reset) pnotify.pnotify_cancel_remove();
                    //                    Do not update
                    if (opts.pnotify_closer && !opts.pnotify_nonblock) pnotify.closer.css("visibility", "visible");
                },
                "mouseleave": function(e) {
                    if (opts.pnotify_nonblock) e.stopPropagation();
                    nonblock_last_elem = null;
                    pnotify.css("cursor", "auto");
                    if (opts.pnotify_nonblock && animating != "out")
                        pnotify.animate({"opacity": opts.pnotify_opacity}, "fast");
                    if (opts.pnotify_hide && opts.pnotify_mouse_reset) pnotify.pnotify_queue_remove();
                    //                    Do not update
                    pnotify.closer.css("visibility", "hidden");
                    $.pnotify_position_all();
                },
                "mouseover": function(e) {
                    if (opts.pnotify_nonblock) e.stopPropagation();
                },
                "mouseout": function(e) {
                    if (opts.pnotify_nonblock) e.stopPropagation();
                },
                "mousemove": function(e) {
                    if (opts.pnotify_nonblock) {
                        e.stopPropagation();
                        nonblock_pass(e, "onmousemove");
                    }
                },
                "mousedown": function(e) {
                    if (opts.pnotify_nonblock) {
                        e.stopPropagation();
                        e.preventDefault();
                        nonblock_pass(e, "onmousedown");
                    }
                },
                "mouseup": function(e) {
                    if (opts.pnotify_nonblock) {
                        e.stopPropagation();
                        e.preventDefault();
                        nonblock_pass(e, "onmouseup");
                    }
                },
                "click": function(e) {
                    if (opts.pnotify_nonblock) {
                        e.stopPropagation();
                        nonblock_pass(e, "onclick");
                    }
                },
                "dblclick": function(e) {
                    if (opts.pnotify_nonblock) {
                        e.stopPropagation();
                        nonblock_pass(e, "ondblclick");
                    }
                }
            });
            pnotify.opts = opts;
            // Create a drop shadow.
            if (opts.pnotify_shadow && !$.browser.msie)
                pnotify.shadow_container = $("<div />", {"class": "rf-ntf-shdw"}).prependTo(pnotify);
            // Create a container for the notice contents.
            pnotify.container = $("<div />", {"class": "rf-ntf-cnt"})
                    .appendTo(pnotify);

            pnotify.pnotify_version = "1.0.2";

            // This function is for updating the notice.
            pnotify.pnotify = function(options) {
                // Update the notice.
                var old_opts = opts;
                if (typeof options == "string")
                    opts.pnotify_text = options;
                else
                    opts = $.extend({}, opts, options);
                pnotify.opts = opts;
                // Update the shadow.
                if (opts.pnotify_shadow != old_opts.pnotify_shadow) {
                    if (opts.pnotify_shadow && !$.browser.msie)
                        pnotify.shadow_container = $("<div />", {"class": "rf-ntf-shdw"}).prependTo(pnotify);
                    else
                        pnotify.children(".rf-ntf-shdw").remove();
                }
                // Update the additional classes.
                if (opts.pnotify_addclass === false)
                    pnotify.removeClass(old_opts.pnotify_addclass);
                else if (opts.pnotify_addclass !== old_opts.pnotify_addclass)
                    pnotify.removeClass(old_opts.pnotify_addclass).addClass(opts.pnotify_addclass);
                // Update the title.
                if (opts.pnotify_title === false)
                    pnotify.title_container.hide("fast");
                else if (opts.pnotify_title !== old_opts.pnotify_title)
                    pnotify.title_container.html(opts.pnotify_title).show(200);
                // Update the text.
                if (opts.pnotify_text === false) {
                    pnotify.text_container.hide("fast");
                } else if (opts.pnotify_text !== old_opts.pnotify_text) {
                    if (opts.pnotify_insert_brs)
                        opts.pnotify_text = opts.pnotify_text.replace(/\n/g, "<br />");
                    pnotify.text_container.html(opts.pnotify_text).show(200);
                }
                pnotify.pnotify_history = opts.pnotify_history;
                // Change the notice type.
                if (opts.pnotify_type != old_opts.pnotify_type)
                    pnotify.container.toggleClass("rf-ntf-cnt rf-ntf-cnt-hov");
                if ((opts.pnotify_notice_icon != old_opts.pnotify_notice_icon && opts.pnotify_type == "notice") ||
                        (opts.pnotify_error_icon != old_opts.pnotify_error_icon && opts.pnotify_type == "error") ||
                        (opts.pnotify_type != old_opts.pnotify_type)) {
                    // Remove any old icon.
                    pnotify.container.find("div.rf-ntf-ico").remove();
                    //					if ((opts.pnotify_error_icon && opts.pnotify_type == "error") || (opts.pnotify_notice_icon)) {
                    // Build the new icon.
                    $("<div />", {"class": "rf-ntf-ico"})
                            .append($("<span />", {"class": opts.pnotify_type == "error" ? opts.pnotify_error_icon : opts.pnotify_notice_icon}))
                            .prependTo(pnotify.container);
                    //					}
                }
                // Update the width.
                if (opts.pnotify_width !== old_opts.pnotify_width)
                    pnotify.animate({width: opts.pnotify_width});
                // Update the minimum height.
                if (opts.pnotify_min_height !== old_opts.pnotify_min_height)
                    pnotify.container.animate({minHeight: opts.pnotify_min_height});
                // Update the opacity.
                if (opts.pnotify_opacity !== old_opts.pnotify_opacity)
                    pnotify.fadeTo(opts.pnotify_animate_speed, opts.pnotify_opacity);
                if (!opts.pnotify_hide)
                    pnotify.pnotify_cancel_remove();
                else if (!old_opts.pnotify_hide)
                    pnotify.pnotify_queue_remove();
                pnotify.pnotify_queue_position();
                return pnotify;
            };

            // Queue the position function so it doesn't run repeatedly and use
            // up resources.
            pnotify.pnotify_queue_position = function() {
                if (timer)
                    clearTimeout(timer);
                timer = setTimeout($.pnotify_position_all, 10);
            };

            // Display the notice.
            pnotify.pnotify_display = function() {
                // If the notice is not in the DOM, append it.
                if (!pnotify.parent().length)
                    pnotify.appendTo(body);
                // Run callback.
                if (opts.pnotify_before_open) {
                    if (opts.pnotify_before_open(pnotify) === false)
                        return;
                }
                pnotify.pnotify_queue_position();
                // First show it, then set its opacity, then hide it.
                if (opts.pnotify_animation == "fade" || opts.pnotify_animation.effect_in == "fade") {
                    // If it's fading in, it should start at 0.
                    pnotify.show().fadeTo(0, 0).hide();
                } else {
                    // Or else it should be set to the opacity.
                    if (opts.pnotify_opacity != 1)
                        pnotify.show().fadeTo(0, opts.pnotify_opacity).hide();
                }
                pnotify.animate_in(function() {
                    if (opts.pnotify_after_open)
                        opts.pnotify_after_open(pnotify);

                    pnotify.pnotify_queue_position();

                    // Now set it to hide.
                    if (opts.pnotify_hide)
                        pnotify.pnotify_queue_remove();
                });
            };

            // Remove the notice.
            pnotify.pnotify_remove = function() {
                if (pnotify.timer) {
                    window.clearTimeout(pnotify.timer);
                    pnotify.timer = null;
                }
                // Run callback.
                if (opts.pnotify_before_close) {
                    if (opts.pnotify_before_close(pnotify) === false)
                        return;
                }
                pnotify.animate_out(function() {
                    if (opts.pnotify_after_close) {
                        if (opts.pnotify_after_close(pnotify) === false)
                            return;
                    }
                    pnotify.pnotify_queue_position();
                    // If we're supposed to remove the notice from the DOM, do it.
                    if (opts.pnotify_remove)
                        pnotify.detach();
                });
            };

            // Animate the notice in.
            pnotify.animate_in = function(callback) {
                // Declare that the notice is animating in. (Or has completed animating in.)
                animating = "in";
                var animation;
                if (typeof opts.pnotify_animation.effect_in != "undefined")
                    animation = opts.pnotify_animation.effect_in;
                else
                    animation = opts.pnotify_animation;
                if (animation == "none") {
                    pnotify.show();
                    callback();
                } else if (animation == "show")
                    pnotify.show(opts.pnotify_animate_speed, callback);
                else if (animation == "fade")
                    pnotify.show().fadeTo(opts.pnotify_animate_speed, opts.pnotify_opacity, callback);
                else if (animation == "slide")
                    pnotify.slideDown(opts.pnotify_animate_speed, callback);
                else if (typeof animation == "function")
                    animation("in", callback, pnotify);
                else if (pnotify.effect)
                    pnotify.effect(animation, {}, opts.pnotify_animate_speed, callback);
            };

            // Animate the notice out.
            pnotify.animate_out = function(callback) {
                // Declare that the notice is animating out. (Or has completed animating out.)
                animating = "out";
                var animation;
                if (typeof opts.pnotify_animation.effect_out != "undefined")
                    animation = opts.pnotify_animation.effect_out;
                else
                    animation = opts.pnotify_animation;
                if (animation == "none") {
                    pnotify.hide();
                    callback();
                } else if (animation == "show")
                    pnotify.hide(opts.pnotify_animate_speed, callback);
                else if (animation == "fade")
                    pnotify.fadeOut(opts.pnotify_animate_speed, callback);
                else if (animation == "slide")
                    pnotify.slideUp(opts.pnotify_animate_speed, callback);
                else if (typeof animation == "function")
                    animation("out", callback, pnotify);
                else if (pnotify.effect)
                    pnotify.effect(animation, {}, opts.pnotify_animate_speed, callback);
            };

            // Cancel any pending removal timer.
            pnotify.pnotify_cancel_remove = function() {
                if (pnotify.timer)
                    window.clearTimeout(pnotify.timer);
            };

            // Queue a removal timer.
            pnotify.pnotify_queue_remove = function() {
                // Cancel any current removal timer.
                pnotify.pnotify_cancel_remove();
                pnotify.timer = window.setTimeout(function() {
                    pnotify.pnotify_remove();
                }, (isNaN(opts.pnotify_delay) ? 0 : opts.pnotify_delay));
            };

            // Provide a button to close the notice.
            pnotify.closer = $("<div />", {
                "class": "rf-ntf-cls",
                "css": {"cursor": "pointer", "visibility": "hidden"},
                "click": function() {
                    pnotify.pnotify_remove();
                    //                    Do not update
                    pnotify.closer.css("visibility", "hidden");
                }
            })
                    .append($("<span />", {"class": "rf-ntf-cls-ico"}))
                    .appendTo(pnotify.container);

            // Add the appropriate icon.
            //			if ((opts.pnotify_error_icon && opts.pnotify_type == "error") || (opts.pnotify_notice_icon)) {
            $("<div />", {"class": "rf-ntf-ico"})
                    .append($("<span />", {"class": opts.pnotify_type == "error" ? opts.pnotify_error_icon : opts.pnotify_notice_icon}))
                    .appendTo(pnotify.container);
            //			}

            // Add a title.
            pnotify.title_container = $("<div />", {
                "class": "rf-ntf-sum",
                "html": opts.pnotify_title
            })
                    .appendTo(pnotify.container);
            if (opts.pnotify_title === false)
                pnotify.title_container.hide();

            // Replace new lines with HTML line breaks.
            if (opts.pnotify_insert_brs && typeof opts.pnotify_text == "string")
                opts.pnotify_text = opts.pnotify_text.replace(/\n/g, "<br />");
            // Add text.
            pnotify.text_container = $("<div />", {
                "class": "rf-ntf-det",
                "html": opts.pnotify_text
            })
                    .appendTo(pnotify.container);
            if (opts.pnotify_text === false)
                pnotify.text_container.hide();

            //Append div with clear:both class
            $("<div />", {"class":"rf-ntf-clr"}).appendTo(pnotify.container);

            // Set width and min height.
            if (typeof opts.pnotify_width == "string")
                pnotify.css("width", opts.pnotify_width);
            if (typeof opts.pnotify_min_height == "string")
                pnotify.container.css("min-height", opts.pnotify_min_height);

            // The history variable controls whether the notice gets redisplayed
            // by the history pull down.
            pnotify.pnotify_history = opts.pnotify_history;

            // Add the notice to the notice array.
            var body_data = body.data("pnotify");
            if (body_data == null || typeof body_data != "object")
                body_data = [];
            if (opts.pnotify_stack.push == "top")
                body_data = $.merge([pnotify], body_data);
            else
                body_data = $.merge(body_data, [pnotify]);
            body.data("pnotify", body_data);

            // Run callback.
            if (opts.pnotify_after_init)
                opts.pnotify_after_init(pnotify);

            if (opts.pnotify_history) {
                // If there isn't a history pull down, create one.
                var body_history = body.data("pnotify_history");
                if (typeof body_history == "undefined") {
                    body_history = $("<div />", {
                        "class": "rf-ntf-hstr",
                        "mouseleave": function() {
                            body_history.animate({top: "-" + history_handle_top + "px"}, {duration: 100, queue: false});
                        }
                    })
                            .append($("<div />", {"class": "rf-ntf-hstr-hdr", "text": "Redisplay"}))
                            .append($("<button />", {
                        "class": "rf-ntf-hstr-all",
                        "text": "All",
                        //							"mouseenter": function(){
                        //								$(this).addClass("ui-state-hover");
                        //							},
                        //							"mouseleave": function(){
                        //								$(this).removeClass("ui-state-hover");
                        //							},
                        "click": function() {
                            // Display all notices. (Disregarding non-history notices.)
                            //                            Don't change it to pnotify's new version, cause using body_data here is a bug
                            $.each(body.data("pnotify"), function() {
                                if (this.pnotify_history && this.pnotify_display)
                                    this.pnotify_display();
                            });
                            return false;
                        }
                    }))
                            .append($("<button />", {
                        "class": "rf-ntf-hstr-last",
                        "text": "Last",
                        //							"mouseenter": function(){
                        //								$(this).addClass("ui-state-hover");
                        //							},
                        //							"mouseleave": function(){
                        //								$(this).removeClass("ui-state-hover");
                        //							},
                        "click": function() {
                            // Look up the last history notice, and display it.
                            var i = 1;
                            var body_data = body.data("pnotify");
                            while (!body_data[body_data.length - i] || !body_data[body_data.length - i].pnotify_history || body_data[body_data.length - i].is(":visible")) {
                                if (body_data.length - i === 0)
                                    return false;
                                i++;
                            }
                            var n = body_data[body_data.length - i];
                            if (n.pnotify_display)
                                n.pnotify_display();
                            return false;
                        }
                    }))
                            .appendTo(body);

                    // Make a handle so the user can pull down the history pull down.
                    var handle = $("<span />", {
                        "class": "rf-ntf-hstr-hndl",
                        "mouseenter": function() {
                            body_history.animate({top: "0"}, {duration: 100, queue: false});
                        }
                    })
                            .appendTo(body_history);

                    // Get the top of the handle.
                    history_handle_top = handle.offset().top + 2;
                    // Hide the history pull down up to the top of the handle.
                    body_history.css({top: "-" + history_handle_top + "px"});
                    // Save the history pull down.
                    body.data("pnotify_history", body_history);
                }
            }

            // Mark the stack so it won't animate the new notice.
            opts.pnotify_stack.animation = false;

            // Display the notice.
            pnotify.pnotify_display();

            return pnotify;
        }
    });

    // Some useful regexes.
    var re_on = /^on/;
    var re_mouse_events = /^(dbl)?click$|^mouse(move|down|up|over|out|enter|leave)$|^contextmenu$/;
    var re_ui_events = /^(focus|blur|select|change|reset)$|^key(press|down|up)$/;
    var re_html_events = /^(scroll|resize|(un)?load|abort|error)$/;
    // Fire a DOM event.
    var dom_event = function(e, orig_e) {
        var event_object;
        e = e.toLowerCase();
        if (document.createEvent && this.dispatchEvent) {
            // FireFox, Opera, Safari, Chrome
            e = e.replace(re_on, '');
            if (e.match(re_mouse_events)) {
                // This allows the click event to fire on the notice. There is
                // probably a much better way to do it.
                $(this).offset();
                event_object = document.createEvent("MouseEvents");
                event_object.initMouseEvent(
                        e, orig_e.bubbles, orig_e.cancelable, orig_e.view, orig_e.detail,
                        orig_e.screenX, orig_e.screenY, orig_e.clientX, orig_e.clientY,
                        orig_e.ctrlKey, orig_e.altKey, orig_e.shiftKey, orig_e.metaKey, orig_e.button, orig_e.relatedTarget
                        );
            } else if (e.match(re_ui_events)) {
                event_object = document.createEvent("UIEvents");
                event_object.initUIEvent(e, orig_e.bubbles, orig_e.cancelable, orig_e.view, orig_e.detail);
            } else if (e.match(re_html_events)) {
                event_object = document.createEvent("HTMLEvents");
                event_object.initEvent(e, orig_e.bubbles, orig_e.cancelable);
            }
            if (!event_object) return;
            this.dispatchEvent(event_object);
        } else {
            // Internet Explorer
            if (!e.match(re_on)) e = "on" + e;
            event_object = document.createEventObject(orig_e);
            this.fireEvent(e, event_object);
        }
    };

    $.pnotify.defaults = {
        // The notice's title.
        pnotify_title: false,
        // The notice's text.
        pnotify_text: false,
        // Additional classes to be added to the notice. (For custom styling.)
        pnotify_addclass: "",
        // Create a non-blocking notice. It lets the user click elements underneath it.
        pnotify_nonblock: false,
        // The opacity of the notice (if it's non-blocking) when the mouse is over it.
        pnotify_nonblock_opacity: .2,
        // Display a pull down menu to redisplay previous notices, and place the notice in the history.
        pnotify_history: true,
        // Width of the notice.
        pnotify_width: "300px",
        // Minimum height of the notice. It will expand to fit content.
        pnotify_min_height: "16px",
        // Type of the notice. "notice" or "error".
        pnotify_type: "notice",
        // The icon class to use if type is notice.
        pnotify_notice_icon: "",
        // The icon class to use if type is error.
        pnotify_error_icon: "",
        // The animation to use when displaying and hiding the notice. "none", "show", "fade", and "slide" are built in to jQuery. Others require jQuery UI. Use an object with effect_in and effect_out to use different effects.
        pnotify_animation: "fade",
        // Speed at which the notice animates in and out. "slow", "def" or "normal", "fast" or number of milliseconds.
        pnotify_animate_speed: "slow",
        // Opacity of the notice.
        pnotify_opacity: 1,
        // Display a drop shadow.
        pnotify_shadow: false,
        // Provide a button for the user to manually close the notice.
        pnotify_closer: true,
        // After a delay, remove the notice.
        pnotify_hide: true,
        // Delay in milliseconds before the notice is removed.
        pnotify_delay: 8000,
        // Reset the hide timer if the mouse moves over the notice.
        pnotify_mouse_reset: true,
        // Remove the notice's elements from the DOM after it is removed.
        pnotify_remove: true,
        // Change new lines to br tags.
        pnotify_insert_brs: true,
        // The stack on which the notices will be placed. Also controls the direction the notices stack.
        pnotify_stack: {"dir1": "down", "dir2": "left", "push": "bottom"}
    };
})(jQuery);;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 * 
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */


(function ($, rf) {

    rf.ui = rf.ui || {};

    var __DEFAULT_OPTIONS = {
        disabled : false,
        selectable: true,
        unselectable: false,
        mode: "client",
        stylePrefix: "rf-pm-itm",
        itemStep: 20
    };

    var SELECT_ITEM = {

        /**
         *
         * @return {void}
         * */
        exec : function (item) {

            if (item.expanded) {
                var flag = item.options.expandEvent == item.options.collapseEvent && item.options.collapseEvent == "click";
                if (flag && item.__fireEvent("beforeswitch") == false) return false;
                if (!item.expanded()) {
                    if (item.options.expandEvent == "click" && item.__fireEvent("beforeexpand") == false) return false;
                } else {
                    if (item.options.collapseEvent == "click" && item.__fireEvent("beforecollapse") == false) return false;
                }
            }

            var mode = item.mode;
            if (mode == "server") {
                return this.execServer(item);
            } else if (mode == "ajax") {
                return this.execAjax(item);
            } else if (mode == "client" || mode == "none") {
                return this.execClient(item);
            } else {
                rf.log.error("SELECT_ITEM.exec : unknown mode (" + mode + ")");
            }
        },

        /**
         * @protected
         *
         * @return {Boolean} false
         * */
        execServer : function (item) {
            item.__changeState();
            //TODO nick - 'target' attribute?

            var params = {};
            params[item.__panelMenu().id] = item.itemName; // TODO
            params[item.id] = item.id;

            $.extend(params, item.options["ajax"]["parameters"] || {});

            rf.submitForm(this.__getParentForm(item), params);

            return false;
        },

        /**
         * @protected
         *
         * @return {Boolean} false
         * */
        execAjax : function (item) {
            var oldItem = item.__changeState();
            //TODO nick - check for interaction with queue
            rf.ajax(item.id, null, $.extend({}, item.options["ajax"], {}));
            item.__restoreState(oldItem);

            return true;
        },

        /**
         * @protected
         *
         * @return {undefined}
         *             - false - if process has been terminated
         *             - true  - in other cases
         * */
        execClient : function (item) {
            var panelMenu = item.__rfPanelMenu();
            var prevItem = panelMenu.getSelectedItem();
            if (prevItem) {
                prevItem.unselect();
            }

            panelMenu.selectedItem(item.itemName);

            item.__select();
            var result = item.__fireSelect();

            if (item.__switch) {
                var mode = item.mode;
                if (mode == "client" || mode == "none") {
                    item.__switch(!item.expanded());
                }
            }

            return result;
        },

        /**
         * @private
         * */
        __getParentForm : function (item) {
            return $($(rf.getDomElement(item.id)).parents("form")[0]);
        }
    };

    rf.ui.PanelMenuItem = rf.BaseComponent.extendClass({
            // class name
            name:"PanelMenuItem",

            /**
             * @class PanelMenuItem
             * @name PanelMenuItem
             *
             * @constructor
             * @param {String} componentId - component id
             * @param {Hash} options - params
             * */
            init : function (componentId, options) {
                $super.constructor.call(this, componentId);
                var rootElt = $(this.attachToDom());

                this.options = $.extend(this.options, __DEFAULT_OPTIONS, options || {});

                this.mode = this.options.mode;
                this.itemName = this.options.name;
                var panelMenu = this.__rfPanelMenu();
                panelMenu.addItem(this);

                // todo move it
                this.selectionClass = this.options.stylePrefix + "-sel";

                if (!this.options.disabled) {
                    var item = this;

                    if (this.options.selectable) {
                        this.__header().bind("click", function() {
                            if (item.__rfPanelMenu().selectedItem() == item.id) {
                                if (item.options.unselectable) {
                                    return item.unselect();
                                }

                                // we shouldn't select one item several times
                            } else {
                                return item.select();
                            }
                        });
                    }
                }

                item = this;
                $(this.__panelMenu()).ready(function () {
                    item.__renderNestingLevel();
                });

                this.__addUserEventHandler("select");
                this.__addUserEventHandler("beforeselect");
            },

            /***************************** Public Methods  ****************************************************************/

            selected : function () {
                return this.__header().hasClass(this.selectionClass);
            },

            /**
             * @methodOf
             * @name PanelMenuItem#select
             *
             * TODO ...
             *
             * @return {void} TODO ...
             */
            select: function () {
                var continueProcess = this.__fireBeforeSelect();
                if (!continueProcess) {
                    return false;
                }

                return SELECT_ITEM.exec(this)
            },

            /**
             * please, remove this method when client side ajax events will be added
             *
             * */
            onCompleteHandler : function () {
                SELECT_ITEM.execClient(this);
            },

            unselect: function () {
                var panelMenu = this.__rfPanelMenu();
                if (panelMenu.selectedItem() == this.itemName) {
                    panelMenu.selectedItem(null);
                } else {
                    rf.log.warn("You tried to unselect item (name=" + this.itemName + ") that isn't seleted")
                }

                this.__unselect();

                return this.__fireUnselect();
            },

            /***************************** Private Methods ****************************************************************/
            __rfParentItem : function () {
                var res = this.__item().parents(".rf-pm-gr")[0];
                if (!res) {
                    res = this.__item().parents(".rf-pm-top-gr")[0];
                }

                if (!res) {
                    res = this.__panelMenu();
                }

                return res ? rf.$(res) : null;
            },

            __getNestingLevel : function () {
                if (!this.nestingLevel) {
                    var parentItem = this.__rfParentItem();
                    if (parentItem && parentItem.__getNestingLevel) {
                        this.nestingLevel = parentItem.__getNestingLevel() + 1;
                    } else {
                        this.nestingLevel = 0;
                    }
                }

                return this.nestingLevel;
            },

            __renderNestingLevel : function () {
                this.__item().find("td").first().css("padding-left", this.options.itemStep * this.__getNestingLevel());
            },

            __panelMenu : function () {
                return this.__item().parents(".rf-pm")[0];
            },

            __rfPanelMenu : function () {
                return rf.$(this.__panelMenu());
            },

            __changeState : function () {
                return this.__rfPanelMenu().selectedItem(this.itemName);
            },

            __restoreState : function (state) {
                if (state) {
                    this.__rfPanelMenu().selectedItem(state);
                }
            },

            __item : function () {
                return $(rf.getDomElement(this.id));
            },

            __header : function () {
                return this.__item();
            },

            __isSelected: function() {
                return this.__header().hasClass(this.selectionClass);
            },

            __select: function () {
                this.__header().addClass(this.selectionClass);
            },

            __unselect: function () {
                this.__header().removeClass(this.selectionClass);
            },

            __fireBeforeSelect : function () {
                return rf.Event.fireById(this.id, "beforeselect", {
                        item: this
                    });
            },

            __fireSelect : function () {
                return rf.Event.fireById(this.id, "select", {
                        item: this
                    });
            },

            __fireUnselect : function () {
                return rf.Event.fireById(this.id, "unselect", {
                        item: this
                    });
            },

            __fireEvent : function (eventType, event) {
                return this.invokeEvent(eventType, rf.getDomElement(this.id), event, {id: this.id, item: this});
            },

            /**
             * @private
             * */
            __addUserEventHandler : function (name) {
                var handler = this.options["on" + name];
                if (handler) {
                    rf.Event.bindById(this.id, name, handler);
                }
            },

            __rfTopGroup : function () {
                var res = this.__item().parents(".rf-pm-top-gr")[0];
                return res ? res : null;
            },

            destroy: function () {
                var panelMenu = this.__rfPanelMenu();
                if (panelMenu) {
                    panelMenu.deleteItem(this);
                }

                $super.destroy.call(this);
            }
        });

    // define super class link
    var $super = rf.ui.PanelMenuItem.$super;
})(jQuery, RichFaces);
;(function ($, richfaces) {

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.PopupPanel.Border = function(id, modalPanel, cursor, sizer) {

        $super.constructor.call(this, id);

        this.element = $(richfaces.getDomElement(id));
        this.element.css('cursor', cursor);
        var border = this;
        this.element.bind('mousedown', {border:border}, this.startDrag);

        this.modalPanel = modalPanel;
        this.sizer = sizer;
    };

    var $super = richfaces.BaseComponent.extend(richfaces.ui.PopupPanel.Border);
    var $super = richfaces.ui.PopupPanel.Border.$super;

    $.extend(richfaces.ui.PopupPanel.Border.prototype, (function (options) {

        return {

            name: "RichFaces.ui.PopupPanel.Border",

            destroy: function() {
                if (this.doingDrag) {
                    $(document).unbind('mousemove', this.doDrag);
                    $(document).unbind('mouseup', this.endDrag);
                }

                this.element.unbind('mousedown', this.startDrag);
                this.element = null;
                this.modalPanel = null;
            },

            show: function() {
                this.element.show();
            },

            hide: function() {
                this.element.hide();
            },

            startDrag: function(event) {
                var border = event.data.border;
                border.doingDrag = true;

                border.dragX = event.clientX;
                border.dragY = event.clientY;
                $(document).bind('mousemove', {border:border}, border.doDrag);
                $(document).bind('mouseup', {border:border}, border.endDrag);

                border.modalPanel.startDrag(border);

                border.onselectStartHandler = document.onselectstart;
                document.onselectstart = function() {
                    return false;
                }
            },

            getWindowSize : function() {
                var myWidth = 0, myHeight = 0;
                if (typeof( window.innerWidth ) == 'number') {
                    myWidth = window.innerWidth;
                    myHeight = window.innerHeight;
                } else if (document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight )) {
                    myWidth = document.documentElement.clientWidth;
                    myHeight = document.documentElement.clientHeight;
                } else if (document.body && ( document.body.clientWidth || document.body.clientHeight )) {
                    myWidth = document.body.clientWidth;
                    myHeight = document.body.clientHeight;
                }
                return {"width":myWidth,"height":myHeight};
            },

            doDrag: function(event) {
                var border = event.data.border;
                if (!border.doingDrag) {
                    return;
                }

                var evtX = event.clientX;
                var evtY = event.clientY;

                var winSize = border.getWindowSize();

                if (evtX < 0) {
                    evtX = 0;
                } else if (evtX >= winSize.width) {
                    evtX = winSize.width - 1;
                }

                if (evtY < 0) {
                    evtY = 0;
                } else if (evtY >= winSize.height) {
                    evtY = winSize.height - 1;
                }

                var dx = evtX - border.dragX;
                var dy = evtY - border.dragY;

                if (dx != 0 || dy != 0) {

                    var id = border.id;

                    var diff = border.sizer.prototype.doDiff(dx, dy);//TODO
                    var doResize;

                    var element = border.modalPanel.cdiv;

                    if (diff.deltaWidth || diff.deltaHeight) {
                        doResize = border.modalPanel.invokeEvent("resize", event, null, element);
                    } else if (diff.deltaX || diff.deltaY) {
                        doResize = border.modalPanel.invokeEvent("move", event, null, element);
                    }

                    var vetoes;

                    if (doResize) {
                        vetoes = border.modalPanel.doResizeOrMove(diff);
                    }

                    if (vetoes) {
                        if (!vetoes.x) {
                            border.dragX = evtX;
                        } else {
                            if (!diff.deltaX) {
                                border.dragX -= vetoes.vx || 0;
                            } else {
                                border.dragX += vetoes.vx || 0;
                            }
                        }

                        if (!vetoes.y) {
                            border.dragY = evtY;
                        } else {
                            if (!diff.deltaY) {
                                border.dragY -= vetoes.vy || 0;
                            } else {
                                border.dragY += vetoes.vy || 0;
                            }
                        }
                    }
                }
            },

            endDrag: function(event) {
                var border = event.data.border;
                border.doingDrag = undefined;

                $(document).unbind('mousemove', border.doDrag);
                $(document).unbind('mouseup', border.endDrag);

                border.modalPanel.endDrag(border);

                border.modalPanel.doResizeOrMove(richfaces.ui.PopupPanel.Sizer.Diff.EMPTY);

                document.onselectstart = border.onselectStartHandler;
                border.onselectStartHandler = null;
            },

            doPosition: function() {
                this.sizer.prototype.doPosition(this.modalPanel, this.element);	//TODO remove prototype
            }
        }

    })());

})(jQuery, window.RichFaces);;(function($, rf) {

    rf.ui = rf.ui || {};

    var defaultOptions = {
        useNative : false
    };

    rf.ui.Focus = rf.BaseComponent.extendClass({

        name : "Focus",

        init : function(componentId, options) {
            $super.constructor.call(this, componentId);
            options = this.options = $.extend({}, defaultOptions, options);
            this.attachToDom(this.id);

            var focusInput = $(document.getElementById(componentId + 'InputFocus'));
            var focusCandidates = this.options.focusCandidates;

            $(document).on('focus', ':tabbable', function(e) {
                var target = $(e.target);
                var ids = e.target.id || '';
                target.parents().each(function() {
                    var id = $(this).attr('id');
                    if (id) {
                        ids += ' ' + id;
                    }
                });
                focusInput.val(ids);
                rf.log.debug('Focus - clientId candidates for components: ' + ids);
            });

            if (this.options.mode === 'VIEW') {
                $(document).on('ajaxsubmit submit', 'form', function(e) {
                    var form = $(e.target);
                    var input = $("input[name='org.richfaces.focus']", form);
                    if (!input.length) {
                        input = $('<input name="org.richfaces.focus" type="hidden" />').appendTo(form);
                    }
                    input.val(focusInput.val());
                });
            }

            this.options.applyFocus = $.proxy(function() {
                var tabbables = $();

                if (focusCandidates) {
                    var candidates = focusCandidates;
                    rf.log.debug('Focus - focus candidates: ' + candidates);
                    candidates = candidates.split(' ');
                    $.each(candidates, function(i, v) {
                        var candidate = $(document.getElementById(v));
                        tabbables = tabbables.add($(":tabbable", candidate));

                        if (candidate.is(":tabbable")) {
                            tabbables = tabbables.add(candidate);
                        }
                    });

                    if (tabbables.length == 0) {
                        tabbables = $('form').has(focusInput).find(':tabbable')
                    }
                } else if (this.options.mode == 'VIEW') {
                    tabbables = $("body form:first :tabbable");
                }

                if (tabbables.length > 0) {
                    tabbables = tabbables.sort(sortTabindex);
                    tabbables.get(0).focus();
                }
            }, this);
        },

        applyFocus : function() {
            jQuery(this.options.applyFocus);
        },

        // destructor definition
        destroy : function() {
            // define destructor if additional cleaning is needed but
            // in most cases its not nessesary.
            // call parent’s destructor
            $super.destroy.call(this);
        }
    });

    /**
     * Returns the tabindex sort order of two elements based on their tabindex and position in the DOM, following real tabbing
     * order implemented by browsers.
     * 
     * Returns negative number when element A has lesser tabindex than B or it is closer the start of the DOM; returns negative
     * number when element B has lesser tabindex than A or it is closer the start of the DOM; returns 0 if both A and B points
     * to same element.
     */
    var sortTabindex = function(a, b) {
        var result = sortTabindexNums($(a).attr('tabindex'), $(b).attr('tabindex'));

        return (result != 0) ? result : sortByDOMOrder(a, b);
    };

    /**
     * Sorts two tabindex values (positive number or undefined).
     * 
     * Returns negative number when tabindex A is lesser than B; returns positive number when tabindex B is lesser than A;
     * returns 0 if both A and B has same values.
     */
    var sortTabindexNums = function(a, b) {
        if (a) {
            if (b) {
                return a - b;
            } else {
                return -1;
            }
        } else {
            if (b) {
                return +1;
            } else {
                return 0;
            }
        }
    };

    /**
     * Detects absolute order of two elements in the DOM tree.
     * 
     * Returns negative number when element A is closer the start of the DOM; returns positive number when element B is closer
     * the start of the DOM; returns 0 if both A and B points to same element
     */
    var sortByDOMOrder = function(a, b) {
        var r = searchCommonParent(a, b);
        if (a == b) {
            return 0;
        } else if (r.parent == a) {
            return -1;
        } else if (r.parent == b) {
            return +1;
        } else {
            return $(r.aPrevious).index() - $(r.bPrevious).index();
        }
    };

    /**
     * Search for common parent for two given elements.
     * 
     * returns object containing following parameters:
     * 
     * result.parent - the commnon parent for A and B result.aPrevious - the parent's direct child which is on the branch
     * leading to A in DOM tree result.bPrevious - the parent's direct child which is on the branch leading to B in DOM tree
     */
    var searchCommonParent = function(a, b) {
        var aParents = $(a).add($(a).parents()).get().reverse();
        var bParents = $(b).add($(b).parents()).get().reverse();
        var r = {
            aPrevious : a,
            bPrevious : b
        };
        $.each(aParents, function(i, ap) {
            $.each(bParents, function(j, bp) {
                if (ap == bp) {
                    r.parent = ap;
                    return false;
                }
                r.bPrevious = bp;
            });
            if (r.parent) {
                return false;
            }
            r.aPrevious = ap;
        });
        if (!r.parent) {
            return null;
        }
        return r;
    };

    /**
     * Exposes sortTabindex family of functions for testing
     */
    rf.ui.Focus.__fn = {
        'sortTabindex' : sortTabindex,
        'sortTabindexNums' : sortTabindexNums,
        'searchCommonParent' : searchCommonParent,
        'sortByDOMOrder' : sortByDOMOrder
    }

    // define super class reference - reference to the parent prototype
    var $super = rf.ui.Focus.$super;
})(jQuery, RichFaces);;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.TogglePanelItem = rf.BaseComponent.extendClass({

            // class name
            name:"TogglePanelItem",

            init : function (componentId, options) {
                $super.constructor.call(this, componentId);
                this.attachToDom(this.id);

                this.options = $.extend(this.options, options || {});
                this.name = this.options.name;
                this.togglePanelId = this.options.togglePanelId;
                this.switchMode = this.options.switchMode;
                this.disabled = this.options.disabled || false;

                this.index = options["index"];
                this.getTogglePanel().getItems()[this.index] = this;

                this.__addUserEventHandler("enter");
                this.__addUserEventHandler("leave");
            },

            /***************************** Public Methods *****************************************************************/
            /**
             * @methodOf TogglePanelItem
             * @name TogglePanelItem#getName
             *
             * @return {String} panel item name
             */
            getName: function () {
                return this.options.name;
            },

            /**
             * @methodOf
             * @name TogglePanelItem#getTogglePanel
             *
             * @return {TogglePanel} parent TogglePanel
             * */
            getTogglePanel : function () {
                return rf.$(this.togglePanelId);
            },

            /**
             * @methodOf
             * @name TogglePanelItem#isSelected
             *
             * @return {Boolean} true if this panel item is selected in the parent toggle panel
             * */
            isSelected : function () {
                return this.getName() == this.getTogglePanel().getSelectItem();
            },


            /***************************** Private Methods ****************************************************************/

            /**
             * @private
             * */
            __addUserEventHandler : function (name) {
                var handler = this.options["on" + name];
                if (handler) {
                    rf.Event.bindById(this.id, name, handler);
                }
            },

            /**
             * @private
             *
             * used in TogglePanel
             * */
            __enter : function () {
                rf.getDomElement(this.id).style.display = "block";

                return this.__fireEnter();
            },

            /**
             * @private
             *
             * used in TogglePanel
             * */
            __leave : function () {
                var continueProcess = this.__fireLeave();
                if (!continueProcess) {
                    return false;
                }

                rf.getDomElement(this.id).style.display = "none";
                return true;
            },

            __fireLeave : function () {
                return rf.Event.fireById(this.id, "leave");
            },

            __fireEnter : function () {
                return rf.Event.fireById(this.id, "enter");
            },

            // class stuff
            destroy: function () {
                var parent = this.getTogglePanel();
                if (parent) {
                    delete parent.getItems()[this.index];
                }

                $super.destroy.call(this);
            }
        });

    // define super class link
    var $super = rf.ui.TogglePanelItem.$super;
})(jQuery, RichFaces);
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    var ITEMS_SWITCHER = {

        /**
         * @param {TogglePanelItem} oldPanel
         * @param {TogglePanelItem} newPanel
         *
         * @return {void}
         * */
        exec : function (oldPanel, newPanel) {
            if (newPanel.switchMode == "server") {
                return this.execServer(oldPanel, newPanel);
            } else if (newPanel.switchMode == "ajax") {
                return this.execAjax(oldPanel, newPanel);
            } else if (newPanel.switchMode == "client") {
                return this.execClient(oldPanel, newPanel);
            } else {
                rf.log.error("SwitchItems.exec : unknown switchMode (" + newPanel.switchMode + ")");
            }
        },

        /**
         * @protected
         * @param {TogglePanelItem} oldPanel
         * @param {TogglePanelItem} newPanel
         *
         * @return {Boolean} false
         * */
        execServer : function (oldPanel, newPanel) {
            if (oldPanel) {
                var continueProcess = oldPanel.__leave();
                if (!continueProcess) {
                    return false;
                }
            }

            this.__setActiveItem(newPanel);

            var params = {};

            params[newPanel.getTogglePanel().id] = newPanel.name;
            params[newPanel.id] = newPanel.id;

            $.extend(params, newPanel.getTogglePanel().options["ajax"] || {});

            rf.submitForm(this.__getParentForm(newPanel), params);

            return false;
        },

        /**
         * @protected
         * @param {TogglePanelItem} oldPanel
         * @param {TogglePanelItem} newPanel
         *
         * @return {Boolean} false
         * */
        execAjax : function (oldPanel, newPanel) {
            var options = $.extend({}, newPanel.getTogglePanel().options["ajax"], {});

            this.__setActiveItem(newPanel);
            rf.ajax(newPanel.id, null, options);

            if (oldPanel) {
                this.__setActiveItem(oldPanel);
            }

            return false;
        },

        /**
         * @protected
         * @param {TogglePanelItem} oldPanel
         * @param {TogglePanelItem} newPanel
         *
         * @return {undefined}
         *             - false - if process has been terminated
         *             - true  - in other cases
         * */
        execClient : function (oldPanel, newPanel) {
            if (oldPanel) {
                var continueProcess = oldPanel.__leave();
                if (!continueProcess) {
                    return false;
                }
            }

            this.__setActiveItem(newPanel);

            newPanel.__enter();
            newPanel.getTogglePanel().__fireItemChange(oldPanel, newPanel);

            return true;
        },

        /**
         * @private
         * */
        __getParentForm : function (comp) {
            return $(rf.getDomElement(comp.id)).parents('form:first');
        },

        /**
         * @private
         * */
        __setActiveItem : function (item) {
            rf.getDomElement(item.togglePanelId + "-value").value = item.getName(); // todo it is should be toogle panel method
            item.getTogglePanel().activeItem = item.getName();
        }
    };


    rf.ui.TabPanel = rf.ui.TogglePanel.extendClass({
            // class name
            name:"TabPanel",

            /**
             * @class TabPanel
             * @name TabPanel
             *
             * @constructor
             * @param {String} componentId - component id
             * @param {Hash} options - params
             * */
            init : function (componentId, options) {
                rf.ui.TogglePanel.call(this, componentId, options);
                this.items = [];

                this.isKeepHeight = options["isKeepHeight"] || false
            },

            __itemsSwitcher : function () {
                return ITEMS_SWITCHER;
            }

        });
})(jQuery, RichFaces);
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
(function(jsf, richfaces, _$) {

    var COMPONENT_NAME = "Push";

    var RICH_NAMESPACE = richfaces.Event.RICH_NAMESPACE;

    var EVENT_NAMESPACE_SEPARATOR = richfaces.Event.EVENT_NAMESPACE_SEPARATOR;

    var DATA_EVENT_NAME = 'dataAvailable' + EVENT_NAMESPACE_SEPARATOR + RICH_NAMESPACE + EVENT_NAMESPACE_SEPARATOR + COMPONENT_NAME;
    
    var SUBSCRIBED_EVENT_NAME = 'subscribed' + EVENT_NAMESPACE_SEPARATOR + RICH_NAMESPACE + EVENT_NAMESPACE_SEPARATOR + COMPONENT_NAME;

    var ERROR_EVENT_NAME = 'error' + EVENT_NAMESPACE_SEPARATOR + RICH_NAMESPACE + EVENT_NAMESPACE_SEPARATOR + COMPONENT_NAME;

    var getDataEventNamespace = function(address) {
        return DATA_EVENT_NAME + EVENT_NAMESPACE_SEPARATOR + address;
    };
    
    var getSubscribedEventNamespace = function(address) {
        return SUBSCRIBED_EVENT_NAME + EVENT_NAMESPACE_SEPARATOR + address;
    };

    var getErrorEventNamespace = function(address) {
        return ERROR_EVENT_NAME + EVENT_NAMESPACE_SEPARATOR + address;
    };

    richfaces.Push = (function() {

        var addedTopics = {};

        var removedTopics = {};
        
        var subscribedTopics = {};

        var handlersCounter = {};

        var pushResourceUrl = null;

        var pushHandlerUrl = null;

        var pushSessionId = null;

        var suspendMessageEndMarker = /^(<!--[^>]+-->\s*)+/;

        var messageTokenExpr = /<([^>]*)>/g;

        var lastMessageNumber = -1;

        var qualifyUrl = function(url) {
            var result = url;

            if (url.charAt(0) == '/') {
                result = location.protocol + '//' + location.host + url;
            }

            return result;
        };

        var messageCallback = function(response) {
            var dataString = response.responseBody.replace(suspendMessageEndMarker, "");
            if (dataString) {
                var messageToken;
                while (messageToken = messageTokenExpr.exec(dataString)) {
                    if (!messageToken[1]) {
                        continue;
                    }

                    var message = _$.parseJSON('{' + messageToken[1] + '}');

                    if (message.number <= lastMessageNumber) {
                        continue;
                    }

                    richfaces.Event.fire(document, getDataEventNamespace(message.topic), message.data);
                    lastMessageNumber = message.number;
                }
            }
        };

        var connect = function() {
            var newlySubcribed = {}; 
            
            var pushSessionIdRequestHandler = function(data) {
                var subscriptionData = _$.parseJSON(data);


                for (var failedTopicKey in subscriptionData.failures) {
                    richfaces.Event.fire(
                        document,
                        getErrorEventNamespace(failedTopicKey),
                        subscriptionData.failures[failedTopicKey]
                    );
                }

                if (subscriptionData.sessionId) {
                    pushSessionId = subscriptionData.sessionId;

                    _$.atmosphere.subscribe((pushHandlerUrl || pushResourceUrl) + "?__richfacesPushAsync=1&pushSessionId=" + pushSessionId, messageCallback, {
                            transport: richfaces.Push.transport,
                            fallbackTransport: richfaces.Push.fallbackTransport,
                            logLevel: richfaces.Push.logLevel
                        });
                    
                    // fire subscribed events
                    for (var topicName in newlySubcribed) {
                        subscribedTopics[topicName] = true;
                        richfaces.Event.fire(document, getSubscribedEventNamespace(topicName));
                    }
                }
            };

            var topics = new Array();
            for (var topicName in handlersCounter) {
                topics.push(topicName);
                if (!subscribedTopics[topicName]) {
                    newlySubcribed[topicName] = true;
                }
            }

            var data = {
                "pushTopic": topics
            };

            if (pushSessionId) {
                data['forgetPushSessionId'] = pushSessionId;
            }

            //TODO handle request errors
            _$.ajax({
                    data: data,
                    dataType: 'text',
                    success: pushSessionIdRequestHandler,
                    traditional: true,
                    type: 'POST',
                    url: pushResourceUrl
                });
        };

        var disconnect = function() {
            _$.atmosphere.unsubscribe();
        };

        return {
            increaseSubscriptionCounters: function(address) {
                if (isNaN(handlersCounter[address]++)) {
                    handlersCounter[address] = 1;
                    addedTopics[address] = true;
                }
            },

            decreaseSubscriptionCounters: function(address) {
                if (--handlersCounter[address] == 0) {
                    delete handlersCounter[address];
                    removedTopics[address] = true;
                    subscribedTopics[address] = false;
                }
            },

            setPushResourceUrl: function(url) {
                pushResourceUrl = qualifyUrl(url);
            },

            setPushHandlerUrl: function(url) {
                pushHandlerUrl = qualifyUrl(url);
            },

            updateConnection: function() {
                if (_$.isEmptyObject(handlersCounter)) {
                    disconnect();
                } else if (!_$.isEmptyObject(addedTopics) || !_$.isEmptyObject(removedTopics)) {
                    disconnect();
                    connect();
                }

                addedTopics = {};
                removedTopics = {};
            }
        };

    }());

    _$(document).ready(richfaces.Push.updateConnection);

    richfaces.Push.transport = "long-polling";// "websocket";
    richfaces.Push.fallbackTransport = undefined;//"long-polling";
    richfaces.Push.logLevel = "info";

    var ajaxEventHandler = function(event) {
        if (event.type == 'event') {
            if (event.status != 'success') {
                return;
            }
        } else if (event.type != 'error') {
            return;
        }

        richfaces.Push.updateConnection();
    };

    jsf.ajax.addOnEvent(ajaxEventHandler);
    jsf.ajax.addOnError(ajaxEventHandler);

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.Push = richfaces.BaseComponent.extendClass({

            name: COMPONENT_NAME,

            init: function (id, options) {
                $super.constructor.call(this, id);
                this.attachToDom();

                this.__address = options.address;
                this.__handlers = {};

                if (options.ondataavailable) {
                    this.__bindDataHandler(options.ondataavailable);
                }
                
                if (options.onsubscribed) {
                    this.__bindSubscribedHandler(options.onsubscribed);
                }

                if (options.onerror) {
                    this.__bindErrorHandler(options.onerror);
                }

                richfaces.Push.increaseSubscriptionCounters(this.__address);
            },

            __bindDataHandler: function(handlerCode) {
                var ns = getDataEventNamespace(this.__address);
                this.__handlers.data = richfaces.Event.bind(document, ns, $.proxy(handlerCode, document.getElementById(this.id)), this);
            },

            __unbindDataHandler: function() {
                if (this.__handlers.data) {
                    var ns = getDataEventNamespace(this.__address);
                    richfaces.Event.unbind(document, ns, this.__handlers.data);

                    this.__handlers.data = null;
                }
            },
            
            __bindSubscribedHandler: function(handlerCode) {
                var ns = getSubscribedEventNamespace(this.__address);
                this.__handlers.subscribed = richfaces.Event.bind(document, ns, $.proxy(handlerCode, document.getElementById(this.id)), this);
            },

            __unbindSubscribedHandler: function() {
                if (this.__handlers.subscribed) {
                    var ns = getSubscribedEventNamespace(this.__address);
                    richfaces.Event.unbind(document, ns, this.__handlers.subscribed);

                    this.__handlers.subscribed = null;
                }
            },

            __bindErrorHandler: function(handlerCode) {
                var ns = getErrorEventNamespace(this.__address);
                this.__handlers.error = richfaces.Event.bind(document, ns, $.proxy(handlerCode, document.getElementById(this.id)), this);
            },

            __unbindErrorHandler: function() {
                if (this.__handlers.error) {
                    var ns = getErrorEventNamespace(this.__address);
                    richfaces.Event.unbind(document, ns, this.__handlers.error);

                    this.__handlers.error = null;
                }
            },

            destroy: function() {
                this.__unbindDataHandler();
                this.__unbindErrorHandler();
                this.__unbindSubscribedHandler();

                richfaces.Push.decreaseSubscriptionCounters(this.__address);
                $super.destroy.call(this);
            }
        });

    // define super class link
    var $super = richfaces.ui.Push.$super;

}(jsf, window.RichFaces, jQuery));;/**
 * @author Ilya Shaikovsky
 * @author Lukas Fryc
 */

(function($, rf) {

    rf.ui = rf.ui || {};

    var defaultOptions = {
        enabledInInput : false,
        preventDefault : true
    };
    
    var types = [ 'keydown', 'keyup' ];

    rf.ui.HotKey = function(componentId, options) {
        $super.constructor.call(this, componentId);
        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, this.id);
        this.attachToDom(this.componentId);
        this.options = $.extend({}, defaultOptions, options);
        this.__handlers = {};
        
        this.options.selector = (this.options.selector) ? this.options.selector : document;

        $(document).ready($.proxy(function() {
            this.__bindDefinedHandlers();
        }, this));
    };

    rf.BaseComponent.extend(rf.ui.HotKey);

    var $super = rf.ui.HotKey.$super;

    $.extend(rf.ui.HotKey.prototype, {

        name : "HotKey",
        
        __bindDefinedHandlers : function() {
            for (var i = 0; i < types.length; i++) {
                if (this.options['on' + types[i]]) {
                    this.__bindHandler(types[i]);
                }
            }
        },
        
        __bindHandler : function(type) {
            this.__handlers[type] = $.proxy(function(event) {
                var result = this.invokeEvent.call(this, type, document.getElementById(this.id), event);
                if (this.options.preventDefault) {
                    event.stopPropagation();
                    event.preventDefault();
                    return false;
                }
                return result;
            }, this);
            $(this.options.selector).bind(type + this.namespace, this.options, this.__handlers[type]);
        },

        destroy : function() {
            rf.Event.unbindById(this.id, this.namespace);

            for (var type in this.__handlers) {
                if (this.__handlers.hasOwnProperty(type)) {
                    $(this.options.selector).unbind(type + this.namespace, this.__handlers[type]);
                }
            }

            $super.destroy.call(this);
        }
    });

})(jQuery, RichFaces);;/*!
 * jQuery UI Widget 1.9.2
 * http://jqueryui.com
 *
 * Copyright 2012 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/jQuery.widget/
 */
(function( $, undefined ) {

var uuid = 0,
	slice = Array.prototype.slice,
	_cleanData = $.cleanData;
$.cleanData = function( elems ) {
	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
		try {
			$( elem ).triggerHandler( "remove" );
		// http://bugs.jquery.com/ticket/8235
		} catch( e ) {}
	}
	_cleanData( elems );
};

$.widget = function( name, base, prototype ) {
	var fullName, existingConstructor, constructor, basePrototype,
		namespace = name.split( "." )[ 0 ];

	name = name.split( "." )[ 1 ];
	fullName = namespace + "-" + name;

	if ( !prototype ) {
		prototype = base;
		base = $.Widget;
	}

	// create selector for plugin
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
		return !!$.data( elem, fullName );
	};

	$[ namespace ] = $[ namespace ] || {};
	existingConstructor = $[ namespace ][ name ];
	constructor = $[ namespace ][ name ] = function( options, element ) {
		// allow instantiation without "new" keyword
		if ( !this._createWidget ) {
			return new constructor( options, element );
		}

		// allow instantiation without initializing for simple inheritance
		// must use "new" keyword (the code above always passes args)
		if ( arguments.length ) {
			this._createWidget( options, element );
		}
	};
	// extend with the existing constructor to carry over any static properties
	$.extend( constructor, existingConstructor, {
		version: prototype.version,
		// copy the object used to create the prototype in case we need to
		// redefine the widget later
		_proto: $.extend( {}, prototype ),
		// track widgets that inherit from this widget in case this widget is
		// redefined after a widget inherits from it
		_childConstructors: []
	});

	basePrototype = new base();
	// we need to make the options hash a property directly on the new instance
	// otherwise we'll modify the options hash on the prototype that we're
	// inheriting from
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
	$.each( prototype, function( prop, value ) {
		if ( $.isFunction( value ) ) {
			prototype[ prop ] = (function() {
				var _super = function() {
						return base.prototype[ prop ].apply( this, arguments );
					},
					_superApply = function( args ) {
						return base.prototype[ prop ].apply( this, args );
					};
				return function() {
					var __super = this._super,
						__superApply = this._superApply,
						returnValue;

					this._super = _super;
					this._superApply = _superApply;

					returnValue = value.apply( this, arguments );

					this._super = __super;
					this._superApply = __superApply;

					return returnValue;
				};
			})();
		}
	});
	constructor.prototype = $.widget.extend( basePrototype, {
		// TODO: remove support for widgetEventPrefix
		// always use the name + a colon as the prefix, e.g., draggable:start
		// don't prefix for widgets that aren't DOM-based
		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
	}, prototype, {
		constructor: constructor,
		namespace: namespace,
		widgetName: name,
		// TODO remove widgetBaseClass, see #8155
		widgetBaseClass: fullName,
		widgetFullName: fullName
	});

	// If this widget is being redefined then we need to find all widgets that
	// are inheriting from it and redefine all of them so that they inherit from
	// the new version of this widget. We're essentially trying to replace one
	// level in the prototype chain.
	if ( existingConstructor ) {
		$.each( existingConstructor._childConstructors, function( i, child ) {
			var childPrototype = child.prototype;

			// redefine the child widget using the same prototype that was
			// originally used, but inherit from the new version of the base
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
		});
		// remove the list of existing child constructors from the old constructor
		// so the old child constructors can be garbage collected
		delete existingConstructor._childConstructors;
	} else {
		base._childConstructors.push( constructor );
	}

	$.widget.bridge( name, constructor );
};

$.widget.extend = function( target ) {
	var input = slice.call( arguments, 1 ),
		inputIndex = 0,
		inputLength = input.length,
		key,
		value;
	for ( ; inputIndex < inputLength; inputIndex++ ) {
		for ( key in input[ inputIndex ] ) {
			value = input[ inputIndex ][ key ];
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
				// Clone objects
				if ( $.isPlainObject( value ) ) {
					target[ key ] = $.isPlainObject( target[ key ] ) ?
						$.widget.extend( {}, target[ key ], value ) :
						// Don't extend strings, arrays, etc. with objects
						$.widget.extend( {}, value );
				// Copy everything else by reference
				} else {
					target[ key ] = value;
				}
			}
		}
	}
	return target;
};

$.widget.bridge = function( name, object ) {
	var fullName = object.prototype.widgetFullName || name;
	$.fn[ name ] = function( options ) {
		var isMethodCall = typeof options === "string",
			args = slice.call( arguments, 1 ),
			returnValue = this;

		// allow multiple hashes to be passed on init
		options = !isMethodCall && args.length ?
			$.widget.extend.apply( null, [ options ].concat(args) ) :
			options;

		if ( isMethodCall ) {
			this.each(function() {
				var methodValue,
					instance = $.data( this, fullName );
				if ( !instance ) {
					return $.error( "cannot call methods on " + name + " prior to initialization; " +
						"attempted to call method '" + options + "'" );
				}
				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
				}
				methodValue = instance[ options ].apply( instance, args );
				if ( methodValue !== instance && methodValue !== undefined ) {
					returnValue = methodValue && methodValue.jquery ?
						returnValue.pushStack( methodValue.get() ) :
						methodValue;
					return false;
				}
			});
		} else {
			this.each(function() {
				var instance = $.data( this, fullName );
				if ( instance ) {
					instance.option( options || {} )._init();
				} else {
					$.data( this, fullName, new object( options, this ) );
				}
			});
		}

		return returnValue;
	};
};

$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];

$.Widget.prototype = {
	widgetName: "widget",
	widgetEventPrefix: "",
	defaultElement: "<div>",
	options: {
		disabled: false,

		// callbacks
		create: null
	},
	_createWidget: function( options, element ) {
		element = $( element || this.defaultElement || this )[ 0 ];
		this.element = $( element );
		this.uuid = uuid++;
		this.eventNamespace = "." + this.widgetName + this.uuid;
		this.options = $.widget.extend( {},
			this.options,
			this._getCreateOptions(),
			options );

		this.bindings = $();
		this.hoverable = $();
		this.focusable = $();

		if ( element !== this ) {
			// 1.9 BC for #7810
			// TODO remove dual storage
			$.data( element, this.widgetName, this );
			$.data( element, this.widgetFullName, this );
			this._on( true, this.element, {
				remove: function( event ) {
					if ( event.target === element ) {
						this.destroy();
					}
				}
			});
			this.document = $( element.style ?
				// element within the document
				element.ownerDocument :
				// element is window or document
				element.document || element );
			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
		}

		this._create();
		this._trigger( "create", null, this._getCreateEventData() );
		this._init();
	},
	_getCreateOptions: $.noop,
	_getCreateEventData: $.noop,
	_create: $.noop,
	_init: $.noop,

	destroy: function() {
		this._destroy();
		// we can probably remove the unbind calls in 2.0
		// all event bindings should go through this._on()
		this.element
			.unbind( this.eventNamespace )
			// 1.9 BC for #7810
			// TODO remove dual storage
			.removeData( this.widgetName )
			.removeData( this.widgetFullName )
			// support: jquery <1.6.3
			// http://bugs.jquery.com/ticket/9413
			.removeData( $.camelCase( this.widgetFullName ) );
		this.widget()
			.unbind( this.eventNamespace )
			.removeAttr( "aria-disabled" )
			.removeClass(
				this.widgetFullName + "-disabled " +
				"ui-state-disabled" );

		// clean up events and states
		this.bindings.unbind( this.eventNamespace );
		this.hoverable.removeClass( "ui-state-hover" );
		this.focusable.removeClass( "ui-state-focus" );
	},
	_destroy: $.noop,

	widget: function() {
		return this.element;
	},

	option: function( key, value ) {
		var options = key,
			parts,
			curOption,
			i;

		if ( arguments.length === 0 ) {
			// don't return a reference to the internal hash
			return $.widget.extend( {}, this.options );
		}

		if ( typeof key === "string" ) {
			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
			options = {};
			parts = key.split( "." );
			key = parts.shift();
			if ( parts.length ) {
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
				for ( i = 0; i < parts.length - 1; i++ ) {
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
					curOption = curOption[ parts[ i ] ];
				}
				key = parts.pop();
				if ( value === undefined ) {
					return curOption[ key ] === undefined ? null : curOption[ key ];
				}
				curOption[ key ] = value;
			} else {
				if ( value === undefined ) {
					return this.options[ key ] === undefined ? null : this.options[ key ];
				}
				options[ key ] = value;
			}
		}

		this._setOptions( options );

		return this;
	},
	_setOptions: function( options ) {
		var key;

		for ( key in options ) {
			this._setOption( key, options[ key ] );
		}

		return this;
	},
	_setOption: function( key, value ) {
		this.options[ key ] = value;

		if ( key === "disabled" ) {
			this.widget()
				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
				.attr( "aria-disabled", value );
			this.hoverable.removeClass( "ui-state-hover" );
			this.focusable.removeClass( "ui-state-focus" );
		}

		return this;
	},

	enable: function() {
		return this._setOption( "disabled", false );
	},
	disable: function() {
		return this._setOption( "disabled", true );
	},

	_on: function( suppressDisabledCheck, element, handlers ) {
		var delegateElement,
			instance = this;

		// no suppressDisabledCheck flag, shuffle arguments
		if ( typeof suppressDisabledCheck !== "boolean" ) {
			handlers = element;
			element = suppressDisabledCheck;
			suppressDisabledCheck = false;
		}

		// no element argument, shuffle and use this.element
		if ( !handlers ) {
			handlers = element;
			element = this.element;
			delegateElement = this.widget();
		} else {
			// accept selectors, DOM elements
			element = delegateElement = $( element );
			this.bindings = this.bindings.add( element );
		}

		$.each( handlers, function( event, handler ) {
			function handlerProxy() {
				// allow widgets to customize the disabled handling
				// - disabled as an array instead of boolean
				// - disabled class as method for disabling individual parts
				if ( !suppressDisabledCheck &&
						( instance.options.disabled === true ||
							$( this ).hasClass( "ui-state-disabled" ) ) ) {
					return;
				}
				return ( typeof handler === "string" ? instance[ handler ] : handler )
					.apply( instance, arguments );
			}

			// copy the guid so direct unbinding works
			if ( typeof handler !== "string" ) {
				handlerProxy.guid = handler.guid =
					handler.guid || handlerProxy.guid || $.guid++;
			}

			var match = event.match( /^(\w+)\s*(.*)$/ ),
				eventName = match[1] + instance.eventNamespace,
				selector = match[2];
			if ( selector ) {
				delegateElement.delegate( selector, eventName, handlerProxy );
			} else {
				element.bind( eventName, handlerProxy );
			}
		});
	},

	_off: function( element, eventName ) {
		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
		element.unbind( eventName ).undelegate( eventName );
	},

	_delay: function( handler, delay ) {
		function handlerProxy() {
			return ( typeof handler === "string" ? instance[ handler ] : handler )
				.apply( instance, arguments );
		}
		var instance = this;
		return setTimeout( handlerProxy, delay || 0 );
	},

	_hoverable: function( element ) {
		this.hoverable = this.hoverable.add( element );
		this._on( element, {
			mouseenter: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-hover" );
			},
			mouseleave: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-hover" );
			}
		});
	},

	_focusable: function( element ) {
		this.focusable = this.focusable.add( element );
		this._on( element, {
			focusin: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-focus" );
			},
			focusout: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-focus" );
			}
		});
	},

	_trigger: function( type, event, data ) {
		var prop, orig,
			callback = this.options[ type ];

		data = data || {};
		event = $.Event( event );
		event.type = ( type === this.widgetEventPrefix ?
			type :
			this.widgetEventPrefix + type ).toLowerCase();
		// the original event may come from any element
		// so we need to reset the target on the new event
		event.target = this.element[ 0 ];

		// copy original event properties over to the new event
		orig = event.originalEvent;
		if ( orig ) {
			for ( prop in orig ) {
				if ( !( prop in event ) ) {
					event[ prop ] = orig[ prop ];
				}
			}
		}

		this.element.trigger( event, data );
		return !( $.isFunction( callback ) &&
			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
			event.isDefaultPrevented() );
	}
};

$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
		if ( typeof options === "string" ) {
			options = { effect: options };
		}
		var hasOptions,
			effectName = !options ?
				method :
				options === true || typeof options === "number" ?
					defaultEffect :
					options.effect || defaultEffect;
		options = options || {};
		if ( typeof options === "number" ) {
			options = { duration: options };
		}
		hasOptions = !$.isEmptyObject( options );
		options.complete = callback;
		if ( options.delay ) {
			element.delay( options.delay );
		}
		if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
			element[ method ]( options );
		} else if ( effectName !== method && element[ effectName ] ) {
			element[ effectName ]( options.duration, options.easing, callback );
		} else {
			element.queue(function( next ) {
				$( this )[ method ]();
				if ( callback ) {
					callback.call( element[ 0 ] );
				}
				next();
			});
		}
	};
});

// DEPRECATED
if ( $.uiBackCompat !== false ) {
	$.Widget.prototype._getCreateOptions = function() {
		return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
	};
}

})( jQuery );
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.Accordion = rf.ui.TogglePanel.extendClass({
            // class name
            name:"Accordion",

            /**
             * @class Accordion
             * @name Accordion
             *
             * @constructor
             * @param {String} componentId - component id
             * @param {Hash} options - params
             * */
            init : function (componentId, options) {
                $super.constructor.call(this, componentId, options);
                this.items = [];

                this.isKeepHeight = options["isKeepHeight"] || false
            },

            /***************************** Public Methods  ****************************************************************/

            getHeight : function (recalculate) {
                if (recalculate || !this.__height) {
                    this.__height = $(rf.getDomElement(this.id)).outerHeight(true)
                }

                return this.__height;
            },

            getInnerHeight : function (recalculate) {
                if (recalculate || !this.__innerHeight) {
                    this.__innerHeight = $(rf.getDomElement(this.id)).innerHeight()
                }

                return this.__innerHeight;
            },

            /***************************** Private Methods ********************************************************/


            destroy: function () {
                rf.Event.unbindById(this.id, "." + this.namespace);
                $super.destroy.call(this);
            }
        });

    // define super class link
    var $super = rf.ui.Accordion.$super;
})(jQuery, RichFaces);
;/**
 * @author Lukas Fryc
 */

(function($, rf) {
    rf.ui = rf.ui || {};

    /**
     * Default component configuration
     */
    var defaultOptions = {
        toolbar : 'Basic',
        skin: 'richfaces',
        readonly : false,
        style : '',
        styleClass : '',
        editorStyle : '',
        editorClass : '',
        width : '100%',
        height : '200px'
    };
    
    /**
     * Default CKEditor configuration
     */
    var defaultConfig = {
        customConfig : '' // do not load config.js since it is empty
    };
    
    var eventsForDirty = [ "key", "paste", "undo", "redo" ];

    rf.ui.Editor = function(componentId, options, config) {
        $super.constructor.call(this, componentId);
        this.options = $.extend({}, defaultOptions, options);

        this.componentId = componentId;
        this.textareaId = componentId + ':inp';
        this.editorElementId = 'cke_' + this.textareaId;
        this.valueChanged = false;
        this.dirtyState = false;
        this.config = $.extend({}, defaultConfig, config);

        this.attachToDom(this.componentId);

        $(document).ready($.proxy(this.__initializationHandler, this));
        rf.Event.bindById(this.__getTextarea(), 'init', this.options.oninit, this);
        rf.Event.bindById(this.__getTextarea(), 'dirty', this.options.ondirty, this);
    };

    rf.BaseComponent.extend(rf.ui.Editor);

    var $super = rf.ui.Editor.$super;

    $.extend(rf.ui.Editor.prototype, {

        name : "Editor",

        __initializationHandler : function() {
            this.ckeditor = CKEDITOR.replace(this.textareaId, this.__getConfiguration());

            // register event handlers
            if (this.__getForm()) {
                this.__updateTextareaHandlerWrapper = rf.Event.bind(this.__getForm(), 'ajaxsubmit', $.proxy(this.__updateTextareaHandler, this));
            }
            this.ckeditor.on('instanceReady', $.proxy(this.__instanceReadyHandler, this));
            this.ckeditor.on('blur', $.proxy(this.__blurHandler, this));
            this.ckeditor.on('focus', $.proxy(this.__focusHandler, this));
            // register handlers for 'dirty' event
            for (var i in eventsForDirty) {
                this.ckeditor.on(eventsForDirty[i], $.proxy(this.__checkDirtyHandlerWithDelay, this));
            }
            // interval for dirty checking
            this.dirtyCheckingInterval = window.setInterval($.proxy(this.__checkDirtyHandler, this), 100);
        },
        
        __checkDirtyHandlerWithDelay : function() {
            window.setTimeout($.proxy(this.__checkDirtyHandler, this), 0);
        },
        
        __checkDirtyHandler : function() {
            if (this.ckeditor.checkDirty()) {
                this.dirtyState = true;
                this.valueChanged = true;
                this.ckeditor.resetDirty();
                this.__dirtyHandler();
            }
        },
        
        __dirtyHandler : function() {
            this.invokeEvent.call(this, "dirty", document.getElementById(this.textareaId));
        },
        
        __updateTextareaHandler : function() {
            this.ckeditor.updateElement();
        },

        __instanceReadyHandler : function(e) {
            this.__setupStyling();
            this.__setupPassThroughAttributes();

            this.invokeEvent.call(this, "init", document.getElementById(this.textareaId), e);
        },

        __blurHandler : function(e) {
            this.invokeEvent.call(this, "blur", document.getElementById(this.textareaId), e);
            if (this.isDirty()) {
                this.valueChanged = true;
                this.__changeHandler();
            }
            this.dirtyState = false;
        },

        __focusHandler : function(e) {
            this.invokeEvent.call(this, "focus", document.getElementById(this.textareaId), e);
        },

        __changeHandler : function(e) {
            this.invokeEvent.call(this, "change", document.getElementById(this.textareaId), e);
        },

        __getTextarea : function() {
            return $(document.getElementById(this.textareaId));
        },

        /**
         * Returns the form where this editor component is placed
         */
        __getForm : function() {
            return $('form').has(this.__getTextarea()).get(0);
        },

        __getConfiguration : function() {
            var textarea = this.__getTextarea();
            return $.extend({
                skin : this.options.skin,
                toolbar : this.__getToolbar(),
                readOnly : textarea.attr('readonly') || this.options.readonly,
                width : this.__resolveUnits(this.options.width),
                height : this.__resolveUnits(this.options.height),
                bodyClass : 'rf-ed-b',
                defaultLanguage : this.options.lang,
                contentsLanguage : this.options.lang
            }, this.config);
        },

        __setupStyling : function() {
            var span = $(document.getElementById(this.editorElementId));
            if (!span.hasClass('rf-ed')) {
                span.addClass('rf-ed');
            }
            var styleClass = $.trim(this.options.styleClass + ' ' + this.options.editorClass);
            if (this.initialStyle == undefined) {
                this.initialStyle = span.attr('style');
            }
            var style = this.__concatStyles(this.initialStyle, this.options.style, this.options.editorStyle);
            if (this.oldStyleClass !== styleClass) {
                if (this.oldStyleClass) {
                    span.removeClass(this.oldStyleClass);
                }
                span.addClass(styleClass);
                this.oldStyleClass = styleClass;
            }
            if (this.oldStyle !== style) {
                span.attr('style', style);
                this.oldStyle = style;
            }
        },

        __setupPassThroughAttributes : function() {
            var textarea = this.__getTextarea();
            var span = $(document.getElementById(this.editorElementId));

            // title
            span.attr('title', textarea.attr('title'));
        },

        __concatStyles : function() {
            var result = "";
            for ( var i = 0; i < arguments.length; i++) {
                var style = $.trim(arguments[i]);
                if (style) {
                    result = result + style + "; ";
                }
            }
            return result;
        },

        __getToolbar : function() {
            var toolbar = this.options.toolbar;

            var lowercase = toolbar.toLowerCase();
            if (lowercase === 'basic') {
                return 'Basic';
            }
            if (lowercase === 'full') {
                return 'Full';
            }

            return toolbar;
        },

        __setOptions : function(options) {
            this.options = $.extend({}, defaultOptions, options);
        },

        __resolveUnits : function(dimension) {
            var dimension = $.trim(dimension);
            if (dimension.match(/^[0-9]+$/)) {
                return dimension + 'px';
            } else {
                return dimension;
            }
        },

        getEditor : function() {
            return this.ckeditor;
        },

        setValue : function(newValue) {
            this.ckeditor.setData(newValue, $.proxy(function() {
                this.valueChanged = false;
                this.dirtyState = false;
                this.ckeditor.resetDirty();
            }, this));
        },

        getValue : function() {
            return this.ckeditor.getData();
        },

        getInput : function() {
            return document.getElementById(this.textareaId);
        },

        focus : function() {
            this.ckeditor.focus();
        },

        blur : function() {
            this.ckeditor.focusManager.forceBlur();
        },

        isFocused : function() {
            return this.ckeditor.focusManager.hasFocus;
        },

        isDirty : function() {
            return this.dirtyState || this.ckeditor.checkDirty();
        },

        isValueChanged : function() {
            return this.valueChanged || this.isDirty();
        },

        setReadOnly : function(readOnly) {
            this.ckeditor.setReadOnly(readOnly !== false);
        },

        isReadOnly : function() {
            return this.ckeditor.readOnly;
        },

        destroy : function() {
            window.clearInterval(this.dirtyCheckingInterval);
            
            if (this.__getForm()) {
                rf.Event.unbind(this.__getForm(), 'ajaxsubmit', this.__updateTextareaHandlerWrapper);
            }

            if (this.ckeditor) {
                this.ckeditor.destroy();
                this.ckeditor = null;
            }

            this.__getTextarea().show();

            $super.destroy.call(this);
        }
    });
})(jQuery, RichFaces);;(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.InputBase = function(id, options) {
        $super.constructor.call(this, id);
        this.namespace = this.getNamespace() || "." + rf.Event.createNamespace(this.getName(), this.getId());

        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, this.id);

        this.input = $(document.getElementById(id + "Input"));
        this.attachToDom();

        var inputEventHandlers = {};
        inputEventHandlers[($.browser.opera || $.browser.mozilla ? "keypress" : "keydown") + this.namespace] = $.proxy(this.__keydownHandler, this);
        inputEventHandlers["blur" + this.namespace] = $.proxy(this.__blurHandler, this);
        inputEventHandlers["change" + this.namespace] = $.proxy(this.__changeHandler, this);
        inputEventHandlers["focus" + this.namespace] = $.proxy(this.__focusHandler, this);
        rf.Event.bind(this.input, inputEventHandlers, this);
    };

    rf.BaseComponent.extend(rf.ui.InputBase);

    // define super class link
    var $super = rf.ui.InputBase.$super;

    $.extend(rf.ui.InputBase.prototype, ( function () {

        return {

            name : "inputBase",


            getName: function() {
                return this.name;
            },

            getNamespace: function() {
                return this.namespace;
            },

            __focusHandler: function(e) {
            },

            __keydownHandler: function(e) {
            },

            __blurHandler: function(e) {
            },

            __changeHandler: function(e) {
            },

            __setInputFocus: function() {
                this.input.focus();
            },

            __getValue: function() {
                return this.input.val();
            },

            __setValue: function(value) {
                this.input.val(value);
                if (this.defaultLabelClass) {
                    if (value == this.defaultLabel) {
                        this.input.addClass(this.defaultLabelClass);
                    } else {
                        this.input.removeClass(this.defaultLabelClass);
                    }
                }
            },

            getValue: function() {
                return this.__getValue();
            },

            setValue: function(value) {
                this.__setValue(value);
            },

            getInput: function() {
                return this.input;
            },

            getId: function() {
                return    this.id;
            },
            destroy: function() {
                rf.Event.unbindById(this.input, this.namespace);
                this.input = null;
                $super.destroy.call(this);
            }
        }
    })());

})(jQuery, window.RichFaces);;/*
 * jQuery UI Effects Highlight 1.8.5
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Effects/Highlight
 *
 * Depends:
 *	jquery.effects.core.js
 */
(function( $, undefined ) {

$.effects.highlight = function(o) {
	return this.queue(function() {
		var elem = $(this),
			props = ['backgroundImage', 'backgroundColor', 'opacity'],
			mode = $.effects.setMode(elem, o.options.mode || 'show'),
			animation = {
				backgroundColor: elem.css('backgroundColor')
			};

		if (mode == 'hide') {
			animation.opacity = 0;
		}

		$.effects.save(elem, props);
		elem
			.show()
			.css({
				backgroundImage: 'none',
				backgroundColor: o.options.color || '#ffff99'
			})
			.animate(animation, {
				queue: false,
				duration: o.duration,
				easing: o.options.easing,
				complete: function() {
					(mode == 'hide' && elem.hide());
					$.effects.restore(elem, props);
					(mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
					(o.callback && o.callback.apply(this, arguments));
					elem.dequeue();
				}
			});
	});
};

})(jQuery);
;(function($, rf) {
    
    rf.ui = rf.ui || {};
    
    var defaultOptions = {
        styleClass: '',
        nonblocking: false,
        nonblockingOpacity: 0.2,
        showHistory: false,
        animationSpeed: 'slow',
        opacity: '1',
        showShadow: false,
        showCloseButton: true,
        appearAnimation: 'fade',
        hideAnimation: 'fade',
        sticky: false,
        stayTime: 8000,
        delay: 0
    };
    
    var defaultStackId = "org.richfaces.notifyStack.default";
    
    var events = "click dblclick  keydown keypress keyup mousedown mousemove mouseout mouseover mouseup";
    
    var propertyTranslation = {
        'summary':'pnotify_title',
        'detail': 'pnotify_text',
        'styleClass': 'pnotify_addclass',
        'nonblocking': 'pnotify_nonblock',
        'nonblockingOpacity': 'pnotify_nonblock_opacity',
        'showHistory': 'pnotify_history',
        'animation': 'pnotify_animation',
        'appearAnimation': 'effect_in',
        'hideAnimation': 'effect_out',
        'animationSpeed': 'pnotify_animate_speed',
        'opacity': 'pnotify_opacity',
        'showShadow': 'pnotify_shadow',
        'showCloseButton': 'pnotify_closer',
        'sticky': 'pnotify_hide',
        'stayTime': 'pnotify_delay'
    };
    
    var severityClasses = ["rf-ntf-inf", "rf-ntf-wrn", "rf-ntf-err", "rf-ntf-ftl"];
    
    var translateProperties = function(target, source, translation) {
        for (var attr in source) {
            var targetAttr = translation[attr] != null ? translation[attr] : attr;
            target[targetAttr] = source[attr];
            if (target[targetAttr] instanceof Object) {
                target[targetAttr] = $.extend({}, target[targetAttr], translation);
            }
        }
        return target;
    };
    
    var getDefaultStack = function() {
        if (!document.getElementById(defaultStackId)) {
            var stackElement = $('<span id="' + defaultStackId + '" class="rf-ntf-stck" />');
            $('body').append(stackElement);
            new RichFaces.ui.NotifyStack(defaultStackId);
        }
        return getStack(defaultStackId);
    };
    
    var getStack = function(stackId) {
        if (!stackId) {
            return getDefaultStack();
        }
        return rf.$(stackId).getStack();
    };
    

    var array_remove = function(array, from, to) {
        var rest = array.slice((to || from) + 1 || array.length);
        array.length = from < 0 ? array.length + from : from;
        return array.push.apply(array, rest);
    };
    
    rf.ui.Notify = function(options) {
        var options = $.extend({}, defaultOptions, options);
        
        if (typeof options.severity == "number") {
            var severity = severityClasses[options.severity];
            options.styleClass = options.styleClass ? severity + " " + options.styleClass : severity;
        }
        
        var pnotifyOptions = translateProperties({}, options, propertyTranslation);

        var display = function() {
            var stack = getStack(options.stackId);
            pnotifyOptions.pnotify_stack = stack;
            pnotifyOptions.pnotify_addclass += ' rf-ntf-pos-' + stack.position;
            pnotifyOptions.pnotify_after_close = function(pnotify) {
                var index = $.inArray(pnotify, stack.notifications);
                if (index >= 0) {
                    array_remove(stack.notifications, index);
                }
            }
            var pnotify = $.pnotify(pnotifyOptions);
            pnotify.on(events, function(e) {
                if (options['on' + e.type]) {
                    options['on' + e.type].call(this, e);
                }
            });
            stack.addNotification(pnotify);
        }
        
        if (options.sticky !== null) {
            pnotifyOptions.pnotify_hide = !options.sticky;
        }
        
        $(document).ready(function() {
            if (options.delay) {
                setTimeout(function() {
                    display();
                }, options.delay);
            } else {
                display();
            }
        });
    };

})(jQuery, RichFaces);;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 * 
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */


(function ($, rf) {

    rf.ui = rf.ui || {};

    var __DEFAULT_OPTIONS = {
        expanded : false,
        stylePrefix : "rf-pm-gr",
        expandEvent: "click",
        collapseEvent: "click",

        // TODO we should use selectionType = {none, selectable, unselectable}
        selectable : false,
        unselectable : false // unselectable can be only selectable item => if selectable == false than unselectable = false
    };

    var EXPAND_ITEM = {

        /**
         *
         * @return {void}
         * */
        exec : function (group, expand) {
            var mode = group.mode;
            if (mode == "server") {
                return this.execServer(group);
            } else if (mode == "ajax") {
                return this.execAjax(group);
            } else if (mode == "client" || mode == "none") {
                return this.execClient(group, expand);
            } else {
                rf.log.error("EXPAND_ITEM.exec : unknown mode (" + mode + ")");
            }
        },

        /**
         * @protected
         *
         * @return {Boolean} false
         * */
        execServer : function (group) {
            group.__changeState();
            rf.submitForm(this.__getParentForm(group), group.options["ajax"]["parameters"] || {});

            return false;
        },

        /**
         * @protected
         *
         * @return {Boolean} false
         * */
        execAjax : function (group) {
            var oldState = group.__changeState();
            rf.ajax(group.id, null, $.extend({}, group.options["ajax"], {}));
            group.__restoreState(oldState);

            return true;
        },

        /**
         * @protected
         *
         * @param {PanelMenuGroup} group
         * @param {Boolean} expand
         * @return {undefined}
         *             - false - if process has been terminated
         *             - true  - in other cases
         * */
        execClient : function (group, expand) {
            if (expand) {
                group.__expand();
            } else {
                group.__collapse();
            }

            return group.__fireEvent("switch");
        },

        /**
         * @private
         * */
        __getParentForm : function (item) {
            return $($(rf.getDomElement(item.id)).parents("form")[0]);
        }
    };

    rf.ui.PanelMenuGroup = rf.ui.PanelMenuItem.extendClass({
            // class name
            name:"PanelMenuGroup",

            /**
             * @class PanelMenuGroup
             * @name PanelMenuGroup
             *
             * @constructor
             * @param {String} componentId - component id
             * @param {Hash} options - params
             * */
            init : function (componentId, options) {
                $super.constructor.call(this, componentId, $.extend({}, __DEFAULT_OPTIONS, options || {}));

                this.options.bubbleSelection = this.__rfPanelMenu().options.bubbleSelection;
                this.options.expandSingle = this.__rfPanelMenu().options.expandSingle;

                if (!this.options.disabled) {
                    var menuGroup = this;

                    if (!this.options.selectable) {

                        //TODO nick - this can be replaced by jQuery.delegate on menu itself
                        if (this.options.expandEvent == this.options.collapseEvent) {
                            this.__header().bind(this.options.expandEvent, function () {
                                menuGroup.switchExpantion();
                            });

                        } else {
                            this.__header().bind(this.options.expandEvent, function () {
                                if (menuGroup.collapsed()) {
                                    return menuGroup.expand();
                                }
                            });

                            this.__header().bind(this.options.collapseEvent, function () {
                                if (menuGroup.expanded()) {
                                    return menuGroup.collapse();
                                }
                            });
                        }
                    } else {

                        if (this.options.expandEvent == this.options.collapseEvent) {
                            if (this.options.expandEvent != 'click') {
                                this.__header().bind(this.options.expandEvent, function () {
                                    menuGroup.switchExpantion();
                                });
                            }

                        } else {
                            if (this.options.expandEvent != 'click') {
                                this.__header().bind(this.options.expandEvent, function () {
                                    if (menuGroup.collapsed()) {
                                        return menuGroup.expand();
                                    }
                                });
                            }

                            if (this.options.collapseEvent != 'click') {
                                this.__header().bind(this.options.collapseEvent, function () {
                                    if (menuGroup.expanded()) {
                                        return menuGroup.collapse();
                                    }
                                });
                            }
                        }

                    }

                    if (this.options.selectable || this.options.bubbleSelection) {
                        this.__content().bind("select", function (event) {
                            if (menuGroup.options.selectable && menuGroup.__isMyEvent(event)) {
                                menuGroup.expand();
                            }

                            if (menuGroup.options.bubbleSelection && !menuGroup.__isMyEvent(event)) {
                                menuGroup.__select();
                                if (!menuGroup.expanded()) {
                                    menuGroup.expand();
                                }
                            }
                        });

                        this.__content().bind("unselect", function (event) {
                            if (menuGroup.options.selectable && menuGroup.__isMyEvent(event)) {
                                menuGroup.collapse();
                            }

                            if (menuGroup.options.bubbleSelection && !menuGroup.__isMyEvent(event)) {
                                menuGroup.__unselect();
                            }
                        });
                    }

                    /*this.__addUserEventHandler("beforecollapse");
                     this.__addUserEventHandler("collapse");
                     this.__addUserEventHandler("beforeexpand");
                     this.__addUserEventHandler("expand");
                     this.__addUserEventHandler("beforeswitch");
                     this.__addUserEventHandler("switch");*/
                }
            },

            /***************************** Public Methods  ****************************************************************/
            expanded : function () {
                // TODO check invariant in dev mode
                // return this.__content().hasClass("rf-pm-exp")
                return this.__getExpandValue();
            },

            expand : function () {
                if (this.expanded()) return;
                if (!this.__fireEvent("beforeexpand")) {
                    return false;
                }

                EXPAND_ITEM.exec(this, true);
            },

            __expand : function () {
                this.__updateStyles(true);
                this.__collapseForExpandSingle();

                return this.__fireEvent("expand");
            },

            collapsed : function () {
                // TODO check invariant in dev mode
                // return this.__content().hasClass("rf-pm-colps")
                return !this.__getExpandValue();
            },

            collapse : function () {
                if (!this.expanded()) return;
                if (!this.__fireEvent("beforecollapse")) {
                    return false;
                }

                EXPAND_ITEM.exec(this, false);
            },

            __collapse : function () {
                this.__updateStyles(false);

                this.__childGroups().each(function(index, group) {
                    //TODO nick - why not group.collapse()?
                    rf.$(group.id).__collapse();
                });

                return this.__fireEvent("collapse");
            },

            __updateStyles : function (expand) {
                if (expand) {
                    //expand
                    this.__content().removeClass("rf-pm-colps").addClass("rf-pm-exp");
                    this.__header().removeClass("rf-pm-hdr-colps").addClass("rf-pm-hdr-exp");

                    this.__setExpandValue(true);
                } else {
                    this.__content().addClass("rf-pm-colps").removeClass("rf-pm-exp");
                    this.__header().addClass("rf-pm-hdr-colps").removeClass("rf-pm-hdr-exp");

                    this.__setExpandValue(false);
                }
            },

            /**
             * @methodOf
             * @name PanelMenuGroup#switch
             *
             * TODO ...
             *
             * @param {boolean} expand
             * @return {void} TODO ...
             */
            switchExpantion : function () { // TODO rename
                var continueProcess = this.__fireEvent("beforeswitch");
                if (!continueProcess) {
                    return false;
                }

                if (this.expanded()) {
                    this.collapse();
                } else {
                    this.expand();
                }
            },

            /**
             * please, remove this method when client side ajax events will be added
             *
             * */
            onCompleteHandler : function () {
                if (this.options.selectable) {
                    $super.onCompleteHandler.call(this);
                }

                EXPAND_ITEM.execClient(this, this.expanded());
            },

            __switch : function (expand) {
                if (expand) {
                    this.__expand();
                } else {
                    this.__collapse();
                }
                return this.__fireEvent("switch");
            },

            /***************************** Private Methods ****************************************************************/
            __childGroups : function () {
                return this.__content().children(".rf-pm-gr")
            },

            __group : function () {
                return $(rf.getDomElement(this.id))
            },

            __header : function () {
                return $(rf.getDomElement(this.id + ":hdr"))
            },

            __content : function () {
                return $(rf.getDomElement(this.id + ":cnt"))
            },

            __expandValueInput : function () {
                return document.getElementById(this.id + ":expanded");
            },

            __getExpandValue : function () {
                return this.__expandValueInput().value == "true";
            },

            __collapseForExpandSingle: function() {
                if (this.options.expandSingle) {
                    this.__rfPanelMenu().__collapseGroups(this);
                }
            },

            /**
             * @methodOf
             * @name PanelMenuGroup#__setExpandValue
             *
             * @param {boolean} value - is group expanded?
             * @return {boolean} preview value
             */
            __setExpandValue : function (value) {
                var input = this.__expandValueInput();
                var oldValue = input.value;

                input.value = value;

                return oldValue;
            },

            __changeState : function () {
                if (!this.__getExpandValue()) {
                    this.__collapseForExpandSingle();
                }

                var state = {};
                state["expanded"] = this.__setExpandValue(!this.__getExpandValue());
                if (this.options.selectable) {
                    state["itemName"] = this.__rfPanelMenu().selectedItem(this.itemName); // TODO bad function name for function which change component state
                }

                return state;
            },

            __restoreState : function (state) {
                if (!state) {
                    return;
                }

                if (state["expanded"]) {
                    this.__setExpandValue(state["expanded"]);
                }

                if (state["itemName"]) {
                    this.__rfPanelMenu().selectedItem(state["itemName"]);
                }
            },

            __isMyEvent: function (event) {
                return this.id == event.target.id;
            },

            destroy: function () {
                rf.Event.unbindById(this.id, "." + this.namespace);

                $super.destroy.call(this);
            }
        });

    // define super class link
    var $super = rf.ui.PanelMenuGroup.$super;
})(jQuery, RichFaces);
;(function ($, richfaces) {

    richfaces.ui = richfaces.ui || {};

    richfaces.ui.PopupPanel.Sizer = function(id, modalPanel, cursor, sizer) {

        $super.constructor.call(this, id);

    };

    var $super = richfaces.BaseComponent.extend(richfaces.ui.PopupPanel.Sizer);
    var $super = richfaces.ui.PopupPanel.Sizer.$super;
    $.extend(richfaces.ui.PopupPanel.Sizer.prototype, (function (options) {
        return {

            name: "richfaces.ui.PopupPanel.Sizer",

            doSetupSize: function (modalPanel, elt) {
                var width = 0;
                var height = 0;
                var element = $(richfaces.getDomElement(elt));
                var reductionData = modalPanel.reductionData;

                if (reductionData) {
                    if (reductionData.w) {
                        width = reductionData.w / 2;
                    }

                    if (reductionData.h) {
                        height = reductionData.h / 2;
                    }
                }

                if (width > 0) {
                    if (elt.clientWidth > width) {
                        if (!elt.reducedWidth) {
                            elt.reducedWidth = element.css('width');
                        }
                        element.css('width', width + 'px');
                    } else if (width < 4 && elt.reducedWidth == 4 + 'px') {
                        element.css('width', width + 'px');
                    }
                } else {
                    if (elt.reducedWidth) {
                        element.css('width', elt.reducedWidth);
                        elt.reducedWidth = undefined;
                    }
                }

                if (height > 0) {
                    if (elt.clientHeight > height) {
                        if (!elt.reducedHeight) {
                            elt.reducedHeight = element.css('height');
                        }
                        elt.style.height = height + 'px';
                    } else if (height < 4 && elt.reducedHeight == 4 + 'px') {
                        element.css('height', height + 'px');
                    }
                } else {
                    if (elt.reducedHeight) {
                        element.css('height', elt.reducedHeight);
                        elt.reducedHeight = undefined;
                    }
                }
            },

            doSetupPosition: function (modalPanel, elt, left, top) {
                var element = $(richfaces.getDomElement(elt));
                if (!isNaN(left) && !isNaN(top)) {
                    element.css('left', left + 'px');
                    element.css('top', top + 'px');
                }
            },

            doPosition: function (modalPanel, elt) {

            },

            doDiff: function (dx, dy) {

            }
        }

    })());
    richfaces.ui.PopupPanel.Sizer.Diff = function(dX, dY, dWidth, dHeight) {

        this.deltaX = dX;
        this.deltaY = dY;

        this.deltaWidth = dWidth;
        this.deltaHeight = dHeight;

    };

    richfaces.ui.PopupPanel.Sizer.Diff.EMPTY = function() {
        return new richfaces.ui.PopupPanel.Sizer.Diff(0, 0, 0, 0);
    },

        richfaces.ui.PopupPanel.Sizer.N = function() {

        }

    $.extend(richfaces.ui.PopupPanel.Sizer.N.prototype, richfaces.ui.PopupPanel.Sizer.prototype);
    $.extend(richfaces.ui.PopupPanel.Sizer.N.prototype, {


            name: "richfaces.ui.PopupPanel.Sizer.N",

            doPosition : function (popupPanel, elt) {
                var element = $(richfaces.getDomElement(elt));
                element.css('width', popupPanel.width() + 'px');
                this.doSetupPosition(popupPanel, elt, 0, 0);
            },

            doDiff : function(dx, dy) {
                return new richfaces.ui.PopupPanel.Sizer.Diff(0, dy, 0, -dy);
            }

        });

    richfaces.ui.PopupPanel.Sizer.NW = function() {

    }
    $.extend(richfaces.ui.PopupPanel.Sizer.NW.prototype, richfaces.ui.PopupPanel.Sizer.prototype);
    $.extend(richfaces.ui.PopupPanel.Sizer.NW.prototype, {

            name: "richfaces.ui.PopupPanel.Sizer.NW",

            doPosition : function (popupPanel, elt) {
                this.doSetupSize(popupPanel, elt);
                this.doSetupPosition(popupPanel, elt, 0, 0);
            },

            doDiff : function(dx, dy) {
                return new richfaces.ui.PopupPanel.Sizer.Diff(dx, dy, -dx, -dy);
            }

        });

    richfaces.ui.PopupPanel.Sizer.NE = function() {

    }
    $.extend(richfaces.ui.PopupPanel.Sizer.NE.prototype, richfaces.ui.PopupPanel.Sizer.prototype);
    $.extend(richfaces.ui.PopupPanel.Sizer.NE.prototype, {

            name: "richfaces.ui.PopupPanel.Sizer.NE",

            doPosition : function (popupPanel, elt) {
                this.doSetupSize(popupPanel, elt);
                this.doSetupPosition(popupPanel, elt, popupPanel.width() - elt.clientWidth, 0);
            },

            doDiff : function(dx, dy) {
                return new richfaces.ui.PopupPanel.Sizer.Diff(0, dy, dx, -dy);
            }

        });

    richfaces.ui.PopupPanel.Sizer.E = function() {

    }
    $.extend(richfaces.ui.PopupPanel.Sizer.E.prototype, richfaces.ui.PopupPanel.Sizer.prototype);
    $.extend(richfaces.ui.PopupPanel.Sizer.E.prototype, {

            name: "richfaces.ui.PopupPanel.Sizer.E",

            doPosition : function (popupPanel, elt) {
                var element = $(richfaces.getDomElement(elt));
                element.css('height', popupPanel.height() + 'px');
                this.doSetupPosition(popupPanel, elt, popupPanel.width() - elt.clientWidth, 0);
            },

            doDiff : function(dx, dy) {
                return new richfaces.ui.PopupPanel.Sizer.Diff(0, 0, dx, 0);
            }

        });

    richfaces.ui.PopupPanel.Sizer.SE = function() {

    }
    $.extend(richfaces.ui.PopupPanel.Sizer.SE.prototype, richfaces.ui.PopupPanel.Sizer.prototype);
    $.extend(richfaces.ui.PopupPanel.Sizer.SE.prototype, {

            name: "richfaces.ui.PopupPanel.Sizer.SE",

            doPosition : function (popupPanel, elt) {
                this.doSetupSize(popupPanel, elt);
                this.doSetupPosition(popupPanel, elt, popupPanel.width() - elt.clientWidth,
                    popupPanel.height() - elt.clientHeight);
            },

            doDiff : function(dx, dy) {
                return new richfaces.ui.PopupPanel.Sizer.Diff(0, 0, dx, dy);
            }

        });

    richfaces.ui.PopupPanel.Sizer.S = function() {

    }
    $.extend(richfaces.ui.PopupPanel.Sizer.S.prototype, richfaces.ui.PopupPanel.Sizer.prototype);
    $.extend(richfaces.ui.PopupPanel.Sizer.S.prototype, {

            name: "richfaces.ui.PopupPanel.Sizer.S",

            doPosition : function (popupPanel, elt) {
                var element = $(richfaces.getDomElement(elt));
                element.css('width', popupPanel.width() + 'px');
                this.doSetupPosition(popupPanel, elt, 0, popupPanel.height() - elt.clientHeight);
            },

            doDiff : function(dx, dy) {
                return new richfaces.ui.PopupPanel.Sizer.Diff(0, 0, 0, dy);
            }

        });


    richfaces.ui.PopupPanel.Sizer.SW = function() {

    }
    $.extend(richfaces.ui.PopupPanel.Sizer.SW.prototype, richfaces.ui.PopupPanel.Sizer.prototype);
    $.extend(richfaces.ui.PopupPanel.Sizer.SW.prototype, {


            name: "richfaces.ui.PopupPanel.Sizer.SW",

            doPosition : function (popupPanel, elt) {
                this.doSetupSize(popupPanel, elt);
                this.doSetupPosition(popupPanel, elt, 0, popupPanel.height() - elt.clientHeight);
            },

            doDiff : function(dx, dy) {
                return new richfaces.ui.PopupPanel.Sizer.Diff(dx, 0, -dx, dy);
            }

        });

    richfaces.ui.PopupPanel.Sizer.W = function() {

    }
    $.extend(richfaces.ui.PopupPanel.Sizer.W.prototype, richfaces.ui.PopupPanel.Sizer.prototype);
    $.extend(richfaces.ui.PopupPanel.Sizer.W.prototype, {


            name: "richfaces.ui.PopupPanel.Sizer.W",

            doPosition : function (popupPanel, elt) {
                var element = $(richfaces.getDomElement(elt));
                element.css('height', popupPanel.height() + 'px');
                this.doSetupPosition(popupPanel, elt, 0, 0);
            },

            doDiff : function(dx, dy) {
                return new richfaces.ui.PopupPanel.Sizer.Diff(dx, 0, -dx, 0);
            }


        });


    richfaces.ui.PopupPanel.Sizer.Header = function() {

    }
    $.extend(richfaces.ui.PopupPanel.Sizer.Header.prototype, richfaces.ui.PopupPanel.Sizer.prototype);
    $.extend(richfaces.ui.PopupPanel.Sizer.Header.prototype, {


            name: "richfaces.ui.PopupPanel.Sizer.Header",

            doPosition : function (popupPanel, elt) {

            },

            doDiff : function(dx, dy) {
                return new richfaces.ui.PopupPanel.Sizer.Diff(dx, dy, 0, 0);
            }


        });


})(jQuery, window.RichFaces);;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.Tab = rf.ui.TogglePanelItem.extendClass({
            // class name
            name:"Tab",

            /**
             * @class AccordionItem
             * @name AccordionItem
             *
             * @constructor
             * @param {String} componentId - component id
             * @param {Hash} options - params
             * */
            init : function (componentId, options) {
                $super.constructor.call(this, componentId, options);
                this.index = options["index"];
                this.getTogglePanel().getItems()[this.index] = this;

                //TODO - optimize this
                rf.Event.bindById(this.id + ":header:active", "click", this.__onHeaderClick, this);
                rf.Event.bindById(this.id + ":header:inactive", "click", this.__onHeaderClick, this)
            },

            /***************************** Public Methods  ****************************************************************/

            __onHeaderClick : function (comp) {
                this.getTogglePanel().switchToItem(this.getName());
            },

            /**
             * @param state {string} = inactive | active | disabled
             *     in that case looking header by css class appropriate to this state
             *
             * @return {jQuery Object}
             * */
            __header : function (state) {
                var res = $(rf.getDomElement(this.id + ":header"));
                if (state) {
                    return $(rf.getDomElement(this.id + ":header:" + state));
                }

                return res;
            },

            /**
             * @return {jQuery Object}
             * */
            __content : function () {
                if (!this.__content_) {
                    this.__content_ = $(rf.getDomElement(this.id));
                }
                return this.__content_;
            },

            /**
             * @private
             *
             * used in TogglePanel
             * */
            __enter : function () {

                this.__content().show();
                this.__header("inactive").hide();
                this.__header("active").show();

                return this.__fireEnter();
            },

            __fireLeave : function () {
                return rf.Event.fireById(this.id + ":content", "leave");
            },

            __fireEnter : function () {
                return rf.Event.fireById(this.id + ":content", "enter");
            },

            __addUserEventHandler : function (name) {
                var handler = this.options["on" + name];
                if (handler) {
                    var userHandler = rf.Event.bindById(this.id + ":content", name, handler);
                }
            },

            getHeight : function (recalculate) {
                if (recalculate || !this.__height) {
                    this.__height = $(rf.getDomElement(this.id)).outerHeight(true)
                }

                return this.__height;
            },

            /**
             * @private
             *
             * used in TogglePanel
             * */
            __leave : function () {
                var continueProcess = this.__fireLeave();
                if (!continueProcess) {
                    return false;
                }

                this.__content().hide();
                this.__header("active").hide();
                this.__header("inactive").show();

                return true;
            },

            /***************************** Private Methods ********************************************************/


            destroy: function () {
                var parent = this.getTogglePanel();
                if (parent && parent.getItems && parent.getItems()[this.index]) {
                    delete parent.getItems()[this.index];
                }

                rf.Event.unbindById(this.id);

                //TODO - optimize
                rf.Event.unbindById(this.id + ":header:active");
                rf.Event.unbindById(this.id + ":header:inactive");

                $super.destroy.call(this);
            }
        });

    // define super class link
    var $super = rf.ui.Tab.$super;
})(jQuery, RichFaces);
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.AccordionItem = rf.ui.TogglePanelItem.extendClass({
            // class name
            name:"AccordionItem",

            /**
             * @class AccordionItem
             * @name AccordionItem
             *
             * @constructor
             * @param {String} componentId - component id
             * @param {Hash} options - params
             * */
            init : function (componentId, options) {
                $super.constructor.call(this, componentId, options);

                if (!this.disabled) {
                    rf.Event.bindById(this.id + ":header", "click", this.__onHeaderClick, this);
                }

                if (this.isSelected()) {
                    var item = this;
                    $(document).one("javascriptServiceComplete", function () {
                        item.__fitToHeight(item.getTogglePanel());
                    });
                }
            },

            /***************************** Public Methods  ****************************************************************/

            __onHeaderClick : function (comp) {
                this.getTogglePanel().switchToItem(this.getName());
            },

            /**
             * @return {jQuery Object}
             * */
            __header : function () {
                return $(rf.getDomElement(this.id + ":header"));
            },

            /**
             * @return {jQuery Object}
             * */
            __content : function () {
                if (!this.__content_) {
                    this.__content_ = $(rf.getDomElement(this.id + ":content"));
                }
                return this.__content_;
            },

            /**
             * @private
             *
             * used in TogglePanel
             * */
            __enter : function () {
                var parentPanel = this.getTogglePanel();
                if (parentPanel.isKeepHeight) {
                    this.__content().hide(); // TODO ?
                    this.__fitToHeight(parentPanel);
                }

                this.__content().show();
                this.__header().addClass("rf-ac-itm-hdr-act").removeClass("rf-ac-itm-hdr-inact");

                return this.__fireEnter();
            },

            __fitToHeight : function (parentPanel) {
                var h = parentPanel.getInnerHeight();

                var items = parentPanel.getItems();
                for (var i in items) {
                    h -= items[i].__header().outerHeight();
                }

                this.__content().height(h - 20); // 20 it is padding top and bottom
            },

            getHeight : function (recalculate) {
                if (recalculate || !this.__height) {
                    this.__height = $(rf.getDomElement(this.id)).outerHeight(true)
                }

                return this.__height;
            },

            /**
             * @private
             *
             * used in TogglePanel
             * */
            __leave : function () {
                var continueProcess = this.__fireLeave();
                if (!continueProcess) {
                    return false;
                }

                this.__content().hide();
                this.__header().removeClass("rf-ac-itm-hdr-act").addClass("rf-ac-itm-hdr-inact");

                return true;
            }
        });

    // define super class link
    var $super = rf.ui.AccordionItem.$super;
})(jQuery, RichFaces);
;/*!
 * jQuery UI Mouse 1.9.2
 * http://jqueryui.com
 *
 * Copyright 2012 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/mouse/
 *
 * Depends:
 *	jquery.ui.widget.js
 */
(function( $, undefined ) {

var mouseHandled = false;
$( document ).mouseup( function( e ) {
	mouseHandled = false;
});

$.widget("ui.mouse", {
	version: "1.9.2",
	options: {
		cancel: 'input,textarea,button,select,option',
		distance: 1,
		delay: 0
	},
	_mouseInit: function() {
		var that = this;

		this.element
			.bind('mousedown.'+this.widgetName, function(event) {
				return that._mouseDown(event);
			})
			.bind('click.'+this.widgetName, function(event) {
				if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
					$.removeData(event.target, that.widgetName + '.preventClickEvent');
					event.stopImmediatePropagation();
					return false;
				}
			});

		this.started = false;
	},

	// TODO: make sure destroying one instance of mouse doesn't mess with
	// other instances of mouse
	_mouseDestroy: function() {
		this.element.unbind('.'+this.widgetName);
		if ( this._mouseMoveDelegate ) {
			$(document)
				.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
				.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
		}
	},

	_mouseDown: function(event) {
		// don't let more than one widget handle mouseStart
		if( mouseHandled ) { return; }

		// we may have missed mouseup (out of window)
		(this._mouseStarted && this._mouseUp(event));

		this._mouseDownEvent = event;

		var that = this,
			btnIsLeft = (event.which === 1),
			// event.target.nodeName works around a bug in IE 8 with
			// disabled inputs (#7620)
			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
			return true;
		}

		this.mouseDelayMet = !this.options.delay;
		if (!this.mouseDelayMet) {
			this._mouseDelayTimer = setTimeout(function() {
				that.mouseDelayMet = true;
			}, this.options.delay);
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted = (this._mouseStart(event) !== false);
			if (!this._mouseStarted) {
				event.preventDefault();
				return true;
			}
		}

		// Click event may never have fired (Gecko & Opera)
		if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
			$.removeData(event.target, this.widgetName + '.preventClickEvent');
		}

		// these delegates are required to keep context
		this._mouseMoveDelegate = function(event) {
			return that._mouseMove(event);
		};
		this._mouseUpDelegate = function(event) {
			return that._mouseUp(event);
		};
		$(document)
			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);

		event.preventDefault();

		mouseHandled = true;
		return true;
	},

	_mouseMove: function(event) {
		// IE mouseup check - mouseup happened when mouse was out of window
		if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
			return this._mouseUp(event);
		}

		if (this._mouseStarted) {
			this._mouseDrag(event);
			return event.preventDefault();
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted =
				(this._mouseStart(this._mouseDownEvent, event) !== false);
			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
		}

		return !this._mouseStarted;
	},

	_mouseUp: function(event) {
		$(document)
			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);

		if (this._mouseStarted) {
			this._mouseStarted = false;

			if (event.target === this._mouseDownEvent.target) {
				$.data(event.target, this.widgetName + '.preventClickEvent', true);
			}

			this._mouseStop(event);
		}

		return false;
	},

	_mouseDistanceMet: function(event) {
		return (Math.max(
				Math.abs(this._mouseDownEvent.pageX - event.pageX),
				Math.abs(this._mouseDownEvent.pageY - event.pageY)
			) >= this.options.distance
		);
	},

	_mouseDelayMet: function(event) {
		return this.mouseDelayMet;
	},

	// These are placeholder methods, to be overriden by extending plugin
	_mouseStart: function(event) {},
	_mouseDrag: function(event) {},
	_mouseStop: function(event) {},
	_mouseCapture: function(event) { return true; }
});

})(jQuery);
;(function ($, rf) {

    rf.ui = rf.ui || {};

    // Constructor definition
    rf.ui.AutocompleteBase = function(componentId, selectId, fieldId, options) {
        // call constructor of parent class
        $super.constructor.call(this, componentId);
        this.selectId = selectId;
        this.fieldId = fieldId;
        this.options = $.extend({}, defaultOptions, options);
        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, this.selectId);
        this.currentValue = "";
        this.tempValue = this.getValue();
        this.isChanged = this.tempValue.length != 0;
        bindEventHandlers.call(this);
    };

    // Extend component class and add protected methods from parent class to our container
    rf.BaseComponent.extend(rf.ui.AutocompleteBase);

    // define super class link
    var $super = rf.ui.AutocompleteBase.$super;

    var defaultOptions = {
        changeDelay:8
    };

    var bindEventHandlers = function() {

        var inputEventHandlers = {};

        if (this.options.buttonId) {
            inputEventHandlers["mousedown" + this.namespace] = onButtonShow;
            inputEventHandlers["mouseup" + this.namespace] = onSelectMouseUp;
            rf.Event.bindById(this.options.buttonId, inputEventHandlers, this);
        }

        inputEventHandlers = {};
        inputEventHandlers["focus" + this.namespace] = onFocus;
        inputEventHandlers["blur" + this.namespace] = onBlur;
        inputEventHandlers["click" + this.namespace] = onClick;
        inputEventHandlers[($.browser.opera || $.browser.mozilla ? "keypress" : "keydown") + this.namespace] = onKeyDown;
        inputEventHandlers["change" + this.namespace] = function (event) {
            if (this.focused) {
                event.stopPropagation()
            }
        };
        rf.Event.bindById(this.fieldId, inputEventHandlers, this);

        inputEventHandlers = {};
        inputEventHandlers["mousedown" + this.namespace] = onSelectMouseDown;
        inputEventHandlers["mouseup" + this.namespace] = onSelectMouseUp;
        rf.Event.bindById(this.selectId, inputEventHandlers, this);
    };

    var onSelectMouseDown = function () {
        this.isMouseDown = true;
    };
    var onSelectMouseUp = function () {
        rf.getDomElement(this.fieldId).focus();
    };

    var onButtonShow = function (event) {
        this.isMouseDown = true;
        if (this.timeoutId) {
            window.clearTimeout(this.timeoutId);
            this.timeoutId = null;
        }

        rf.getDomElement(this.fieldId).focus();
        if (this.isVisible) {
            this.__hide(event);
        } else {
            onShow.call(this, event);
        }
    };

    var onFocus = function (event) {
        if (!this.focused) {
            this.__focusValue = this.getValue();
            this.focused = true;
            this.invokeEvent("focus", rf.getDomElement(this.fieldId), event);
        }
    };

    var onBlur = function (event) {
        if (this.isMouseDown) {
            rf.getDomElement(this.fieldId).focus();
            this.isMouseDown = false;
        } else if (!this.isMouseDown) {
            if (this.isVisible) {
                var _this = this;
                this.timeoutId = window.setTimeout(function() {
                    if (_this.isVisible) {
                        _this.__hide(event);
                    }
                }, 200);
            }
            if (this.focused) {
                this.focused = false;
                this.invokeEvent("blur", rf.getDomElement(this.fieldId), event);
                if (this.__focusValue != this.getValue()) {
                    this.invokeEvent("change", rf.getDomElement(this.fieldId), event);
                }
            }
        }
    };

    var onClick = function (event) {
    };

    var onChange = function (event) {
        if (this.isChanged) {
            if (this.getValue() == this.tempValue) return;
        }
        this.isChanged = false;
        var value = this.getValue();
        var flag = value != this.currentValue;
        //TODO: is it needed to chesk keys?
        //TODO: we need to set value when autoFill used when LEFT or RIGHT was pressed
        if (event.keyCode == rf.KEYS.LEFT || event.keyCode == rf.KEYS.RIGHT || flag) {
            if (flag) {
                this.currentValue = this.getValue();
                this.__onChangeValue(event, undefined, (!this.isVisible ? this.__show : undefined));
            } else if (this.isVisible) {
                this.__onChangeValue(event);
            }
        }
    };

    var onShow = function (event) {
        if (this.isChanged) {
            this.isChanged = false;
            onChange.call(this, {});
        } else {
            !this.__updateState(event) && this.__show(event);
        }
    };

    var onKeyDown = function (event) {
        switch (event.keyCode) {
            case rf.KEYS.UP:
                event.preventDefault();
                if (this.isVisible) {
                    this.__onKeyUp(event);
                }
                break;
            case rf.KEYS.DOWN:
                event.preventDefault();
                if (this.isVisible) {
                    this.__onKeyDown(event);
                } else {
                    onShow.call(this, event);
                }
                break;
            case rf.KEYS.PAGEUP:
                if (this.isVisible) {
                    event.preventDefault();
                    this.__onPageUp(event);
                }
                break;
            case rf.KEYS.PAGEDOWN:
                if (this.isVisible) {
                    event.preventDefault();
                    this.__onPageDown(event);
                }
                break;
            case rf.KEYS.HOME:
                if (this.isVisible) {
                    event.preventDefault();
                    this.__onKeyHome(event);
                }
                break;
            case rf.KEYS.END:
                if (this.isVisible) {
                    event.preventDefault();
                    this.__onKeyEnd(event);
                }
                break;
            case rf.KEYS.RETURN:
                if (this.isVisible) {
                    event.preventDefault();
                    this.__onEnter(event);
                    //TODO: bind form submit event handler to cancel form submit under the opera
                    //cancelSubmit = true;
                    this.__hide(event);
                    return false;
                }
                break;
            case rf.KEYS.ESC:
                this.__hide(event);
                break;
            default:
                if (!this.options.selectOnly) {
                    var _this = this;
                    window.clearTimeout(this.changeTimerId);
                    this.changeTimerId = window.setTimeout(function() {
                        onChange.call(_this, event);
                    }, this.options.changeDelay)
                }
                break;
        }
    };

    /*
     * public API functions definition
     */
    var show = function (event) {
        if (!this.isVisible) {
            if (this.__onBeforeShow(event) != false) {
                this.scrollElements = rf.Event.bindScrollEventHandlers(this.selectId, this.__hide, this, this.namespace);
                var element = rf.getDomElement(this.selectId);
                if (this.options.attachToBody) {
                    this.parentElement = element.parentNode;
                    document.body.appendChild(element);
                }
                $(element).setPosition({id: this.fieldId}, {type:"DROPDOWN"}).show();
                this.isVisible = true;
                this.__onShow(event);
            }
        }
    };
    var hide = function (event) {
        if (this.isVisible) {
            this.__conceal();
            this.isVisible = false;
            this.__onHide(event);
        }
    };
    
    var conceal = function () {
        if (this.isVisible) {
            if (this.scrollElements) {
                rf.Event.unbindScrollEventHandlers(this.scrollElements, this);
                this.scrollElements = null;
            }
            $(rf.getDomElement(this.selectId)).hide();
            if (this.options.attachToBody && this.parentElement) {
                this.parentElement.appendChild(rf.getDomElement(this.selectId));
                this.parentElement = null;
            }
        }
    };

    var updateInputValue = function (value) {
        if (this.fieldId) {
            rf.getDomElement(this.fieldId).value = value;
            return value;
        } else {
            return "";
        }
    };

    /*
     * Prototype definition
     */
    $.extend(rf.ui.AutocompleteBase.prototype, (function () {
        return {
            /*
             * public API functions
             */
            name:"AutocompleteBase",
            showPopup: function (event) {
                if (!this.focused) {
                    rf.getDomElement(this.fieldId).focus();
                }
                onShow.call(this, event);
            },
            hidePopup: function (event) {
                this.__hide(event)
            },
            getNamespace: function () {
                return this.namespace;
            },
            getValue: function () {
                return this.fieldId ? rf.getDomElement(this.fieldId).value : "";
            },
            setValue: function (value) {
                if (value == this.currentValue) return;
                updateInputValue.call(this, value);
                this.isChanged = true;
            },
            /*
             * Protected methods
             */
            __updateInputValue: updateInputValue,
            __show: show,
            __hide: hide,
            __conceal: conceal,
            /*
             * abstract protected methods
             */
            __onChangeValue: function (event) {
            },
            __onKeyUp: function (event) {
            },
            __onKeyDown: function (event) {
            },
            __onPageUp: function (event) {
            },
            __onPageDown: function (event) {
            },
            __onKeyHome: function (event) {
            },
            __onKeyEnd: function (event) {
            },
            __onBeforeShow: function (event) {
            },
            __onShow: function (event) {
            },
            __onHide: function (event) {
            },
            /*
             * Destructor
             */
            destroy: function () {
                this.parentNode = null;
                if (this.scrollElements) {
                    rf.Event.unbindScrollEventHandlers(this.scrollElements, this);
                    this.scrollElements = null;
                }
                this.options.buttonId && rf.Event.unbindById(this.options.buttonId, this.namespace);
                rf.Event.unbindById(this.fieldId, this.namespace);
                rf.Event.unbindById(this.selectId, this.namespace);
                $super.destroy.call(this);
            }
        };
    })());
})(jQuery, RichFaces);
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.CollapsiblePanel = rf.ui.TogglePanel.extendClass({

            name:"CollapsiblePanel",

            /**
             * @class CollapsiblePanel
             * @name CollapsiblePanel
             *
             * @constructor
             * @param {String} componentId - component id
             * @param {Hash} options - params
             * */
            init : function (componentId, options) {
                rf.ui.TogglePanel.call(this, componentId, options);
                this.switchMode = options.switchMode;

                this.__addUserEventHandler("beforeswitch");
                this.__addUserEventHandler("switch");

                this.options.cycledSwitching = true;

                var panel = this;
                $(document.getElementById(this.id)).ready(function () { // TODO
                    rf.Event.bindById(panel.id + ":header", "click", panel.__onHeaderClick, panel);

                    new RichFaces.ui.CollapsiblePanelItem(
                        panel.id + ":content", {"index":0, "togglePanelId":panel.id, "switchMode":panel.switchMode, "name":"true"}),

                        new RichFaces.ui.CollapsiblePanelItem(
                            panel.id + ":empty", {"index":1, "togglePanelId":panel.id, "switchMode":panel.switchMode, "name":"false"})
                })
            },

            switchPanel : function (to) {
                this.switchToItem(to || "@next");
            },

            /***************************** Private Methods ********************************************************/

            __onHeaderClick : function () {
                this.switchToItem("@next");
            },

            __fireItemChange : function (oldItem, newItem) {
                return new rf.Event.fireById(this.id, "switch", {
                        id: this.id,
                        isExpanded : newItem.getName()
                    });
            },

            __fireBeforeItemChange : function (oldItem, newItem) {
                return rf.Event.fireById(this.id, "beforeswitch", {
                        id: this.id,
                        isExpanded : newItem.getName()
                    });
            }
        });
})(jQuery, RichFaces);
;/* SpinButton control
 *
 * Adds bells and whistles to any ordinary textbox to
 * make it look and feel like a SpinButton Control.
 *
 * Originally written by George Adamson, Software Unity (george.jquery@softwareunity.com) August 2006.
 * - Added min/max options
 * - Added step size option
 * - Added bigStep (page up/down) option
 *
 * Modifications made by Mark Gibson, (mgibson@designlinks.net) September 2006:
 * - Converted to jQuery plugin
 * - Allow limited or unlimited min/max values
 * - Allow custom class names, and add class to input element
 * - Removed global vars
 * - Reset (to original or through config) when invalid value entered
 * - Repeat whilst holding mouse button down (with initial pause, like keyboard repeat)
 * - Support mouse wheel in Firefox
 * - Fix double click in IE
 * - Refactored some code and renamed some vars
 *
 * Tested in IE6, Opera9, Firefox 1.5
 * v1.0  11 Aug 2006 - George Adamson	- First release
 * v1.1     Aug 2006 - George Adamson	- Minor enhancements
 * v1.2  27 Sep 2006 - Mark Gibson		- Major enhancements
 * v1.3a 28 Sep 2006 - George Adamson	- Minor enhancements
 * rf1.3a 15 Nov 2007 - Pavel Yaschenko - some changes
 
 Sample usage:
 
	// Create group of settings to initialise spinbutton(s). (Optional)
	var myOptions = {
					min: 0,						// Set lower limit.
					max: 100,					// Set upper limit.
					step: 1,					// Set increment size.
					spinClass: mySpinBtnClass,	// CSS class to style the spinbutton. (Class also specifies url of the up/down button image.)
					upClass: mySpinUpClass,		// CSS class for style when mouse over up button.
					downClass: mySpinDnClass	// CSS class for style when mouse over down button.
					}
 
	$(document).ready(function(){

		// Initialise INPUT element(s) as SpinButtons: (passing options if desired)
		$("#myInputElement").SpinButton(myOptions);

	});
 
 */
var sbjQuery = jQuery;
sbjQuery.fn.SpinButton = function(cfg){
	return this.each(function(){

		// Apply specified options or defaults:
		// (Ought to refactor this some day to use $.extend() instead)
		this.spinCfg = {
			//min: cfg && cfg.min ? Number(cfg.min) : null,
			//max: cfg && cfg.max ? Number(cfg.max) : null,
			min: cfg && !isNaN(parseFloat(cfg.min)) ? Number(cfg.min) : null,	// Fixes bug with min:0
			max: cfg && !isNaN(parseFloat(cfg.max)) ? Number(cfg.max) : null,
			step: cfg && cfg.step ? Number(cfg.step) : 1,
			page: cfg && cfg.page ? Number(cfg.page) : 10,
			upClass: cfg && cfg.upClass ? cfg.upClass : 'up',
			downClass: cfg && cfg.downClass ? cfg.downClass : 'down',
			reset: cfg && cfg.reset ? cfg.reset : this.value,
			delay: cfg && cfg.delay ? Number(cfg.delay) : 500,
			interval: cfg && cfg.interval ? Number(cfg.interval) : 100,
			_btn_width: 20,
			_btn_height: 12,
			_direction: null,
			_delay: null,
			_repeat: null,
			
			digits: cfg && cfg.digits ? Number(cfg.digits) : 1			
		};
		
		this.adjustValue = function(i){
			var v = this.value.toLowerCase();
			if (v=="am") 
			{
				this.value="PM";
				return; 
			}
			else if (v=="pm") {
				this.value="AM";
				return;
			} 
			v = (isNaN(this.value) ? this.spinCfg.reset : Number(this.value)) + Number(i);
			if (this.spinCfg.min !== null) v = (v<this.spinCfg.min ? (this.spinCfg.max != null ? this.spinCfg.max : this.spinCfg.min) : v);
			if (this.spinCfg.max !== null) v = (v>this.spinCfg.max ? (this.spinCfg.min != null ? this.spinCfg.min : this.spinCfg.max) : v);

			var value = String(v);
			while (value.length<this.spinCfg.digits) value="0"+value;
			
			this.value = value;
		};
		
		sbjQuery(this)
//		.addClass(cfg && cfg.spinClass ? cfg.spinClass : 'spin-button')
//		
//		.mousemove(function(e){
//			// Determine which button mouse is over, or not (spin direction):
//			var x = e.pageX || e.x;
//			var y = e.pageY || e.y;
//			var el = e.target || e.srcElement;
//			var direction = 
//				(x > coord(el,'offsetLeft') + el.offsetWidth - this.spinCfg._btn_width)
//				? ((y < coord(el,'offsetTop') + this.spinCfg._btn_height) ? 1 : -1) : 0;
//			
//			if (direction !== this.spinCfg._direction) {
//				// Style up/down buttons:
//				switch(direction){
//					case 1: // Up arrow:
//						sbjQuery(this).removeClass(this.spinCfg.downClass).addClass(this.spinCfg.upClass);
//						break;
//					case -1: // Down arrow:
//						sbjQuery(this).removeClass(this.spinCfg.upClass).addClass(this.spinCfg.downClass);
//						break;
//					default: // Mouse is elsewhere in the textbox
//						sbjQuery(this).removeClass(this.spinCfg.upClass).removeClass(this.spinCfg.downClass);
//				}
//				
//				// Set spin direction:
//				this.spinCfg._direction = direction;
//			}
//		})
//		
//		.mouseout(function(){
//			// Reset up/down buttons to their normal appearance when mouse moves away:
//			sbjQuery(this).removeClass(this.spinCfg.upClass).removeClass(this.spinCfg.downClass);
//			this.spinCfg._direction = null;
//		})
		
//		.mousedown(function(e){
//			if (this.spinCfg._direction != 0) {
//				// Respond to click on one of the buttons:
//				var self = this;
//				var adjust = function() {
//					self.adjustValue(self.spinCfg._direction * self.spinCfg.step);
//				};
//			
//				adjust();
//				
//				// Initial delay before repeating adjustment
//				self.spinCfg._delay = window.setTimeout(function() {
//					adjust();
//					// Repeat adjust at regular intervals
//					self.spinCfg._repeat = window.setInterval(adjust, self.spinCfg.interval);
//				}, self.spinCfg.delay);
//			}
//		})
//		
//		.mouseup(function(e){
//			// Cancel repeating adjustment
//			window.clearInterval(this.spinCfg._repeat);
//			window.clearTimeout(this.spinCfg._delay);
//		})
//		
//		.dblclick(function(e) {
//			if (sbjQuery.browser.msie)
//				this.adjustValue(this.spinCfg._direction * this.spinCfg.step);
//		})
		
		.keydown(function(e){
			// Respond to up/down arrow keys.
			switch(e.keyCode){
				case 38: this.adjustValue(this.spinCfg.step);  break; // Up
				case 40: this.adjustValue(-this.spinCfg.step); break; // Down
				case 33: this.adjustValue(this.spinCfg.page);  break; // PageUp
				case 34: this.adjustValue(-this.spinCfg.page); break; // PageDown
			}
		})

		.bind("mousewheel", function(e){
			// Respond to mouse wheel in IE. (It returns up/dn motion in multiples of 120)
			if (e.wheelDelta >= 120)
				this.adjustValue(this.spinCfg.step);
			else if (e.wheelDelta <= -120)
				this.adjustValue(-this.spinCfg.step);
			
			e.preventDefault();
		})
		
		.change(function(e){
			this.adjustValue(0);
		});
		
		var self = this;
		
		var btnUp = document.getElementById(this.id + 'BtnUp');
		sbjQuery(btnUp)
			.mousedown(function(e){
				// Respond to click on one of the buttons:
				var adjust = function() {
					self.adjustValue(self.spinCfg.step);
				};
			
				adjust();
				
				// Initial delay before repeating adjustment
				self.spinCfg._delay = window.setTimeout(function() {
					adjust();
					// Repeat adjust at regular intervals
					self.spinCfg._repeat = window.setInterval(adjust, self.spinCfg.interval);
				}, self.spinCfg.delay);
				self.spinCfg._repeater = true;
				return false;
			})
			
			.mouseup(function(e){
				// Cancel repeating adjustment
				self.spinCfg._repeater = false;
				window.clearInterval(self.spinCfg._repeat);
				window.clearTimeout(self.spinCfg._delay);
			})
			
			.dblclick(function(e) {
				if (sbjQuery.browser.msie)
					self.adjustValue(self.spinCfg.step);
			})
			.mouseout(function(e){
				// Cancel repeating adjustment
				if (self.spinCfg._repeater)
				{
					self.spinCfg._repeater = false
					window.clearInterval(self.spinCfg._repeat);
					window.clearTimeout(self.spinCfg._delay);
				}
			});
		
		var btnDown = document.getElementById(this.id + 'BtnDown');
		sbjQuery(btnDown)
			.mousedown(function(e){
				// Respond to click on one of the buttons:
				var adjust = function() {
					self.adjustValue(-self.spinCfg.step);
				};
			
				adjust();
				
				// Initial delay before repeating adjustment
				self.spinCfg._delay = window.setTimeout(function() {
					adjust();
					// Repeat adjust at regular intervals
					self.spinCfg._repeat = window.setInterval(adjust, self.spinCfg.interval);
				}, self.spinCfg.delay);
				self.spinCfg._repeater = true;
				return false;
			})
			
			.mouseup(function(e){
				// Cancel repeating adjustment
				self.spinCfg._repeater = false;
				window.clearInterval(self.spinCfg._repeat);
				window.clearTimeout(self.spinCfg._delay);
			})
			
			.dblclick(function(e) {
				if (sbjQuery.browser.msie)
					self.adjustValue(-self.spinCfg.step);
			})
			.mouseout(function(e){
				// Cancel repeating adjustment
				if (self.spinCfg._repeater)
				{
					self.spinCfg._repeater = false
					window.clearInterval(self.spinCfg._repeat);
					window.clearTimeout(self.spinCfg._delay);
				}
			});
			
		
		if (this.addEventListener) {
			// Respond to mouse wheel in Firefox
			this.addEventListener('DOMMouseScroll', function(e) {
				if (e.detail > 0)
					this.adjustValue(-this.spinCfg.step);
				else if (e.detail < 0)
					this.adjustValue(this.spinCfg.step);
				
				e.preventDefault();
			}, false);
		}
	});
	
	function coord(el,prop) {
		var c = el[prop], b = document.body;
		
		while ((el = el.offsetParent) && (el != b)) {
			if (!sbjQuery.browser.msie || (el.currentStyle.position != 'relative'))
				c += el[prop];
		}
		
		return c;
	}
};
;(function($, rf) {
    
    rf.ui = rf.ui || {};
    
    var defaultOptions = {
        position: "tr",
        direction: "vertical",
        method: "last",
        notifications: [],
        addNotification: function(pnotify) {
            this.notifications.push(pnotify);
        }
    };

    rf.ui.NotifyStack = rf.BaseComponent.extendClass({
        
        name : "NotifyStack",

        init : function(componentId, options) {
            $super.constructor.call(this, componentId);
            this.attachToDom(this.id);
            this.__initializeStack(options);
        },
        
        __initializeStack : function(options) {
            var stack = $.extend({}, $.pnotify.defaults.pnotify_stack, defaultOptions, options);
            
            var isVertical = (stack.direction == 'vertical');
            var isFirst = (stack.method == 'first');
            
            stack.push = isFirst ? 'top' : 'bottom';
            
            switch (stack.position) {
                case "tl": // topLeft
                    stack.dir1 = isVertical ? 'down' : 'right';
                    stack.dir2 = isVertical ? 'right' : 'down';
                    break;
                case "tr": // topRight
                    stack.dir1 = isVertical ? 'down' : 'left';
                    stack.dir2 = isVertical ? 'left' : 'down';
                    break;
                case "bl": // bottomLeft
                    stack.dir1 = isVertical ? 'up' : 'right';
                    stack.dir2 = isVertical ? 'right' : 'up';
                    break;
                case "br": // bottomRight
                    stack.dir1 = isVertical ? 'up' : 'left';
                    stack.dir2 = isVertical ? 'left' : 'up';
                    break;
                default:
                    throw "wrong stack position: " + stack.position;
            }
            
            this.stack = stack;
        },
    
        getStack : function() {
            return this.stack;
        },
        
        removeNotifications: function() {
            var pnotify;
            while (pnotify = this.stack.notifications.pop()) {
                pnotify.pnotify_remove();
            }
        },
        
        destroy : function() {
            this.removeNotifications();
            this.stack = null;
            $super.destroy.call(this);
        }
    });
    
    var $super = rf.ui.NotifyStack.$super;

})(jQuery, RichFaces);;(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.InplaceBase = function(id, options) {
        $super.constructor.call(this, id);
        var mergedOptions = $.extend({}, defaultOptions, options);
        this.editEvent = mergedOptions.editEvent;
        this.noneCss = mergedOptions.noneCss;
        this.changedCss = mergedOptions.changedCss;
        this.editCss = mergedOptions.editCss;
        this.defaultLabel = mergedOptions.defaultLabel;
        this.state = mergedOptions.state;

        this.options = mergedOptions;

        this.element = $(document.getElementById(id));
        this.editContainer = $(document.getElementById(id + "Edit"));
        this.element.bind(this.editEvent, $.proxy(this.__editHandler, this));
        this.isSaved = false;
        this.useDefaultLabel = false;
        this.editState = false;
    };

    rf.ui.InputBase.extend(rf.ui.InplaceBase);
    var $super = rf.ui.InplaceBase.$super;

    var defaultOptions = {
        editEvent: "click",
        state: "ready"
    };

    $.extend(rf.ui.InplaceBase.prototype, ( function () {

        var STATE = {
            READY : 'ready',
            CHANGED: 'changed',
            DISABLE: 'disable',
            EDIT: 'edit'
        };

        return {

            getLabel: function() {
            },

            setLabel: function(value) {
            },

            onshow: function() {
            },

            onhide: function() {
            },

            onsave: function() {
            },

            oncancel: function() {
            },

            save: function() {
                var value = this.__getValue()
                if (value.length > 0) {
                    this.setLabel(value);
                    this.useDefaultLabel = false;
                } else {
                    this.setLabel(this.defaultLabel);
                    this.useDefaultLabel = true;
                }

                this.isSaved = true;

                this.__applyChangedStyles();
                this.onsave();
            },

            cancel: function() {
                var text = "";
                if (!this.useDefaultLabel) {
                    text = this.getLabel();
                }
                this.__setValue(text);
                this.isSaved = true;
                this.oncancel();
            },

            isValueSaved: function() {
                return this.isSaved;
            },

            isEditState: function() {
                return this.editState;
            },

            __applyChangedStyles: function() {
                if (this.isValueChanged()) {
                    this.element.addClass(this.changedCss);
                } else {
                    this.element.removeClass(this.changedCss);
                }
            },

            __show: function() {
                this.scrollElements = rf.Event.bindScrollEventHandlers(this.id, this.__scrollHandler, this);
                this.editState = true;
                this.onshow();
            },

            __hide: function() {
                if (this.scrollElements) {
                    rf.Event.unbindScrollEventHandlers(this.scrollElements, this);
                    this.scrollElements = null;
                }
                this.editState = false;
                this.editContainer.addClass(this.noneCss);
                this.element.removeClass(this.editCss);
                this.onhide();
            },

            __editHandler: function(e) {
                this.isSaved = false;
                this.element.addClass(this.editCss);
                this.editContainer.removeClass(this.noneCss);
                this.__show();
            },
            __scrollHandler: function(e) {
                this.cancel();
            },

            destroy: function () {
                $super.destroy.call(this);
            }
        }

    })());

})(jQuery, window.RichFaces);
;/*!
 * jQuery UI Draggable 1.9.2
 * http://jqueryui.com
 *
 * Copyright 2012 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/draggable/
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.mouse.js
 *	jquery.ui.widget.js
 */
(function( $, undefined ) {

$.widget("ui.draggable", $.ui.mouse, {
	version: "1.9.2",
	widgetEventPrefix: "drag",
	options: {
		addClasses: true,
		appendTo: "parent",
		axis: false,
		connectToSortable: false,
		containment: false,
		cursor: "auto",
		cursorAt: false,
		grid: false,
		handle: false,
		helper: "original",
		iframeFix: false,
		opacity: false,
		refreshPositions: false,
		revert: false,
		revertDuration: 500,
		scope: "default",
		scroll: true,
		scrollSensitivity: 20,
		scrollSpeed: 20,
		snap: false,
		snapMode: "both",
		snapTolerance: 20,
		stack: false,
		zIndex: false
	},
	_create: function() {

		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
			this.element[0].style.position = 'relative';

		(this.options.addClasses && this.element.addClass("ui-draggable"));
		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));

		this._mouseInit();

	},

	_destroy: function() {
		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
		this._mouseDestroy();
	},

	_mouseCapture: function(event) {

		var o = this.options;

		// among others, prevent a drag on a resizable-handle
		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
			return false;

		//Quit if we're not on a valid handle
		this.handle = this._getHandle(event);
		if (!this.handle)
			return false;

		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
			.css({
				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
				position: "absolute", opacity: "0.001", zIndex: 1000
			})
			.css($(this).offset())
			.appendTo("body");
		});

		return true;

	},

	_mouseStart: function(event) {

		var o = this.options;

		//Create and append the visible helper
		this.helper = this._createHelper(event);

		this.helper.addClass("ui-draggable-dragging");

		//Cache the helper size
		this._cacheHelperProportions();

		//If ddmanager is used for droppables, set the global draggable
		if($.ui.ddmanager)
			$.ui.ddmanager.current = this;

		/*
		 * - Position generation -
		 * This block generates everything position related - it's the core of draggables.
		 */

		//Cache the margins of the original element
		this._cacheMargins();

		//Store the helper's css position
		this.cssPosition = this.helper.css("position");
		this.scrollParent = this.helper.scrollParent();

		//The element's absolute position on the page minus margins
		this.offset = this.positionAbs = this.element.offset();
		this.offset = {
			top: this.offset.top - this.margins.top,
			left: this.offset.left - this.margins.left
		};

		$.extend(this.offset, {
			click: { //Where the click happened, relative to the element
				left: event.pageX - this.offset.left,
				top: event.pageY - this.offset.top
			},
			parent: this._getParentOffset(),
			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
		});

		//Generate the original position
		this.originalPosition = this.position = this._generatePosition(event);
		this.originalPageX = event.pageX;
		this.originalPageY = event.pageY;

		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));

		//Set a containment if given in the options
		if(o.containment)
			this._setContainment();

		//Trigger event + callbacks
		if(this._trigger("start", event) === false) {
			this._clear();
			return false;
		}

		//Recache the helper size
		this._cacheHelperProportions();

		//Prepare the droppable offsets
		if ($.ui.ddmanager && !o.dropBehaviour)
			$.ui.ddmanager.prepareOffsets(this, event);


		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position

		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
		if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);

		return true;
	},

	_mouseDrag: function(event, noPropagation) {

		//Compute the helpers position
		this.position = this._generatePosition(event);
		this.positionAbs = this._convertPositionTo("absolute");

		//Call plugins and callbacks and use the resulting position if something is returned
		if (!noPropagation) {
			var ui = this._uiHash();
			if(this._trigger('drag', event, ui) === false) {
				this._mouseUp({});
				return false;
			}
			this.position = ui.position;
		}

		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);

		return false;
	},

	_mouseStop: function(event) {

		//If we are using droppables, inform the manager about the drop
		var dropped = false;
		if ($.ui.ddmanager && !this.options.dropBehaviour)
			dropped = $.ui.ddmanager.drop(this, event);

		//if a drop comes from outside (a sortable)
		if(this.dropped) {
			dropped = this.dropped;
			this.dropped = false;
		}

		//if the original element is no longer in the DOM don't bother to continue (see #8269)
		var element = this.element[0], elementInDom = false;
		while ( element && (element = element.parentNode) ) {
			if (element == document ) {
				elementInDom = true;
			}
		}
		if ( !elementInDom && this.options.helper === "original" )
			return false;

		if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
			var that = this;
			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
				if(that._trigger("stop", event) !== false) {
					that._clear();
				}
			});
		} else {
			if(this._trigger("stop", event) !== false) {
				this._clear();
			}
		}

		return false;
	},

	_mouseUp: function(event) {
		//Remove frame helpers
		$("div.ui-draggable-iframeFix").each(function() {
			this.parentNode.removeChild(this);
		});

		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
		if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);

		return $.ui.mouse.prototype._mouseUp.call(this, event);
	},

	cancel: function() {

		if(this.helper.is(".ui-draggable-dragging")) {
			this._mouseUp({});
		} else {
			this._clear();
		}

		return this;

	},

	_getHandle: function(event) {

		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
		$(this.options.handle, this.element)
			.find("*")
			.andSelf()
			.each(function() {
				if(this == event.target) handle = true;
			});

		return handle;

	},

	_createHelper: function(event) {

		var o = this.options;
		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);

		if(!helper.parents('body').length)
			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));

		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
			helper.css("position", "absolute");

		return helper;

	},

	_adjustOffsetFromHelper: function(obj) {
		if (typeof obj == 'string') {
			obj = obj.split(' ');
		}
		if ($.isArray(obj)) {
			obj = {left: +obj[0], top: +obj[1] || 0};
		}
		if ('left' in obj) {
			this.offset.click.left = obj.left + this.margins.left;
		}
		if ('right' in obj) {
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
		}
		if ('top' in obj) {
			this.offset.click.top = obj.top + this.margins.top;
		}
		if ('bottom' in obj) {
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
		}
	},

	_getParentOffset: function() {

		//Get the offsetParent and cache its position
		this.offsetParent = this.helper.offsetParent();
		var po = this.offsetParent.offset();

		// This is a special case where we need to modify a offset calculated on start, since the following happened:
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
			po.left += this.scrollParent.scrollLeft();
			po.top += this.scrollParent.scrollTop();
		}

		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
			po = { top: 0, left: 0 };

		return {
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
		};

	},

	_getRelativeOffset: function() {

		if(this.cssPosition == "relative") {
			var p = this.element.position();
			return {
				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
			};
		} else {
			return { top: 0, left: 0 };
		}

	},

	_cacheMargins: function() {
		this.margins = {
			left: (parseInt(this.element.css("marginLeft"),10) || 0),
			top: (parseInt(this.element.css("marginTop"),10) || 0),
			right: (parseInt(this.element.css("marginRight"),10) || 0),
			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
		};
	},

	_cacheHelperProportions: function() {
		this.helperProportions = {
			width: this.helper.outerWidth(),
			height: this.helper.outerHeight()
		};
	},

	_setContainment: function() {

		var o = this.options;
		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
		if(o.containment == 'document' || o.containment == 'window') this.containment = [
			o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
			o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
			(o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
			(o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
		];

		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
			var c = $(o.containment);
			var ce = c[0]; if(!ce) return;
			var co = c.offset();
			var over = ($(ce).css("overflow") != 'hidden');

			this.containment = [
				(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
				(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
				(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
				(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
			];
			this.relative_container = c;

		} else if(o.containment.constructor == Array) {
			this.containment = o.containment;
		}

	},

	_convertPositionTo: function(d, pos) {

		if(!pos) pos = this.position;
		var mod = d == "absolute" ? 1 : -1;
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);

		return {
			top: (
				pos.top																	// The absolute mouse position
				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
			),
			left: (
				pos.left																// The absolute mouse position
				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
			)
		};

	},

	_generatePosition: function(event) {

		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
		var pageX = event.pageX;
		var pageY = event.pageY;

		/*
		 * - Position constraining -
		 * Constrain the position to a mix of grid, containment.
		 */

		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
			var containment;
			if(this.containment) {
			if (this.relative_container){
				var co = this.relative_container.offset();
				containment = [ this.containment[0] + co.left,
					this.containment[1] + co.top,
					this.containment[2] + co.left,
					this.containment[3] + co.top ];
			}
			else {
				containment = this.containment;
			}

				if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
				if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
				if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
				if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
			}

			if(o.grid) {
				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
				var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
				pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;

				var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
				pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
			}

		}

		return {
			top: (
				pageY																// The absolute mouse position
				- this.offset.click.top													// Click offset (relative to the element)
				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
			),
			left: (
				pageX																// The absolute mouse position
				- this.offset.click.left												// Click offset (relative to the element)
				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
			)
		};

	},

	_clear: function() {
		this.helper.removeClass("ui-draggable-dragging");
		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
		this.helper = null;
		this.cancelHelperRemoval = false;
	},

	// From now on bulk stuff - mainly helpers

	_trigger: function(type, event, ui) {
		ui = ui || this._uiHash();
		$.ui.plugin.call(this, type, [event, ui]);
		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
		return $.Widget.prototype._trigger.call(this, type, event, ui);
	},

	plugins: {},

	_uiHash: function(event) {
		return {
			helper: this.helper,
			position: this.position,
			originalPosition: this.originalPosition,
			offset: this.positionAbs
		};
	}

});

$.ui.plugin.add("draggable", "connectToSortable", {
	start: function(event, ui) {

		var inst = $(this).data("draggable"), o = inst.options,
			uiSortable = $.extend({}, ui, { item: inst.element });
		inst.sortables = [];
		$(o.connectToSortable).each(function() {
			var sortable = $.data(this, 'sortable');
			if (sortable && !sortable.options.disabled) {
				inst.sortables.push({
					instance: sortable,
					shouldRevert: sortable.options.revert
				});
				sortable.refreshPositions();	// Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
				sortable._trigger("activate", event, uiSortable);
			}
		});

	},
	stop: function(event, ui) {

		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
		var inst = $(this).data("draggable"),
			uiSortable = $.extend({}, ui, { item: inst.element });

		$.each(inst.sortables, function() {
			if(this.instance.isOver) {

				this.instance.isOver = 0;

				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)

				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
				if(this.shouldRevert) this.instance.options.revert = true;

				//Trigger the stop of the sortable
				this.instance._mouseStop(event);

				this.instance.options.helper = this.instance.options._helper;

				//If the helper has been the original item, restore properties in the sortable
				if(inst.options.helper == 'original')
					this.instance.currentItem.css({ top: 'auto', left: 'auto' });

			} else {
				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
				this.instance._trigger("deactivate", event, uiSortable);
			}

		});

	},
	drag: function(event, ui) {

		var inst = $(this).data("draggable"), that = this;

		var checkPos = function(o) {
			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
			var itemHeight = o.height, itemWidth = o.width;
			var itemTop = o.top, itemLeft = o.left;

			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
		};

		$.each(inst.sortables, function(i) {

			var innermostIntersecting = false;
			var thisSortable = this;
			//Copy over some variables to allow calling the sortable's native _intersectsWith
			this.instance.positionAbs = inst.positionAbs;
			this.instance.helperProportions = inst.helperProportions;
			this.instance.offset.click = inst.offset.click;

			if(this.instance._intersectsWith(this.instance.containerCache)) {
				innermostIntersecting = true;
				$.each(inst.sortables, function () {
					this.instance.positionAbs = inst.positionAbs;
					this.instance.helperProportions = inst.helperProportions;
					this.instance.offset.click = inst.offset.click;
					if  (this != thisSortable
						&& this.instance._intersectsWith(this.instance.containerCache)
						&& $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
						innermostIntersecting = false;
						return innermostIntersecting;
				});
			}


			if(innermostIntersecting) {
				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
				if(!this.instance.isOver) {

					this.instance.isOver = 1;
					//Now we fake the start of dragging for the sortable instance,
					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
					//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
					this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
					this.instance.options.helper = function() { return ui.helper[0]; };

					event.target = this.instance.currentItem[0];
					this.instance._mouseCapture(event, true);
					this.instance._mouseStart(event, true, true);

					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
					this.instance.offset.click.top = inst.offset.click.top;
					this.instance.offset.click.left = inst.offset.click.left;
					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;

					inst._trigger("toSortable", event);
					inst.dropped = this.instance.element; //draggable revert needs that
					//hack so receive/update callbacks work (mostly)
					inst.currentItem = inst.element;
					this.instance.fromOutside = inst;

				}

				//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
				if(this.instance.currentItem) this.instance._mouseDrag(event);

			} else {

				//If it doesn't intersect with the sortable, and it intersected before,
				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
				if(this.instance.isOver) {

					this.instance.isOver = 0;
					this.instance.cancelHelperRemoval = true;

					//Prevent reverting on this forced stop
					this.instance.options.revert = false;

					// The out event needs to be triggered independently
					this.instance._trigger('out', event, this.instance._uiHash(this.instance));

					this.instance._mouseStop(event, true);
					this.instance.options.helper = this.instance.options._helper;

					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
					this.instance.currentItem.remove();
					if(this.instance.placeholder) this.instance.placeholder.remove();

					inst._trigger("fromSortable", event);
					inst.dropped = false; //draggable revert needs that
				}

			};

		});

	}
});

$.ui.plugin.add("draggable", "cursor", {
	start: function(event, ui) {
		var t = $('body'), o = $(this).data('draggable').options;
		if (t.css("cursor")) o._cursor = t.css("cursor");
		t.css("cursor", o.cursor);
	},
	stop: function(event, ui) {
		var o = $(this).data('draggable').options;
		if (o._cursor) $('body').css("cursor", o._cursor);
	}
});

$.ui.plugin.add("draggable", "opacity", {
	start: function(event, ui) {
		var t = $(ui.helper), o = $(this).data('draggable').options;
		if(t.css("opacity")) o._opacity = t.css("opacity");
		t.css('opacity', o.opacity);
	},
	stop: function(event, ui) {
		var o = $(this).data('draggable').options;
		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
	}
});

$.ui.plugin.add("draggable", "scroll", {
	start: function(event, ui) {
		var i = $(this).data("draggable");
		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
	},
	drag: function(event, ui) {

		var i = $(this).data("draggable"), o = i.options, scrolled = false;

		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {

			if(!o.axis || o.axis != 'x') {
				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
			}

			if(!o.axis || o.axis != 'y') {
				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
			}

		} else {

			if(!o.axis || o.axis != 'x') {
				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
			}

			if(!o.axis || o.axis != 'y') {
				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
			}

		}

		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
			$.ui.ddmanager.prepareOffsets(i, event);

	}
});

$.ui.plugin.add("draggable", "snap", {
	start: function(event, ui) {

		var i = $(this).data("draggable"), o = i.options;
		i.snapElements = [];

		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
			var $t = $(this); var $o = $t.offset();
			if(this != i.element[0]) i.snapElements.push({
				item: this,
				width: $t.outerWidth(), height: $t.outerHeight(),
				top: $o.top, left: $o.left
			});
		});

	},
	drag: function(event, ui) {

		var inst = $(this).data("draggable"), o = inst.options;
		var d = o.snapTolerance;

		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;

		for (var i = inst.snapElements.length - 1; i >= 0; i--){

			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;

			//Yes, I know, this is insane ;)
			if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
				if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
				inst.snapElements[i].snapping = false;
				continue;
			}

			if(o.snapMode != 'inner') {
				var ts = Math.abs(t - y2) <= d;
				var bs = Math.abs(b - y1) <= d;
				var ls = Math.abs(l - x2) <= d;
				var rs = Math.abs(r - x1) <= d;
				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
			}

			var first = (ts || bs || ls || rs);

			if(o.snapMode != 'outer') {
				var ts = Math.abs(t - y1) <= d;
				var bs = Math.abs(b - y2) <= d;
				var ls = Math.abs(l - x1) <= d;
				var rs = Math.abs(r - x2) <= d;
				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
			}

			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);

		};

	}
});

$.ui.plugin.add("draggable", "stack", {
	start: function(event, ui) {

		var o = $(this).data("draggable").options;

		var group = $.makeArray($(o.stack)).sort(function(a,b) {
			return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
		});
		if (!group.length) { return; }

		var min = parseInt(group[0].style.zIndex) || 0;
		$(group).each(function(i) {
			this.style.zIndex = min + i;
		});

		this[0].style.zIndex = min + group.length;

	}
});

$.ui.plugin.add("draggable", "zIndex", {
	start: function(event, ui) {
		var t = $(ui.helper), o = $(this).data("draggable").options;
		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
		t.css('zIndex', o.zIndex);
	},
	stop: function(event, ui) {
		var o = $(this).data("draggable").options;
		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
	}
});

})(jQuery);
;(function ($, rf) {

    /*
     * TODO: add user's event handlers call from options
     * TODO: add fire events
     */

    rf.ui = rf.ui || {};
    // Constructor definition
    rf.ui.Autocomplete = function(componentId, fieldId, options) {
        this.namespace = "." + rf.Event.createNamespace(this.name, componentId);
        this.options = {};
        // call constructor of parent class
        $super.constructor.call(this, componentId, componentId + ID.SELECT, fieldId, options);
        this.attachToDom();
        this.options = $.extend(this.options, defaultOptions, options);
        this.value = "";
        this.index = null;
        this.isFirstAjax = true;
        this.lastMouseX = null;
        this.lastMouseY = null;
        updateTokenOptions.call(this);
        bindEventHandlers.call(this);
        updateItemsList.call(this, "");
    };

    // Extend component class and add protected methods from parent class to our container
    rf.ui.AutocompleteBase.extend(rf.ui.Autocomplete);

    // define super class link
    var $super = rf.ui.Autocomplete.$super;

    var defaultOptions = {
        itemClass:'rf-au-itm',
        selectedItemClass:'rf-au-itm-sel',
        subItemClass:'rf-au-opt',
        selectedSubItemClass:'rf-au-opt-sel',
        autofill:true,
        minChars:1,
        selectFirst:true,
        ajaxMode:true,
        lazyClientMode:false,
        isCachedAjax:true,
        tokens: "",
        attachToBody:true,
        filterFunction: undefined
        //nothingLabel = "Nothing";
    };

    var ID = {
        SELECT:'List',
        ITEMS:'Items',
        VALUE:'Value'
    };

    var REGEXP_TRIM = /^[\n\s]*(.*)[\n\s]*$/;

    var getData = function (nodeList) {
        var data = [];
        nodeList.each(function () {
            data.push($(this).text().replace(REGEXP_TRIM, "$1"));
        });
        return data;
    }

    var updateTokenOptions = function () {
        this.useTokens = (typeof this.options.tokens == "string" && this.options.tokens.length > 0);
        if (this.useTokens) {
            var escapedTokens = this.options.tokens.split('').join("\\");
            this.REGEXP_TOKEN_RIGHT = new RegExp('[' + escapedTokens + ']', 'i');
            this.getLastTokenIndex = function(value) {
                return RichFaces.ui.Autocomplete.__getLastTokenIndex(escapedTokens, value);
            }
        }
    };

    var bindEventHandlers = function () {
        var handlers = {};
        handlers["click" + this.namespace] = handlers["mouseover" + this.namespace] = onMouseAction;
        if (!$.browser.msie && !$.browser.opera) {
            handlers["mouseenter" + this.namespace] = onMouseEnter;
            handlers["mouseleave" + this.namespace] = onMouseLeave;
        }
        rf.Event.bind(rf.getDomElement(this.id + ID.ITEMS).parentNode, handlers, this);
    };

    var onMouseLeave = function(event) {
        rf.Event.unbind(rf.getDomElement(this.id + ID.ITEMS).parentNode, "mousemove" + this.namespace);
        this.lastMouseX = null;
        this.lastMouseY = null;
    };

    var onMouseMove = function(event) {
        this.lastMouseX = event.pageX;
        this.lastMouseY = event.pageY;
    };

    var onMouseEnter = function(event) {
        this.lastMouseX = event.pageX;
        this.lastMouseY = event.pageY;
        rf.Event.bind(rf.getDomElement(this.id + ID.ITEMS).parentNode, "mousemove" + this.namespace, onMouseMove, this);
    };

    var onMouseAction = function(event) {
        var element = $(event.target).closest("." + this.options.itemClass, event.currentTarget).get(0);

        if (element) {
            if (event.type == "mouseover") {
                if (this.lastMouseX == null || this.lastMouseX != event.pageX || this.lastMouseY != event.pageY) {
                    //window.console && console.log && console.log("[mouseover] lastMouseX:" + this.lastMouseX+" lastMouseY:" + this.lastMouseY);
                    //window.console && console.log && console.log("[mouseover] pageX:" + event.pageX+" pageY:" + event.pageY);
                    var index = this.items.index(element);
                    selectItem.call(this, event, index);
                }
            } else {
                this.__onEnter(event);
                rf.Selection.setCaretTo(rf.getDomElement(this.fieldId));
                this.__hide(event);
            }
        }
    };

    var updateItemsList = function (value, fetchValues) {
        var itemsContainer = $(rf.getDomElement(this.id + ID.ITEMS));
        this.items = itemsContainer.find("." + this.options.itemClass);
        var data = itemsContainer.data();
        itemsContainer.removeData();
        if (this.items.length > 0) {
            this.cache = new rf.utils.Cache((this.options.ajaxMode ? value : ""), this.items, fetchValues || data.componentData || getData, !this.options.ajaxMode);
        }
    };

    var scrollToSelectedItem = function() {
        var offset = 0;
        this.items.slice(0, this.index).each(function() {
            offset += this.offsetHeight;
        });
        var parentContainer = $(rf.getDomElement(this.id + ID.ITEMS)).parent();
        if (offset < parentContainer.scrollTop()) {
            parentContainer.scrollTop(offset);
        } else {
            offset += this.items.eq(this.index).outerHeight();
            if (offset - parentContainer.scrollTop() > parentContainer.innerHeight()) {
                parentContainer.scrollTop(offset - parentContainer.innerHeight());
            }
        }
    };

    var autoFill = function (inputValue, value) {
        if (this.options.autofill && value.toLowerCase().indexOf(inputValue) == 0) {
            var field = rf.getDomElement(this.fieldId);
            var start = rf.Selection.getStart(field);
            this.__setInputValue(inputValue + value.substring(inputValue.length));
            var end = start + value.length - inputValue.length;
            rf.Selection.set(field, start, end);
        }
    };

    var callAjax = function(event, callback) {

        rf.getDomElement(this.id + ID.VALUE).value = this.value;

        var _this = this;
        var _event = event;
        var ajaxSuccess = function (event) {
            updateItemsList.call(_this, _this.value, event.componentData && event.componentData[_this.id]);
            if (_this.options.lazyClientMode && _this.value.length != 0) {
                updateItemsFromCache.call(_this, _this.value);
            }
            if (_this.items.length != 0) {
                if (callback) {
                    (_this.focused || _this.isMouseDown) && callback.call(_this, _event);
                } else {
                    _this.isVisible && _this.options.selectFirst && selectItem.call(_this, _event, 0);
                }
            } else {
                _this.__hide(_event);
            }
        };

        var ajaxError = function (event) {
            _this.__hide(_event);
            clearItems.call(_this);
        };

        this.isFirstAjax = false;
        //caution: JSF submits inputs with empty names causing "WARNING: Parameters: Invalid chunk ignored." in Tomcat log
        var params = {};
        params[this.id + ".ajax"] = "1";
        rf.ajax(this.id, event, {parameters: params, error: ajaxError, complete:ajaxSuccess});
    };

    var clearSelection = function () {
        if (this.index != null) {
            var element = this.items.eq(this.index);
            if (element.removeClass(this.options.selectedItemClass).hasClass(this.options.subItemClass)) {
                element.removeClass(this.options.selectedSubItemClass);
            }
            this.index = null;
        }
    };

    var selectItem = function(event, index, isOffset) {
        if (this.items.length == 0 || (!isOffset && index == this.index)) return;

        if (index == null || index == undefined) {
            clearSelection.call(this);
            return;
        }

        if (isOffset) {
            if (this.index == null) {
                index = 0;
            } else {
                index = this.index + index;
            }
        }
        if (index < 0) {
            index = 0;
        } else if (index >= this.items.length) {
            index = this.items.length - 1;
        }
        if (index == this.index) return;

        clearSelection.call(this);
        this.index = index;

        var item = this.items.eq(this.index);
        if (item.addClass(this.options.selectedItemClass).hasClass(this.options.subItemClass)) {
            item.addClass(this.options.selectedSubItemClass);
        }
        scrollToSelectedItem.call(this);
        if (event &&
            event.keyCode != rf.KEYS.BACKSPACE &&
            event.keyCode != rf.KEYS.DEL &&
            event.keyCode != rf.KEYS.LEFT &&
            event.keyCode != rf.KEYS.RIGHT) {
            autoFill.call(this, this.value, getSelectedItemValue.call(this));
        }
    };

    var updateItemsFromCache = function (value) {
        var newItems = this.cache.getItems(value, this.options.filterFunction);
        this.items = $(newItems);
        //TODO: works only with simple markup, not with <tr>
        $(rf.getDomElement(this.id + ID.ITEMS)).empty().append(this.items);
    };

    var clearItems = function () {
        $(rf.getDomElement(this.id + ID.ITEMS)).removeData().empty();
        this.items = [];
    };

    var onChangeValue = function (event, value, callback) {
        selectItem.call(this, event);

        // value is undefined if called from AutocompleteBase onChange
        var subValue = (typeof value == "undefined") ? this.__getSubValue() : value;
        var oldValue = this.value;
        this.value = subValue;

        if ((this.options.isCachedAjax || !this.options.ajaxMode) &&
            this.cache && this.cache.isCached(subValue)) {
            if (oldValue != subValue) {
                updateItemsFromCache.call(this, subValue);
            }
            if (this.items.length != 0) {
                callback && callback.call(this, event);
            } else {
                this.__hide(event);
            }
            if (event.keyCode == rf.KEYS.RETURN || event.type == "click") {
                this.__setInputValue(subValue);
            } else if (this.options.selectFirst) {
                selectItem.call(this, event, 0);
            }
        } else {
            if (event.keyCode == rf.KEYS.RETURN || event.type == "click") {
                this.__setInputValue(subValue);
            }
            if (subValue.length >= this.options.minChars) {
                if ((this.options.ajaxMode || this.options.lazyClientMode) && oldValue != subValue) {
                    callAjax.call(this, event, callback);
                }
            } else {
                if (this.options.ajaxMode) {
                    clearItems.call(this);
                    this.__hide(event);
                }
            }
        }

    };

    var getSelectedItemValue = function () {
        if (this.index != null) {
            var element = this.items.eq(this.index);
            return this.cache.getItemValue(element);
        }
        return undefined;
    };

    var getSubValue = function () {
        //TODO: add posibility to use space chars before and after tokens if space not a token char
        if (this.useTokens) {
            var field = rf.getDomElement(this.fieldId);
            var value = field.value;
            
            var cursorPosition = rf.Selection.getStart(field);
            var beforeCursorStr = value.substring(0, cursorPosition);
            var afterCursorStr = value.substring(cursorPosition);
            var result = beforeCursorStr.substring(this.getLastTokenIndex(beforeCursorStr));
            r = afterCursorStr.search(this.REGEXP_TOKEN_RIGHT);
            if (r == -1) r = afterCursorStr.length;
            result += afterCursorStr.substring(0, r);

            return result;
        } else {
            return this.getValue();
        }
    };
    
    var getCursorPosition = function(field) {
        var pos = rf.Selection.getStart(field);
        if (pos <= 0) {
            // when cursorPosition is not determined (input is not focused),
            // use position of last token occurence) 
            pos = this.getLastTokenIndex(field.value);
        }
        return pos;
    }

    var updateInputValue = function (value) {
        var field = rf.getDomElement(this.fieldId);
        var inputValue = field.value;

        var cursorPosition = this.__getCursorPosition(field);
        var beforeCursorStr = inputValue.substring(0, cursorPosition);
        var afterCursorStr = inputValue.substring(cursorPosition);
        var pos = this.getLastTokenIndex(beforeCursorStr);
        var startPos = pos != -1 ? pos : beforeCursorStr.length;
        pos = afterCursorStr.search(this.REGEXP_TOKEN_RIGHT);
        var endPos = pos != -1 ? pos : afterCursorStr.length;

        var beginNewValue = inputValue.substring(0, startPos) + value;
        cursorPosition = beginNewValue.length;
        field.value = beginNewValue + afterCursorStr.substring(endPos);
        field.focus();
        rf.Selection.setCaretTo(field, cursorPosition);
        return field.value;
    };

    var getPageLastItem = function() {
        if (this.items.length == 0) return -1;
        var parentContainer = $(rf.getDomElement(this.id + ID.ITEMS)).parent();
        var h = parentContainer.scrollTop() + parentContainer.innerHeight() + this.items[0].offsetTop;
        var item;
        var i = (this.index != null && this.items[this.index].offsetTop <= h) ? this.index : 0;
        for (i; i < this.items.length; i++) {
            item = this.items[i];
            if (item.offsetTop + item.offsetHeight > h) {
                i--;
                break;
            }
        }
        if (i != this.items.length - 1 && i == this.index) {
            h += this.items[i].offsetTop - parentContainer.scrollTop();
            for (++i; i < this.items.length; i++) {
                item = this.items[i];
                if (item.offsetTop + item.offsetHeight > h) {
                    break;
                }
            }
        }
        return i;
    };

    var getPageFirstItem = function() {
        if (this.items.length == 0) return -1;
        var parentContainer = $(rf.getDomElement(this.id + ID.ITEMS)).parent();
        var h = parentContainer.scrollTop() + this.items[0].offsetTop;
        var item;
        var i = (this.index != null && this.items[this.index].offsetTop >= h) ? this.index - 1 : this.items.length - 1;
        for (i; i >= 0; i--) {
            item = this.items[i];
            if (item.offsetTop < h) {
                i++;
                break;
            }
        }
        if (i != 0 && i == this.index) {
            h = this.items[i].offsetTop - parentContainer.innerHeight();
            if (h < this.items[0].offsetTop) h = this.items[0].offsetTop;
            for (--i; i >= 0; i--) {
                item = this.items[i];
                if (item.offsetTop < h) {
                    i++;
                    break;
                }
            }
        }
        return i;
    };

    /*
     * Prototype definition
     */
    $.extend(rf.ui.Autocomplete.prototype, (function () {
        return {
            /*
             * public API functions
             */
            name:"Autocomplete",
            /*
             * Protected methods
             */
            __updateState: function (event) {
                var subValue = this.__getSubValue();
                // called from AutocompleteBase when not actually value changed
                if (this.items.length == 0 && this.isFirstAjax) {
                    if ((this.options.ajaxMode && subValue.length >= this.options.minChars) || this.options.lazyClientMode) {
                        this.value = subValue;
                        callAjax.call(this, event, this.__show);
                        return true;
                    }
                }
                return false;
            },
            __getSubValue: getSubValue,
            __getCursorPosition: getCursorPosition,
            __updateInputValue: function (value) {
                if (this.useTokens) {
                    return updateInputValue.call(this, value);
                } else {
                    return $super.__updateInputValue.call(this, value);
                }
            },
            __setInputValue: function (value) {
                this.currentValue = this.__updateInputValue(value);
            },
            __onChangeValue: onChangeValue,
            /*
             * Override abstract protected methods
             */
            __onKeyUp: function (event) {
                selectItem.call(this, event, -1, true);
            },
            __onKeyDown: function (event) {
                selectItem.call(this, event, 1, true);
            },
            __onPageUp: function (event) {
                selectItem.call(this, event, getPageFirstItem.call(this));
            },
            __onPageDown: function (event) {
                selectItem.call(this, event, getPageLastItem.call(this));
            },
            __onKeyHome: function (event) {
                selectItem.call(this, event, 0);
            },
            __onKeyEnd: function (event) {
                selectItem.call(this, event, this.items.length - 1);
            },
            __onBeforeShow: function (event) {
            },
            __onEnter: function (event) {
                var value = getSelectedItemValue.call(this);
                this.__onChangeValue(event, value);
                this.invokeEvent("selectitem", rf.getDomElement(this.fieldId), event, value);
            },
            __onShow: function (event) {
                if (this.options.selectFirst) {
                    selectItem.call(this, event, 0);
                }
            },
            __onHide: function (event) {
                selectItem.call(this, event);
            },
            /*
             * Destructor
             */
            destroy: function () {
                //TODO: add all unbind
                this.items = null;
                this.cache = null;
                var itemsContainer = rf.getDomElement(this.id + ID.ITEMS);
                $(itemsContainer).removeData();
                rf.Event.unbind(itemsContainer.parentNode, this.namespace);
                this.__conceal();
                $super.destroy.call(this);
            }
        };
    })());

    $.extend(rf.ui.Autocomplete, {
            setData: function (id, data) {
                $(rf.getDomElement(id)).data({componentData:data});
            },
            
            __getLastTokenIndex:  function (tokens, value) {
                var LAST_TOKEN_OCCURENCE = new RegExp("[" + tokens + "][^" + tokens + "]*$", "i");
                var AFTER_LAST_TOKEN_WITH_SPACES = new RegExp("[^" + tokens + " ]", "i");
                
                var value = value || "";

                var lastTokenIndex = value.search(LAST_TOKEN_OCCURENCE);
                if (lastTokenIndex < 0) {
                    return 0;
                }
                var beforeToken = value.substring(lastTokenIndex);
                var afterLastTokenIndex = beforeToken.search(AFTER_LAST_TOKEN_WITH_SPACES);
                if (afterLastTokenIndex <= 0) {
                    afterLastTokenIndex = beforeToken.length;
                }
            
                return lastTokenIndex + afterLastTokenIndex;
            }
        });

})(jQuery, RichFaces);;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    var DEFAULT_OPTIONS = {switchMode: 'ajax'};

    rf.ui.CollapsiblePanelItem = rf.ui.TogglePanelItem.extendClass({

            init : function (componentId, options) {
                rf.ui.TogglePanelItem.call(this, componentId, $.extend({}, DEFAULT_OPTIONS, options));

                this.headerClass = "rf-cp-hdr-" + this.__state();
            },

            __enter : function () {
                this.__content().show();
                this.__header().addClass(this.headerClass);

                return true;
            },

            __leave : function () {
                this.__content().hide();

                if (this.options.switchMode == 'client') {
                    this.__header().removeClass(this.headerClass);
                }

                return true;
            },

            __state : function () {
                return this.getName() === "true" ? "exp" : "colps";
            },

            __content : function () {
                return $(rf.getDomElement(this.id));
            },

            __header : function () {
                return $(rf.getDomElement(this.togglePanelId + ":header"));
            }
        });
})(jQuery, RichFaces);
;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.Popup = function(id, options) {
        $super.constructor.call(this, id);
        this.options = $.extend({}, defaultOptions, options);
        this.positionOptions = {type: this.options.positionType, from:this.options.jointPoint, to:this.options.direction, offset: this.options.positionOffset};

        this.popup = $(document.getElementById(id));

        this.visible = this.options.visible;
        this.attachTo = this.options.attachTo;
        this.attachToBody = this.options.attachToBody;
        this.positionType = this.options.positionType;
        this.positionOffset = this.options.positionOffset;
    };

    rf.BaseComponent.extend(rf.ui.Popup);
    var $super = rf.ui.Popup.$super;

    var defaultOptions = {
        visible: false
    };

    $.extend(rf.ui.Popup.prototype, {

            name : "popup",

            show: function(event) {
                if (!this.visible) {
                    if (this.attachToBody) {
                        this.parentElement = this.popup.parent().get(0);
                        document.body.appendChild(this.popup.get(0));
                    }
                    this.visible = true;
                }

                this.popup.setPosition(event || {id: this.attachTo}, this.positionOptions).show();
            },

            hide: function() {
                if (this.visible) {
                    this.popup.hide();
                    this.visible = false;
                    if (this.attachToBody && this.parentElement) {
                        this.parentElement.appendChild(this.popup.get(0));
                        this.parentElement = null;
                    }
                }
            },

            isVisible: function() {
                return this.visible;
            },

            getId: function() {
                return this.id;
            },

            destroy: function() {
                if (this.attachToBody && this.parentElement) {
                    this.parentElement.appendChild(this.popup.get(0));
                    this.parentElement = null;
                }
            }
        });

})(jQuery, window.RichFaces);;(function ($, rf) {

    rf.calendarUtils = rf.calendarUtils || {};

    var getDefaultMonthNames = function(shortNames) {
        return (shortNames
            ? ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
            : ['January','February','March','April','May','June','July','August','September','October','November','December']);
    };

    $.extend(rf.calendarUtils, {
            // TODO: rewrite this function or use the same function if exists
            /*clonePosition: function (elements, source)
             {
             if (!elements.length) elements = [elements];
             var offset = Position.cumulativeOffset(source);
             offset = {left:offset[0], top:offset[1]};
             var offsetTemp;
             if (source.style.position!='absolute')
             {
             offsetTemp = Position.realOffset(source);
             offset.left -= offsetTemp.left;
             offset.top -= offsetTemp.top;
             offsetTemp = Richfaces.Calendar.getWindowScrollOffset();
             offset.left += offsetTemp.left;
             offset.top += offsetTemp.top;
             }

             for (var i=0;i<elements.length;i++)
             {
             offsetTemp = Richfaces.Calendar.getParentOffset(elements[i]);
             elements[i].style.left = (offset.left - offsetTemp.left) + 'px';
             elements[i].style.top = (offset.top - offsetTemp.top) + 'px';
             }
             return offset;
             }*/

            //TODO: not used
            /*Object.extend(Event, {
             findElementByAttr : function(event, tagName, attribute, value, flag) {
             var element = Event.findElement(event, tagName);
             while (!element[attribute] || (flag ? element[attribute].indexOf(value)!=0 : element[attribute]!=value) )
             {
             element = element.parentNode;
             }
             return element;
             }
             });

             Object.extend(Element, {
             replaceClassName : function (element, whichClassName, toClassName) {
             if (!(element = $(element))) return;
             var e = Element.classNames(element);
             e.remove(whichClassName);
             e.add(toClassName);
             return element;
             }
             });*/

            // TODO: move joinArray to richfaces utils
            joinArray: function(array, begin, end, separator) {
                var value = '';
                if (array.length != 0) value = begin + array.pop() + end;
                while (array.length)
                    value = begin + array.pop() + end + separator + value;
                return value;
            },

            getMonthByLabel: function (monthLabel, monthNames) {
                var toLowerMonthLabel = monthLabel.toLowerCase();
                var i = 0;
                while (i < monthNames.length) {
                    if (monthNames[i].toLowerCase() == toLowerMonthLabel) {
                        return i;
                    }

                    i++;
                }
            },

            createDate: function (yy, mm, dd, h, m, s) {
                h = h || 0;
                m = m || 0;
                s = s || 0;
                var date = new Date(yy, mm, dd, h, m, s);
                if (date.getDate() != dd) {
                    date = new Date(yy, mm);
                    date.setHours(h);
                    date.setMinutes(m);
                    date.setSeconds(s);
                    date.setUTCDate(dd);
                }
                return date;
            },

            /* Year:
             *	y,yy - 00-99
             *	yyy+ - 1999
             * Month:
             *	M - 1-12
             *	MM - 01-12
             *	MMM - short (Jul)
             *	MMMM+ - long (July)
             * Date:
             *	d - 1-31
             *	dd+ - 01-31 */
            parseDate: function(dateString, pattern, monthNames, monthNamesShort) {
                var re = /([.*+?^<>=!:${}()\[\]\/\\])/g;
                var monthNamesStr
                var monthNamesShortStr;
                if (!monthNames) {
                    monthNames = getDefaultMonthNames();
                    monthNamesStr = monthNames.join('|');
                } else {
                    monthNamesStr = monthNames.join('|').replace(re, '\\$1');
                }

                if (!monthNamesShort) {
                    monthNamesShort = getDefaultMonthNames(true);
                    monthNamesShortStr = monthNamesShort.join('|');
                } else {
                    monthNamesShortStr = monthNamesShort.join('|').replace(re, '\\$1');
                }

                var counter = 1;
                var y,m,d;
                var a,h,min,s;
                var shortLabel = false;

                pattern = pattern.replace(/([.*+?^<>=!:${}()|\[\]\/\\])/g, '\\$1');
                pattern = pattern.replace(/(y+|M+|d+|a|H{1,2}|h{1,2}|m{2}|s{2})/g,
                    function($1) {
                        switch ($1) {
                            case 'y'  :
                            case 'yy' :
                                y = counter;
                                counter++;
                                return '(\\d{2})';
                            case 'MM' :
                                m = counter;
                                counter++;
                                return '(\\d{2})';
                            case 'M'  :
                                m = counter;
                                counter++;
                                return '(\\d{1,2})';
                            case 'd'  :
                                d = counter;
                                counter++;
                                return '(\\d{1,2})';
                            case 'MMM':
                                m = counter;
                                counter++;
                                shortLabel = true;
                                return '(' + monthNamesShortStr + ')';
                            case 'a'  :
                                a = counter;
                                counter++;
                                return '(AM|am|PM|pm)?';
                            case 'HH' :
                            case 'hh' :
                                h = counter;
                                counter++;
                                return '(\\d{2})?';
                            case 'H'  :
                            case 'h'  :
                                h = counter;
                                counter++;
                                return '(\\d{1,2})?';
                            case 'mm' :
                                min = counter;
                                counter++;
                                return '(\\d{2})?';
                            case 'ss' :
                                s = counter;
                                counter++;
                                return '(\\d{2})?';

                        }
                        // y+,M+,d+
                        var ch = $1.charAt(0);
                        if (ch == 'y') {
                            y = counter;
                            counter++;
                            return '(\\d{3,4})'
                        }
                        ;
                        if (ch == 'M') {
                            m = counter;
                            counter++;
                            return '(' + monthNamesStr + ')'
                        }
                        ;
                        if (ch == 'd') {
                            d = counter;
                            counter++;
                            return '(\\d{2})'
                        }
                        ;
                    }
                );

                var re = new RegExp(pattern, 'i');
                var match = dateString.match(re);
                if (match != null && y != undefined && m != undefined && d != undefined) {
                    // set default century start
                    var correctYear = false;
                    var defaultCenturyStart = new Date();
                    defaultCenturyStart.setFullYear(defaultCenturyStart.getFullYear() - 80);

                    var yy = parseInt(match[y], 10);
                    if (isNaN(yy)) return null;
                    else if (yy < 100) {
                        // calculate full year if year has only two digits
                        var defaultCenturyStartYear = defaultCenturyStart.getFullYear();
                        var ambiguousTwoDigitYear = defaultCenturyStartYear % 100;
                        correctYear = yy == ambiguousTwoDigitYear;
                        yy += Math.floor(defaultCenturyStartYear / 100) * 100 + (yy < ambiguousTwoDigitYear ? 100 : 0);
                    }

                    var mm = parseInt(match[m], 10);
                    if (isNaN(mm)) mm = this.getMonthByLabel(match[m], shortLabel ? monthNamesShort : monthNames); else if (--mm < 0 || mm > 11) return null;
                    var addDay = correctYear ? 1 : 0;
                    var dd = parseInt(match[d], 10);
                    if (isNaN(dd) || dd < 1 || dd > this.daysInMonth(yy, mm) + addDay) return null;

                    var date;

                    // time parsing
                    if (min != undefined && h != undefined) {
                        var hh,mmin,aa;
                        mmin = parseInt(match[min], 10);
                        if (isNaN(mmin) || mmin < 0 || mmin > 59) return null;
                        hh = parseInt(match[h], 10);
                        if (isNaN(hh)) return null;
                        if (a != undefined) {
                            aa = match[a];
                            if (!aa) return null;
                            aa = aa.toLowerCase();
                            if ((aa != 'am' && aa != 'pm') || hh < 1 || hh > 12) return null;
                            if (aa == 'pm') {
                                if (hh != 12) hh += 12;
                            } else if (hh == 12) hh = 0;
                        }
                        else if (hh < 0 || hh > 23) return null;

                        date = this.createDate(yy, mm, dd, hh, mmin);
                        if (s != undefined) {
                            sec = parseInt(match[s], 10);
                            if (isNaN(sec) || sec < 0 || sec > 59) return null;
                            date.setSeconds(sec);
                        }
                    } else {
                        date = this.createDate(yy, mm, dd);
                    }

                    if (correctYear) {
                        if (date.getTime() < defaultCenturyStart.getTime()) {
                            date.setFullYear(yy + 100);
                        }
                        if (date.getMonth() != mm) return null;
                    }

                    return date;
                }
                return null;
            },

            formatDate: function(date, pattern, monthNames, monthNamesShort) {
                if (!monthNames) monthNames = getDefaultMonthNames();
                if (!monthNamesShort) monthNamesShort = getDefaultMonthNames(true);
                var mm,dd,hh,min,sec;
                var result = pattern.replace(/(\\\\|\\[yMdaHhms])|(y+|M+|d+|a|H{1,2}|h{1,2}|m{2}|s{2})/g,
                    function($1, $2, $3) {
                        if ($2) return $2.charAt(1);
                        switch ($3) {
                            case 'y':
                            case 'yy':
                                return date.getYear().toString().slice(-2);
                            case 'M':
                                return (date.getMonth() + 1);
                            case 'MM':
                                return ((mm = date.getMonth() + 1) < 10 ? '0' + mm : mm);
                            case 'MMM':
                                return monthNamesShort[date.getMonth()];
                            case 'd':
                                return date.getDate();
                            case 'a'  :
                                return (date.getHours() < 12 ? 'AM' : 'PM');
                            case 'HH' :
                                return ((hh = date.getHours()) < 10 ? '0' + hh : hh);
                            case 'H'  :
                                return date.getHours();
                            case 'hh' :
                                return ((hh = date.getHours()) == 0 ? '12' : (hh < 10 ? '0' + hh : (hh > 21 ? hh - 12 : (hh > 12) ? '0' + (hh - 12) : hh)));
                            case 'h'  :
                                return ((hh = date.getHours()) == 0 ? '12' : (hh > 12 ? hh - 12 : hh));
                            case 'mm' :
                                return ((min = date.getMinutes()) < 10 ? '0' + min : min);
                            case 'ss' :
                                return ((sec = date.getSeconds()) < 10 ? '0' + sec : sec);
                        }
                        // y+,M+,d+
                        var ch = $3.charAt(0);
                        if (ch == 'y') return date.getFullYear();
                        if (ch == 'M') return monthNames[date.getMonth()];
                        if (ch == 'd') return ((dd = date.getDate()) < 10 ? '0' + dd : dd);
                    }
                );
                return result;
            },

            isLeapYear: function(year) {
                return new Date(year, 1, 29).getDate() == 29;
            },

            daysInMonth: function(year, month) {
                return 32 - new Date(year, month, 32).getDate();
            },

            daysInMonthByDate: function(date) {
                return 32 - new Date(date.getFullYear(), date.getMonth(), 32).getDate();
            },

            getDay: function(date, firstWeekDay) {
                var value = date.getDay() - firstWeekDay;
                if (value < 0) value = 7 + value;
                return value;
            },

            getFirstWeek: function(year, mdifw, fdow) {
                var date = new Date(year, 0, 1);
                var firstday = this.getDay(date, fdow);

                var weeknumber = (7 - firstday < mdifw) ? 0 : 1;

                return {date:date, firstDay:firstday, weekNumber:weeknumber, mdifw:mdifw, fdow:fdow};
            },

            getLastWeekOfPrevYear: function(o) {
                var year = o.date.getFullYear() - 1;
                var days = (this.isLeapYear(year) ? 366 : 365);
                var obj = this.getFirstWeek(year, o.mdifw, o.fdow);
                days = (days - 7 + o.firstDay);
                var weeks = Math.ceil(days / 7);

                return  weeks + obj.weekNumber;
            },

            weekNumber: function(year, month, mdifw, fdow) {

                var o = this.getFirstWeek(year, mdifw, fdow);

                if (month == 0) {
                    if (o.weekNumber == 1) return 1;
                    return this.getLastWeekOfPrevYear(o);
                }
                var oneweek = 604800000;
                var d = new Date(year, month, 1);
                d.setDate(1 + o.firstDay + (this.getDay(d, fdow) == 0 ? 1 : 0));

                weeknumber = o.weekNumber + Math.floor((d.getTime() - o.date.getTime()) / oneweek);

                return weeknumber;
            }

        });

    rf.calendarTemplates = rf.calendarTemplates || {};

    $.extend(rf.calendarTemplates, (function () {

        var VARIABLE_NAME_PATTERN = /^\s*[_,A-Z,a-z][\w,_\.]*\s*$/;

        var getObjectValue = function (str, object) {
            var a = str.split(".");
            var value = object[a[0]];
            var c = 1;
            while (value && c < a.length) value = value[a[c++]];
            return (value ? value : "");
        };

        return  {
            evalMacro: function(template, object) {
                var _value_ = "";
                // variable evaluation
                if (VARIABLE_NAME_PATTERN.test(template)) {
                    if (template.indexOf('.') == -1) {
                        _value_ = object[template];
                        if (!_value_)    _value_ = window[template];
                    }
                    // object's variable evaluation
                    else {
                        _value_ = getObjectValue(template, object);
                        if (!_value_) _value_ = getObjectValue(template, window);
                    }
                    if (_value_ && typeof _value_ == 'function') _value_ = _value_(object);
                    if (!_value_) _value_ = "";
                }
                //js string evaluation
                else {
                    try {
                        if (object.eval) {
                            _value_ = object.eval(template);
                        }
                        else with (object) {
                            _value_ = eval(template);
                        }

                        if (typeof _value_ == 'function') {
                            _value_ = _value_(object);
                        }
                    } catch (e) {
                        LOG.warn("Exception: " + e.Message + "\n[" + template + "]");
                    }
                }
                return _value_;
            }
        };
    })());

})(jQuery, RichFaces);;/*!
 * jQuery UI Droppable 1.9.2
 * http://jqueryui.com
 *
 * Copyright 2012 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/droppable/
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.widget.js
 *	jquery.ui.mouse.js
 *	jquery.ui.draggable.js
 */
(function( $, undefined ) {

$.widget("ui.droppable", {
	version: "1.9.2",
	widgetEventPrefix: "drop",
	options: {
		accept: '*',
		activeClass: false,
		addClasses: true,
		greedy: false,
		hoverClass: false,
		scope: 'default',
		tolerance: 'intersect'
	},
	_create: function() {

		var o = this.options, accept = o.accept;
		this.isover = 0; this.isout = 1;

		this.accept = $.isFunction(accept) ? accept : function(d) {
			return d.is(accept);
		};

		//Store the droppable's proportions
		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };

		// Add the reference and positions to the manager
		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
		$.ui.ddmanager.droppables[o.scope].push(this);

		(o.addClasses && this.element.addClass("ui-droppable"));

	},

	_destroy: function() {
		var drop = $.ui.ddmanager.droppables[this.options.scope];
		for ( var i = 0; i < drop.length; i++ )
			if ( drop[i] == this )
				drop.splice(i, 1);

		this.element.removeClass("ui-droppable ui-droppable-disabled");
	},

	_setOption: function(key, value) {

		if(key == 'accept') {
			this.accept = $.isFunction(value) ? value : function(d) {
				return d.is(value);
			};
		}
		$.Widget.prototype._setOption.apply(this, arguments);
	},

	_activate: function(event) {
		var draggable = $.ui.ddmanager.current;
		if(this.options.activeClass) this.element.addClass(this.options.activeClass);
		(draggable && this._trigger('activate', event, this.ui(draggable)));
	},

	_deactivate: function(event) {
		var draggable = $.ui.ddmanager.current;
		if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
		(draggable && this._trigger('deactivate', event, this.ui(draggable)));
	},

	_over: function(event) {

		var draggable = $.ui.ddmanager.current;
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element

		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
			if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
			this._trigger('over', event, this.ui(draggable));
		}

	},

	_out: function(event) {

		var draggable = $.ui.ddmanager.current;
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element

		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
			this._trigger('out', event, this.ui(draggable));
		}

	},

	_drop: function(event,custom) {

		var draggable = custom || $.ui.ddmanager.current;
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element

		var childrenIntersection = false;
		this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
			var inst = $.data(this, 'droppable');
			if(
				inst.options.greedy
				&& !inst.options.disabled
				&& inst.options.scope == draggable.options.scope
				&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
				&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
			) { childrenIntersection = true; return false; }
		});
		if(childrenIntersection) return false;

		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
			if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
			this._trigger('drop', event, this.ui(draggable));
			return this.element;
		}

		return false;

	},

	ui: function(c) {
		return {
			draggable: (c.currentItem || c.element),
			helper: c.helper,
			position: c.position,
			offset: c.positionAbs
		};
	}

});

$.ui.intersect = function(draggable, droppable, toleranceMode) {

	if (!droppable.offset) return false;

	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
	var l = droppable.offset.left, r = l + droppable.proportions.width,
		t = droppable.offset.top, b = t + droppable.proportions.height;

	switch (toleranceMode) {
		case 'fit':
			return (l <= x1 && x2 <= r
				&& t <= y1 && y2 <= b);
			break;
		case 'intersect':
			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
			break;
		case 'pointer':
			var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
				isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
			return isOver;
			break;
		case 'touch':
			return (
					(y1 >= t && y1 <= b) ||	// Top edge touching
					(y2 >= t && y2 <= b) ||	// Bottom edge touching
					(y1 < t && y2 > b)		// Surrounded vertically
				) && (
					(x1 >= l && x1 <= r) ||	// Left edge touching
					(x2 >= l && x2 <= r) ||	// Right edge touching
					(x1 < l && x2 > r)		// Surrounded horizontally
				);
			break;
		default:
			return false;
			break;
		}

};

/*
	This manager tracks offsets of draggables and droppables
*/
$.ui.ddmanager = {
	current: null,
	droppables: { 'default': [] },
	prepareOffsets: function(t, event) {

		var m = $.ui.ddmanager.droppables[t.options.scope] || [];
		var type = event ? event.type : null; // workaround for #2317
		var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();

		droppablesLoop: for (var i = 0; i < m.length; i++) {

			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;	//No disabled and non-accepted
			for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; 									//If the element is not visible, continue

			if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables

			m[i].offset = m[i].element.offset();
			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };

		}

	},
	drop: function(draggable, event) {

		var dropped = false;
		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {

			if(!this.options) return;
			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
				dropped = this._drop.call(this, event) || dropped;

			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
				this.isout = 1; this.isover = 0;
				this._deactivate.call(this, event);
			}

		});
		return dropped;

	},
	dragStart: function( draggable, event ) {
		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
			if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
		});
	},
	drag: function(draggable, event) {

		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);

		//Run through all droppables and check their positions based on specific tolerance options
		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {

			if(this.options.disabled || this.greedyChild || !this.visible) return;
			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);

			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
			if(!c) return;

			var parentInstance;
			if (this.options.greedy) {
				// find droppable parents with same scope
				var scope = this.options.scope;
				var parent = this.element.parents(':data(droppable)').filter(function () {
					return $.data(this, 'droppable').options.scope === scope;
				});

				if (parent.length) {
					parentInstance = $.data(parent[0], 'droppable');
					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
				}
			}

			// we just moved into a greedy child
			if (parentInstance && c == 'isover') {
				parentInstance['isover'] = 0;
				parentInstance['isout'] = 1;
				parentInstance._out.call(parentInstance, event);
			}

			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
			this[c == "isover" ? "_over" : "_out"].call(this, event);

			// we just moved out of a greedy child
			if (parentInstance && c == 'isout') {
				parentInstance['isout'] = 0;
				parentInstance['isover'] = 1;
				parentInstance._over.call(parentInstance, event);
			}
		});

	},
	dragStop: function( draggable, event ) {
		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
		if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
	}
};

})(jQuery);
;(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.List = function(id, options) {
        $super.constructor.call(this, id);
        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, this.id);
        this.attachToDom();
        var mergedOptions = $.extend({}, defaultOptions, options);
        this.list = $(document.getElementById(id));
        this.selectListener = mergedOptions.selectListener;
        this.selectItemCss = mergedOptions.selectItemCss;
        this.selectItemCssMarker = mergedOptions.selectItemCss.split(" ", 1)[0];
        this.scrollContainer = $(mergedOptions.scrollContainer);
        this.itemCss = mergedOptions.itemCss.split(" ", 1)[0]; // we only need one of the item css classes to identify the item
        this.listCss = mergedOptions.listCss;
        this.clickRequiredToSelect = mergedOptions.clickRequiredToSelect;
        this.index = -1;
        this.disabled = mergedOptions.disabled;

        this.focusKeeper = $(document.getElementById(id + "FocusKeeper"));
        this.focusKeeper.focused = false;

        this.lastMouseX = null;
        this.lastMouseY = null;

        this.isMouseDown = false;
        this.list
            .bind("mousedown", $.proxy(this.__onMouseDown, this))
            .bind("mouseup", $.proxy(this.__onMouseUp, this));


        bindEventHandlers.call(this);
        if (mergedOptions.focusKeeperEnabled) {
            bindFocusEventHandlers.call(this);
        }

        this.__updateItemsList(); // initialize this.items
        if (mergedOptions.clientSelectItems !== null) {
            var clientSelectItemsMap = [];
            $.each(mergedOptions.clientSelectItems, function(i) {
                clientSelectItemsMap[this.id] = this;
            });
            this.__storeClientSelectItems(this.items, clientSelectItemsMap);
        }
    };

    rf.BaseComponent.extend(rf.ui.List);
    var $super = rf.ui.List.$super;

    var defaultOptions = {
        clickRequiredToSelect: false,
        disabled : false,
        selectListener : false,
        clientSelectItems : null,
        focusKeeperEnabled : true
    };

    var bindEventHandlers = function () {
        var handlers = {};
        handlers["click" + this.namespace] = $.proxy(this.onClick, this);
        handlers["dblclick" + this.namespace] = $.proxy(this.onDblclick, this);
        handlers["mouseover" + this.namespace] = onMouseOver;
        if (!$.browser.msie && !$.browser.opera) {
            handlers["mouseenter" + this.namespace] = onMouseEnter;
            handlers["mouseleave" + this.namespace] = onMouseLeave;
        }
        rf.Event.bind(this.list, handlers, this);
    };

    var bindFocusEventHandlers = function () {
        var focusEventHandlers = {};
        focusEventHandlers[($.browser.opera || $.browser.mozilla ? "keypress" : "keydown") + this.namespace] = $.proxy(this.__keydownHandler, this);
        focusEventHandlers["blur" + this.namespace] = $.proxy(this.__blurHandler, this);
        focusEventHandlers["focus" + this.namespace] = $.proxy(this.__focusHandler, this);
        rf.Event.bind(this.focusKeeper, focusEventHandlers, this);
    };

    var onMouseLeave = function(e) {
        rf.Event.unbind(this.list, "mousemove" + this.namespace);
        this.lastMouseX = null;
        this.lastMouseY = null;
    };

    var onMouseMove = function(e) {
        this.lastMouseX = e.pageX;
        this.lastMouseY = e.pageY;
    };

    var onMouseEnter = function(e) {
        this.lastMouseX = e.pageX;
        this.lastMouseY = e.pageY;
        rf.Event.bind(this.list, "mousemove" + this.namespace, onMouseMove, this);
    };

    var onMouseOver = function(e) {
        if (this.lastMouseX == null || this.lastMouseX != e.pageX || this.lastMouseY != e.pageY) {
            var item = this.__getItem(e);
            if (item && !this.clickRequiredToSelect && !this.disabled) {
                this.__select(item);
            }
        }
    };

    $.extend(rf.ui.List.prototype, ( function () {

        return{

            name : "list",

            processItem: function(item) {
                if (this.selectListener.processItem && typeof this.selectListener.processItem == 'function') {
                    this.selectListener.processItem(item);
                }
            },

            isSelected: function(item) {
                return item.hasClass(this.selectItemCssMarker);
            },

            selectItem: function(item) {
                if (this.selectListener.selectItem && typeof this.selectListener.selectItem == 'function') {
                    this.selectListener.selectItem(item);
                } else {
                    item.addClass(this.selectItemCss);
                    rf.Event.fire(this, "selectItem", item);
                }
                this.__scrollToSelectedItem(this);
            },

            unselectItem: function(item) {
                if (this.selectListener.unselectItem && typeof this.selectListener.unselectItem == 'function') {
                    this.selectListener.unselectItem(item);
                } else {
                    item.removeClass(this.selectItemCss);
                    rf.Event.fire(this, "unselectItem", item);
                }
            },

            __focusHandler : function(e) {
                if (! this.focusKeeper.focused) {
                    this.focusKeeper.focused = true;
                    rf.Event.fire(this, "listfocus" + this.namespace, e);
                }
            },

            __blurHandler: function(e) {
                if (!this.isMouseDown) {
                    var that = this;
                    this.timeoutId = window.setTimeout(function() {
                        that.focusKeeper.focused = false;
                        that.invokeEvent.call(that, "blur", document.getElementById(that.id), e);
                        rf.Event.fire(that, "listblur" + that.namespace, e);
                    }, 200);
                } else {
                    this.isMouseDown = false;
                }
            },

            __onMouseDown: function(e) {
                this.isMouseDown = true;
            },

            __onMouseUp: function(e) {
                this.isMouseDown = false;
            },

            __keydownHandler: function(e) {
                if (e.isDefaultPrevented()) return;
                if (e.metaKey || e.ctrlKey) return;

                var code;
                if (e.keyCode) {
                    code = e.keyCode;
                } else if (e.which) {
                    code = e.which;
                }

                switch (code) {
                    case rf.KEYS.DOWN:
                        e.preventDefault();
                        this.__selectNext();
                        break;

                    case rf.KEYS.UP:
                        e.preventDefault();
                        this.__selectPrev();
                        break;

                    case rf.KEYS.HOME:
                        e.preventDefault();
                        this.__selectByIndex(0);
                        break;

                    case rf.KEYS.END:
                        e.preventDefault();
                        this.__selectByIndex(this.items.length - 1);
                        break;

                    default:
                        break;
                }
            },

            onClick: function(e) {
                this.setFocus();
                var item = this.__getItem(e);
                this.processItem(item);
                var clickModified = e.metaKey || e.ctrlKey;
                if (!this.disabled) {
                    this.__select(item, clickModified && this.clickRequiredToSelect);
                }
            },

            onDblclick: function(e) {
                this.setFocus();
                var item = this.__getItem(e);
                this.processItem(item);
                if (!this.disabled) {
                    this.__select(item, false);
                }
            },

            currentSelectItem: function() {
                if (this.items && this.index != -1) {
                    return $(this.items[this.index]);
                }
            },

            getSelectedItemIndex: function() {
                return this.index;
            },

            removeItems: function(items) {
                $(items).detach();
                this.__updateItemsList();
                rf.Event.fire(this, "removeitems", items);
            },

            removeAllItems: function() {
                var items = this.__getItems();
                this.removeItems(items);
                return items;
            },

            addItems: function(items) {
                var parentContainer = this.scrollContainer;
                parentContainer.append(items);
                this.__updateItemsList();
                rf.Event.fire(this, "additems", items);
            },

            move: function(items, step) {
                if (step === 0) {
                    return;
                }
                var that = this;
                if (step > 0) {
                    items = $(items.get().reverse());
                }
                items.each(function(i) {
                    var index = that.items.index(this);
                    var indexNew = index + step;
                    var existingItem = that.items[indexNew];
                    if (step < 0) {
                        $(this).insertBefore(existingItem);
                    } else {
                        $(this).insertAfter(existingItem);
                    }
                    that.index = that.index + step;
                    that.__updateItemsList();
                });
                rf.Event.fire(this, "moveitems", items);
            },

            getItemByIndex: function(i) {
                if (i >= 0 && i < this.items.length) {
                    return this.items[i];
                }
            },

            getClientSelectItemByIndex: function(i) {
                if (i >= 0 && i < this.items.length) {
                    return $(this.items[i]).data('clientSelectItem');
                }
            },

            resetSelection: function() {
                var item = this.currentSelectItem();
                if (item) {
                    this.unselectItem($(item));
                }
                this.index = -1;
            },

            isList: function(target) {
                var parentId = target.parents("." + this.listCss).attr("id");
                return (parentId && (parentId == this.getId()));
            },

            length: function() {
                return this.items.length;
            },

            __updateIndex: function(item) {
                if (item === null) {
                    this.index = -1;
                } else {
                    var index = this.items.index(item);
                    if (index < 0) {
                        index = 0;
                    } else if (index >= this.items.length) {
                        index = this.items.length - 1;
                    }
                    this.index = index;
                }
            },

            __updateItemsList: function () {
                return (this.items = this.list.find("." + this.itemCss));
            },

            __storeClientSelectItems: function(items, clientSelectItemsMap) {
                items.each(function (i)  {
                    var item = $(this);
                    var id = item.attr("id");
                    var clientSelectItem = clientSelectItemsMap[id];
                    item.data('clientSelectItem', clientSelectItem);
                })
            },

            __select: function(item, clickModified) {
                var index = this.items.index(item);
                this.__selectByIndex(index, clickModified);
            },

            __selectByIndex: function(index, clickModified) {
                if (! this.__isSelectByIndexValid(index)) {
                    return;
                }

                if (!this.clickRequiredToSelect && this.index == index) {
                    return; // do nothing if re-selecting the same item
                }

                var oldIndex = this.__unselectPrevious();

                if (this.clickRequiredToSelect && oldIndex == index) {
                    return; //do nothing after unselecting item
                }

                this.index = this.__sanitizeSelectedIndex(index);

                var item = this.items.eq(this.index);
                if (this.isSelected(item)) {
                    this.unselectItem(item);
                } else {
                    this.selectItem(item);
                }
            },

            __isSelectByIndexValid: function(index) {
                if (this.items.length == 0) {
                    return false;
                }
                if (index == undefined) {
                    this.index = -1;
                    return false;
                }
                return true;
            },

            __sanitizeSelectedIndex: function(index) {
                var sanitizedIndex;
                if (index < 0) {
                    sanitizedIndex = 0;
                } else if (index >= this.items.length) {
                    sanitizedIndex = this.items.length - 1;
                } else {
                    sanitizedIndex = index;
                }
                return sanitizedIndex;
            },

            __unselectPrevious: function() {
                var oldIndex = this.index;
                if (oldIndex != -1) {
                    var item = this.items.eq(oldIndex);
                    this.unselectItem(item);
                    this.index = -1;
                }
                return oldIndex;
            },

            __selectItemByValue: function(value) {
                var item = null;
                this.resetSelection();
                var that = this;
                this.__getItems().each(function( i ) {
                    if ($(this).data('clientSelectItem').value == value) {
                        that.__selectByIndex(i);
                        item = $(this);
                        return false; //break
                    }
                });
                return item;
            },

            csvEncodeValues: function() {
                var encoded = new Array();
                this.__getItems().each(function( index ) {
                    encoded.push($(this).data('clientSelectItem').value);
                });
                return encoded.join(",");
            },

            __selectCurrent: function() {
                var item;
                if (this.items && this.index >= 0) {
                    item = this.items.eq(this.index);
                    this.processItem(item);
                }
            },

            __getAdjacentIndex: function(offset) {
                var index = this.index + offset;
                if (index < 0) {
                    index = this.items.length - 1;
                } else if (index >= this.items.length) {
                    index = 0;
                }
                return index;
            },

            __selectPrev: function() {
                this.__selectByIndex(this.__getAdjacentIndex(-1));
            },

            __selectNext: function() {
                this.__selectByIndex(this.__getAdjacentIndex(1));
            },

            __getItem: function(e) {
                return $(e.target).closest("." + this.itemCss, e.currentTarget).get(0);
            },

            __getItems: function () {
                return this.items;
            },

            __setItems: function(items) {
                this.items = items;
            },

            __scrollToSelectedItem : function() {
                if (this.scrollContainer) {
                    var offset = 0;

                    this.items.slice(0, this.index).each(function() {
                        offset += this.offsetHeight;
                    });

                    var parentContainer = this.scrollContainer;
                    if (offset < parentContainer.scrollTop()) {
                        parentContainer.scrollTop(offset);
                    } else {
                        offset += this.items.get(this.index).offsetHeight;
                        if (offset - parentContainer.scrollTop() > parentContainer.get(0).clientHeight) {
                            parentContainer.scrollTop(offset - parentContainer.innerHeight());
                        }
                    }
                }
            },

            setFocus : function() {
    		    this.focusKeeper.focus();
	        }

        }
    })());

})(jQuery, window.RichFaces);;/*if(!window.LOG){
 window.LOG = {warn:function(){}};
 }*/

// TODO: try to change RichFaces.$ to $$ if possible

(function ($, rf) {

    rf.ui = rf.ui || {};

    //calendar templates
    var CalendarView = {
        getControl: function(text, attributes, functionName, paramsStr) {
            var attr = $.extend({
                    onclick: (functionName ? "RichFaces.$$('Calendar',this)." + functionName + "(" + (paramsStr ? paramsStr : "") + ");" : "") + "return true;"
                }, attributes);
            return new E('div', attr, [new T(text)]);
        },

        getSelectedDateControl: function(calendar) {

            if (!calendar.selectedDate || calendar.options.showApplyButton) return "";

            var text = rf.calendarUtils.formatDate(calendar.selectedDate, (calendar.timeType ? calendar.datePattern : calendar.options.datePattern), calendar.options.monthLabels, calendar.options.monthLabelsShort);
            var onclick = "RichFaces.$$('Calendar',this).showSelectedDate(); return true;"
            var markup = ( calendar.options.disabled ?
                new E('div', {'class': 'rf-cal-tl-btn-dis'}, [new ET(text)]) :
                new E('div', {'class': 'rf-cal-tl-btn', 'onclick': onclick}, [new ET(text)]) );

            return markup;
        },

        getTimeControl: function(calendar) {

            if (!calendar.selectedDate || !calendar.timeType) return "";

            var text = rf.calendarUtils.formatDate(calendar.selectedDate, calendar.timePattern, calendar.options.monthLabels, calendar.options.monthLabelsShort);

            var onmouseover = "jQuery(this).removeClass('rf-cal-btn-press');";
            var onmouseout = "jQuery(this).addClass('rf-cal-btn-press');";
            var onclick = "RichFaces.$$('Calendar',this).showTimeEditor();return true;";
            var markup = calendar.options.disabled || calendar.options.readonly ?
                new E('div', {'class': 'rf-cal-tl-btn-btn-dis'}, [new ET(text)]) :
                new E('div', {'class': 'rf-cal-tl-btn rf-cal-tl-btn-hov rf-cal-btn-press', 'onclick': onclick,
                        'onmouseover': + onmouseover ,
                        'onmouseout' : + onmouseout}, [new ET(text)]);

            return markup;
        },

        toolButtonAttributes: {className: "rf-cal-tl-btn", onmouseover:"this.className='rf-cal-tl-btn rf-cal-tl-btn-hov'", onmouseout:"this.className='rf-cal-tl-btn'", onmousedown:"this.className='rf-cal-tl-btn rf-cal-tl-btn-hov rf-cal-tl-btn-btn-press'", onmouseup:"this.className='rf-cal-tl-btn rf-cal-tl-btn-hov'"},
        nextYearControl: function (context) {
            return (!context.calendar.options.disabled ? CalendarView.getControl(">>", CalendarView.toolButtonAttributes, "nextYear") : "");
        },
        previousYearControl: function (context) {
            return (!context.calendar.options.disabled ? CalendarView.getControl("<<", CalendarView.toolButtonAttributes, "prevYear") : "");
        },
        nextMonthControl: function (context) {
            return (!context.calendar.options.disabled ? CalendarView.getControl(">", CalendarView.toolButtonAttributes, "nextMonth") : "");
        },
        previousMonthControl: function (context) {
            return (!context.calendar.options.disabled ? CalendarView.getControl("<", CalendarView.toolButtonAttributes, "prevMonth") : "");
        },
        currentMonthControl: function (context) {
            var text = rf.calendarUtils.formatDate(context.calendar.getCurrentDate(), "MMMM, yyyy", context.monthLabels, context.monthLabelsShort);
            var markup = context.calendar.options.disabled ?
                new E('div', {className: "rf-cal-tl-btn-dis"}, [new T(text)]) :
                CalendarView.getControl(text, CalendarView.toolButtonAttributes, "showDateEditor");
            return markup;
        },
        todayControl: function (context) {
            return (!context.calendar.options.disabled && context.calendar.options.todayControlMode != 'hidden' ? CalendarView.getControl(context.controlLabels.today, CalendarView.toolButtonAttributes, "today") : "");
        },
        closeControl: function (context) {
            return (context.calendar.options.popup ? CalendarView.getControl(context.controlLabels.close, CalendarView.toolButtonAttributes, "close", "false") : "");
        },
        applyControl: function (context) {
            return (!context.calendar.options.disabled && !context.calendar.options.readonly && context.calendar.options.showApplyButton ? CalendarView.getControl(context.controlLabels.apply, CalendarView.toolButtonAttributes, "close", "true") : "");
        },
        cleanControl: function (context) {
            return (!context.calendar.options.disabled && !context.calendar.options.readonly && context.calendar.selectedDate ? CalendarView.getControl(context.controlLabels.clean, CalendarView.toolButtonAttributes, "__resetSelectedDate") : "");
        },

        selectedDateControl: function (context) {
            return CalendarView.getSelectedDateControl(context.calendar);
        },
        timeControl: function (context) {
            return CalendarView.getTimeControl(context.calendar);
        },
        timeEditorFields: function (context) {
            return context.calendar.timePatternHtml;
        },

        header: [
            new E('table', {'border': '0', 'cellpadding': '0', 'cellspacing': '0', 'width': '100%'},
                [
                    new E('tbody', {},
                        [
                            new E('tr', {},
                                [
                                    new E('td', {'class': 'rf-cal-tl'},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("previousYearControl", context)
                                            })
                                        ]),
                                    new E('td', {'class': 'rf-cal-tl'},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("previousMonthControl", context)
                                            })
                                        ]),
                                    new E('td', {'class': 'rf-cal-hdr-month'},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("currentMonthControl", context)
                                            })
                                        ]),
                                    new E('td', {'class': 'rf-cal-tl'},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("nextMonthControl", context)
                                            })
                                        ]),
                                    new E('td', {'class': 'rf-cal-tl'},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("nextYearControl", context)
                                            })
                                        ]),
                                    new E('td', {'class': 'rf-cal-tl rf-cal-btn-close', 'style':function(context) {
                                            return (this.isEmpty ? 'display:none;' : '');
                                        }},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("closeControl", context)
                                            })
                                        ])
                                ])
                        ])
                ]
            )],

        footer: [
            new E('table', {'border': '0', 'cellpadding': '0', 'cellspacing': '0', 'width': '100%'},
                [
                    new E('tbody', {},
                        [
                            new E('tr', {},
                                [
                                    new E('td', {'class': 'rf-cal-tl-ftr', 'style':function(context) {
                                            return (this.isEmpty ? 'display:none;' : '');
                                        }},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("selectedDateControl", context)
                                            })
                                        ]),
                                    new E('td', {'class': 'rf-cal-tl-ftr', 'style':function(context) {
                                            return (this.isEmpty ? 'display:none;' : '');
                                        }},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("cleanControl", context)
                                            })
                                        ]),
                                    new E('td', {'class': 'rf-cal-tl-ftr', 'style':function(context) {
                                            return (this.isEmpty ? 'display:none;' : '');
                                        }},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("timeControl", context)
                                            })
                                        ]),
                                    new E('td', {'class': 'rf-cal-tl-ftr', 'style': 'background-image:none;', 'width': '100%'}, []),
                                    new E('td', {'class': 'rf-cal-tl-ftr', 'style':function(context) {
                                            return (this.isEmpty ? 'display:none;' : '') + (context.calendar.options.disabled || context.calendar.options.readonly || !context.calendar.options.showApplyButton ? 'background-image:none;' : '');
                                        }},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("todayControl", context)
                                            })
                                        ]),
                                    new E('td', {'class': 'rf-cal-tl-ftr', 'style':function(context) {
                                            return (this.isEmpty ? 'display:none;' : '') + 'background-image:none;';
                                        }},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("applyControl", context)
                                            })
                                        ])
                                ])
                        ])
                ]
            )],

        timeEditorLayout: [

            new E('table', {'id': function(context) {
                    return context.calendar.TIME_EDITOR_LAYOUT_ID
                }, 'border': '0', 'cellpadding': '0', 'cellspacing': '0', 'class': 'rf-cal-timepicker-cnt'},
                [
                    new E('tbody', {},
                        [
                            new E('tr', {},
                                [
                                    new E('td', {'class': 'rf-cal-timepicker-inp', 'colspan': '2', 'align': 'center'},
                                        [
                                            new ET(function (context) {
                                                return rf.calendarTemplates.evalMacro("timeEditorFields", context)
                                            })
                                        ])
                                ]),
                            new E('tr', {},
                                [
                                    new E('td', {'class': 'rf-cal-timepicker-ok'},
                                        [
                                            new E('div', {'id': function(context) {
                                                    return context.calendar.TIME_EDITOR_BUTTON_OK
                                                }, 'class': 'rf-cal-time-btn', 'style': 'float:right;', 'onmousedown': "jQuery(this).addClass('rf-cal-time-btn-press');", 'onmouseout': "jQuery(this).removeClass('rf-cal-time-btn-press');", 'onmouseup': "jQuery(this).removeClass('rf-cal-time-btn-press');", 'onclick': function(context) {
                                                    return "RichFaces.$('" + context.calendar.id + "').hideTimeEditor(true)";
                                                }},
                                                [
                                                    new E('span', {},
                                                        [
                                                            new ET(function (context) {
                                                                return context.controlLabels.ok;
                                                            })
                                                        ])
                                                ])
                                        ])
                                    ,
                                    new E('td', {'class': 'rf-cal-timepicker-cancel'},
                                        [
                                            new E('div', {'id': function(context) {
                                                    return context.calendar.TIME_EDITOR_BUTTON_CANCEL
                                                }, 'class': 'rf-cal-time-btn', 'style': 'float:left;', 'onmousedown': "jQuery(this).addClass('rf-cal-time-btn-press');", 'onmouseout': "jQuery(this).removeClass('rf-cal-time-btn-press');", 'onmouseup': "jQuery(this).removeClass('rf-cal-time-btn-press');", 'onclick': function(context) {
                                                    return "RichFaces.$('" + context.calendar.id + "').hideTimeEditor(false)";
                                                }},
                                                [
                                                    new E('span', {},
                                                        [
                                                            new ET(function (context) {
                                                                return context.controlLabels.cancel;
                                                            })
                                                        ])
                                                ])
                                        ])
                                ])
                        ])
                ]
            )],

        dayList: [new ET(function (context) {
            return context.day
        })],
        weekNumber: [new ET(function (context) {
            return context.weekNumber
        })],
        weekDay: [new ET(function (context) {
            return context.weekDayLabelShort
        })]
    };
    // calendar templates end

    // calendar context
    var CalendarContext = function(calendar) {
        this.calendar = calendar;
        this.monthLabels = calendar.options.monthLabels;
        this.monthLabelsShort = calendar.options.monthLabelsShort;
        this.weekDayLabels = calendar.options.weekDayLabels;
        this.weekDayLabelsShort = calendar.options.weekDayLabelsShort;
        this.controlLabels = calendar.options.labels;
    };

    $.extend(CalendarContext.prototype, {
            nextYearControl: CalendarView.nextYearControl,
            previousYearControl: CalendarView.previousYearControl,
            nextMonthControl: CalendarView.nextMonthControl,
            previousMonthControl: CalendarView.previousMonthControl,
            currentMonthControl: CalendarView.currentMonthControl,
            selectedDateControl: CalendarView.selectedDateControl,
            cleanControl: CalendarView.cleanControl,
            timeControl: CalendarView.timeControl,
            todayControl: CalendarView.todayControl,
            closeControl: CalendarView.closeControl,
            applyControl: CalendarView.applyControl,
            timeEditorFields: CalendarView.timeEditorFields
        });

    // must be :defaultTime, minDaysInFirstWeek, firstWeekday, weekDayLabels, weekDayLabelsShort, monthLabels, monthLabelsShort

    // defaults definition
    var defaultOptions = {
        showWeekDaysBar: true,
        showWeeksBar: true,
        datePattern: "MMM d, yyyy",
        horizontalOffset: 0,
        verticalOffset: 0,
        dayListMarkup: CalendarView.dayList,
        weekNumberMarkup: CalendarView.weekNumber,
        weekDayMarkup: CalendarView.weekDay,
        headerMarkup: CalendarView.header,
        footerMarkup: CalendarView.footer,
        isDayEnabled: function (context) {
            return true;
        },
        dayStyleClass: function (context) {
            return "";
        },
        showHeader: true,
        showFooter: true,
        direction: "AA",
        jointPoint: "AA",
        popup: true,
        boundaryDatesMode: "inactive",
        todayControlMode: "select",
        style: "",
        className: "",
        disabled: false,
        readonly: false,
        enableManualInput: false,
        showInput: true,
        resetTimeOnDateSelect: false,
        style: "z-index: 3;",
        showApplyButton: false,
        selectedDate: null,
        currentDate: null,
        defaultTime: {hours:12,minutes:0, seconds:0},
        mode: "client",
        hidePopupOnScroll: true,
        defaultLabel:""
    };

    var defaultLabels = {apply:'Apply', today:'Today', clean:'Clean', ok:'OK', cancel:'Cancel', close:'x'};

    var eventHandlerNames = ["change", "dateselect", "beforedateselect", "currentdateselect",
        "beforecurrentdateselect", "currentdateselect", "clean", "complete", "collapse",
        "datemouseout", "datemouseover", "show", "hide", "timeselect", "beforetimeselect"];

    var updateDefaultLabel = function (value) {
        var field = rf.getDomElement(this.INPUT_DATE_ID);
        if (
            (field.value == this.options.defaultLabel && !value) ||
                (value == this.options.defaultLabel && !field.value)
            ) {
            field.value = value;
            if (value) {
                $(field).addClass("rf-cal-dflt-lbl");
            } else {
                $(field).removeClass("rf-cal-dflt-lbl");
            }
        }
    }

    var onFocusBlur = function (event) {
        this.isFocused = event.type == "focus";
        if (!this.isFocused && this.isVisible) return;
        updateDefaultLabel.call(this, (event.type == "focus" ? "" : this.options.defaultLabel));
    }

    // Constructor definition
    rf.ui.Calendar = function(componentId, locale, options, markups) {

        // dayListMarkup - day cell markup
        //		context: {day, date, weekNumber, weekDayNumber, isWeekend, isCurrentMonth,  elementId, component}
        // weekNumberMarkup - week number cell markup
        //		context: {weekNumber, elementId, component}
        // weekDayMarkup - week day cell markup
        //		context: {weekDayLabel, weekDayLabelShort, weekDayNumber, isWeekend, elementId, component}

        // headerMarkup
        // footerMarkup
        // optionalHeaderMarkup - user defined header (optional)
        // optionalFooterMarkup - user defined footer (optional)

        // currentDate - date to show month (day not used) (MM/yyyy)
        // selectedDate - selected date (mm/dd/yyyy)
        // weekDayLabels - collection of week day labels keyed by week day numbers
        // weekDayLabelsShort - collection of week day short labels keyed by week day numbers
        // minDaysInFirstWeek - locale-specific constant defining number of days in the first week
        // firstWeekDay - (0..6) locale-specific constant defining number of the first week day
        // showWeekDaysBar - show WeekDays Bar [default value is true]
        // showWeeksBar - show Weeks numbers bar [default value is true]
        // showApplyButton
        // showHeader
        // showFooter

        // POPUP description
        // direction - [top-left, top-right, bottom-left, bottom-right, auto]
        // jointPoint - [top-left, top-right, bottom-left, bottom-right]
        // popup - true
        // id+PopupButton, id+InputDate,

        // boundaryDatesMode - boundary dates onclick action:
        // 						"inactive" or undefined - no action (default)
        //						"scroll" - change current month
        //						"select" - change current month and select date
        //						"hidden" - does not render content for boundary dates
        //
        // todayControlMode - today control onclick action:
        //						"scroll"
        //						"select"
        //						"hidden"

        // isDayEnabled - end-developer JS function
        // dayStyleClass - end-developer JS function that provide style class for day's cells.

        // dayCellClass - add div to day cell with class 'rf-cal-c-cnt' and add this class to TD if defined
        // style - table style
        // styleClass - table class

        // disabled
        // readonly

        //var _d = new Date();

        // call constructor of parent class
        $super.constructor.call(this, componentId);

        this.namespace = "." + rf.Event.createNamespace(this.name, componentId);

        //create parameters
        //this.options = $.extend(this.options, defaultOptions, options);
        this.options = $.extend(this.options, defaultOptions, locales[locale], options, markups);

        // labels
        var value = options.labels || {};
        for (var name in defaultLabels) {
            if (!value[name]) value[name] = defaultLabels[name];
        }
        this.options.labels = value;

        this.popupOffset = [this.options.horizontalOffset, this.options.verticalOffset];

        //
        if (!this.options.popup) this.options.showApplyButton = false;

        //
        this.options.boundaryDatesMode = this.options.boundaryDatesMode.toLowerCase();
        this.hideBoundaryDatesContent = this.options.boundaryDatesMode == "hidden";
        this.options.todayControlMode = this.options.todayControlMode.toLowerCase();

        // time
        this.setTimeProperties();

        this.customDayListMarkup = (this.options.dayListMarkup != CalendarView.dayList);

        this.currentDate = this.options.currentDate ? this.options.currentDate : (this.options.selectedDate ? this.options.selectedDate : new Date());
        this.currentDate.setDate(1);
        this.selectedDate = this.options.selectedDate;

        this.todayDate = new Date();

        this.firstWeekendDayNumber = 6 - this.options.firstWeekDay;
        this.secondWeekendDayNumber = (this.options.firstWeekDay > 0 ? 7 - this.options.firstWeekDay : 0);

        this.calendarContext = new CalendarContext(this);

        // TODO: move it from constructor
        this.DATE_ELEMENT_ID = this.id + 'DayCell';
        this.WEEKNUMBER_BAR_ID = this.id + "WeekNum";
        this.WEEKNUMBER_ELEMENT_ID = this.WEEKNUMBER_BAR_ID + 'Cell';
        this.WEEKDAY_BAR_ID = this.id + "WeekDay";
        this.WEEKDAY_ELEMENT_ID = this.WEEKDAY_BAR_ID + 'Cell';
        this.POPUP_ID = this.id + 'Popup';
        this.POPUP_BUTTON_ID = this.id + 'PopupButton';
        this.INPUT_DATE_ID = this.id + 'InputDate';
        this.EDITOR_ID = this.id + 'Editor';
        this.EDITOR_SHADOW_ID = this.id + 'EditorShadow';

        this.TIME_EDITOR_LAYOUT_ID = this.id + 'TimeEditorLayout';
        this.DATE_EDITOR_LAYOUT_ID = this.id + 'DateEditorLayout';
        this.EDITOR_LAYOUT_SHADOW_ID = this.id + 'EditorLayoutShadow';
        this.TIME_EDITOR_BUTTON_OK = this.id + 'TimeEditorButtonOk';
        this.TIME_EDITOR_BUTTON_CANCEL = this.id + 'TimeEditorButtonCancel';
        this.DATE_EDITOR_BUTTON_OK = this.id + 'DateEditorButtonOk';
        this.DATE_EDITOR_BUTTON_CANCEL = this.id + 'DateEditorButtonCancel';
        this.CALENDAR_CONTENT = this.id + "Content";

        this.firstDateIndex = 0;

        this.daysData = {startDate:null, days:[]};
        this.days = [];
        this.todayCellId = null;
        this.todayCellColor = "";

        this.selectedDateCellId = null;
        this.selectedDateCellColor = "";

        var popupStyles = "";
        this.isVisible = true;
        if (this.options.popup == true) {
            // popup mode initialisation
            popupStyles = "display:none; position:absolute;"
            this.isVisible = false;
        }

        var tempStr = "RichFaces.$('" + this.id + "').";

        var htmlTextHeader = '<table id="' + this.CALENDAR_CONTENT + '" border="0" cellpadding="0" cellspacing="0" class="rf-cal-extr rf-cal-popup ' + this.options.styleClass + '" style="' + popupStyles + this.options.style + '" onclick="' + tempStr + 'skipEventOnCollapse=true;"><tbody>';
        var colspan = (this.options.showWeeksBar ? "8" : "7");
        var htmlHeaderOptional = (this.options.optionalHeaderMarkup) ? '<tr><td class="rf-cal-hdr-optnl" colspan="' + colspan + '" id="' + this.id + 'HeaderOptional"></td></tr>' : '';
        var htmlFooterOptional = (this.options.optionalFooterMarkup) ? '<tr><td class="rf-cal-ftr-optl" colspan="' + colspan + '" id="' + this.id + 'FooterOptional"></td></tr>' : '';
        var htmlControlsHeader = (this.options.showHeader ? '<tr><td class="rf-cal-hdr" colspan="' + colspan + '" id="' + this.id + 'Header"></td></tr>' : '');
        var htmlControlsFooter = (this.options.showFooter ? '<tr><td class="rf-cal-ftr" colspan="' + colspan + '" id="' + this.id + 'Footer"></td></tr>' : '');
        var htmlTextFooter = '</tbody></table>'

        // days bar creation
        var styleClass;
        var bottomStyleClass;
        var htmlTextWeekDayBar = [];
        var context;

        var eventsStr = this.options.disabled || this.options.readonly ? '' : 'onclick="' + tempStr + 'eventCellOnClick(event, this);" onmouseover="' + tempStr + 'eventCellOnMouseOver(event, this);" onmouseout="' + tempStr + 'eventCellOnMouseOut(event, this);"';
        if (this.options.showWeekDaysBar) {
            htmlTextWeekDayBar.push('<tr id="' + this.WEEKDAY_BAR_ID + '">');
            if (this.options.showWeeksBar) htmlTextWeekDayBar.push('<td class="rf-cal-day-lbl"><br/></td>');
            var weekDayCounter = this.options.firstWeekDay;
            for (var i = 0; i < 7; i++) {
                context = {weekDayLabel: this.options.weekDayLabels[weekDayCounter], weekDayLabelShort: this.options.weekDayLabelsShort[weekDayCounter], weekDayNumber:weekDayCounter, isWeekend:this.isWeekend(i), elementId:this.WEEKDAY_ELEMENT_ID + i, component:this};
                var weekDayHtml = this.evaluateMarkup(this.options.weekDayMarkup, context);
                if (weekDayCounter == 6) weekDayCounter = 0; else weekDayCounter++;

                styleClass = "rf-cal-day-lbl";
                if (context.isWeekend) {
                    styleClass += " rf-cal-holliday-lbl";
                }
                if (i == 6) styleClass += " rf-cal-right-c";
                htmlTextWeekDayBar.push('<td class="' + styleClass + '" id="' + context.elementId + '">' + weekDayHtml + '</td>');
            }
            htmlTextWeekDayBar.push('</tr>\n');
        }

        // week & weekNumber creation
        var htmlTextWeek = [];
        var p = 0;
        this.dayCellClassName = [];

        for (k = 1; k < 7; k++) {
            bottomStyleClass = (k == 6 ? "rf-btm-c " : "");
            htmlTextWeek.push('<tr id="' + this.WEEKNUMBER_BAR_ID + k + '">');
            if (this.options.showWeeksBar) {
                context = {weekNumber: k, elementId:this.WEEKNUMBER_ELEMENT_ID + k, component:this};
                var weekNumberHtml = this.evaluateMarkup(this.options.weekNumberMarkup, context);
                htmlTextWeek.push('<td class="rf-cal-week ' + bottomStyleClass + '" id="' + context.elementId + '">' + weekNumberHtml + '</td>');
            }

            // day cells creation
            for (var i = 0; i < 7; i++) {
                styleClass = bottomStyleClass + (!this.options.dayCellClass ? "rf-cal-c-cnt-overflow" : (!this.customDayListMarkup ? this.options.dayCellClass : "")) + " rf-cal-c";
                if (i == this.firstWeekendDayNumber || i == this.secondWeekendDayNumber) styleClass += " rf-cal-holiday";
                if (i == 6) styleClass += " rf-cal-right-c";

                this.dayCellClassName.push(styleClass);
                htmlTextWeek.push('<td class="' + styleClass + '" id="' + this.DATE_ELEMENT_ID + p + '" ' +
                    eventsStr +
                    '>' + (this.customDayListMarkup ? '<div class="rf-cal-c-cnt' + (this.options.dayCellClass ? ' ' + this.options.dayCellClass : '') + '"></div>' : '') + '</td>');
                p++;
            }
            htmlTextWeek.push('</tr>');
        }

        var div = rf.getDomElement(this.CALENDAR_CONTENT);
        div = $(div).replaceWith(htmlTextHeader + htmlHeaderOptional + htmlControlsHeader + htmlTextWeekDayBar.join('') + htmlTextWeek.join('') + htmlControlsFooter + htmlFooterOptional + htmlTextFooter);
        this.attachToDom(); // TODO: optimize double $

        // memory leaks fix // from old 3.3.x code, may be not needed now
        div = null;

        // add onclick event handlers to input field and popup button
        if (this.options.popup && !this.options.disabled) {
            var handler = new Function('event', "RichFaces.$('" + this.id + "').switchPopup();");
            rf.Event.bindById(this.POPUP_BUTTON_ID, "click" + this.namespace, handler, this);
            if (!this.options.enableManualInput) {
                rf.Event.bindById(this.INPUT_DATE_ID, "click" + this.namespace, handler, this);
            }
            if (this.options.defaultLabel) {
                updateDefaultLabel.call(this, this.options.defaultLabel);
                rf.Event.bindById(this.INPUT_DATE_ID, "focus" + this.namespace + " blur" + this.namespace, onFocusBlur, this);
            }
        }

        this.scrollElements = null;

        //define isAjaxMode variable
        this.isAjaxMode = this.options.mode == "ajax";

        //alert(new Date().getTime()-_d.getTime());
    };

    // Extend component class and add protected methods from parent class to our container
    rf.BaseComponent.extend(rf.ui.Calendar);

    // define super class link
    var $super = rf.ui.Calendar.$super;

    // static methods definition
    var locales = {};

    rf.ui.Calendar.addLocale = function (locale, symbols) {
        if (!locales[locale]) {
            locales[locale] = symbols;
        }
    };

    /*
     * Prototype definition
     */
    $.extend(rf.ui.Calendar.prototype, {
            name: "Calendar",
            destroy: function() {
                if (this.options.popup && this.isVisible) {
                    this.scrollElements && rf.Event.unbindScrollEventHandlers(this.scrollElements, this);
                    this.scrollElements = null;
                    rf.Event.unbind(window.document, "click" + this.namespace);
                }
                $super.destroy.call(this);
            },

            dateEditorSelectYear: function(value) {
                if (this.dateEditorYearID) {
                    $(rf.getDomElement(this.dateEditorYearID)).removeClass('rf-cal-edtr-btn-sel');
                }
                this.dateEditorYear = this.dateEditorStartYear + value;
                this.dateEditorYearID = this.DATE_EDITOR_LAYOUT_ID + 'Y' + value;
                $(rf.getDomElement(this.dateEditorYearID)).addClass('rf-cal-edtr-btn-sel');
            },

            dateEditorSelectMonth: function(value) {
                this.dateEditorMonth = value;
                $(rf.getDomElement(this.dateEditorMonthID)).removeClass('rf-cal-edtr-btn-sel');
                this.dateEditorMonthID = this.DATE_EDITOR_LAYOUT_ID + 'M' + value;
                $(rf.getDomElement(this.dateEditorMonthID)).addClass('rf-cal-edtr-btn-sel');
            },

            scrollEditorYear: function(value) {
                var element = rf.getDomElement(this.DATE_EDITOR_LAYOUT_ID + 'TR');

                if (this.dateEditorYearID) {
                    $(rf.getDomElement(this.dateEditorYearID)).removeClass('rf-cal-edtr-btn-sel');
                    this.dateEditorYearID = '';
                }

                if (!value) {
                    // update month selection when open editor (value == 0)
                    if (this.dateEditorMonth != this.getCurrentMonth()) {
                        this.dateEditorMonth = this.getCurrentMonth();
                        $(rf.getDomElement(this.dateEditorMonthID)).removeClass('rf-cal-edtr-btn-sel');
                        this.dateEditorMonthID = this.DATE_EDITOR_LAYOUT_ID + 'M' + this.dateEditorMonth;
                        $(rf.getDomElement(this.dateEditorMonthID)).addClass('rf-cal-edtr-btn-sel');
                    }
                }

                if (element) {
                    var div;
                    var year = this.dateEditorStartYear = this.dateEditorStartYear + value * 10;
                    for (var i = 0; i < 5; i++) {
                        element = element.nextSibling;
                        div = element.firstChild.nextSibling.nextSibling;
                        div.firstChild.innerHTML = year;
                        if (year == this.dateEditorYear) {
                            $(div.firstChild).addClass('rf-cal-edtr-btn-sel');
                            this.dateEditorYearID = div.firstChild.id;
                        }
                        div = div.nextSibling;
                        div.firstChild.innerHTML = year + 5;
                        if (year + 5 == this.dateEditorYear) {
                            $(div.firstChild).addClass('rf-cal-edtr-btn-sel');
                            this.dateEditorYearID = div.firstChild.id;
                        }
                        year++;
                    }
                }
            },

            updateDateEditor: function() {
                this.dateEditorYear = this.getCurrentYear();
                this.dateEditorStartYear = this.getCurrentYear() - 4;
                this.scrollEditorYear(0);
            },

            updateTimeEditor: function() {
                var th = rf.getDomElement(this.id + 'TimeHours');
                var ts = rf.getDomElement(this.id + 'TimeSign');
                var tm = rf.getDomElement(this.id + 'TimeMinutes');

                var h = this.selectedDate.getHours();
                var m = this.selectedDate.getMinutes();
                if (this.timeType == 2) {
                    var a = (h < 12 ? 'AM' : 'PM');
                    ts.value = a;
                    h = (h == 0 ? '12' : (h > 12 ? h - 12 : h));
                }
                th.value = (this.timeHoursDigits == 2 && h < 10 ? '0' + h : h);
                tm.value = (m < 10 ? '0' + m : m);

                if (this.showSeconds) {
                    var tsec = rf.getDomElement(this.id + 'TimeSeconds');
                    var s = this.selectedDate.getSeconds();
                    tsec.value = (s < 10 ? '0' + s : s);
                }
            },


            createEditor: function() {
                var element = $(rf.getDomElement(this.CALENDAR_CONTENT));
                var zindex = parseInt(element.css('z-index'), 10);
                var htmlBegin = '<div id="' + this.EDITOR_SHADOW_ID + '" class="rf-cal-edtr-shdw" style="position:absolute; display:none;z-index:' + zindex + '"></div><table border="0" cellpadding="0" cellspacing="0" id="' + this.EDITOR_ID + '" style="position:absolute; display:none;z-index:' + (zindex + 1) + '" onclick="RichFaces.$(\'' + this.id + '\').skipEventOnCollapse=true;"><tbody><tr><td class="rf-cal-edtr-cntr" align="center"><div style="position:relative; display:inline-block;">';
                var htmlContent = '<div id="' + this.EDITOR_LAYOUT_SHADOW_ID + '" class="rf-cal-edtr-layout-shdw"></div>';

                var htmlEnd = '</div></td></tr></tbody></table>';
                element.after(htmlBegin + htmlContent + htmlEnd);

                this.isEditorCreated = true;

                return rf.getDomElement(this.EDITOR_ID);
            },

            createTimeEditorLayout: function(editor) {
                $(rf.getDomElement(this.EDITOR_LAYOUT_SHADOW_ID)).after(this.evaluateMarkup(CalendarView.timeEditorLayout, this.calendarContext));

                var th = rf.getDomElement(this.id + 'TimeHours');
                var ts;
                var tm = rf.getDomElement(this.id + 'TimeMinutes');
                if (this.timeType == 1) {
                    sbjQuery(th).SpinButton({digits:this.timeHoursDigits,min:0,max:23});
                }
                else {
                    sbjQuery(th).SpinButton({digits:this.timeHoursDigits,min:1,max:12});
                    ts = rf.getDomElement(this.id + 'TimeSign');
                    sbjQuery(ts).SpinButton({});
                }
                sbjQuery(tm).SpinButton({digits:2,min:0,max:59});
                if (this.showSeconds) {
                    var tsec = rf.getDomElement(this.id + 'TimeSeconds');
                    sbjQuery(tsec).SpinButton({digits:2,min:0,max:59});
                }

                this.correctEditorButtons(editor, this.TIME_EDITOR_BUTTON_OK, this.TIME_EDITOR_BUTTON_CANCEL);

                this.isTimeEditorLayoutCreated = true;
            },

            correctEditorButtons: function(editor, buttonID1, buttonID2) {
                var button1 = rf.getDomElement(buttonID1);
                var button2 = rf.getDomElement(buttonID2);
                editor.style.visibility = "hidden";
                editor.style.display = "";
                var width1 = $(button1.firstChild).width();
                var width2 = $(button2.firstChild).width();
                editor.style.display = "none";
                editor.style.visibility = "";

                if (width1 != width2) {
                    button1.style.width = button2.style.width = (width1 > width2 ? width1 : width2) + "px";
                }
            },

            createDECell: function(id, value, buttonType, param, className) {
                if (buttonType == 0) {
                    return '<div id="' + id + '" class="rf-cal-edtr-btn' + (className ? ' ' + className : '') +
                        '" onmouseover="this.className=\'rf-cal-edtr-btn rf-cal-edtr-tl-over\';" onmouseout="this.className=\'rf-cal-edtr-btn\';" onmousedown="this.className=\'rf-cal-edtr-btn rf-cal-edtr-tl-press\';" onmouseup="this.className=\'rf-cal-edtr-btn rf-cal-edtr-tl-over\';" onclick="RichFaces.$(\'' + this.id + '\').scrollEditorYear(' + param + ');">' + value + '</div>';
                }
                else {
                    var onclick = (buttonType == 1 ? 'RichFaces.$(\'' + this.id + '\').dateEditorSelectMonth(' + param + ');' :
                        'RichFaces.$(\'' + this.id + '\').dateEditorSelectYear(' + param + ');' );
                    return '<div id="' + id + '" class="rf-cal-edtr-btn' + (className ? ' ' + className : '') +
                        '" onmouseover="jQuery(this).addClass(\'rf-cal-edtr-btn-over\');" onmouseout="$(this).removeClass(\'rf-cal-edtr-btn-over\');" onclick="' + onclick + '">' + value + '</div>';
                }
            },

            createDateEditorLayout: function(editor) {
                var htmlBegin = '<table id="' + this.DATE_EDITOR_LAYOUT_ID + '" class="rf-cal-monthpicker-cnt" border="0" cellpadding="0" cellspacing="0"><tbody><tr id="' + this.DATE_EDITOR_LAYOUT_ID + 'TR">';
                var htmlEnd = '</tr></tbody></table>';
                var month = 0;
                this.dateEditorYear = this.getCurrentYear();
                var year = this.dateEditorStartYear = this.dateEditorYear - 4;
                var htmlContent = '<td align="center">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'M' + month, this.options.monthLabelsShort[month], 1, month) + '</td>'
                    + '<td align="center" class="rf-cal-monthpicker-split">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'M' + (month + 6), this.options.monthLabelsShort[month + 6], 1, month + 6) + '</td>'
                    + '<td align="center">' + this.createDECell('', '&lt;', 0, -1) + '</td>'
                    + '<td align="center">' + this.createDECell('', '&gt;', 0, 1) + '</td>';
                month++;

                for (var i = 0; i < 5; i++) {
                    htmlContent += '</tr><tr><td align="center">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'M' + month, this.options.monthLabelsShort[month], 1, month) + '</td>'
                        + '<td align="center" class="rf-cal-monthpicker-split">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'M' + (month + 6), this.options.monthLabelsShort[month + 6], 1, month + 6) + '</td>'
                        + '<td align="center">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'Y' + i, year, 2, i, (i == 4 ? 'rf-cal-edtr-btn-sel' : '')) + '</td>'
                        + '<td align="center">' + this.createDECell(this.DATE_EDITOR_LAYOUT_ID + 'Y' + (i + 5), year + 5, 2, i + 5) + '</td>';
                    month++;
                    year++;
                }
                this.dateEditorYearID = this.DATE_EDITOR_LAYOUT_ID + 'Y4';
                this.dateEditorMonth = this.getCurrentMonth();
                this.dateEditorMonthID = this.DATE_EDITOR_LAYOUT_ID + 'M' + this.dateEditorMonth;

                htmlContent += '</tr><tr><td colspan="2" class="rf-cal-monthpicker-ok">' +
                    '<div id="' + this.DATE_EDITOR_BUTTON_OK + '" class="rf-cal-time-btn" style="float:right;" onmousedown="jQuery(this).addClass(\'rf-cal-time-btn-press\');" onmouseout="jQuery(this).removeClass(\'rf-cal-time-btn-press\');" onmouseup="jQuery(this).removeClass(\'rf-cal-time-btn-press\');" onclick="RichFaces.$(\'' + this.id + '\').hideDateEditor(true);"><span>' + this.options.labels.ok + '</span></div>' +
                    '</td><td colspan="2" class="rf-cal-monthpicker-cancel">' +
                    '<div id="' + this.DATE_EDITOR_BUTTON_CANCEL + '" class="rf-cal-time-btn" style="float:left;" onmousedown="jQuery(this).addClass(\'rf-cal-time-btn-press\');" onmouseout="jQuery(this).removeClass(\'rf-cal-time-btn-press\');" onmouseup="jQuery(this).removeClass(\'rf-cal-time-btn-press\');" onclick="RichFaces.$(\'' + this.id + '\').hideDateEditor(false);"><span>' + this.options.labels.cancel + '</span></div>' +
                    '</td>';


                $(rf.getDomElement(this.EDITOR_LAYOUT_SHADOW_ID)).after(htmlBegin + htmlContent + htmlEnd);

                $(rf.getDomElement(this.dateEditorMonthID)).addClass('rf-cal-edtr-btn-sel');

                this.correctEditorButtons(editor, this.DATE_EDITOR_BUTTON_OK, this.DATE_EDITOR_BUTTON_CANCEL);

                this.isDateEditorLayoutCreated = true;
            },

            createSpinnerTable: function(id) {
                return '<table cellspacing="0" cellpadding="0" border="0"><tbody><tr>' +
                    '<td class="rf-cal-sp-inp-ctnr">' +
                    '<input id="' + id + '" name="' + id + '" class="rf-cal-sp-inp" type="text" />' +
                    '</td>' +
                    '<td class="rf-cal-sp-btn">' +
                    '<table border="0" cellspacing="0" cellpadding="0"><tbody>' +
                    '<tr><td>' +
                    '<div id="' + id + 'BtnUp" class="rf-cal-sp-up"' +
                    ' onmousedown="this.className=\'rf-cal-sp-up rf-cal-sp-press\'"' +
                    ' onmouseup="this.className=\'rf-cal-sp-up\'"' +
                    ' onmouseout="this.className=\'rf-cal-sp-up\'"><span></span></div>' +
                    '</td></tr>' +
                    '<tr><td>' +
                    '<div id="' + id + 'BtnDown" class="rf-cal-sp-down"' +
                    ' onmousedown="this.className=\'rf-cal-sp-down rf-cal-sp-press\'"' +
                    ' onmouseup="this.className=\'rf-cal-sp-down\'"' +
                    ' onmouseout="this.className=\'rf-cal-sp-down\'"><span></span></div>' +
                    '</td></tr>' +
                    '</tbody></table>' +
                    '</td>' +
                    '</tr></tbody></table>';
            },

            setTimeProperties: function() {
                this.timeType = 0;

                var dateTimePattern = this.options.datePattern;
                var pattern = [];
                var re = /(\\\\|\\[yMdaHhms])|(y+|M+|d+|a|H{1,2}|h{1,2}|m{2}|s{2})/g;
                var r;
                while (r = re.exec(dateTimePattern))
                    if (!r[1])
                        pattern.push({str:r[0],marker:r[2],idx:r.index});

                var datePattern = "";
                var timePattern = "";

                var digits,h,hh,m,s,a;
                var id = this.id;

                var getString = function (p) {
                    return (p.length == 0 ? obj.marker : dateTimePattern.substring(pattern[i - 1].str.length + pattern[i - 1].idx, obj.idx + obj.str.length));
                };

                for (var i = 0; i < pattern.length; i++) {
                    var obj = pattern[i];
                    var ch = obj.marker.charAt(0);
                    if (ch == 'y' || ch == 'M' || ch == 'd') datePattern += getString(datePattern);
                    else if (ch == 'a') {
                        a = true;
                        timePattern += getString(timePattern);
                    }
                    else if (ch == 'H') {
                        h = true;
                        digits = obj.marker.length;
                        timePattern += getString(timePattern);
                    }
                    else if (ch == 'h') {
                        hh = true;
                        digits = obj.marker.length;
                        timePattern += getString(timePattern);
                    }
                    else if (ch == 'm') {
                        m = true;
                        timePattern += getString(timePattern);
                    }
                    else if (ch == 's') {
                        this.showSeconds = true;
                        timePattern += getString(timePattern);
                    }


                }
                this.datePattern = datePattern;
                this.timePattern = timePattern;

                var calendar = this;

                this.timePatternHtml = timePattern.replace(/(\\\\|\\[yMdaHhms])|(H{1,2}|h{1,2}|m{2}|s{2}|a)/g,
                    function($1, $2, $3) {
                        if ($2) return $2.charAt(1);
                        switch ($3) {
                            case 'a'  :
                                return '</td><td>' + calendar.createSpinnerTable(id + 'TimeSign') + '</td><td>';
                            case 'H'  :
                            case 'HH' :
                            case 'h'  :
                            case 'hh' :
                                return '</td><td>' + calendar.createSpinnerTable(id + 'TimeHours') + '</td><td>';
                            case 'mm' :
                                return '</td><td>' + calendar.createSpinnerTable(id + 'TimeMinutes') + '</td><td>';
                            case 'ss' :
                                return '</td><td>' + calendar.createSpinnerTable(id + 'TimeSeconds') + '</td><td>';
                        }
                    }
                );

                this.timePatternHtml = '<table border="0" cellpadding="0"><tbody><tr><td>' + this.timePatternHtml + '</td></tr></tbody></table>';

                if (m && h) {
                    this.timeType = 1;
                }
                else if (m && hh && a) {
                    this.timeType = 2;
                }
                this.timeHoursDigits = digits;
            },

            eventOnScroll: function (e) {
                this.hidePopup();
            },

            hidePopup: function() {

                if (!this.options.popup || !this.isVisible) return;

                if (this.invokeEvent("hide", rf.getDomElement(this.id))) {
                    if (this.isEditorVisible) this.hideEditor();
                    this.scrollElements && rf.Event.unbindScrollEventHandlers(this.scrollElements, this);
                    this.scrollElements = null;
                    rf.Event.unbind(window.document, "click" + this.namespace);

                    $(rf.getDomElement(this.CALENDAR_CONTENT)).hide();
                    this.isVisible = false;
                    if (this.options.defaultLabel && !this.isFocused) {
                        updateDefaultLabel.call(this, this.options.defaultLabel);
                    }
                }
            },

            showPopup: function(e) {
                if (!this.isRendered) {
                    this.isRendered = true;
                    this.render();
                }
                this.skipEventOnCollapse = false;
                if (e && e.type == 'click') this.skipEventOnCollapse = true;
                if (!this.options.popup || this.isVisible) return;

                var element = rf.getDomElement(this.id);

                if (this.invokeEvent("show", element, e)) {
                    var base = rf.getDomElement(this.POPUP_ID)
                    var baseInput = base.firstChild;
                    var baseButton = baseInput.nextSibling;

                    if (this.options.defaultLabel) {
                        if (!this.isFocused) updateDefaultLabel.call(this, "");
                    }
                    if (baseInput.value) {
                        this.__selectDate(baseInput.value, false, {event:e, element:element});
                    }

                    //rect calculation

                    if (this.options.showInput) {
                        base = base.children;
                    } else {
                        base = baseButton;
                    }
                    ;

                    $(rf.getDomElement(this.CALENDAR_CONTENT)).setPosition(base, {type:"DROPDOWN", from: this.options.jointPoint, to:this.options.direction, offset: this.popupOffset}).show();

                    this.isVisible = true;

                    rf.Event.bind(window.document, "click" + this.namespace, this.eventOnCollapse, this);

                    this.scrollElements && rf.Event.unbindScrollEventHandlers(this.scrollElements, this);
                    this.scrollElements = null;
                    if (this.options.hidePopupOnScroll) {
                        this.scrollElements = rf.Event.bindScrollEventHandlers(element, this.eventOnScroll, this);
                    }
                }
            },

            switchPopup: function(e) {
                this.isVisible ? this.hidePopup() : this.showPopup(e);
            },

            eventOnCollapse: function (e) {
                if (this.skipEventOnCollapse) {
                    this.skipEventOnCollapse = false;
                    return true;
                }

                if (e.target.id == this.POPUP_BUTTON_ID || (!this.options.enableManualInput && e.target.id == this.INPUT_DATE_ID)) return true;

                this.hidePopup();

                return true;
            },

            setInputField: function(dateStr, event) {
                var field = rf.getDomElement(this.INPUT_DATE_ID);
                if (field.value != dateStr) {
                    field.value = dateStr;
                    this.invokeEvent("change", rf.getDomElement(this.id), event, this.selectedDate);
                    $(rf.getDomElement(this.INPUT_DATE_ID)).blur();
                }
            },

            getCurrentDate: function() {
                return this.currentDate;
            },
            __getSelectedDate: function() {
                if (!this.selectedDate) return null; else return this.selectedDate;
            },
            __getSelectedDateString: function(pattern) {
                if (!this.selectedDate) return "";
                if (!pattern) pattern = this.options.datePattern;
                return rf.calendarUtils.formatDate(this.selectedDate, pattern, this.options.monthLabels, this.options.monthLabelsShort);
            },

            getPrevYear: function() {
                var value = this.currentDate.getFullYear() - 1;
                if (value < 0) value = 0;
                return value;
            },
            getPrevMonth: function(asMonthLabel) {
                var value = this.currentDate.getMonth() - 1;
                if (value < 0) value = 11;
                if (asMonthLabel) {
                    return this.options.monthLabels[value];
                } else return value;
            },
            getCurrentYear: function() {
                return this.currentDate.getFullYear();
            },
            getCurrentMonth: function(asMonthLabel) {
                var value = this.currentDate.getMonth();
                if (asMonthLabel) {
                    return this.options.monthLabels[value];
                } else return value;
            },
            getNextYear: function() {
                return this.currentDate.getFullYear() + 1;
            },
            getNextMonth: function(asMonthLabel) {
                var value = this.currentDate.getMonth() + 1;
                if (value > 11) value = 0;
                if (asMonthLabel) {
                    return this.options.monthLabels[value];
                } else return value;
            },

            isWeekend: function(weekday) {
                return (weekday == this.firstWeekendDayNumber || weekday == this.secondWeekendDayNumber);
            },

            setupTimeForDate: function (date) {
                var result = new Date(date);
                if (this.selectedDate && (!this.options.resetTimeOnDateSelect ||
                    (this.selectedDate.getFullYear() == date.getFullYear() &&
                        this.selectedDate.getMonth() == date.getMonth() &&
                        this.selectedDate.getDate() == date.getDate()))) {
                    result = rf.calendarUtils.createDate(date.getFullYear(), date.getMonth(), date.getDate(), this.selectedDate.getHours(), this.selectedDate.getMinutes(), this.selectedDate.getSeconds());
                } else {
                    result = rf.calendarUtils.createDate(date.getFullYear(), date.getMonth(), date.getDate(), this.options.defaultTime.hours, this.options.defaultTime.minutes, this.options.defaultTime.seconds);
                }
                return result;
            },

            eventCellOnClick: function (e, obj) {
                var daydata = this.days[parseInt(obj.id.substr(this.DATE_ELEMENT_ID.length), 10)];
                if (daydata.enabled && daydata._month == 0) {
                    var date = rf.calendarUtils.createDate(this.currentDate.getFullYear(), this.currentDate.getMonth(), daydata.day);
                    if (this.timeType) {
                        date = this.setupTimeForDate(date);
                    }

                    if (this.__selectDate(date, true, {event:e, element:obj}) && !this.options.showApplyButton) {
                        this.hidePopup();
                    }

                } else if (daydata._month != 0) {
                    if (this.options.boundaryDatesMode == "scroll")
                        if (daydata._month == -1) this.prevMonth(); else this.nextMonth();
                    else if (this.options.boundaryDatesMode == "select") {
                        var date = new Date(daydata.date);
                        if (this.timeType) {
                            date = this.setupTimeForDate(date);
                        }

                        if (this.__selectDate(date, false, {event:e, element:obj}) && !this.options.showApplyButton) {
                            this.hidePopup();
                        }
                    }
                }
            },

            eventCellOnMouseOver: function (e, obj) {
                var daydata = this.days[parseInt(obj.id.substr(this.DATE_ELEMENT_ID.length), 10)];
                if (this.invokeEvent("datemouseover", obj, e, daydata.date) && daydata.enabled) {
                    if (daydata._month == 0 && obj.id != this.selectedDateCellId && obj.id != this.todayCellId) {
                        $(obj).addClass('rf-cal-hov');
                    }
                }
            },

            eventCellOnMouseOut: function (e, obj) {
                var daydata = this.days[parseInt(obj.id.substr(this.DATE_ELEMENT_ID.length), 10)];
                if (this.invokeEvent("datemouseout", obj, e, daydata.date) && daydata.enabled) {
                    if (daydata._month == 0 && obj.id != this.selectedDateCellId && obj.id != this.todayCellId) {
                        $(obj).removeClass('rf-cal-hov');
                    }
                }
            },

            load:function(daysData, isAjaxMode) {
                //	startDate,
                //	daysData:array[]
                //	{
                //			day
                //			enabled boolean
                //			text1: 'Meeting...',
                //			text2: 'Meeting...'
                //			tooltip
                //			hasTooltip
                //			styleClass
                //	}


                if (daysData) {
                    this.daysData = this.indexData(daysData, isAjaxMode);
                } else {
                    this.daysData = null;
                }

                this.isRendered = false;
                if (this.isVisible) {
                    this.render();
                }
                ;

                if (typeof this.afterLoad == 'function') {
                    this.afterLoad();
                    this.afterLoad = null;
                }
            },

            indexData:function(daysData, isAjaxMode) {

                var dateYear = daysData.startDate.year;
                var dateMonth = daysData.startDate.month;
                daysData.startDate = new Date(dateYear, dateMonth)

                daysData.index = [];
                daysData.index[dateYear + '-' + dateMonth] = 0;
                if (isAjaxMode) {
                    this.currentDate = daysData.startDate;
                    this.currentDate.setDate(1);
                    return daysData;
                }
                var idx = rf.calendarUtils.daysInMonthByDate(daysData.startDate) - daysData.startDate.getDate() + 1;

                while (daysData.days[idx]) {
                    if (dateMonth == 11) {
                        dateYear++;
                        dateMonth = 0;
                    } else dateMonth++;
                    daysData.index[dateYear + '-' + dateMonth] = idx;
                    idx += (32 - new Date(dateYear, dateMonth, 32).getDate());
                }
                return daysData;
            },

            getCellBackgroundColor: function(element) {
                return $(element).css('background-color');
            },

            clearEffect: function (element_id, className, className1) {
                if (element_id) {
                    var e = $(rf.getDomElement(element_id)).stop(true, true);
                    if (className) e.removeClass(className);
                    if (className1) e.addClass(className1);
                }
                return null;
            },

            render:function() {
                //var _d=new Date();
                this.isRendered = true;
                this.todayDate = new Date();

                var currentYear = this.getCurrentYear();
                var currentMonth = this.getCurrentMonth();

                var todayflag = (currentYear == this.todayDate.getFullYear() && currentMonth == this.todayDate.getMonth());
                var todaydate = this.todayDate.getDate();

                var selectedflag = this.selectedDate && (currentYear == this.selectedDate.getFullYear() && currentMonth == this.selectedDate.getMonth())
                var selecteddate = this.selectedDate && this.selectedDate.getDate();

                var wd = rf.calendarUtils.getDay(this.currentDate, this.options.firstWeekDay);
                var currentMonthDays = rf.calendarUtils.daysInMonthByDate(this.currentDate);
                var previousMonthDays = rf.calendarUtils.daysInMonth(currentYear, currentMonth - 1);

                var p = 0;
                var month = -1;
                this.days = [];
                var dayCounter = previousMonthDays - wd + 1;

                // previuos month days
                if (wd > 0) while (dayCounter <= previousMonthDays) {
                    this.days.push({day:dayCounter, isWeekend: this.isWeekend(p), _month:month});
                    dayCounter++;
                    p++;
                }

                dayCounter = 1;
                month = 0;

                this.firstDateIndex = p;

                // current month days
                if (this.daysData && this.daysData.index[currentYear + '-' + currentMonth] != undefined) {
                    var idx = this.daysData.index[currentYear + '-' + currentMonth];
                    if (this.daysData.startDate.getFullYear() == currentYear && this.daysData.startDate.getMonth() == currentMonth) {
                        var firstDay = firstDay = (this.daysData.days[idx].day ? this.daysData.days[idx].day : this.daysData.startDate.getDate());
                        while (dayCounter < firstDay) {
                            this.days.push({day:dayCounter, isWeekend:this.isWeekend(p % 7), _month:month});

                            dayCounter++;
                            p++;
                        }
                    }

                    var len = this.daysData.days.length;
                    var obj;
                    var flag;
                    while (idx < len && dayCounter <= currentMonthDays) {
                        flag = this.isWeekend(p % 7);
                        obj = this.daysData.days[idx];
                        obj.day = dayCounter;
                        obj.isWeekend = flag;
                        obj._month = month;
                        this.days.push(obj);
                        idx++;
                        dayCounter++;
                        p++;
                    }
                }
                while (p < 42) {
                    if (dayCounter > currentMonthDays) {
                        dayCounter = 1;
                        month = 1;
                    }
                    this.days.push({day:dayCounter, isWeekend: this.isWeekend(p % 7), _month:month});
                    dayCounter++;
                    p++;
                }

                // render
                this.renderHF();

                //days render
                p = 0;
                var element;
                var dataobj;
                var wn;
                if (this.options.showWeeksBar) wn = rf.calendarUtils.weekNumber(currentYear, currentMonth, this.options.minDaysInFirstWeek, this.options.firstWeekDay); /// fix it
                this.selectedDayElement = null;
                var weekflag = true;

                var e;

                var boundaryDatesModeFlag = (this.options.boundaryDatesMode == "scroll" || this.options.boundaryDatesMode == "select");

                this.todayCellId = this.clearEffect(this.todayCellId);
                this.selectedDateCellId = this.clearEffect(this.selectedDateCellId);

                //var _d=new Date();
                var obj = rf.getDomElement(this.WEEKNUMBER_BAR_ID + "1");
                for (var k = 1; k < 7; k++) {
                    //
                    dataobj = this.days[p];

                    element = obj.firstChild;
                    var weeknumber;

                    // week number update
                    if (this.options.showWeeksBar) {
                        // TODO: fix:  there is no weekNumber in dataobj if showWeeksBar == false;
                        if (weekflag && currentMonth == 11 &&
                            (k == 5 || k == 6) &&
                            (dataobj._month == 1 || (7 - (currentMonthDays - dataobj.day + 1)) >= this.options.minDaysInFirstWeek)) {
                            wn = 1;
                            weekflag = false;
                        }
                        weeknumber = wn;
                        element.innerHTML = this.evaluateMarkup(this.options.weekNumberMarkup, {weekNumber: wn++, elementId:element.id, component:this});
                        if (k == 1 && wn > 52) wn = 1;
                        element = element.nextSibling;
                    }

                    var weekdaycounter = this.options.firstWeekDay;
                    var contentElement = null;

                    while (element) {
                        dataobj.elementId = element.id;
                        dataobj.date = new Date(currentYear, currentMonth + dataobj._month, dataobj.day);
                        dataobj.weekNumber = weeknumber;
                        dataobj.component = this;
                        dataobj.isCurrentMonth = (dataobj._month == 0);
                        dataobj.weekDayNumber = weekdaycounter;

                        // call user function to get day state
                        if (dataobj.enabled != false) dataobj.enabled = this.options.isDayEnabled(dataobj);
                        // call user function to custom class style
                        if (!dataobj.styleClass) dataobj.customStyleClass = this.options.dayStyleClass(dataobj);
                        else {
                            var styleclass = this.options.dayStyleClass(dataobj);
                            dataobj.customStyleClass = dataobj.styleClass;
                            if (styleclass) dataobj.customStyleClass += " " + styleclass;
                        }

                        contentElement = (this.customDayListMarkup ? element.firstChild : element);
                        contentElement.innerHTML = this.hideBoundaryDatesContent && dataobj._month != 0 ? "" : this.evaluateMarkup(this.options.dayListMarkup, dataobj);

                        if (weekdaycounter == 6) weekdaycounter = 0; else weekdaycounter++;

                        var classNames = this.dayCellClassName[p];

                        // class styles
                        if (dataobj._month != 0) {
                            classNames += ' rf-cal-boundary-day';
                            if (!this.options.disabled && !this.options.readonly && boundaryDatesModeFlag) {
                                classNames += ' rf-cal-btn';
                            }
                        }
                        else {
                            if (todayflag && dataobj.day == todaydate) {
                                this.todayCellId = element.id;
                                this.todayCellColor = this.getCellBackgroundColor(element);
                                classNames += " rf-cal-today";
                            }

                            if (selectedflag && dataobj.day == selecteddate) {
                                this.selectedDateCellId = element.id;
                                this.selectedDateCellColor = this.getCellBackgroundColor(element);
                                classNames += " rf-cal-sel";
                            }
                            else if (!this.options.disabled && !this.options.readonly && dataobj.enabled) classNames += ' rf-cal-btn';

                            // add custom style class
                            if (dataobj.customStyleClass) {
                                classNames += ' ' + dataobj.customStyleClass;
                            }
                        }
                        element.className = classNames;

                        p++;

                        dataobj = this.days[p];
                        element = element.nextSibling;
                    }
                    obj = obj.nextSibling;
                }

                //alert(new Date().getTime()-_d.getTime());

            },

            renderHF: function() {
                if (this.options.showHeader) this.renderMarkup(this.options.headerMarkup, this.id + "Header", this.calendarContext);
                if (this.options.showFooter) this.renderMarkup(this.options.footerMarkup, this.id + "Footer", this.calendarContext);

                this.renderHeaderOptional();
                this.renderFooterOptional();
            },

            renderHeaderOptional: function() {
                this.renderMarkup(this.options.optionalHeaderMarkup, this.id + "HeaderOptional", this.calendarContext);
            },

            renderFooterOptional: function() {
                this.renderMarkup(this.options.optionalFooterMarkup, this.id + "FooterOptional", this.calendarContext);
            },

            renderMarkup: function (markup, elementId, context) {
                if (!markup) return;

                var e = rf.getDomElement(elementId);
                if (!e) return;

                e.innerHTML = this.evaluateMarkup(markup, context);
            },

            evaluateMarkup: function(markup, context) {
                if (!markup) return "";

                var result = [];
                var m;
                for (var i = 0; i < markup.length; i++) {
                    m = markup[i];
                    if (m['getContent']) {
                        result.push(m.getContent(context));
                    }
                }
                return result.join('');
            },

            onUpdate: function() {
                var formattedDate = rf.calendarUtils.formatDate(this.getCurrentDate(), "MM/yyyy");
                rf.getDomElement(this.id + 'InputCurrentDate').value = formattedDate;

                if (this.isAjaxMode && this.callAjax)
                    this.callAjax.call(this, formattedDate);
                else
                    this.render();
            },

            callAjax: function(calendar, date) {
                var _this = this;
                var ajaxSuccess = function (event) {
                    var dataDays = event && event.componentData && event.componentData[_this.id];
                    _this.load(dataDays, true);
                }
                var ajaxError = function (event) {
                    // do nothing
                }
                var params = {};
                params[this.id + ".ajax"] = "1";

                rf.ajax(this.id, null, {parameters: params, error: ajaxError, complete:ajaxSuccess});

            },

            nextMonth: function() {
                this.changeCurrentDateOffset(0, 1);
            },

            prevMonth: function() {
                this.changeCurrentDateOffset(0, -1);
            },

            nextYear: function() {
                this.changeCurrentDateOffset(1, 0);
            },

            prevYear: function() {
                this.changeCurrentDateOffset(-1, 0);
            },

            changeCurrentDate: function(year, month, noUpdate) {
                if (this.getCurrentMonth() != month || this.getCurrentYear() != year) {
                    var date = new Date(year, month, 1);
                    if (this.invokeEvent("beforecurrentdateselect", rf.getDomElement(this.id), null, date)) {
                        // fix for RF-2450.
                        // Additional event is fired: after the hidden input with current date
                        // value is updated in function onUpdate() and then
                        // the "currentdateselected" Event is fired.
                        this.currentDate = date;
                        if (noUpdate) this.render(); else this.onUpdate();
                        this.invokeEvent("currentdateselect", rf.getDomElement(this.id), null, date);
                        return true;
                    }
                }
                return false;
            },

            changeCurrentDateOffset: function(yearOffset, monthOffset) {
                var date = new Date(this.currentDate.getFullYear() + yearOffset, this.currentDate.getMonth() + monthOffset, 1);

                if (this.invokeEvent("beforecurrentdateselect", rf.getDomElement(this.id), null, date)) {
                    // fix for RF-2450.
                    // Additional event is fired: after the hidden input with current date
                    // value is updated in function onUpdate() and then
                    // the "currentdateselected" Event is fired.
                    this.currentDate = date;
                    this.onUpdate();
                    this.invokeEvent("currentdateselect", rf.getDomElement(this.id), null, date);
                }
            },

            today: function(noUpdate, noHighlight) {

                var now = new Date();

                var nowyear = now.getFullYear();
                var nowmonth = now.getMonth();
                var nowdate = now.getDate();
                var updateflag = false;

                if (nowdate != this.todayDate.getDate()) {
                    updateflag = true;
                    this.todayDate = now;
                }

                if (nowyear != this.currentDate.getFullYear() || nowmonth != this.currentDate.getMonth()) {
                    updateflag = true;
                    this.currentDate = new Date(nowyear, nowmonth, 1);
                }

                if (this.options.todayControlMode == 'select') {
                    noHighlight = true;
                }

                if (updateflag) {
                    if (noUpdate) this.render(); else this.onUpdate();
                }
                else {
                    // highlight today

                    if (this.isVisible && this.todayCellId && !noHighlight) {
                        this.clearEffect(this.todayCellId);
                        if (this.todayCellColor != "transparent") {
                            $(rf.getDomElement(this.todayCellId)).effect("highlight", {easing:'easeInOutSine', color: this.todayCellColor}, 300);
                        }
                    }
                }

                // todayControl select mode
                if (this.options.todayControlMode == 'select' && !this.options.disabled && !this.options.readonly)
                    if (updateflag && !noUpdate && this.submitFunction) {
                        this.afterLoad = this.selectToday;
                    }
                    else this.selectToday();

            },

            selectToday: function() {
                if (this.todayCellId) {
                    var daydata = this.days[parseInt(this.todayCellId.substr(this.DATE_ELEMENT_ID.length), 10)];
                    var today = new Date();
                    var date = new Date(today);
                    if (this.timeType) {
                        date = this.setupTimeForDate(date);
                    }
                    if (daydata.enabled && this.__selectDate(date, true) && !this.options.showApplyButton) {
                        this.hidePopup();
                    }
                }
            },

            __selectDate: function(date, noUpdate, eventData, applySelection) {

                if (!eventData) {
                    eventData = {event: null, element: null};
                }

                if (typeof applySelection === "undefined") {
                    applySelection = !this.options.showApplyButton
                }

                var oldSelectedDate = this.selectedDate;
                var newSelectedDate;
                if (date) {
                    if (typeof date == 'string') {
                        date = rf.calendarUtils.parseDate(date, this.options.datePattern, this.options.monthLabels, this.options.monthLabelsShort);
                    }
                    newSelectedDate = date;
                }
                else {
                    newSelectedDate = null;
                }

                // fire user event
                var flag = true;
                var isDateChange = false;
                if ((oldSelectedDate - newSelectedDate) && (oldSelectedDate != null || newSelectedDate != null)) {
                    isDateChange = true;
                    flag = this.invokeEvent("beforedateselect", eventData.element, eventData.event, date);
                }

                if (flag) {
                    if (newSelectedDate != null) {
                        if (newSelectedDate.getMonth() == this.currentDate.getMonth() && newSelectedDate.getFullYear() == this.currentDate.getFullYear()) {
                            this.selectedDate = newSelectedDate;
                            if (!oldSelectedDate || (oldSelectedDate - this.selectedDate)) {
                                // find cell and change style class
                                var e = $(rf.getDomElement(this.DATE_ELEMENT_ID + (this.firstDateIndex + this.selectedDate.getDate() - 1)));

                                this.clearEffect(this.selectedDateCellId, "rf-cal-sel", (this.options.disabled || this.options.readonly ? null : "rf-cal-btn"));
                                this.selectedDateCellId = e.attr('id');
                                this.selectedDateCellColor = this.getCellBackgroundColor(e);

                                e.removeClass("rf-cal-btn");
                                e.removeClass("rf-cal-hov");
                                e.addClass("rf-cal-sel");

                                this.renderHF();
                            }
                            else if (this.timeType != 0) this.renderHF();
                        }
                        else {
                            //RF-5600
                            this.selectedDate = newSelectedDate;

                            // change currentDate and call this.onUpdate();
                            if (this.changeCurrentDate(newSelectedDate.getFullYear(), newSelectedDate.getMonth(), noUpdate)) {
                                //this.selectedDate = newSelectedDate;
                            } else {
                                this.selectedDate = oldSelectedDate;
                                isDateChange = false;
                            }
                        }
                    }
                    else {
                        this.selectedDate = null;

                        this.clearEffect(this.selectedDateCellId, "rf-cal-sel", (this.options.disabled || this.options.readonly ? null : "rf-cal-btn"));

                        if (this.selectedDateCellId) {
                            this.selectedDateCellId = null;
                            this.renderHF();
                        }

                        var date = new Date();
                        if (this.currentDate.getMonth() == date.getMonth() && this.currentDate.getFullYear() == date.getFullYear()) {
                            this.renderHF();
                        }

                        var todayControlMode = this.options.todayControlMode;
                        this.options.todayControlMode = '';
                        this.today(noUpdate, true);
                        this.options.todayControlMode = todayControlMode;
                    }

                    // call user event
                    if (isDateChange) {
                        this.invokeEvent("dateselect", eventData.element, eventData.event, this.selectedDate);
                        if (applySelection === true) {
                            this.setInputField(this.selectedDate != null ? this.__getSelectedDateString(this.options.datePattern) : "", eventData.event);
                        }
                    }
                }

                return isDateChange;
            },

            __resetSelectedDate: function() {
                if (!this.selectedDate) return;
                if (this.invokeEvent("beforedateselect", null, null, null)) {
                    this.selectedDate = null;
                    this.invokeEvent("dateselect", null, null, null);

                    this.selectedDateCellId = this.clearEffect(this.selectedDateCellId, "rf-cal-sel", (this.options.disabled || this.options.readonly ? null : "rf-cal-btn"));
                    this.invokeEvent("clean", null, null, null);
                    this.renderHF();
                    if (!this.options.showApplyButton) {
                        this.setInputField("", null);
                        this.hidePopup();
                    }
                }
            },

            showSelectedDate: function() {
                if (!this.selectedDate) return;
                if (this.currentDate.getMonth() != this.selectedDate.getMonth() || this.currentDate.getFullYear() != this.selectedDate.getFullYear()) {
                    this.currentDate = new Date(this.selectedDate);
                    this.currentDate.setDate(1);
                    this.onUpdate();
                }
                else {
                    // highlight Selected Date
                    if (this.isVisible && this.selectedDateCellId) {
                        this.clearEffect(this.selectedDateCellId);
                        if (this.selectedDateCellColor != "transparent") {
                            $(rf.getDomElement(this.selectedDateCellId)).effect("highlight", {easing:'easeInOutSine', color: this.selectedDateCellColor}, 300);

                        }
                    }
                }
            },

            close: function(updateDate) {
                if (updateDate) {
                    this.setInputField(this.__getSelectedDateString(this.options.datePattern), null);
                }
                this.hidePopup();
            },

            clonePosition: function (source, elements, offset) {
                var jqe = $(source);
                if (!elements.length) elements = [elements];
                offset = offset || {left:0,top:0};
                var width = jqe.outerWidth() + "px", height = jqe.outerHeight() + "px";
                var pos = jqe.position();
                var left = Math.floor(pos.left) + offset.left + "px", top = Math.floor(pos.top) + offset.top + "px";
                var element;
                for (var i = 0; i < elements.length; i++) {
                    element = elements[i];
                    element.style.width = width;
                    element.style.height = height;
                    element.style.left = left;
                    element.style.top = top;
                }
            },

            showTimeEditor: function() {
                var editor;
                if (this.timeType == 0) return;
                if (!this.isEditorCreated) editor = this.createEditor();
                else editor = rf.getDomElement(this.EDITOR_ID);
                if (!this.isTimeEditorLayoutCreated) this.createTimeEditorLayout(editor);

                $(rf.getDomElement(this.TIME_EDITOR_LAYOUT_ID)).show();

                var editor_shadow = rf.getDomElement(this.EDITOR_SHADOW_ID);

                this.clonePosition(rf.getDomElement(this.CALENDAR_CONTENT), [editor, editor_shadow]);

                this.updateTimeEditor();

                $(editor_shadow).show();

                $(editor).show();

                this.clonePosition(rf.getDomElement(this.TIME_EDITOR_LAYOUT_ID), rf.getDomElement(this.EDITOR_LAYOUT_SHADOW_ID), {left: 3, top: 3});
                this.isEditorVisible = true;
            },

            hideEditor: function() {
                if (this.isTimeEditorLayoutCreated) $(rf.getDomElement(this.TIME_EDITOR_LAYOUT_ID)).hide();
                if (this.isDateEditorLayoutCreated) $(rf.getDomElement(this.DATE_EDITOR_LAYOUT_ID)).hide();
                $(rf.getDomElement(this.EDITOR_ID)).hide();
                $(rf.getDomElement(this.EDITOR_SHADOW_ID)).hide();
                this.isEditorVisible = false;
            },

            hideTimeEditor: function(updateTime) {
                this.hideEditor();
                if (updateTime && this.selectedDate) {
                    var s = this.showSeconds ? parseInt(rf.getDomElement(this.id + 'TimeSeconds').value, 10) : this.options.defaultTime.seconds;
                    var m = parseInt(rf.getDomElement(this.id + 'TimeMinutes').value, 10);
                    var h = parseInt(rf.getDomElement(this.id + 'TimeHours').value, 10);
                    if (this.timeType == 2) {
                        if (rf.getDomElement(this.id + 'TimeSign').value.toLowerCase() == "am") {
                            if (h == 12) h = 0;
                        }
                        else {
                            if (h != 12) h += 12;
                        }
                    }
                    var date = rf.calendarUtils.createDate(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), this.selectedDate.getDate(), h, m, s);
                    if (date - this.selectedDate && this.invokeEvent("beforetimeselect", null, null, date)) {
                        this.selectedDate = date;
                        this.renderHF();
                        if (!this.options.popup || !this.options.showApplyButton) this.setInputField(this.__getSelectedDateString(this.options.datePattern), null);
                        this.invokeEvent("timeselect", null, null, this.selectedDate);
                    }
                }
                if (this.options.popup && !this.options.showApplyButton) this.close(false);
            },

            showDateEditor: function() {
                var editor;
                if (!this.isEditorCreated) editor = this.createEditor();
                else editor = rf.getDomElement(this.EDITOR_ID);
                if (!this.isDateEditorLayoutCreated) this.createDateEditorLayout(editor);
                else this.updateDateEditor();

                $(rf.getDomElement(this.DATE_EDITOR_LAYOUT_ID)).show();

                var editor_shadow = rf.getDomElement(this.EDITOR_SHADOW_ID);

                this.clonePosition(rf.getDomElement(this.CALENDAR_CONTENT), [editor, editor_shadow]);

                $(editor_shadow).show();
                $(editor).show();

                this.clonePosition(rf.getDomElement(this.DATE_EDITOR_LAYOUT_ID), rf.getDomElement(this.EDITOR_LAYOUT_SHADOW_ID), {left: 3, top: 3});

                this.isEditorVisible = true;
            },

            hideDateEditor: function(updateCurrentDate) {
                this.hideEditor();
                if (updateCurrentDate) {
                    this.changeCurrentDate(this.dateEditorYear, this.dateEditorMonth);
                }
            },

            getValue: function() {
                return this.__getSelectedDate();
            },

            getValueAsString: function(pattern) {
                return this.__getSelectedDateString(pattern);
            },

            setValue: function(value) {
                this.__selectDate(value, undefined, undefined, true);
            },

            resetValue: function() {
                this.__resetSelectedDate();
                if (this.options.defaultLabel && !this.isFocused) {
                    updateDefaultLabel.call(this, this.options.defaultLabel);
                }
            },

            getNamespace: function () {
                return this.namespace;
            }
        });
})(jQuery, RichFaces);
;(function($, rf) {

    rf.ui = rf.ui || {};
    //rf.ui.MenuKeyNavigation = rf.ui.MenuKeyNavigation || {};

    rf.ui.MenuKeyNavigation = {

        __updateItemsList : function() {
            var items = $('.' + this.options.cssClasses.listContainerCss + ':first',
                this.popup.popup).find('>.' + this.options.cssClasses.itemCss).not(
                '.' + this.options.cssClasses.disabledItemCss);
            return (this.items = items);
        },

        __selectPrev : function() {
            if (-1 == this.currentSelectedItemIndex) {
                this.currentSelectedItemIndex = this.items.length - 1;
            } else {
                this.__deselectCurrentItem();
            }

            if (this.currentSelectedItemIndex > 0) {
                this.currentSelectedItemIndex--;
            } else {
                this.currentSelectedItemIndex = this.items.length - 1;
            }

            this.__selectCurrentItem();
        },

        __selectNext : function() {
            if (-1 != this.currentSelectedItemIndex) {
                this.__deselectCurrentItem();
            }
            if (this.currentSelectedItemIndex < this.items.length - 1) {
                this.currentSelectedItemIndex++;
            } else {
                this.currentSelectedItemIndex = 0;
            }

            this.__selectCurrentItem();
        },

        __deselectCurrentItem : function() {
            this.__deselectByIndex(this.currentSelectedItemIndex);
        },

        __selectCurrentItem : function() {
            this.__selectByIndex(this.currentSelectedItemIndex);
        },

        __selectFirstItem : function() {
            this.currentSelectedItemIndex = 0;
            this.__selectCurrentItem();
        },

        __selectByIndex : function(index) {
            if (-1 != index) {
                rf.$(this.items.eq(index)).select();
            }
        },

        __deselectByIndex : function(index) {
            if (index > -1) {
                rf.$(this.items.eq(index)).unselect();
            }

        },

        __openGroup : function() {
            var item = this.__getItemByIndex(this.currentSelectedItemIndex);
            if (this.__isGroup(item)) {
                rf.$(item).show();
                rf.$(item).__selectFirstItem();
                this.active = false;
            }
        },

        __closeGroup : function() {
            var item = this.__getItemByIndex(this.currentSelectedItemIndex);
            if (this.__isGroup(item)) {
                rf.$(item).__deselectCurrentItem();
                rf.$(item).hide();
                this.active = true;
            }
        },

        __returnToParentMenu : function() {
            var item = this.__getItemByIndex(this.currentSelectedItemIndex);
            var menu;
            menu = this.__getParentMenu() || this.__getParentMenuFromItem(item);
            if (menu != null && this.id != rf.$(menu).id) {
                this.hide();
                rf.$(menu).popupElement.focus();
            } else {
                this.hide();
            }
        },

        __activateMenuItem : function() {
            var item = this.__getCurrentItem();
            if (item) {
                menuItemId = item.attr('id');
                this.activateItem(menuItemId);
            }
        },

        __getItemByIndex : function(index) {
            if (index > -1) {
                return this.items.eq(index);
            } else {
                return null;
            }
        },

        __getCurrentItem : function() {
            return this.__getItemByIndex(this.currentSelectedItemIndex);
        },

        __keydownHandler : function(e) {
            var code;

            if (e.keyCode) {
                code = e.keyCode;
            } else if (e.which) {
                code = e.which;
            }

            activeMenu = rf.ui.MenuManager.getActiveSubMenu();

            if (this.popup.isVisible()) {
                switch (code) {
                    case rf.KEYS.DOWN:
                        e.preventDefault();
                        activeMenu.__selectNext();
                        //this.__setInputFocus();
                        break;

                    case rf.KEYS.UP:
                        e.preventDefault();
                        activeMenu.__selectPrev();
                        //this.__setInputFocus();
                        break;
                    case rf.KEYS.LEFT:
                        e.preventDefault();
                        activeMenu.__returnToParentMenu();
                        break;

                    case rf.KEYS.RIGHT:
                        e.preventDefault();
                        activeMenu.__openGroup();
                        break;

                    case rf.KEYS.ESC:
                        e.preventDefault();
                        activeMenu.__returnToParentMenu();
                        break;

                    case rf.KEYS.RETURN:
                        e.preventDefault();
                        activeMenu.__activateMenuItem();
                        //this.__setInputFocus();
                        //return false;
                        break;
                }
                e.stopPropagation();
            }
        }
    }
})(jQuery, RichFaces);;/*
 * code review by Pavel Yaschenko
 * 
 * No event's unbindings when component would be destroyed Hint: easy way to
 * unbind - use namespaces when bind event handlers
 * 
 */

(function($, rf) {

    rf.ui = rf.ui || {};

    var defaultIndicatorClasses = {
        rejectClass : "rf-ind-rejt",
        acceptClass : "rf-ind-acpt",
        draggingClass : "rf-ind-drag"
    };

    var defaultOptions = {
    };

    rf.ui.Droppable = function(id, options) {
        this.options = {};
        $.extend(this.options, defaultOptions, options || {});
        $super.constructor.call(this, id);

        this.namespace = this.namespace || "."
            + rf.Event.createNamespace(this.name, this.id);

        this.id = id;

        this.parentId = this.options.parentId;

        this.attachToDom(this.parentId);

        this.dropElement = $(document.getElementById(this.parentId));
        this.dropElement.droppable({
                addClasses : false
            });
        this.dropElement.data("init", true);

        rf.Event.bind(this.dropElement, 'drop' + this.namespace, this.drop, this);
        rf.Event.bind(this.dropElement, 'dropover' + this.namespace, this.dropover, this);
        rf.Event.bind(this.dropElement, 'dropout' + this.namespace, this.dropout, this);

    };

    rf.BaseNonVisualComponent.extend(rf.ui.Droppable);

    var $super = rf.ui.Droppable.$super;

    $.extend(rf.ui.Droppable.prototype, (function() {
        return {
            drop : function(e) {
                var ui = e.rf.data;
                if (this.accept(ui.draggable)) {
                    this.__callAjax(e, ui);
                }
                var dragIndicatorObj = this.__getIndicatorObject(ui.helper);
                if (dragIndicatorObj) {
                    ui.helper.removeClass(dragIndicatorObj.getAcceptClass());
                    ui.helper.removeClass(dragIndicatorObj.getRejectClass());
                } else {
                    ui.helper.removeClass(defaultIndicatorClasses.acceptClass);
                    ui.helper.removeClass(defaultIndicatorClasses.rejectClass);
                }
            },

            dropover : function(e) {
                var ui = e.rf.data;
                var draggable = ui.draggable;
                var dragIndicatorObj = this.__getIndicatorObject(ui.helper);
                this.dropElement.addClass("rf-drp-hvr");
                if (dragIndicatorObj) {
                    if (this.accept(draggable)) {
                        ui.helper.removeClass(dragIndicatorObj.getRejectClass());
                        ui.helper.addClass(dragIndicatorObj.getAcceptClass());
                        this.dropElement.addClass("rf-drp-hlight");
                    } else {
                        ui.helper.removeClass(dragIndicatorObj.getAcceptClass());
                        ui.helper.addClass(dragIndicatorObj.getRejectClass());
                        this.dropElement.removeClass("rf-drp-hlight");
                    }
                } else {
                    if (this.accept(draggable)) {
                        ui.helper.removeClass(defaultIndicatorClasses.rejectClass);
                        ui.helper.addClass(defaultIndicatorClasses.acceptClass);
                        this.dropElement.addClass("rf-drp-hlight");
                    } else {
                        ui.helper.removeClass(defaultIndicatorClasses.acceptClass);
                        ui.helper.addClass(defaultIndicatorClasses.rejectClass);
                        this.dropElement.removeClass("rf-drp-hlight");
                    }
                }
            },

            dropout : function(e) {
                var ui = e.rf.data;
                var draggable = ui.draggable;
                var dragIndicatorObj = this.__getIndicatorObject(ui.helper);
                this.dropElement.removeClass("rf-drp-hvr rf-drp-hlight");
                if (dragIndicatorObj) {
                    ui.helper.removeClass(dragIndicatorObj.getAcceptClass());
                    ui.helper.removeClass(dragIndicatorObj.getRejectClass());
                } else {
                    ui.helper.removeClass(defaultIndicatorClasses.acceptClass);
                    ui.helper.removeClass(defaultIndicatorClasses.rejectClass);
                }
            },

            accept : function(draggable) {
                var accept = false;
                var acceptType = draggable.data("type");
                if (acceptType && this.options.acceptedTypes) {
                    $.each(this.options.acceptedTypes, function() {
                        if (this == "@none") {
                            return false;
                        }

                        if (this == acceptType || this == "@all") {
                            accept = true;
                            return false;
                        }
                    });
                }
                return accept;
            },
            
            __getIndicatorObject: function(helper) {
                var indicatorCloneId = helper.attr('id');
                if (indicatorCloneId) {
                    var indicatorId = indicatorCloneId.match(/(.*)Clone$/)[1];
                    return rf.$(indicatorId);
                }
            },

            __callAjax : function(e, ui) {
                if (ui.draggable) {
                    var dragSource = ui.draggable.data("id");
                    var ajaxFunc = this.options.ajaxFunction;
                    if (ajaxFunc && typeof ajaxFunc == 'function') {
                        ajaxFunc.call(this, e, dragSource);
                    }
                }
            },

            destroy : function() {
                // clean up code here
                this.detach(this.parentId);
                rf.Event.unbind(this.dropElement, this.namespace);

                // call parent's destroy method
                $super.destroy.call(this);

            }


        }
    })());

})(jQuery, window.RichFaces);;/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */


(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.TooltipMode = {
        client : "client",
        ajax : "ajax",
        DEFAULT: "client"
    };

    var TooltipMode = rf.ui.TooltipMode;

    var DEFAULT_OPTIONS = {
        jointPoint : "AA",
        direction : "AA",
        offset : [10, 10],
        attached : true,
        mode : TooltipMode.DEFAULT,
        hideDelay : 0,
        hideEvent : "mouseleave",
        showDelay : 0,
        showEvent : "mouseenter",
        followMouse : true
    };

    var SHOW_ACTION = {

        /**
         *
         * @return {void}
         * */
        exec : function (tooltip, event) {
            var mode = tooltip.mode;
            if (mode == TooltipMode.ajax) {
                return this.execAjax(tooltip, event);
            } else if (mode == TooltipMode.client) {
                return this.execClient(tooltip, event);
            } else {
                rf.log.error("SHOW_ACTION.exec : unknown mode (" + mode + ")");
            }
        },

        /**
         * @protected
         *
         * @return {Boolean} false
         * */
        execAjax : function (tooltip, event) {
            tooltip.__loading().show();
            tooltip.__content().hide();
            tooltip.__show(event);

            rf.ajax(tooltip.id, null, $.extend({}, tooltip.options["ajax"], {}));

            return true;
        },

        /**
         * @protected
         *
         * @return {undefined}
         *             - false - if process has been terminated
         *             - true  - in other cases
         * */
        execClient : function (tooltip, event) {
            tooltip.__show(event);

            return tooltip.__fireShow();
        }
    };

    rf.ui.Tooltip = rf.BaseComponent.extendClass({
            // class name
            name:"Tooltip",

            /**
             * @class Tooltip
             * @name Tooltip
             *
             * @constructor
             * @param {String} componentId - component id
             * */
            init : function (componentId, options) {
                $super.constructor.call(this, componentId);
                this.namespace = "." + rf.Event.createNamespace(this.name, this.id);
                this.options = $.extend(this.options, DEFAULT_OPTIONS, options || {});
                this.attachToDom();

                this.mode = this.options.mode;
                this.target = this.options.target;
                this.shown = false;

                this.__addUserEventHandler("hide");
                this.__addUserEventHandler("show");
                this.__addUserEventHandler("beforehide");
                this.__addUserEventHandler("beforeshow");
                this.popupId = this.id + ':wrp';
                this.popup = new rf.ui.Popup(this.popupId, {
                        attachTo: this.target,
                        attachToBody: true,
                        positionType: "TOOLTIP",
                        positionOffset: this.options.offset,
                        jointPoint: this.options.jointPoint,
                        direction: this.options.direction
                    });

                var handlers = {};
                handlers[this.options.showEvent + this.namespace] = this.__showHandler;
                handlers[this.options.hideEvent + this.namespace] = this.__hideHandler;

                rf.Event.bindById(this.target, handlers, this);

                if (this.options.hideEvent == 'mouseleave') {
                    rf.Event.bindById(this.popupId, this.options.hideEvent + this.namespace, this.__hideHandler, this);
                }
            },

            /***************************** Public Methods  ****************************************************************/
            /**
             * @methodOf
             * @name PanelMenuItem#hide
             *
             * TODO ...
             *
             * @return {void} TODO ...
             */
            hide: function () {

                var tooltip = this;
                if (tooltip.hidingTimerHandle) {
                    window.clearTimeout(tooltip.hidingTimerHandle);
                    tooltip.hidingTimerHandle = undefined;
                }
                if (this.shown) {
                    this.__hide();
                }
            },

            __hideHandler: function(event) {
                if (event.type == 'mouseleave' && this.__isInside(event.relatedTarget)) {
                    return;
                }

                this.hide();

                if (this.options.followMouse) {
                    rf.Event.unbindById(this.target, "mousemove" + this.namespace);
                }

            },

            /**
             * @private
             * @return {void} TODO ...
             */
            __hide: function () {
                var tooltip = this;
                this.__delay(this.options.hideDelay, function () {
                    tooltip.__fireBeforeHide();
                    tooltip.popup.hide();
                    tooltip.shown = false;
                    tooltip.__fireHide();
                });
            },

            __mouseMoveHandler: function(event) {
                this.saveShowEvent = event;
                if (this.shown) {
                    this.popup.show(this.saveShowEvent);
                }
            },

            __showHandler: function(event) {
                this.show(event);
                var tooltip = this;

                if (tooltip.options.followMouse) {
                    rf.Event.bindById(tooltip.target, "mousemove" + tooltip.namespace, tooltip.__mouseMoveHandler, tooltip);
                }
            },

            /**
             * @methodOf
             * @name PanelMenuItem#show
             *
             * TODO ...
             *
             * @return {void} TODO ...
             */
            show: function (event) {
                var tooltip = this;
                if (tooltip.hidingTimerHandle) {
                    window.clearTimeout(tooltip.hidingTimerHandle);
                    tooltip.hidingTimerHandle = undefined;
                }

                if (!this.shown) {
                    SHOW_ACTION.exec(this, event);
                }

            },

            onCompleteHandler : function () {
                this.__content().show();
                this.__loading().hide();

                return this.__fireShow();
            },

            /**
             * @private
             * @return {void} TODO ...
             */
            __show: function (event) {
                var tooltip = this;
                this.__delay(this.options.showDelay, function () {
                    if (!tooltip.options.followMouse) {
                        tooltip.saveShowEvent = event;
                    }
                    if (!tooltip.shown) {
                        tooltip.__fireBeforeShow();
                        tooltip.popup.show(tooltip.saveShowEvent);
                    }
                    //for showing tooltip in followMouse mode
                    tooltip.shown = true;
                });
            },

            /***************************** Private Methods ****************************************************************/
            __delay : function (delay, action) {
                var tooltip = this;

                if (delay > 0) {
                    tooltip.hidingTimerHandle = window.setTimeout(function() {
                        action();

                        if (tooltip.hidingTimerHandle) {
                            window.clearTimeout(tooltip.hidingTimerHandle);
                            tooltip.hidingTimerHandle = undefined;
                        }
                    }, delay);
                } else {
                    action();
                }
            },

            __detectAncestorNode: function(leaf, element) {
                // Return true if "element" is "leaf" or one of its parents
                var node = leaf;
                while (node != null && node != element) {
                    node = node.parentNode;
                }
                return (node != null);
            },

            __loading : function () {
                return $(document.getElementById(this.id + ":loading"));
            },

            __content : function () {
                return $(document.getElementById(this.id + ":content"));
            },

            __fireHide : function () {
                return rf.Event.fireById(this.id, "hide", { id: this.id });
            },

            __fireShow : function () {
                return rf.Event.fireById(this.id, "show", { id: this.id });
            },

            __fireBeforeHide : function () {
                return rf.Event.fireById(this.id, "beforehide", { id: this.id });
            },

            __fireBeforeShow : function () {
                return rf.Event.fireById(this.id, "beforeshow", { id: this.id });
            },

            /**
             * @private
             * */
            __addUserEventHandler : function (name) {
                var handler = this.options["on" + name];
                if (handler) {
                    rf.Event.bindById(this.id, name + this.namespace, handler);
                }
            },

            __contains: function(id, elt) {
                while (elt) {
                    if (id == elt.id) {
                        return true;
                    }

                    elt = elt.parentNode;
                }
                return false;
            },

            __isInside: function(elt) {
                return this.__contains(this.target, elt) || this.__contains(this.popupId, elt);
            },

            destroy: function () {
                rf.Event.unbindById(this.popupId, this.namespace);
                rf.Event.unbindById(this.target, this.namespace);
                this.popup.destroy();
                this.popup = null;
                $super.destroy.call(this);
            }
        });

    // define super class link
    var $super = rf.ui.Tooltip.$super;
})(jQuery, RichFaces);;/*
 * code review by Pavel Yaschenko
 * 
 * No event's unbindings when component would be destroyed 
 * Hint: easy way to unbind - use namespaces when bind event handlers
 * 
 */

(function ($, rf) {

    rf.ui = rf.ui || {};

    var defaultIndicatorClasses = {
        rejectClass : "rf-ind-rejt",
        acceptClass : "rf-ind-acpt",
        draggingClass : "rf-ind-drag"
    };

    rf.ui.Draggable = function(id, options) {
        this.options = {};
        $.extend(this.options, defaultOptions, options || {});
        $super.constructor.call(this, id);

        this.id = id;

        this.namespace = this.namespace || "."
            + rf.Event.createNamespace(this.name, this.id);

        this.parentId = this.options.parentId;
        this.attachToDom(this.parentId);
        this.dragElement = $(document.getElementById(this.options.parentId));
        this.dragElement.draggable();

        if (options.indicator) {
            var element = $(document.getElementById(options.indicator));
            var clone = element.clone();
            $("*[id]", clone).andSelf().each(function() {
                $(this).removeAttr("id");
            });
            if (element.attr("id")) {
                clone.attr("id", element.attr("id") + "Clone");
            }
            
            this.dragElement.data("indicator", true);
            this.dragElement.draggable("option", "helper", function() {
                return clone;
            });
        } else {
            this.dragElement.data("indicator", false);
            this.dragElement.draggable("option", "helper", 'clone');
        }

        this.dragElement.draggable("option", "addClasses", false);
        this.dragElement.draggable( "option", "appendTo", "body" );
        

        this.dragElement.data('type', this.options.type);
        this.dragElement.data("init", true);
        this.dragElement.data("id", this.id);
        rf.Event.bind(this.dragElement, 'dragstart' + this.namespace, this.dragStart, this);
        rf.Event.bind(this.dragElement, 'drag' + this.namespace, this.drag, this);
    };

    rf.BaseNonVisualComponent.extend(rf.ui.Draggable);

    // define super class link
    var $super = rf.ui.Draggable.$super;

    var defaultOptions = {
    };

    $.extend(rf.ui.Draggable.prototype, ( function () {
        return {
            name : "Draggable",
            dragStart: function(e) {
                var ui = e.rf.data;
                var element = ui.helper[0];
                this.parentElement = element.parentNode;

                if (this.__isCustomDragIndicator()) {
                    ui.helper.detach().appendTo("body").show();
                    
                    // move cursor to the center of custom dragIndicator;
                    var left = (ui.helper.width() / 2);
                    var top = (ui.helper.height() / 2);
                    this.dragElement.data('draggable').offset.click.left = left;
                    this.dragElement.data('draggable').offset.click.top = top;
                    
                }
            },

            drag: function(e) {
                var ui = e.rf.data;
                if (this.__isCustomDragIndicator()) {
                    var indicator = rf.$(this.options.indicator);
                    if (indicator) {
                        ui.helper.addClass(indicator.getDraggingClass());
                    } else {
                        ui.helper.addClass(defaultIndicatorClasses.draggingClass);
                    }
                }
                this.__clearDraggableCss(ui.helper);
            },

            __isCustomDragIndicator: function() {
                return this.dragElement.data("indicator");
            },

            __clearDraggableCss: function(element) {
                if (element && element.removeClass) {
                    //draggable 'addClasses: false' doesn't work so clear jQuery style
                    element.removeClass("ui-draggable-dragging");
                }
            },

            destroy : function() {
                // clean up code here
                this.detach(this.parentId);
                rf.Event.unbind(this.dragElement, this.namespace);
                // call parent's destroy method
                $super.destroy.call(this);
            }
        }
    })());
})(jQuery, window.RichFaces);
;(function($, rf) {

    rf.ui = rf.ui || {};

    var defaultOptions = {
        mode : 'server',
        attachToBody : false,
        showDelay : 50,
        hideDelay : 300,
        verticalOffset : 0,
        horizontalOffset : 0,
        showEvent : 'mouseover',
        positionOffset : [0, 0],
        cssRoot : "ddm",
        cssClasses : {}
    };

    rf.ui.MenuBase = function(componentId, options) {
        $super.constructor.call(this, componentId, options);
        this.id = componentId;
        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, this.id);

        this.options = {};
        $.extend(this.options, defaultOptions, options || {});
        $.extend(this.options.cssClasses, buildCssClasses.call(this, this.options.cssRoot));

        this.attachToDom(componentId);

        this.element = rf.getDomElement(this.id);

        this.displayed = false;

        this.options.positionOffset = [this.options.horizontalOffset, this.options.verticalOffset];
        this.popup = new RichFaces.ui.Popup(this.id + "_list", {
                attachTo : this.id,
                direction : this.options.direction,
                jointPoint : this.options.jointPoint,
                positionType : this.options.positionType,
                positionOffset : this.options.positionOffset,
                attachToBody : this.options.attachToBody
            });

        this.selectedGroup = null;

        rf.Event.bindById(this.id, "mouseenter", $.proxy(this.__overHandler, this), this);
        rf.Event.bindById(this.id, "mouseleave", $.proxy(this.__leaveHandler, this), this);

        this.popupElement = rf.getDomElement(this.popup.id);
        this.popupElement.tabIndex = -1;

        this.__updateItemsList();

        rf.Event.bind(this.items, "mouseenter", $.proxy(this.__itemMouseEnterHandler, this), this);

        this.currentSelectedItemIndex = -1;
        var navEventHandlers;
        navEventHandlers = {};
        navEventHandlers["keydown" + this.namespace] = this.__keydownHandler;

        rf.Event.bind(this.popupElement, navEventHandlers, this);
    };

    var buildCssClasses = function(cssRoot) {
        var cssClasses = {
            itemCss : "rf-" +cssRoot+ "-itm",
            selectItemCss : "rf-" +cssRoot+ "-itm-sel",
            unselectItemCss : "rf-" +cssRoot+ "-itm-unsel",
            disabledItemCss : "rf-" +cssRoot+ "-itm-dis",
            labelCss: "rf-" +cssRoot+ "-lbl",
            listCss : "rf-" +cssRoot+ "-lst",
            listContainerCss : "rf-" +cssRoot+ "-lst-bg"
        }
        return cssClasses;
    }

    rf.BaseComponent.extend(rf.ui.MenuBase);

    // define super class link
    var $super = rf.ui.MenuBase.$super;

    $.extend(rf.ui.MenuBase.prototype, (function() {
        return {
            name : "MenuBase",

            show : function() {
                this.__showPopup();
            },

            hide : function() {
                this.__hidePopup();
            },

            processItem : function(item) {
                if (item && item.attr('id') && !this.__isDisabled(item) && !this.__isGroup(item)) {
                    this.invokeEvent("itemclick", rf.getDomElement(this.id), null);
                    this.hide();
                }
            },

            activateItem : function(menuItemId) {
                var item = $(RichFaces.getDomElement(menuItemId));
                rf.Event.fireById(item.attr('id'), 'click');
            },

            __showPopup : function(e) {
                if (!this.__isShown()) {
                    this.invokeEvent("show", rf.getDomElement(this.id), null);
                    this.popup.show(e);
                    this.displayed = true;
                    rf.ui.MenuManager.setActiveSubMenu(rf.$(this.element));
                }
                this.popupElement.focus();
            },

            __hidePopup : function() {
                window.clearTimeout(this.showTimeoutId);
                this.showTimeoutId = null;
                if (this.__isShown()) {
                    this.invokeEvent("hide", rf.getDomElement(this.id), null);
                    this.__closeChildGroups();
                    this.popup.hide();
                    this.displayed = false;
                    this.__deselectCurrentItem();
                    this.currentSelectedItemIndex = -1;
                    var parentMenu = rf.$(this.__getParentMenu());
                    if (this.id != parentMenu.id) {
                        parentMenu.popupElement.focus();
                        rf.ui.MenuManager.setActiveSubMenu(parentMenu);
                    }
                }
            },

            __closeChildGroups : function() {
                var i = 0;
                var menuItem;
                for (i in this.items) {
                    menuItem = this.items.eq(i);
                    if (this.__isGroup(menuItem)) {
                        rf.$(menuItem).hide();
                    }
                }
            },

            __getParentMenuFromItem : function(item) {
                var menu;
                if (item)
                    menu = item.parents('div.' + this.options.cssClasses.itemCss).has('div.' + this.options.cssClasses.listContainerCss).eq(1);
                if (menu && menu.length > 0)
                    return menu;
                else {
                    menu = item.parents('div.' + this.options.cssClasses.labelCss);
                    if (menu && menu.length > 0) {
                        return menu;
                    }
                    else {
                        return null;
                    }
                }
            },

            __getParentMenu : function() {
                var menu = $(this.element).parents('div.' + this.options.cssClasses.itemCss).has('div.' + this.options.cssClasses.listContainerCss).eq(0);
                if (menu && menu.length > 0) {
                    return menu;
                }
                else {
                    var item = this.items.eq(0);
                    return this.__getParentMenuFromItem(item);
                }
            },

            __isGroup : function(item) {
                return item.find('div.' + this.options.cssClasses.listCss).length > 0;
            },

            __isDisabled : function(item) {
                return item.hasClass(this.options.cssClasses.disabledItemCss);
            },

            __isShown : function() {
                return this.displayed;

            },

            __itemMouseEnterHandler : function(e) {
                var item = this.__getItemFromEvent(e);
                if (item) {
                    //this.__selectItem(item);
                    if (this.currentSelectedItemIndex != this.items.index(item)) {
                        this.__deselectCurrentItem();
                        this.currentSelectedItemIndex = this.items.index(item);
                    }
                }
            },

            __selectItem : function(item) {
                if (!rf.$(item).isSelected) {
                    rf.$(item).select();
                }
            },

            __getItemFromEvent : function(e) {
                return $(e.target).closest("." + this.options.cssClasses.itemCss,e.currentTarget).eq(0);
            },

            __showHandler : function(e) {
                if (!this.__isShown()) {
                    this.showTimeoutId = window.setTimeout($.proxy(function() {
                        this.show(e);
                    }, this), this.options.showDelay);
                    return false;
                }
            },

            __leaveHandler : function() {
                this.hideTimeoutId = window.setTimeout($.proxy(function() {
                    this.hide();
                }, this), this.options.hideDelay);
            },

            __overHandler : function() {
                window.clearTimeout(this.hideTimeoutId);
                this.hideTimeoutId = null;
            },

            destroy : function() {
                // clean up code here
                this.detach(this.id);

                rf.Event.unbind(this.popupElement, "keydown" + this.namespace);

                this.popup.destroy();
                this.popup = null;

                // call parent's destroy method
                $super.destroy.call(this);
            }
        };
    })());

})(jQuery, RichFaces);;(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.ListMulti = function(id, options) {
        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, id);
        var mergedOptions = $.extend({}, defaultOptions, options);
        $super.constructor.call(this, id, mergedOptions);
        this.disabled = mergedOptions.disabled;
    };

    rf.ui.List.extend(rf.ui.ListMulti);
    var $super = rf.ui.ListMulti.$super;

    var defaultOptions = {
        clickRequiredToSelect: true
    };

    $.extend(rf.ui.ListMulti.prototype, ( function () {

        return{

            name : "listMulti",

            getSelectedItems: function() {
                return this.list.find("." + this.selectItemCssMarker);
            },

            removeSelectedItems: function() {
                var items = this.getSelectedItems();
                this.removeItems(items);
                return items;
            },

            __selectByIndex: function(index, clickModified) {
                if (! this.__isSelectByIndexValid(index)) {
                    return;
                }

                this.index = this.__sanitizeSelectedIndex(index);

                var item = this.items.eq(this.index);
                if (! clickModified) {
                    var that = this;
                    this.getSelectedItems().each( function() {
                        that.unselectItem($(this))
                    });
                    this.selectItem(item);
                } else {
                    if (this.isSelected(item)) {
                        this.unselectItem(item);
                    } else {
                        this.selectItem(item);
                    }
                }
            }
        }
    })());

})(jQuery, window.RichFaces);;(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.PopupList = function(id, listener, options) {
        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, id);
        var mergedOptions = $.extend({}, defaultOptions, options);
        $super.constructor.call(this, id, mergedOptions);
        mergedOptions['selectListener']=listener;
        this.list = new rf.ui.List(id, mergedOptions);
    };

    rf.ui.Popup.extend(rf.ui.PopupList);
    var $super = rf.ui.PopupList.$super;

    var defaultOptions = {
        attachToBody: true,
        positionType: "DROPDOWN",
        positionOffset: [0,0]
    };

    $.extend(rf.ui.PopupList.prototype, ( function () {

        return {

            name : "popupList",

            __getList: function() {
                return this.list;
            },

            destroy: function() {
                this.list.destroy();
                this.list = null;
                $super.destroy.call(this);
            }
        }
    })());

})(jQuery, window.RichFaces);;(function($, rf) {
    rf.ui = rf.ui || {};

    var defaultOptions = {
        positionType : "DROPDOWN",
        direction : "AA",
        jointPoint : "AA",
        cssRoot : "ddm",
        cssClasses : {}
    };

    // constructor definition
    rf.ui.Menu = function(componentId, options) {
        this.options = {};
        $.extend(this.options, defaultOptions, options || {});
        $.extend(this.options.cssClasses, buildCssClasses.call(this, this.options.cssRoot));
        $super.constructor.call(this, componentId, this.options);
        this.id = componentId;
        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, this.id);
        this.groupList = new Array();

        this.target = this.getTarget();
        if (this.target) {
            var menu = this;
            $(document).ready(function() {
                var targetComponent = RichFaces.$(menu.target);
                if (targetComponent && targetComponent.contextMenuAttach) {
                    targetComponent.contextMenuAttach(menu);
                } else {
                    rf.Event.bindById(menu.target, menu.options.showEvent, $.proxy(menu.__showHandler, menu), menu)
                }
            });
        }
        this.element = $(rf.getDomElement(this.id));

        if (!rf.ui.MenuManager) {
            rf.ui.MenuManager = {};
        }
        this.menuManager = rf.ui.MenuManager;
    };

    var buildCssClasses = function(cssRoot) {
        var cssClasses = {
            selectMenuCss : "rf-" +cssRoot+ "-sel",
            unselectMenuCss : "rf-" +cssRoot+ "-unsel"
        }
        return cssClasses;
    }

    rf.ui.MenuBase.extend(rf.ui.Menu);

    // define super class link
    var $super = rf.ui.Menu.$super;

    $.extend(rf.ui.Menu.prototype, rf.ui.MenuKeyNavigation);

    $.extend(rf.ui.Menu.prototype, (function() {
        return {
            name : "Menu",
            initiateGroups : function(groupOptions) {
                for (var i in groupOptions) {
                    var groupId = groupOptions[i].id;
                    if (null != groupId) {
                        this.groupList[groupId] = new RichFaces.ui.MenuGroup(
                            groupId, {
                                rootMenuId : this.id,
                                onshow : groupOptions[i].onshow,
                                onhide : groupOptions[i].onhide,
                                horizontalOffset: groupOptions[i].horizontalOffset,
                                verticalOffset: groupOptions[i].verticalOffset,
                                jointPoint : groupOptions[i].jointPoint,
                                direction : groupOptions[i].direction,
                                cssRoot : groupOptions[i].cssRoot
                            });
                    }
                }
            },

            getTarget : function() {
                return this.id + "_label";
            },

            show : function(e) {
                if (this.menuManager.openedMenu != this.id) {
                    this.menuManager.shutdownMenu();
                    this.menuManager.addMenuId(this.id);
                    this.__showPopup();
                }
            },

            hide : function() {
                this.__hidePopup();
                this.menuManager.deletedMenuId();
            },

            select : function() {
                this.element.removeClass(this.options.cssClasses.unselectMenuCss);
                this.element.addClass(this.options.cssClasses.selectMenuCss);
            },
            unselect : function() {
                this.element.removeClass(this.options.cssClasses.selectMenuCss);
                this.element.addClass(this.options.cssClasses.unselectMenuCss);
            },

            __overHandler : function() {
                $super.__overHandler.call(this);
                this.select();
            },

            __leaveHandler : function() {
                $super.__leaveHandler.call(this);
                this.unselect();
            },

            destroy : function() {
                // clean up code here
                this.detach(this.id);

                if (this.target) {
                    rf.Event.unbindById(this.target, this.options.showEvent);
                }

                // call parent's destroy method
                $super.destroy.call(this);

            }
        };
    })());

    rf.ui.MenuManager = {
        openedMenu : null,

        activeSubMenu : null,

        addMenuId : function(menuId) {
            this.openedMenu = menuId;
        },

        deletedMenuId : function() {
            this.openedMenu = null;
        },

        shutdownMenu : function() {
            if (this.openedMenu != null) {
                rf.$(rf.getDomElement(this.openedMenu)).hide();
            }
            this.deletedMenuId();
        },

        setActiveSubMenu : function(submenu) {
            this.activeSubMenu = submenu;
        },

        getActiveSubMenu : function() {
            return this.activeSubMenu;
        }
    }
})(jQuery, RichFaces);;(function($, rf) {
    rf.ui = rf.ui || {};
    var defaultOptions = {
        showEvent : 'mouseenter',
        direction : "AA",
        jointPoint : "AA",
        positionType : "DDMENUGROUP",
        showDelay : 300
    }
    // constructor definition
    rf.ui.MenuGroup = function(componentId, options) {
        this.id = componentId;
        this.options = {};
        $.extend(this.options, defaultOptions, options || {});
        $super.constructor.call(this, componentId, this.options);
        this.namespace = this.namespace || "."
            + rf.Event.createNamespace(this.name, this.id);
        this.attachToDom(componentId);

        rf.Event.bindById(this.id, this.options.showEvent, $.proxy(
            this.__showHandler, this), this);

        this.rootMenu = rf.$(this.options.rootMenuId);

        this.shown = false;
        this.jqueryElement = $(this.element);

    };

    rf.ui.MenuBase.extend(rf.ui.MenuGroup);

    // define super class link
    var $super = rf.ui.MenuGroup.$super;

    $.extend(rf.ui.MenuGroup.prototype, rf.ui.MenuKeyNavigation);

    $.extend(rf.ui.MenuGroup.prototype, (function() {
        return {
            name : "MenuGroup",
            show : function() {
                var id = this.id;
                if (this.rootMenu.groupList[id] && !this.shown) {
                    this.rootMenu.invokeEvent("groupshow", rf
                        .getDomElement(this.rootMenu.id),
                        null);
                    this.__showPopup();
                    this.shown = true;
                }
            },
            hide : function() {
                var menu = this.rootMenu;
                if (menu.groupList[this.id] && this.shown) {
                    menu.invokeEvent("grouphide", rf
                        .getDomElement(menu.id), null);
                    this.__hidePopup();
                    this.shown = false;
                }
            },

            select : function() {
                this.jqueryElement.removeClass(this.options.cssClasses.unselectItemCss);
                this.jqueryElement.addClass(this.options.cssClasses.selectItemCss);
            },
            unselect : function() {
                this.jqueryElement.removeClass(this.options.cssClasses.selectItemCss);
                this.jqueryElement.addClass(this.options.cssClasses.unselectItemCss);
            },

            __showHandler : function() {
                this.select();
                $super.__showHandler.call(this);
            },
            __leaveHandler : function() {
                window.clearTimeout(this.showTimeoutId);
                this.showTimeoutId = null;
                this.hideTimeoutId = window.setTimeout($.proxy(
                    function() {
                        this.hide();
                    }, this), this.options.hideDelay);
                this.unselect();
            },

            destroy : function() {
                // clean up code here
                this.detach(this.id);
                // call parent's destroy method
                $super.destroy.call(this);
            }
        }

    })());
})(jQuery, RichFaces);(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.Select = function(id, options) {
        this.id = id;
        var mergedOptions = $.extend({}, defaultOptions, options);
        mergedOptions['attachTo'] = id;
        mergedOptions['scrollContainer'] = $(document.getElementById(id + "Items")).parent()[0];
        mergedOptions['focusKeeperEnabled'] = false;
        $super.constructor.call(this, id, mergedOptions);

        this.options = mergedOptions;
        this.defaultLabel = mergedOptions.defaultLabel;
        var inputLabel = this.__getValue();
        this.initialValue = (inputLabel != this.defaultLabel) ? inputLabel : "";
        this.selValueInput = $(document.getElementById(id + "selValue"));
        this.container = this.selValueInput.parent();
        this.clientSelectItems = mergedOptions.clientSelectItems;
        this.filterFunction = mergedOptions.filterFunction;


        if (mergedOptions.showControl && !mergedOptions.disabled) {
            this.container.bind("mousedown", $.proxy(this.__onBtnMouseDown, this))
                .bind("mouseup", $.proxy(this.__onMouseUp, this));
        }

        this.selectFirst = mergedOptions.selectFirst;
        this.popupList = new rf.ui.PopupList((id + "List"), this, mergedOptions);
        this.list = this.popupList.__getList();
        this.listElem = $(document.getElementById(id + "List"));

        this.listElem.bind("mousedown", $.proxy(this.__onListMouseDown, this));
        this.listElem.bind("mouseup", $.proxy(this.__onMouseUp, this));

        var listEventHandlers = {};
        listEventHandlers["listshow" + this.namespace] = $.proxy(this.__listshowHandler, this);
        listEventHandlers["listhide" + this.namespace] = $.proxy(this.__listhideHandler, this);
        listEventHandlers["change" + this.namespace] = $.proxy(this.__onInputChangeHandler, this);
        rf.Event.bind(this.input, listEventHandlers, this);

        this.originalItems = this.list.__getItems();
        this.enableManualInput = mergedOptions.enableManualInput;

        if (this.originalItems.length > 0 && this.enableManualInput) {
            this.cache = new rf.utils.Cache("", this.originalItems, getData, true);
        }
        this.changeDelay = mergedOptions.changeDelay;
    };

    rf.ui.InputBase.extend(rf.ui.Select);
    var $super = rf.ui.Select.$super;

    var defaultOptions = {
        defaultLabel: "",
        selectFirst: true,
        showControl: true,
        enableManualInput: false,
        itemCss: "rf-sel-opt",
        selectItemCss: "rf-sel-sel",
        listCss: "rf-sel-lst-cord",
        changeDelay: 8,
        disabled: false,
        filterFunction : undefined
    };

    var REGEXP_TRIM = /^[\n\s]*(.*)[\n\s]*$/;

    var getData = function (nodeList) {
        var data = [];
        nodeList.each(function () {
            ;
            data.push($(this).text().replace(REGEXP_TRIM, "$1"));
        });
        return data;
    }

    $.extend(rf.ui.Select.prototype, ( function () {
        return{
            name : "select",
            defaultLabelClass : "rf-sel-dflt-lbl",

            __listshowHandler: function(e) {
            },

            __listhideHandler: function(e) {
            },
            
            __onInputChangeHandler: function(e) {
                this.__setValue(this.input.val());
            },

            __onBtnMouseDown: function(e) {
                if (!this.popupList.isVisible()) {
                    this.__updateItems();
                    this.__showPopup();
                } else {
                    this.__hidePopup();
                }
                this.isMouseDown = true;
            },

            __focusHandler: function(e) {
                if (!this.focused) {
                    if (this.__getValue() == this.defaultLabel) {
                        this.__setValue("");
                    }
                    this.focusValue = this.selValueInput.val();
                    this.focused = true;
                    this.invokeEvent.call(this, "focus", document.getElementById(this.id), e);
                }
            },

            __keydownHandler: function(e) {
                var code;

                if (e.keyCode) {
                    code = e.keyCode;
                } else if (e.which) {
                    code = e.which;
                }

                var visible = this.popupList.isVisible();

                switch (code) {
                    case rf.KEYS.DOWN:
                        e.preventDefault();
                        if (!visible) {
                            this.__updateItems();
                            this.__showPopup();
                        } else {
                            this.list.__selectNext();
                        }
                        break;

                    case rf.KEYS.UP:
                        e.preventDefault();
                        if (visible) {
                            this.list.__selectPrev();
                        }
                        break;

                    case rf.KEYS.RETURN:
                        e.preventDefault();
                        if (visible) {
                            this.list.__selectCurrent();
                        }
                        return false;
                        break;

                    case rf.KEYS.TAB:
                        break;

                    case rf.KEYS.ESC:
                        e.preventDefault();
                        if (visible) {
                            this.__hidePopup();
                        }
                        break;

                    default:
                        var _this = this;
                        window.clearTimeout(this.changeTimerId);
                        this.changeTimerId = window.setTimeout(function() {
                            _this.__onChangeValue(e);
                        }, this.changeDelay);
                        break;
                }
            },

            __onChangeValue: function(e) {
                this.list.__selectByIndex();
                var newValue = this.__getValue();
                if (this.cache && this.cache.isCached(newValue)) {
                    this.__updateItems();

                    if (this.list.__getItems().length != 0) {
                        this.container.removeClass("rf-sel-fld-err");
                    } else {
                        this.container.addClass("rf-sel-fld-err");
                    }

                    if (!this.popupList.isVisible()) {
                        this.__showPopup();
                    }
                }
            },

            __blurHandler: function(e) {
                if (!this.isMouseDown) {
                    var that = this;
                    this.timeoutId = window.setTimeout(function() {
                        if (that.input !== null) {
                            that.onblur(e);
                        }
                    }, 200);
                } else {
                    this.__setInputFocus();
                    this.isMouseDown = false;
                }
            },

            __onListMouseDown: function(e) {
                this.isMouseDown = true;
            },

            __onMouseUp: function(e) {
                this.isMouseDown = false;
                this.__setInputFocus();
            },

            __updateItems: function() {
                var newValue = this.__getValue();
                newValue = (newValue != this.defaultLabel) ? newValue : "";
                this.__updateItemsFromCache(newValue);

                if (this.selectFirst) {
                    this.list.__selectByIndex(0);
                }
            },

            __updateItemsFromCache: function(value) {
                if (this.originalItems.length > 0 && this.enableManualInput) {
                    var newItems = this.cache.getItems(value, this.filterFunction);
                    var items = $(newItems);
                    this.list.__setItems(items);
                    $(document.getElementById(this.id + "Items")).empty().append(items);
                }
            },

            __getClientItemFromCache: function(inputLabel) {
                var value;
                var label;
                if (this.enableManualInput) {
                    var items = this.cache.getItems(inputLabel, this.filterFunction);
                    if (items && items.length > 0) {
                        var first = $(items[0]);
                        $.each(this.clientSelectItems, function() {
                            if (this.id == first.attr("id")) {
                                label = this.label;
                                value = this.value;
                                return false;
                            }
                        });
                    } else {
                        label = inputLabel;
                        value = "";
                    }
                }

                if (label) {
                    return {'label': label, 'value': value};
                }
            },

            __getClientItem: function(inputLabel) {
                var value;
                var label = inputLabel;
                $.each(this.clientSelectItems, function() {
                    if (label == this.label) {
                        value = this.value;
                    }
                });

                if (label && value) {
                    return {'label': label, 'value': value};
                }
            },

            __showPopup: function() {
                this.popupList.show();
                this.invokeEvent.call(this, "listshow", document.getElementById(this.id));
            },

            __hidePopup: function() {
                this.popupList.hide();
                this.invokeEvent.call(this, "listhide", document.getElementById(this.id));
            },

            showPopup: function() {
                if (!this.popupList.isVisible()) {
                    this.__updateItems();
                    this.__showPopup();
                }
                this.__setInputFocus();
                if (!this.focused) {
                    if (this.__getValue() == this.defaultLabel) {
                        this.__setValue("");
                    }
                    this.focusValue = this.selValueInput.val();
                    this.focused = true;
                    this.invokeEvent.call(this, "focus", document.getElementById(this.id));
                }
            },

            hidePopup: function() {
                if (this.popupList.isVisible()) {
                    this.__hidePopup();
                    var inputLabel = this.__getValue();

                    if (!inputLabel || inputLabel == "") {
                        this.__setValue(this.defaultLabel);
                        this.selValueInput.val("");
                    }

                    this.focused = false;
                    this.invokeEvent.call(this, "blur", document.getElementById(this.id));
                    if (this.focusValue != this.selValueInput.val()) {
                        this.invokeEvent.call(this, "change", document.getElementById(this.id));
                    }
                }
            },

            processItem: function(item) {
                var key = $(item).attr("id");
                var label;
                $.each(this.clientSelectItems, function() {
                    if (this.id == key) {
                        label = this.label;
                        return false;
                    }
                });
                this.__setValue(label);
                this.__hidePopup();
                this.__setInputFocus();
                this.__save();

                this.invokeEvent.call(this, "selectitem", document.getElementById(this.id));
            },

            __save: function() {
                var value = "";
                var label = "";
                var inputLabel = this.__getValue();
                var clientSelectItem;

                if (inputLabel && inputLabel != "") {
                    if (this.enableManualInput) {
                        clientSelectItem = this.__getClientItemFromCache(inputLabel);
                    } else {
                        clientSelectItem = this.__getClientItem(inputLabel);
                    }

                    if (clientSelectItem) {
                        label = clientSelectItem.label;
                        value = clientSelectItem.value;
                    }
                }

                this.__setValue(label);
                this.selValueInput.val(value);
            },

            onblur: function(e) {
                this.__hidePopup();
                var inputLabel = this.__getValue();

                if (!inputLabel || inputLabel == "") {
                    this.__setValue(this.defaultLabel);
                    this.selValueInput.val("");
                }

                this.focused = false;
                this.invokeEvent.call(this, "blur", document.getElementById(this.id), e);
                if (this.focusValue != this.selValueInput.val()) {
                    this.invokeEvent.call(this, "change", document.getElementById(this.id), e);
                }
            },

            getValue: function() {
                return this.selValueInput.val();
            },

            setValue: function(value) {
                if (value == null || value == '') {
                    this.__setValue('');
                    this.__save();
                    this.__updateItems();
                    return;
                }
                var item;
                for (var i = 0; i < this.clientSelectItems.length; i++) {
                    item = this.clientSelectItems[i];
                    if (item.value == value) {
                        this.__setValue(item.label);
                        this.__save();
                        this.list.__selectByIndex(i);
                        return;
                    }
                }
            },

            getLabel: function() {
                return this.__getValue();
            },

            destroy: function() {
                this.popupList.destroy();
                this.popupList = null;
                $super.destroy.call(this);
            }
        }
    })());
    
    // client-side validation
    rf.csv = rf.csv || {};
    rf.csv.validateSelectLabelValue = function (input, id, params, msg) {
        var value = $(document.getElementById(id + 'selValue')).val();
        var label = $(document.getElementById(id + 'Input')).val();
        
        var defaultLabel = RichFaces.$(id).defaultLabel;
        
        if (!value && label && (label != defaultLabel)) {
            throw rf.csv.getMessage(null, 'UISELECTONE_INVALID', [id, ""]);
        }
    };

})(jQuery, window.RichFaces);;(function($, rf) {
    rf.ui = rf.ui || {};

    var defaultOptions = {
        showEvent : 'contextmenu',
        cssRoot : "ctx",
        cssClasses : {},
        attached : true
    };

    // constructor definition
    rf.ui.ContextMenu = function(componentId, options) {
        this.options = {};
        $.extend(this.options, defaultOptions, options || {});
        $super.constructor.call(this, componentId, this.options);
        this.id = componentId;
        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, this.id);
        rf.Event.bind('body', 'click' + this.namespace, $.proxy(this.__leaveHandler, this));
        rf.Event.bindById(this.id, 'click' + this.namespace, $.proxy(this.__clilckHandler, this));
    }

    rf.ui.Menu.extend(rf.ui.ContextMenu);

    // define super class link
    var $super = rf.ui.ContextMenu.$super;

    $.extend(rf.ui.ContextMenu.prototype, (function() {
        return {
            name : "ContextMenu",

            getTarget : function() {
                if (!this.options.attached) {
                    return null;
                }
                var target = typeof this.options.target === 'undefined' ?
                    this.element.parentNode.id : this.options.target;
                return target;
            },

            __showHandler : function(e) {
                if (this.__isShown()) {
                    this.hide();
                }
                return $super.__showHandler.call(this, e);
            },

            show : function(e) {
                if (this.menuManager.openedMenu != this.id) {
                    this.menuManager.shutdownMenu();
                    this.menuManager.addMenuId(this.id);
                    this.__showPopup(e); // include the event to position the popup at the cursor
                    var parent = rf.$(this.target);
                    if (parent && parent.contextMenuShow) {
                        parent.contextMenuShow(this, e);
                    }
                }
            },

            __clilckHandler : function (event) {
                event.preventDefault();
                event.stopPropagation();
            },

            destroy : function() {
                rf.Event.unbind('body', 'click' + this.namespace);
                rf.Event.unbindById(this.id, 'click' + this.namespace);

                // call parent's destroy method
                $super.destroy.call(this);
            }


        };
    })());

})(jQuery, RichFaces);;(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.PickList = function(id, options) {
        var mergedOptions = $.extend({}, defaultOptions, options);
        $super.constructor.call(this, id, mergedOptions);
        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, this.id);
        this.attachToDom();
        mergedOptions['scrollContainer'] = $(document.getElementById(id + "SourceItems"));
        this.sourceList = new rf.ui.ListMulti(id+ "SourceList", mergedOptions);
        mergedOptions['scrollContainer'] = $(document.getElementById(id + "TargetItems"));
        this.selectItemCss = mergedOptions['selectItemCss'];
        var hiddenId = id + "SelValue";
        this.hiddenValues = $(document.getElementById(hiddenId));
        mergedOptions['hiddenId'] = hiddenId;
        this.orderable = mergedOptions['orderable'];

        if (this.orderable) {
            this.orderingList = new rf.ui.OrderingList(id+ "Target", mergedOptions);
            this.targetList = this.orderingList.list;
        } else {
            this.targetList = new rf.ui.ListMulti(id+ "TargetList", mergedOptions);
        }
        this.pickList = $(document.getElementById(id));

        this.addButton = $('.rf-pick-add', this.pickList);
        this.addButton.bind("click", $.proxy(this.add, this));
        this.addAllButton = $('.rf-pick-add-all', this.pickList);
        this.addAllButton.bind("click", $.proxy(this.addAll, this));
        this.removeButton = $('.rf-pick-rem', this.pickList);
        this.removeButton.bind("click", $.proxy(this.remove, this));
        this.removeAllButton = $('.rf-pick-rem-all', this.pickList);
        this.removeAllButton.bind("click", $.proxy(this.removeAll, this));
        this.disabled = mergedOptions.disabled;

        if (mergedOptions['onadditems'] && typeof mergedOptions['onadditems'] == 'function') {
            rf.Event.bind(this.targetList, "additems", mergedOptions['onadditems']);
        }
        rf.Event.bind(this.targetList, "additems", $.proxy(this.toggleButtons, this));

        this.focused = false;
        this.keepingFocus = false;
        bindFocusEventHandlers.call(this, mergedOptions);

        // Adding items to the source list happens after removing them from the target list
        if (mergedOptions['onremoveitems'] && typeof mergedOptions['onremoveitems'] == 'function') {
            rf.Event.bind(this.sourceList, "additems", mergedOptions['onremoveitems']);
        }
        rf.Event.bind(this.sourceList, "additems", $.proxy(this.toggleButtons, this));

        rf.Event.bind(this.sourceList, "selectItem", $.proxy(this.toggleButtons, this));
        rf.Event.bind(this.sourceList, "unselectItem", $.proxy(this.toggleButtons, this));
        rf.Event.bind(this.targetList, "selectItem", $.proxy(this.toggleButtons, this));
        rf.Event.bind(this.targetList, "unselectItem", $.proxy(this.toggleButtons, this));

        if (mergedOptions['switchByClick']) {
            rf.Event.bind(this.sourceList, "click", $.proxy(this.add, this));
            rf.Event.bind(this.targetList, "click", $.proxy(this.remove, this));
        }

        if (mergedOptions['switchByDblClick']) {
            rf.Event.bind(this.sourceList, "dblclick", $.proxy(this.add, this));
            rf.Event.bind(this.targetList, "dblclick", $.proxy(this.remove, this));
        }

        if (options['onchange'] && typeof options['onchange'] == 'function') {
            rf.Event.bind(this, "change" + this.namespace, options['onchange']);
        }

        // TODO: Is there a "Richfaces way" of executing a method after page load?
        $(document).ready($.proxy(this.toggleButtons, this));
    };
    rf.BaseComponent.extend(rf.ui.PickList);
    var $super = rf.ui.PickList.$super;

    var defaultOptions = {
        defaultLabel: "",
        itemCss: "rf-pick-opt",
        selectItemCss: "rf-pick-sel",
        listCss: "rf-pick-lst-cord",
        clickRequiredToSelect: true,
        switchByClick : false,
        switchByDblClick : true,
        disabled : false
    };

    var bindFocusEventHandlers = function (options) {
        // source list
        if (options['onsourcefocus'] && typeof options['onsourcefocus'] == 'function') {
            rf.Event.bind(this.sourceList, "listfocus" + this.sourceList.namespace, options['onsourcefocus']);
        }

        if (options['onsourceblur'] && typeof options['onsourceblur'] == 'function') {
            rf.Event.bind(this.sourceList, "listblur" + this.sourceList.namespace, options['onsourceblur']);
        }

        // target list
        if (options['ontargetfocus'] && typeof options['ontargetfocus'] == 'function') {
            rf.Event.bind(this.targetList, "listfocus" + this.targetList.namespace, options['ontargetfocus']);
        }
        if (options['ontargetblur'] && typeof options['ontargetblur'] == 'function') {
            rf.Event.bind(this.targetList, "listblur" + this.targetList.namespace, options['ontargetblur']);
        }

        // pick list
        if (options['onfocus'] && typeof options['onfocus'] == 'function') {
            rf.Event.bind(this, "listfocus" + this.namespace, options['onfocus']);
        }
        if (options['onblur'] && typeof options['onblur'] == 'function') {
            rf.Event.bind(this, "listblur" + this.namespace, options['onblur']);
        }

        this.pickList.focusin($.proxy(this.__focusHandler, this));
        this.pickList.focusout($.proxy(this.__blurHandler, this));
    };

    $.extend(rf.ui.PickList.prototype, (function () {

        return {
            name : "pickList",
            defaultLabelClass : "rf-pick-dflt-lbl",

            getName: function() {
                return this.name;
            },
            getNamespace: function() {
                return this.namespace;
            },

            __focusHandler: function(e) {
                if (! this.focused) {
                    this.focused = true;
                    rf.Event.fire(this, "listfocus" + this.namespace, e);
                    this.originalValue = this.targetList.csvEncodeValues();
                }
            },

            __blurHandler: function(e) {
                if (this.focused) {
                    this.focused = false;
                    rf.Event.fire(this, "listblur" + this.namespace, e);
                }
            },

            getSourceList: function() {
                return this.sourceList;
            },

            getTargetList: function() {
                return this.targetList;
            },

            add: function() {
                this.targetList.setFocus();
                var items = this.sourceList.removeSelectedItems();
                this.targetList.addItems(items);
                this.encodeHiddenValues();
            },

            remove: function() {
                this.sourceList.setFocus();
                var items = this.targetList.removeSelectedItems();
                this.sourceList.addItems(items);
                this.encodeHiddenValues();
            },

            addAll: function() {
                this.targetList.setFocus();
                var items = this.sourceList.removeAllItems();
                this.targetList.addItems(items);
                this.encodeHiddenValues();
            },

            removeAll: function() {
                this.sourceList.setFocus();
                var items = this.targetList.removeAllItems();
                this.sourceList.addItems(items);
                this.encodeHiddenValues();
            },

            encodeHiddenValues: function() {
                var oldValues = this.hiddenValues.val();
                var newValues = this.targetList.csvEncodeValues();
                if (oldValues !== newValues) {
                    this.hiddenValues.val(newValues);
                }
                rf.Event.fire(this, "change" + this.namespace, {oldValues : oldValues, newValues : newValues});
            },

            toggleButtons: function() {
                this.__toggleButton(this.addButton, this.sourceList.__getItems().filter('.' + this.selectItemCss).length > 0);
                this.__toggleButton(this.removeButton, this.targetList.__getItems().filter('.' + this.selectItemCss).length > 0);
                this.__toggleButton(this.addAllButton, this.sourceList.__getItems().length > 0);
                this.__toggleButton(this.removeAllButton, this.targetList.__getItems().length > 0);
                if (this.orderable) {
                    this.orderingList.toggleButtons();
                }
            },

            __toggleButton: function(button, enabled) {
                if (this.disabled || ! enabled) {
                    if (! button.hasClass('rf-pick-btn-dis')) {
                        button.addClass('rf-pick-btn-dis')
                    }
                    if (! button.attr('disabled')) {
                        button.attr('disabled', true);
                    }
                } else {
                    if (button.hasClass('rf-pick-btn-dis')) {
                        button.removeClass('rf-pick-btn-dis')
                    }
                    if (button.attr('disabled')) {
                        button.attr('disabled', false);
                    }
                }
            }
        };
    })());

})(jQuery, window.RichFaces);
;(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.InplaceInput = function(id, options) {
        var mergedOptions = $.extend({}, defaultOptions, options);
        $super.constructor.call(this, id, mergedOptions);
        this.label = $(document.getElementById(id + "Label"));
        var labelText = this.label.text();
        var inputLabel = this.__getValue();
        this.initialLabel = (labelText == inputLabel) ? labelText : "";
        this.useDefaultLabel = labelText != inputLabel
        this.saveOnBlur = mergedOptions.saveOnBlur;
        this.showControls = mergedOptions.showControls;
        this.getInput().bind("focus", $.proxy(this.__editHandler, this));
        if (this.showControls) {
            var btnContainer = document.getElementById(id + "Btn");
            if (btnContainer) {
                btnContainer.tabIndex = -1;
            }
            this.okbtn = $(document.getElementById(id + "Okbtn"));
            this.cancelbtn = $(document.getElementById(id + "Cancelbtn"));
            this.okbtn.bind("mousedown", $.proxy(this.__saveBtnHandler, this));
            this.cancelbtn.bind("mousedown", $.proxy(this.__cancelBtnHandler, this));
        }
    };

    rf.ui.InplaceBase.extend(rf.ui.InplaceInput);
    var $super = rf.ui.InplaceInput.$super;

    var defaultOptions = {
        defaultLabel: "",
        saveOnBlur: true,
        showControl: true,
        noneCss: "rf-ii-none",
        readyCss: "rf-ii",
        editCss: "rf-ii-act",
        changedCss: "rf-ii-chng"
    };

    $.extend(rf.ui.InplaceInput.prototype, ( function () {

        return {

            name : "inplaceInput",
            defaultLabelClass : "rf-ii-dflt-lbl",

            getName: function() {
                return this.name;
            },

            getNamespace: function() {
                return this.namespace;
            },

            __keydownHandler: function(e) {
                this.tabBlur = false;
                switch (e.keyCode || e.which) {
                    case rf.KEYS.ESC:
                        e.preventDefault();
                        this.cancel();
                        this.onblur(e);
                        break;
                    case rf.KEYS.RETURN:
                        e.preventDefault();
                        this.save();
                        this.onblur(e);
                        break;
                    case rf.KEYS.TAB:
                        this.tabBlur = true;
                        break;
                }
            },

            __blurHandler: function(e) {
                this.onblur(e);
            },

            __isSaveOnBlur: function() {
                return this.saveOnBlur;
            },

            __setInputFocus: function() {
                this.getInput().unbind("focus", this.__editHandler);
                this.getInput().focus();
            },

            __saveBtnHandler: function(e) {
                this.cancelButton = false;
                this.save();
                this.onblur(e);
            },

            __cancelBtnHandler: function(e) {
                this.cancelButton = true;
                this.cancel();
                this.onblur(e);
            },

            __editHandler: function(e) {
                $super.__editHandler.call(this, e);
                this.onfocus(e);
            },

            getLabel: function() {
                return this.label.text();
            },

            setLabel: function(value) {
                this.label.text(value);
                if (value == this.defaultLabel) {
                    this.label.addClass(this.defaultLabelClass);
                } else {
                    this.label.removeClass(this.defaultLabelClass);
                }
            },

            isValueChanged: function () {
                return (this.__getValue() != this.initialLabel);
            },

            onshow: function() {
                this.__setInputFocus();
            },

            onhide: function() {
                if (this.tabBlur) {
                    this.tabBlur = false;
                } else {
                    this.getInput().focus();
                }
            },

            onfocus: function(e) {
                if (!this.__isFocused()) {
                    this.__setFocused(true);
                    this.focusValue = this.__getValue();
                    this.invokeEvent.call(this, "focus", document.getElementById(this.id), e);
                }
            },

            onblur: function(e) {
                if (this.__isFocused()) {
                    this.__setFocused(false);
                    this.invokeEvent.call(this, "blur", document.getElementById(this.id), e);

                    if (this.isValueSaved() || this.__isSaveOnBlur()) {
                        this.save();
                    } else {
                        this.cancel();
                    }

                    this.__hide();

                    if (!this.cancelButton) {
                        if (this.__isValueChanged()) {
                            this.invokeEvent.call(this, "change", document.getElementById(this.id), e);
                        }
                    }
                    var _this = this;
                    window.setTimeout(function() {
                        _this.getInput().bind("focus", $.proxy(_this.__editHandler, _this));
                    }, 1);
                }
            },

            __isValueChanged: function() {
                return (this.focusValue != this.__getValue());
            },

            __setFocused: function(focused) {
                this.focused = focused;
            },

            __isFocused: function() {
                return this.focused;
            },
            setValue: function(value) {
                this.__setValue(value);
                this.save();
            }
        }
    })());

})(jQuery, window.RichFaces);
;(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.OrderingList = function(id, options) {
        var mergedOptions = $.extend({}, defaultOptions, options);
        $super.constructor.call(this, id, mergedOptions);
        this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, this.id);
        this.attachToDom();
        mergedOptions['scrollContainer'] = $(document.getElementById(id + "Items"));
        this.orderingList = $(document.getElementById(id));
        this.list = new rf.ui.ListMulti(id+ "List", mergedOptions);
        var hiddenId = mergedOptions['hiddenId'] ===null ? id + "SelValue" : mergedOptions['hiddenId'];
        this.hiddenValues = $(document.getElementById(hiddenId));
        this.selectItemCss = mergedOptions['selectItemCss'];
        this.disabled = mergedOptions.disabled;

        this.upButton = $('.rf-ord-up', this.orderingList);
        this.upButton.bind("click", $.proxy(this.up, this));
        this.upTopButton = $('.rf-ord-up-tp', this.orderingList);
        this.upTopButton.bind("click", $.proxy(this.upTop, this));
        this.downButton = $('.rf-ord-dn', this.orderingList);
        this.downButton.bind("click", $.proxy(this.down, this));
        this.downBottomButton = $('.rf-ord-dn-bt', this.orderingList);
        this.downBottomButton.bind("click", $.proxy(this.downBottom, this));

        this.focused = false;
        this.keepingFocus = false;
        bindFocusEventHandlers.call(this, mergedOptions);

        if (mergedOptions['onmoveitems'] && typeof mergedOptions['onmoveitems'] == 'function') {
            rf.Event.bind(this.list, "moveitems", mergedOptions['onmoveitems']);
        }
        rf.Event.bind(this.list, "moveitems", $.proxy(this.toggleButtons, this));

        rf.Event.bind(this.list, "selectItem", $.proxy(this.toggleButtons, this));
        rf.Event.bind(this.list, "unselectItem", $.proxy(this.toggleButtons, this));

        rf.Event.bind(this.list, "keydown" + this.list.namespace, $.proxy(this.__keydownHandler, this));

        if (options['onchange'] && typeof options['onchange'] == 'function') {
            rf.Event.bind(this, "change" + this.namespace, options['onchange']);
        }

        // TODO: Is there a "Richfaces way" of executing a method after page load?
        $(document).ready($.proxy(this.toggleButtons, this));
    };
    rf.BaseComponent.extend(rf.ui.OrderingList);
    var $super = rf.ui.OrderingList.$super;

    var defaultOptions = {
        defaultLabel: "",
        itemCss: "rf-ord-opt",
        selectItemCss: "rf-ord-sel",
        listCss: "rf-ord-lst-cord",
        clickRequiredToSelect: true,
        disabled : false,
        hiddenId : null
    };

    var bindFocusEventHandlers = function (options) {
        if (options['onfocus'] && typeof options['onfocus'] == 'function') {
            rf.Event.bind(this, "listfocus" + this.namespace, options['onfocus']);
        }
        if (options['onblur'] && typeof options['onblur'] == 'function') {
            rf.Event.bind(this, "listblur" + this.namespace, options['onblur']);
        }

        var focusEventHandlers = {};
        focusEventHandlers["listfocus" + this.list.namespace] = $.proxy(this.__focusHandler, this);
        focusEventHandlers["listblur" + this.list.namespace] = $.proxy(this.__blurHandler, this);
        rf.Event.bind(this.list, focusEventHandlers, this);

        focusEventHandlers = {};
        focusEventHandlers["focus" + this.namespace] = $.proxy(this.__focusHandler, this);
        focusEventHandlers["blur" + this.namespace] = $.proxy(this.__blurHandler, this);
        rf.Event.bind(this.upButton, focusEventHandlers, this);
        rf.Event.bind(this.upTopButton, focusEventHandlers, this);
        rf.Event.bind(this.downButton, focusEventHandlers, this);
        rf.Event.bind(this.downBottomButton, focusEventHandlers, this);
    };


    $.extend(rf.ui.OrderingList.prototype, (function () {

        return {
            name : "ordList",
            defaultLabelClass : "rf-ord-dflt-lbl",

            getName: function() {
                return this.name;
            },
            getNamespace: function() {
                return this.namespace;
            },

            __focusHandler: function(e) {
                this.keepingFocus = this.focused;
                if (! this.focused) {
                    this.focused = true;
                    rf.Event.fire(this, "listfocus" + this.namespace, e);
                    this.originalValue = this.list.csvEncodeValues();
                }
            },

            __blurHandler: function(e) {
                var that = this;
                this.timeoutId = window.setTimeout(function() {
                    if (!that.keepingFocus) { // If no other orderingList "sub" component has grabbed the focus during the timeout
                        that.focused = false;
                        rf.Event.fire(that, "listblur" + that.namespace, e);
                        var newValue = that.list.csvEncodeValues();
                        if (newValue != that.originalValue) {
                            rf.Event.fire(that, "change" + that.namespace, e);
                        }
                    }
                    that.keepingFocus = false;
                }, 200);
            },

            __keydownHandler: function(e) {
                if (e.isDefaultPrevented()) return;
                if (! e.metaKey) return;

                var code;
                if (e.keyCode) {
                    code = e.keyCode;
                } else if (e.which) {
                    code = e.which;
                }

                switch (code) {
                    case rf.KEYS.DOWN:
                        e.preventDefault();
                        this.down();
                        break;

                    case rf.KEYS.UP:
                        e.preventDefault();
                        this.up();
                        break;

                    case rf.KEYS.HOME:
                        e.preventDefault();
                        this.upTop();
                        break;

                    case rf.KEYS.END:
                        e.preventDefault();
                        this.downBottom();
                        break;

                    default:
                        break;
                }
                return;
            },

            getList: function() {
                return this.list;
            },

            up: function() {
                this.keepingFocus = true;
                this.list.setFocus();
                var items = this.list.getSelectedItems();
                this.list.move(items, -1);
                this.encodeHiddenValues();
            },

            down: function() {
                this.keepingFocus = true;
                this.list.setFocus();
                var items = this.list.getSelectedItems();
                this.list.move(items, 1);
                this.encodeHiddenValues();
            },

            upTop: function() {
                this.keepingFocus = true;
                this.list.setFocus();
                var selectedItems = this.list.getSelectedItems();
                var index = this.list.items.index(selectedItems.first());
                this.list.move(selectedItems, -index);
                this.encodeHiddenValues();
            },

            downBottom: function() {
                this.keepingFocus = true;
                this.list.setFocus();
                var selectedItems = this.list.getSelectedItems();
                var index = this.list.items.index(selectedItems.last());
                this.list.move(selectedItems, (this.list.items.length -1) - index);
                this.encodeHiddenValues();
            },

            encodeHiddenValues: function() {
                this.hiddenValues.val(this.list.csvEncodeValues());
            },

            toggleButtons: function() {
                var list = this.list.__getItems();
                if (this.disabled || this.list.getSelectedItems().length === 0) {
                    this.__disableButton(this.upButton);
                    this.__disableButton(this.upTopButton);
                    this.__disableButton(this.downButton);
                    this.__disableButton(this.downBottomButton);
                } else {
                    if (this.list.items.index(this.list.getSelectedItems().first()) === 0) {
                        this.__disableButton(this.upButton);
                        this.__disableButton(this.upTopButton);
                    } else {
                        this.__enableButton(this.upButton);
                        this.__enableButton(this.upTopButton);
                    }
                    if (this.list.items.index(this.list.getSelectedItems().last()) === (this.list.items.length - 1)) {
                        this.__disableButton(this.downButton);
                        this.__disableButton(this.downBottomButton);
                    } else {
                        this.__enableButton(this.downButton);
                        this.__enableButton(this.downBottomButton);
                    }
                }
            },

            __disableButton: function (button) {
                 if (! button.hasClass('rf-ord-btn-dis')) {
                    button.addClass('rf-ord-btn-dis')
                }
                if (! button.attr('disabled')) {
                    button.attr('disabled', true);
                }
            },

            __enableButton: function(button) {
                if (button.hasClass('rf-ord-btn-dis')) {
                    button.removeClass('rf-ord-btn-dis')
                }
                if (button.attr('disabled')) {
                    button.attr('disabled', false);
                }
            }
        };
    })());

})(jQuery, window.RichFaces);
;(function ($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.InplaceSelect = function(id, options) {
        var mergedOptions = $.extend({}, defaultOptions, options);
        $super.constructor.call(this, id, mergedOptions);
        this.getInput().bind("click", $.proxy(this.__clickHandler, this));
        mergedOptions['attachTo'] = id;
        mergedOptions['scrollContainer'] = $(document.getElementById(id + "Items")).parent()[0];
        mergedOptions['focusKeeperEnabled'] = false;
        this.popupList = new rf.ui.PopupList(id + "List", this, mergedOptions);
        this.list = this.popupList.__getList();
        this.clientSelectItems = mergedOptions.clientSelectItems;
        this.selValueInput = $(document.getElementById(id + "selValue"));
        this.initialValue = this.selValueInput.val();
        this.listHandler = $(document.getElementById(id + "List"));
        this.listHandler.bind("mousedown", $.proxy(this.__onListMouseDown, this));
        this.listHandler.bind("mouseup", $.proxy(this.__onListMouseUp, this));
        this.openOnEdit = mergedOptions.openOnEdit;
        this.saveOnSelect = mergedOptions.saveOnSelect;
        this.savedIndex = -1;

        this.inputItem = $(document.getElementById(id + "Input"));
        this.inputItemWidth = this.inputItem.width();
        this.inputWidthDefined = options.inputWidth !== undefined;
    };
    rf.ui.InplaceInput.extend(rf.ui.InplaceSelect);
    var $super = rf.ui.InplaceSelect.$super;

    var defaultOptions = {
        defaultLabel: "",
        saveOnSelect: true,
        openOnEdit: true,
        showControl: false,
        itemCss: "rf-is-opt",
        selectItemCss: "rf-is-sel",
        listCss: "rf-is-lst-cord",
        noneCss: "rf-is-none",
        editCss: "rf-is-fld-cntr",
        changedCss: "rf-is-chng"
    };

    $.extend(rf.ui.InplaceSelect.prototype, (function () {

        return{
            name : "inplaceSelect",
            defaultLabelClass : "rf-is-dflt-lbl",

            getName: function() {
                return this.name;
            },
            getNamespace: function() {
                return this.namespace;
            },
            onshow: function() {
                $super.onshow.call(this);
                if (this.openOnEdit) {
                    this.__showPopup();
                }
            },
            onhide: function() {
                this.__hidePopup();
            },

            showPopup: function() {
                this.isSaved = false;
                this.element.addClass(this.editCss);
                this.editContainer.removeClass(this.noneCss);

                this.editState = true;
                this.scrollElements = rf.Event.bindScrollEventHandlers(this.id, this.__scrollHandler, this);
                this.__setInputFocus();
                this.onfocus();
                this.__showPopup();

            },
            __showPopup: function() {
                this.popupList.show();
                this.__hideLabel();
            },
            __hidePopup: function() {
                this.popupList.hide();
                this.__showLabel();
            },

            onsave: function() {
                var item = this.list.currentSelectItem();
                if (item) {
                    var index = this.list.getSelectedItemIndex();
                    var clientSelectItem = this.list.getClientSelectItemByIndex(index);
                    var label = clientSelectItem.label;
                    if (label == this.__getValue()) {
                        this.savedIndex = index;
                        this.saveItemValue(clientSelectItem.value);
                        this.list.__selectByIndex(this.savedIndex);
                    } else {
                        this.list.__selectItemByValue(this.getValue());
                    }
                }
            },
            oncancel: function() {
                var value = this.list.getClientSelectItemByIndex(this.savedIndex).value;
                if (value) {
                    this.saveItemValue(value);
                    this.list.__selectByIndex(this.savedIndex);
                } else {
                    this.saveItemValue(this.initialValue);
                    this.list.__selectItemByValue(this.initialValue);
                }
            },
            onblur: function(e) {
                this.__hidePopup();
                $super.onblur.call(this);
            },
            onfocus: function(e) {
                if (!this.__isFocused()) {
                    this.__setFocused(true);
                    this.focusValue = this.selValueInput.val();
                    this.invokeEvent.call(this, "focus", document.getElementById(this.id), e);
                }
            },
            processItem: function(item) {
                var label = $(item).data('clientSelectItem').label;
                this.__setValue(label);

                this.__setInputFocus();
                this.__hidePopup();

                if (this.saveOnSelect) {
                    this.save();
                }

                this.invokeEvent.call(this, "selectitem", document.getElementById(this.id));
            },
            saveItemValue: function(value) {
                this.selValueInput.val(value);

            },
            __isValueChanged: function() {
                return (this.focusValue != this.selValueInput.val());
            },
            __keydownHandler: function(e) {

                var code;

                if (e.keyCode) {
                    code = e.keyCode;
                } else if (e.which) {
                    code = e.which;
                }

                if (this.popupList.isVisible()) {
                    switch (code) {
                        case rf.KEYS.DOWN:
                            e.preventDefault();
                            this.list.__selectNext();
                            this.__setInputFocus();
                            break;

                        case rf.KEYS.UP:
                            e.preventDefault();
                            this.list.__selectPrev();
                            this.__setInputFocus();
                            break;

                        case rf.KEYS.RETURN:
                            e.preventDefault();
                            this.list.__selectCurrent();
                            this.__setInputFocus();
                            return false;
                            break;
                    }
                }

                $super.__keydownHandler.call(this, e);
            },
            __blurHandler: function(e) {
                if (this.saveOnSelect || !this.isMouseDown) {
                    if (this.isEditState()) {
                        this.timeoutId = window.setTimeout($.proxy(function() {
                            this.onblur(e);
                        }, this), 200);
                    }
                } else {
                    this.__setInputFocus();
                    this.isMouseDown = false;
                }
            },
            __clickHandler: function(e) {
                this.__showPopup();
            },
            __onListMouseDown: function(e) {
                this.isMouseDown = true;
            },
            __onListMouseUp: function(e) {
                this.isMouseDown = false;
                this.__setInputFocus();
            },
            __showLabel: function(e) {
                this.label.show();
                this.editContainer.css("position", "absolute");
                this.inputItem.width(this.inputItemWidth);
            },
            __hideLabel: function(e) {
                this.label.hide();
                this.editContainer.css("position", "static");
                if (!this.inputWidthDefined) {
                    this.inputItem.width(this.label.width());
                }
            },
            getValue: function() {
                return this.selValueInput.val();
            },
            setValue: function(value) {
                var item = this.list.__selectItemByValue();
                var clientSelectItem = item.data('clientSelectItem');
                this.__setValue(clientSelectItem.label);
                this.save();
            },
            destroy: function() {
                this.popupList.destroy();
                this.popupList = null;
                $super.destroy.call(this);
            }
        };

    })());
})(jQuery, window.RichFaces);
;
New to GrepCode? Check out our FAQ X