// Declare a single namespace in the global scope)
var QB;
if (!QB) QB = {};
else if (typeof(QB) != 'object')
	throw new Error('Der findes allerede en global variabel ved navn \'QB\', som ikke er et object');

QB.Background = 
{
    // Constants
    TableID: 'QB_Background',

    Timer: null,
    
    // Parameters
    CellWidth: 34,
    CellHeight: 17,
    ColorVariety: 20,
    Move: false,
    ShadowObject: null,
    Suspend: null,
    
    Initialize: function(/*optional*/init_object)
    {
        /* Type of init_object
        init_object = 
        {
            min_width: 10,
            max_width: 100,
            fixed_width: 50,
            min_height: 10,
            max_height: 50,
            fixed_height: 25,
            color_variety: 30,
            move: true,
            shadow_object_id: 'divMain',
            suspend_if: '(a == 2)'
        };*/
        
        if (init_object)
        {
            if (typeof(init_object.fixed_width) == 'number')
                this.CellWidth = init_object.fixed_width;
            else if (init_object.min_width && init_object.max_width)
                this.CellWidth = Math.floor(Math.abs(Math.random() * (init_object.max_width - init_object.min_width)) + Math.abs(init_object.min_width));
                
            if (typeof(init_object.fixed_height) == 'number')
                this.CellHeight = init_object.fixed_height;
            else if (init_object.min_height && init_object.max_height)
                this.CellHeight = Math.floor(Math.abs(Math.random() * (init_object.max_height - init_object.min_height)) + Math.abs(init_object.min_height));
        
            if (this.CellWidth < 2) this.CellWidth = 2;
            if (this.CellHeight < 2) this.CellHeight = 2;
            
            if (typeof(init_object.color_variety) == 'number')
                this.ColorVariety = init_object.color_variety;
                
            if (typeof(init_object.move) == 'boolean')
                this.Move = init_object.move;
                
            if (typeof(init_object.shadow_object_id) == 'string')
                this.ShadowObject = init_object.shadow_object_id;
                
            if (typeof(init_object.suspend_if) == 'string')
                this.Suspend = init_object.suspend_if;
        }
        
        this.Timer = setInterval(this.Start, 100);
    },
    
    Start: function()
    {
        var head = document.getElementsByTagName('head')[0];
        if (head == null) return;
        var body = document.getElementsByTagName('body')[0];
        if (body == null) return;

        clearInterval(QB.Background.Timer);
        
        // Get object to shadow if present
        if (QB.Background.ShadowObject != null)
            QB.Background.ShadowObject = document.getElementById(QB.Background.ShadowObject);

        QB.Background.AppendStyle();
        QB.Background.AppendElement();
        QB.Background.ReplaceElement();
        QB.Background.AttachEvents();
    },
    
    AppendStyle: function()
    {
        var color = (240 - this.ColorVariety).toString(16);
        var sty;
        
        // Create style
        if (document.createStyleSheet)  // IE version
        {
            sty = document.createStyleSheet();
            sty.addRule('body', 'overflow-x:hidden');

            sty.addRule('#' + this.TableID + '_Shadow', 'position:absolute');
            sty.addRule('#' + this.TableID + '_Shadow', 'z-index:-100000');
            sty.addRule('#' + this.TableID + '_Shadow', 'background-color:#000000');
            sty.addRule('#' + this.TableID + '_Shadow', 'filter:alpha(opacity:20)');

            sty.addRule('#' + this.TableID, 'position:absolute');
            sty.addRule('#' + this.TableID, 'z-index:-1000000');
            sty.addRule('#' + this.TableID, 'border-collapse:collapse');
            sty.addRule('#' + this.TableID, 'border:solid 1px #' + color + color + color);
            
            sty.addRule('#' + this.TableID + ' td', 'width:' + this.CellWidth.toString() + 'px');
            sty.addRule('#' + this.TableID + ' td', 'height:' + this.CellHeight.toString() + 'px');
            sty.addRule('#' + this.TableID + ' td', 'line-height:2px');
            sty.addRule('#' + this.TableID + ' td', 'border:solid 1px #' + color + color + color);
        }
        else    // Mozilla version
        {
            var head = document.getElementsByTagName('head')[0];
            sty = document.createElement('style');
            sty.setAttribute('type', 'text/css');
            var s = '#' + this.TableID + '_Shadow{\n' + 
                        'position:absolute;\n' + 
                        'background-color:#000000;\n' + 
                        'z-index:-100000;\n' + 
                        'opacity:0.20;\n' + 
                        '-moz-opacity:0.20;\n' + 
                    '}\n' + 
                    '#' + this.TableID + '{\n' + 
                        'position:fixed;\n' + 
                        'z-index:-1000000;\n' + 
                        'border-collapse:collapse;\n' + 
                    '}\n' + 
                    '#' + this.TableID + ' td{\n' + 
                        'width:' + this.CellWidth.toString() + 'px;\n' + 
                        'height:' + this.CellHeight.toString() + 'px;\n' + 
                        'line-height:2px;\n' + 
                        'border:solid 1px #' + color + color + color + ';\n' + 
                    '}\n';
		    sty.appendChild(document.createTextNode(s));
		    head.appendChild(sty);
		}
    },
    
    AppendElement: function()
    {
        var tbl = document.createElement('div');
        tbl.id = this.TableID;
        document.getElementsByTagName('body')[0].appendChild(tbl);
        
        // Create shadow object
        if (this.ShadowObject != null)
        {
            var pos = QB.Object.GetPosition(this.ShadowObject);
            var size = QB.Object.GetSize(this.ShadowObject);
            var shadow = document.createElement('div');
            shadow.id = this.TableID + '_Shadow';
            document.getElementsByTagName('body')[0].appendChild(shadow);
        }
    },
    
    ReplaceElement: function()
    {
        var window_size = QB.Window.GetSize();
        var tbl = document.createElement('table');
        tbl.id = this.TableID;
        tbl.setAttribute('cellspacing', '0');
        tbl.setAttribute('cellspadding', '0');
        tbl.setAttribute('border', '1');
        tbl.style['top'] = '0px';
        tbl.style['left'] = '0px';
        tbl.style['width'] = window_size[0] + QB.Background.CellWidth + 'px';
        var tbody = document.createElement('tbody');
        
        var num_rows = Math.ceil(parseInt(window_size[1]) / this.CellHeight + 1);
        var num_cols = Math.ceil(parseInt(window_size[0]) / this.CellWidth + 1);
        var tr, td, color;
        for (var n=0; n < num_rows; n++)
        {
            tr = document.createElement('tr');
            for (var m=0; m < num_cols; m++)
            {
                td = document.createElement('td');
                //td.innerHTML = '&nbsp';
                
                color = (Math.floor(Math.random() * this.ColorVariety + (252-this.ColorVariety))).toString(16);
                td.style['backgroundColor'] = '#' + color + color + color;
                
                tr.appendChild(td);
            }
            tbody.appendChild(tr);
        }
        tbl.appendChild(tbody);
        
        var elm = document.getElementById(this.TableID);
        document.getElementsByTagName('body')[0].replaceChild(tbl, elm);
    },
    
    AttachEvents: function()
    {
        QB.Object.AttachEvent(window, 'resize', this.Events.onResize);
        QB.Object.AttachEvent(window, 'scroll', this.Events.onMouseMove);
        if (this.Move)
            QB.Object.AttachEvent(document, 'mousemove', this.Events.onMouseMove);
    },
    
    Events:
    {
        ResizeTimer: null,
        onResize: function(evnt)
        {
            if (QB.Background.Events.ResizeTimer != null)
                clearTimeout(QB.Background.Events.ResizeTimer);
            
            var f = function()
            {
                // Clear timer
                QB.Background.Events.ResizeTimer = null;
                
                QB.Background.ReplaceElement();
            };
            // Don't resize immediately
            QB.Background.Events.ResizeTimer = setTimeout(f, 500);
        },
        
        onScroll: function(evnt)
        {
            var scFF = document.documentElement.scrollTop;
            var scIE = document.getElementsByTagName('body')[0].scrollTop;
            var scroll = 0;
            
            if (scFF > 0)
                scroll = scFF;
            else if (scIE > 0)
                scroll = scIE;
            
            var elm = document.getElementById(QB.Background.TableID);
            var window_size = QB.Window.GetSize();
            var step = window_size[0] / QB.Background.CellWidth;
            var offset = Math.floor(evnt.clientX / step);
            elm.style['left'] = -offset + 'px';
            
            step = window_size[1] / QB.Background.CellHeight;
            offset = Math.floor(evnt.clientY / step);
            elm.style['top'] = -offset + 'px';
            
            
            //alert(QB.Object.getDebugString(document.documentElement, null, 0, ['top', 'location', 'parent','outerText','innerText','outerHTML','innerHTML']));
            
        },
        
        onMouseMove: function(evnt)
        {
            if (QB.Background.Suspend != null && QB.Background.Move)
            {
                if (eval(QB.Background.Suspend))
                    return;
            }
            var scFFTop = document.documentElement.scrollTop;
            var scIETop = document.getElementsByTagName('body')[0].scrollTop;
            var scFFLeft = document.documentElement.scrollLeft;
            var scIELeft = document.getElementsByTagName('body')[0].scrollLeft;
            var scrollTop = 0, scrollLeft = 0;
            
            if (scFFTop > 0)
                ;//scrollTop = scFFTop;
            else if (scIETop > 0)
                scrollTop = scIETop;
            if (scFFLeft > 0)
                ;//scrollLeft = scFF;
            else if (scIELeft > 0)
                scrollLeft = scIELeft;
            
            
            var elm = document.getElementById(QB.Background.TableID);
            var window_size = QB.Window.GetSize();
            var step = window_size[0] / QB.Background.CellWidth;
            var offset = Math.floor(evnt.clientX / step);
            if (!QB.Background.Move) offset = 0;
            elm.style['left'] = scrollLeft-offset + 'px';
            
            step = window_size[1] / QB.Background.CellHeight;
            offset = Math.floor(evnt.clientY / step);
            if (!QB.Background.Move) offset = 0;
            elm.style['top'] = scrollTop-offset + 'px';
            //alert(QB.Object.getDebugString(evnt, null, 0, ['target']));

            // Replace shadow object first as it is the fastest
            if (QB.Background.ShadowObject != null)
            {
                var shadow = document.getElementById(QB.Background.TableID + '_Shadow');
                var pos = QB.Object.GetPosition(QB.Background.ShadowObject);
                var size = QB.Object.GetSize(QB.Background.ShadowObject);
                var middle = [pos[0] + size[0]/2, pos[1] + size[1]/2];
                
                offset = Math.floor((middle[0]-evnt.clientX)/(size[0]/20));
                shadow.style['left'] = (pos[0] + offset) + 'px';
                
                offset = Math.floor((middle[1]-evnt.clientY)/(size[1]/20));
                shadow.style['top'] = (pos[1] + offset) + 'px';
                
                shadow.style['width'] = (size[0]) + 'px';
                shadow.style['height'] = (size[1]) + 'px';
            }
        }
    }
};
