// 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');

// Window object. Can return size and position of the main window
QB.Window = 
{
    GetSize : function(/*optional frame/window*/frame)
    {
        if (arguments.length < 1) frame = window;
        var width=0, height=0;
        
        if (frame.frameElement != null)
            frame = frame.frameElement;
            
//alert(QB.Object.getDebugString(frame.document.documentElement, null, 0, ['outerHTML','innerHTML','top','location','parent']));

        if (typeof(frame.innerWidth) == 'number') 
	        width = frame.innerWidth;						//Non-IE
        else if (frame.document.documentElement && frame.document.documentElement.offsetWidth) 
	        width = frame.document.documentElement.offsetWidth;	//IE 7
        else if (frame.document.documentElement && frame.document.documentElement.clientWidth) 
	        width = frame.document.documentElement.clientWidth;	//IE 6+ in 'standards compliant mode'
        else if (document.body && document.body.clientWidth)
	        width = document.body.clientWidth;				//IE 4 compatible
    		
        if (typeof(frame.innerHeight) == 'number')
	        height = frame.innerHeight;						//Non-IE
        else if (frame.document.documentElement && frame.document.documentElement.offsetHeight)
	        height = frame.document.documentElement.offsetHeight;	    //IE 7
        else if (frame.document.documentElement && frame.document.documentElement.clientHeight)
	        height = frame.document.documentElement.clientHeight;	    //IE 6+ in 'standards compliant mode'
        else if (document.body && document.body.clientHeight)
	        height = document.body.clientHeight;				//IE 4 compatible

        return [width,height];
    },
    
    GetPosition : function(/*optional frame/window*/frame)
    {
        if (arguments.length < 1) frame = window;
        var left=0, top=0;
        
        if (typeof(frame.screenLeft) == 'number') 
        {
            // IE properties
            left = frame.screenLeft;
            top = frame.screenTop;
        }
        else if (typeof(frame.screenX) == 'number') 
        {
            // Firefox properties
            left = frame.screenX;
            top = frame.screenY;
        }    
        return [left,top];
    }
};

// "Object" object. Can return position, size and current style of an object. 
QB.Object = 
{
    AttachEvent: function(obj, str_event, f)
    {
        if (obj == null) return;
        
        // Don't attach more than once
        QB.Object.DetachEvent(obj, str_event, f);
        
        if (obj.attachEvent)
            obj.attachEvent('on' + str_event, f);
        else
            obj.addEventListener(str_event, f, false);
    },
    DetachEvent: function(obj, str_event, f)
    {
        if (obj == null) return;
        try
        {
            if (obj.detachEvent)
                obj.detachEvent('on' + str_event, f);
            else
                obj.removeEventListener(str_event, f, false);
        }
        catch(e)
        {
        }
        
    },
    
    GetPosition : function(obj)
    {
	    var curleft = curtop = 0;
	    if (obj && obj.offsetParent)
	    {
		    curleft = obj.offsetLeft
		    curtop = obj.offsetTop
		    while (obj = obj.offsetParent) 
		    {
			    curleft += obj.offsetLeft
			    curtop += obj.offsetTop
		    }
	    }
	    return [curleft,curtop];
    },
    GetSize : function(obj)
    {
	    var w=0, h=0;
	    if (typeof(obj) == 'object')
	    {
	        w = obj.offsetWidth;
	        h = obj.offsetHeight;
	    }
	    return [w,h];
    },
    GetStyle : function(obj, style_item)
    {
	    if (typeof(obj) != 'object') return null;
	        
        var s = null;
	    if (obj.currentStyle)
	        s = obj.currentStyle[style_item];
	    else if (window.getComputedStyle)
	        s = document.defaultView.getComputedStyle(obj, null)[style_item];

	    // Convert Firefox colors
	    if (s != null && s.indexOf('rgb') > -1)
	    {
	        s = s.replace('rgb', '').replace('(', '').replace(')', '');
	        var c = s.split(',');
	        s = '#';
	        for (var n = 0; n < c.length; n++)
	        {
	            c[n] = parseInt(c[n], 10).toString(16);
	            while (c[n].length < 2)
	                c[n] = '0' + c[n];
	            
	            s += c[n];
	        }
	    }
	    
	    return s;
    },

    // Internal debug helper
    getDebugString: function(obj, /*optional object*/parent, /*option int*/new_offset, /*optional array*/exclude_array)
    {
        var s = '';
        var offset = 0;
        var exclude;
        if (typeof(new_offset) == 'number') offset = new_offset + 1;
        
        for (var p in obj)
        {
            if (p.toString().toLowerCase().substring(0,2) == 'on')
                continue;
            exclude = false;
            if (exclude_array instanceof Array)
            {
                for (var n = 0; n < exclude_array.length; n++)
                {
                    if (p.toString().toLowerCase() == exclude_array[n].toString().toLowerCase())
                    {
                        exclude = true;
                        break;
                    }
                }
            }
            if (exclude) continue;
            
            try
            {
                for (var n = 0; n < offset; n++)
                    s += '    ';
                s += p.toString() + ': ';
                if (obj[p] == null)
                    s += 'null';
                else if (typeof (obj[p]) == 'string')
                    s += '\'' + obj[p] + '\'';
                else if (typeof (obj[p]) == 'function')
                    s += obj[p].toString();
                else if (obj[p] instanceof Array)
                    s += '[' + obj[p].join() + ']';
                else if (obj[p] instanceof Date)
                    s += obj[p].toDateString();
                else if (typeof (obj[p]) == 'object')
                {
                    if (offset > 0)
                        s += '{Object}';
                    else
                        s += '{\n' + QB.Object.getDebugString(obj[p], obj, offset, exclude_array) + '}';
                }
                else
                    s += obj[p].toString();
                s += '\n';
            }
            catch (e)
            {
                s += 'QB-error: ' + e + '\n';
            }
        }
        return s;
    }
};

QB.Event = 
{
    StopPropagation: function(evnt)
    {
        if (!evnt) return;

        // Remove focus from target element
        var that = (evnt.currentTarget ? evnt.currentTarget : evnt.srcElement);
        if (that != null)
            that.blur();

        evnt.cancelBubble = true;
        if (evnt.stopPropagation)
            evnt.stopPropagation();
    },
    
    GetElement: function(evnt, elm_type)
    {
        var elm = (evnt.target ? evnt.target : evnt.srcElement);
        while (elm && elm.tagName.toLowerCase() != elm_type)
            elm = elm.parentNode;
        return elm;    
    }
};


