/*******************************************************************************
 *
 * CloudFlare UI Dashboard Module
 *
 * TODO: Build a subclassable or otherwise manipulable abstract dashboard module
 *  - we shouldn't be specifying a skin-oriented structure in here, but we are.
 * 
 ******************************************************************************/

(function($) {
    
    $.widget('ui.dashboardModule', {
        
        options: {
            
            width: 320,
            height: 240,
            title: "Untitled Module",
            loading: false
            
        },
        
        _internalSettings: {
            
            selfClasses: 'cf-ui dashboard-module',
            innerStub: '<div class="head"><div class="title"></div></div><div class="overlay"><div class="background scale9"><div class="top"><div class="left"></div><div class="middle"></div><div class="right"></div></div><div class="center"><div class="left"></div><div class="middle"></div><div class="right"></div></div><div class="bottom"><div class="left"></div><div class="middle"></div><div class="right"></div></div><img src="/images/ui/module/module-background-center.png" width="100%" height="100%" /></div></div><div class="content"><div class="background scale9"><div class="top"><div class="left"></div><div class="middle"></div><div class="right"></div></div><div class="center"><div class="left"></div><div class="middle"></div><div class="right"></div></div><div class="bottom"><div class="left"></div><div class="middle"></div><div class="right"></div></div><img src="/images/ui/module/module-content-background-center.png" width="100%" height="100%" /></div><div class="body"></div></div><div class="background scale9"><div class="top"><div class="left"></div><div class="middle"></div><div class="right"></div></div><div class="center"><div class="left"></div><div class="middle"></div><div class="right"></div></div><div class="bottom"><div class="left"></div><div class="middle"></div><div class="right"></div></div><img src="/images/ui/module/module-background-center.png" width="100%" height="100%" /></div>'
            
        },
        
        _create: function() {
            
            var self = this;
            
            if(self.element.is('div')) {
                
                if(self.element.children().length == 0) {
                    
                    self.moduleContents = self.element.text();
                    
                } else {
                    
                    self.moduleContents = self.element.children();
                    self.moduleContents.detach();
                    
                }
                
                self.element.empty();
                
                self.element.append($(self._internalSettings.innerStub));
                self.element.addClass(self._internalSettings.selfClasses);
                
                self.moduleLoadingOverlay = self.element.find('div.overlay');
                self.moduleLoadingOverlayAttached = true;
                self.moduleLoadingFlashContainerID = 'DashboardLoader-' + self.options.title.replace(/ /g, '_') + '-' + (new Date()).getTime();
                
                self._detachLoadingOverlay();
                
                self.element.find('div.head div.title').text(self.options.title);
                self.element.find('div.content div.body').append(self.moduleContents);
                
                self._invalidateDimensions(true);
                self._invalidateLoading(true);
                
                
            } else {
                
                self.destroy();
                
            }
            
        },
        
        _setOption: function(key, value) {
            
            $.Widget.prototype._setOption.apply(this, arguments);
            
            var self = this;
            
            self._invalidateDimensions();
            self._invalidateLoading();
            
        },
        
        _invalidateDimensions: function(instant) {
            
            var self = this;
            
            instant = instant || ($.browser.msie && parseInt($.browser.version.substr(0, 1)) < 8 && parseInt($.browser.version.substr(0, 1)) > 5);
            
            if(instant) {
                
                self.element.css(
                    {
                        width: self.options.width < 200 ? 200 : (self.options.width + 'px'),
                        height: self.options.height < 150 ? 150 : (self.options.height + 'px')
                    }
                );
                
                if($.browser.msie && parseInt($.browser.version.substr(0, 1)) <= 7 && parseInt($.browser.version.substr(0, 1)) >= 6) {
                    
                    self.element.find('div.body').width(self.element.find('div.body').width());
                    self.element.find('div.body').height(self.element.find('div.body').height());
                    
                }
                
            } else {
                
                self.element.stop(false).animate(
                    {
                        width: self.options.width < 200 ? 200 : (self.options.width + 'px'),
                        height: self.options.height < 150 ? 150 : (self.options.height + 'px')
                    },
                    700,
                    "swing"
                );
                
            }
            
        },
        
        _attachLoadingOverlay: function() {
            
            var self = this;
            
            if(!self.moduleLoadingOverlayAttached) {
                
                self.moduleLoadingOverlay.append($('<div id="' + self.moduleLoadingFlashContainerID + '"></div>'));
                        
                self.element.prepend(self.moduleLoadingOverlay);
                
                $('#' + self.moduleLoadingFlashContainerID).embedFlash(
                    {
                        source: '/flash/cloudflare.loader.swf', 
                        width: 138, 
                        height: 62, 
                        cssClass: 'flashLoader', 
                        params: {
                            wmode: "transparent"
                        }
                    }
                );
                
                self.moduleLoadingOverlayAttached = true;
                
                self.element.addClass('loading');
                
            }
            
        },
        
        _detachLoadingOverlay: function() {
            
            var self = this;
            
            if(self.moduleLoadingOverlayAttached) {
                
                swfobject.removeSWF(self.moduleLoadingFlashContainerID);
                $('div#' + self.moduleLoadingFlashContainerID).remove();
                
                self.moduleLoadingOverlay.stop().hide().detach();
                
                self.moduleLoadingOverlayAttached = false;
                
                self.element.removeClass('loading');
                
            }
            
        },
        
        _invalidateLoading: function(instant) {
            
            var self = this;
            
            if(self.options.loading) {
                
                self._attachLoadingOverlay();
                
                if(instant) {
                    
                    self.moduleLoadingOverlay.show();
                    
                } else {
                    
                    self.moduleLoadingOverlay.fadeIn(700);
                    
                }
                
            } else {
                
                if(instant) {
                    
                    self._detachLoadingOverlay();
                    
                } else {
                    
                    self.moduleLoadingOverlay.fadeOut(
                        700, 
                        function() {
                            
                            self._detachLoadingOverlay();
                            
                        }
                    );
                    
                }
                
            }
                        
        },
        
        destroy: function() {
            
            
            
        }
        
        
    });


/*******************************************************************************
 *
 * CloudFlare UI Dashboard
 * 
 ******************************************************************************/


    $.widget('ui.dashboard', {
        
        options: {
            
            cellWidth: 320,
            cellHeight: 240,
            sortable: false
            
        },
        
        _internalSettings: {
            
            selfClasses: 'cf-ui dashboard',
            placeholderClasses: '',
            outerStub: '<div></div>'
            
        },
        
        _create: function() {
            
            var self = this;
            
            if(self.element.is('ul')) {
                
                self.element.wrap('<div></div>');
                self.dashboard = self.element.parent();
                
            } else {
                
                self.dashboard = self.element;
                
            }
            
            if(self.dashboard.children('ul').length == 0) {
                
                self.dashboard.prepend('<ul></ul>');
                
            }
            
            self.dashboard.addClass(self._internalSettings.selfClasses);
            
            self.sortable = self.dashboard.children().first();
            self.sortableInstantiated = false;
            
            self.sortable.children('li').addClass(self._moduleContainerClasses());
            
            self.invalidate();
            
            
        },
        
        _invalidateSortable: function() {
            
            var self = this;
            
            if(self.options.sortable && self.sortable && !self.sortableInstantiated) {
                
                self.sortable.sortable(
                    {
                        
                        placeholder: self._modulePlaceholderClasses(),
                        tolerance: 'pointer',
                        forceHelperSize: true,
                        forcePlaceholderSize: true,
                        revert: 200,
                        helper: function(event, element) {
                            
                            return element.clone().css('opacity', 0.5);
                            
                        }
                    }
                );
                
                self.sortableInstantiated = true;
                
            } else if(!self.options.sortable && self.sortable && self.sortableInstantiated) {
                
                self.sortable.sortable('destroy');
                
                self.sortableInstantiated = false;
                
            }
            
        },
        
        _invalidateMeasurements: function() {
            
            var self = this;
            
            self.sortable.children('li.module').css(
                {
                    
                    width: self._moduleContainerWidth() + 'px',
                    height: self._moduleContainerHeight() + 'px'
                    
                }
            );
            
            self.dashboard.css(
                {
                    
                    width: self._dashboardWidth() + 'px',
                    height: self._dashboardHeight() + 'px'
                    
                }
            );
            
        },
        
        _moduleContainerClasses: function() {
            
            return 'module';
            
        },
        
        _modulePlaceholderClasses: function() {
            
            var self = this;
            
            return self._moduleContainerClasses() + ' placeholder';
            
        },
        
        _dashboardWidth: function() {
            
            var self = this;
            
            return self.dashboard.parent().width() - (self.dashboard.outerWidth() - self.dashboard.width());
            
        },
        
        _dashboardHeight: function() {
            
            var self = this;
            
            return Math.ceil(self.sortable.children('li.module').length / Math.floor(self._dashboardWidth() / (self._moduleMeasuredWidth()))) * self._moduleMeasuredHeight();
            
        },
        
        _moduleContainerWidth: function() {
            
            var self = this;
            
            if(self.sortable.children('li.module').length > 0) {
                
                var module = self.sortable.children('li.module').first();
                var marginLeft = module.css('marginLeft');
                var marginRight = module.css('marginLeft');
                var marginOffset = parseInt(marginLeft.substr(0, marginLeft.length - 2)) + parseInt(marginRight.substr(0, marginRight.length - 2));
                
                return self.options.cellWidth - marginOffset;
                
            } else {
                
                return 0;
                
            }
            
        },
        
        _moduleContainerHeight: function() {
            
            var self = this;
            
            if(self.sortable.children('li.module').length > 0) {
                
                var module = self.sortable.children('li.module').first();
                var marginTop = module.css('marginTop');
                var marginBottom = module.css('marginBottom');
                var marginOffset = parseInt(marginTop.substr(0, marginTop.length - 2)) + parseInt(marginBottom.substr(0, marginBottom.length - 2));
                
                return self.options.cellHeight - marginOffset;
                
            } else {
                
                return 0;
                
            }
            
        },
        
        _moduleMeasuredWidth: function() {
            
            var self = this;
            
            if(self.sortable.children('li.module').length > 0) {
                
                var module = self.sortable.children('li.module').first();
                var marginLeft = module.css('marginLeft');
                var marginRight = module.css('marginLeft');
                var marginOffset = parseInt(marginLeft.substr(0, marginLeft.length - 2)) + parseInt(marginRight.substr(0, marginRight.length - 2));
                
                return module.outerWidth() + marginOffset;
                
            } else {
                
                return 0;
                
            }
        
        },
        
        _moduleMeasuredHeight: function() {
            
            var self = this;
            
            if(self.sortable.children('li.module').length > 0) {
                
                var module = self.sortable.children('li.module').first();
                var marginTop = module.css('marginTop');
                var marginBottom = module.css('marginBottom');
                var marginOffset = parseInt(marginTop.substr(0, marginTop.length - 2)) + parseInt(marginBottom.substr(0, marginBottom.length - 2));
                
                return module.outerHeight() + marginOffset;
                
            } else {
                
                return 0;
                
            }
            
        },
        
        invalidate: function() {
            
            var self = this;
            
            self._invalidateSortable();
            self._invalidateMeasurements();
            
        },
        
        addModule: function(moduleContent) {
            
            var self = this;
            
            var listItem = $('<li></li>');
            console.log('add');
            listItem.prepend(moduleContent);
            listItem.addClass(self._moduleContainerClasses());
            
            self.sortable.append(listItem);
            
            self._invalidateMeasurements();
            
        },
        
        destroy: function() {
            
            
            
        }
    
    });
    
/*******************************************************************************
 *
 * CloudFlare UI Generic Dashboard
 * 
 ******************************************************************************/

    $.widget('ui.genericDashboard', $.ui.dashboard, {
        
        _create: function() {
            
            $.ui.dashboard.prototype._create.apply(this, arguments);
            
            var self = this;
            
            self.dashboard.addClass('generic cf-ui-corner-all-six');
            
            self.invalidate();
            
        },
        
        _moduleContainerClasses: function() {
            
            return 'generic cf-ui-corner-all-four ' + $.ui.dashboard.prototype._moduleContainerClasses.apply(this, arguments);
            
        },
        
    });

})(jQuery)