/**
 * Copyright (c) 2009 Sergiy Kovalchuk (serg472@gmail.com)
 * 
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *  
 * Following code is based on Element.mask() implementation from ExtJS framework (http://extjs.com/)
 *
 */
;(function($){
        
        /**
         * Displays loading mask over selected element(s). Accepts both single and multiple selectors.
         *
         * @param label Text message that will be displayed on top of the mask besides a spinner (optional). 
         *                              If not provided only mask will be displayed without a label or a spinner.       
         * @param delay Delay in milliseconds before element is masked (optional). If unmask() is called 
         *              before the delay times out, no mask is displayed. This can be used to prevent unnecessary 
         *              mask display for quick processes.       
         */
        $.fn.mask = function(label, delay , middle){
                $(this).each(function() {
                        if(delay !== undefined && delay > 0) {
                        var element = $(this);
                        element.data("_mask_timeout", setTimeout(function() { $.maskElement(element, label, middle)}, delay , middle));
                        } else {
                                $.maskElement($(this), label);
                        }
                });
        };
        
        /**
         * Removes mask from the element(s). Accepts both single and multiple selectors.
         */
        $.fn.unmask = function(){
                $(this).each(function() {
                        $.unmaskElement($(this));
                });
        };
        
        /**
         * Checks if a single element is masked. Returns false if mask is delayed or not displayed. 
         */
        $.fn.isMasked = function(){
                return this.hasClass("masked");
        };

        $.maskElement = function(element, label , middle){

                //if this element has delayed mask scheduled then remove it and display the new one
                if (element.data("_mask_timeout") !== undefined) {
                        clearTimeout(element.data("_mask_timeout"));
                        element.removeData("_mask_timeout");
                }

                if(element.isMasked()) {
                        $.unmaskElement(element);
                }
                
                if(element.css("position") == "static") {
                        element.addClass("masked-relative");
                }
                
                element.addClass("masked");
                
                var maskDiv = $('<div class="loadmask"></div>');
				$(".loadmask").addCss({
					'-moz-opacity': '0.5',
					'opacity': '.50',
					'filter': 'alpha(opacity=50)',
					'zoom': '1'
				});
                //  calculate scrollLeft and scrollTop  // added by Matthew
                var scrollLeft = 0;
                var scrollTop = 0;
                if (element.get(0) == document.body || (middle !== undefined) ) {
                        scrollLeft = $(window).scrollLeft();
                        scrollTop = $(window).scrollTop();
                }  else {
                        scrollLeft = element.scrollLeft();
                        scrollTop = element.scrollTop();
                }

                //auto height fix for IE  // modified by Matthew
                if(navigator.userAgent.toLowerCase().indexOf("msie") > -1){
                        maskDiv.height(scrollTop + element.height() + parseInt(element.css("padding-top")) + parseInt(element.css("padding-bottom")));
                        maskDiv.width(scrollLeft + element.width() + parseInt(element.css("padding-left")) + parseInt(element.css("padding-right")));
                }  else {
                        maskDiv.height(scrollTop + element.height());
                        maskDiv.width(scrollLeft + element.width());
                }


                //fix for z-index bug with selects in IE6
                if(navigator.userAgent.toLowerCase().indexOf("msie 6") > -1){
                        element.find("select").addClass("masked-hidden");
                }
                
                element.append(maskDiv);
                
                if(label !== undefined) {
                        var maskMsgDiv = $('<div class="loadmask-msg" style="display:none;"></div>');
                        maskMsgDiv.append('<div>' + label + '</div>');
                        element.append(maskMsgDiv);
                        //calculate center position // modified by Matthew
						if(middle !== undefined)         
							maskMsgDiv.css("top", Math.round(scrollTop + maskMsgDiv.height()   - (maskMsgDiv.height() - parseInt(maskMsgDiv.css("padding-top")) - parseInt(maskMsgDiv.css("padding-bottom"))) / 2)+"px");
						else 		
						maskMsgDiv.css("top", Math.round(scrollTop + element.height() / 2 - (maskMsgDiv.height() - parseInt(maskMsgDiv.css("padding-top")) - parseInt(maskMsgDiv.css("padding-bottom"))) / 2)+"px");
                        maskMsgDiv.css("left", Math.round(scrollLeft + element.width() / 2 - (maskMsgDiv.width() - parseInt(maskMsgDiv.css("padding-left")) - parseInt(maskMsgDiv.css("padding-right"))) / 2)+"px");
                        
                        maskMsgDiv.show();
                }
                
        };
        
        $.unmaskElement = function(element){
                //if this element has delayed mask scheduled then remove it
                if (element.data("_mask_timeout") !== undefined) {
                        clearTimeout(element.data("_mask_timeout"));
                        element.removeData("_mask_timeout");
                }
                
                element.find(".loadmask-msg,.loadmask").remove();
                element.removeClass("masked");
                element.removeClass("masked-relative");
                element.find("select").removeClass("masked-hidden");
        };
 
})(jQuery);
