VirtualWindow = Class.create();
VirtualWindow.prototype = {
    initialize: function(options) {
        if(!document.createElement || !document.childNodes) {
           //browser is not DOM compliant
           return;//alert('Uw browser wordt niet ondersteund door deze applicatie.');
        }

        //set the options
        if(this.setOptions)
        {
          this.setOptions(options);
        }
        else
        {
          this.options = options || {};
        }

        //check for each option if a value has been given as param. If not, set the default value
        this.options.width          = this.options.width || 200;
        this.options.height         = this.options.height || 150;
        this.options.sizeUnit       = this.options.sizeUnit || 'px';
        this.options.title          = this.options.title || 'Venster';
        this.options.titleBar       = (this.options.titleBar == false ? false : true);
        this.options.closeButton    = (this.options.closeButton == false ? false : true);
        this.options.cssNamespace   = this.options.cssNamespace || 'VWindow';
        this.options.effect         = (this.options.effect == false ? false : true);
        this.options.draggable      = (this.options.draggable == false ? false : true);
        this.options.id             = (this.options.id == 0 ? this._getRandomID() : this.options.id);
        this.options.randomIdChars  = this.options.randomIdChars || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz';
        this.options.randomIdLength = this.options.randomIdLength || 8;
        this.options.imgDir         = this.options.imgDir || '/';
        this.options.closeImg       = this.options.closeImg || 'button_close.gif';
        this.options.show           = (this.options.show == false ? false : true);
        this.options.background     = (this.options.background == true ? true : false);
        this.options.shadow         = (this.options.shadow == false ? false : true);

        //ensure the id of the window is unique. This prevents rendering problems
        while(this.options.id == $(this.options.id)){this.options.id = this._getRandomID();}

        //ensure the window fits in the current window
        while(this.options.width >= screen.width){this.options.width = this.options.width-10;}
        //set the margings for the vertical and horizental centering of the window
        if(screen.height <= 768)
        {
            this.marginLeft = Math.round(this.options.width / 2);
            this.marginTop = Math.round(this.options.height / 3);
        }   else    {
                this.marginLeft = Math.round(this.options.width / 2);
                this.marginTop = Math.round(this.options.height / 2);
        }

        //options are initialized, now create the window
        this._create();

        //don't show if asked
        if(this.options.show)
        {
            this._show();
        }
    },

    //generate a random id string
    _getRandomID: function()
    {
        this.randomID = '';
        for (var i=0; i < this.options.randomIdLength; i++) {
            var rnum = Math.floor(Math.random() * this.options.randomIdChars.length);
        	this.randomID += this.options.randomIdChars.substring(rnum,rnum+1);
        }

        return this.randomID;
    },

    getId: function()
    {
        return this.options.id;
    },

    //wrapper method for creating the elements
    _create: function()
    {
        //hide flash if there is flash content on the page
        this._hideSelectBoxes();
        this._hideFlash();
        
        //apply the shadow division if configured
        if(this.options.shadow)
        {
            this._createShadowDiv();
        }

        this._createContainerDiv();
        //only create the titlebar if configured
        if(this.options.titleBar)
        {
            this._createTitlebar();
        }
        //create the content container
        this._createContentContainer();

        //create the background if it is configured
        if(this.options.background !=false)
        {
            this._createBackground();
        }

        //make the element draggable if configured
        if(this.options.draggable != false)
        {
            //if the titleBar is created then only make the title bar as a handle for the dragging
            if(this.options.titleBar)
            {
                new Draggable(this.options.id+(this.options.shadow ? '_shadow' : ''), {handle:this.options.id+'_'+this.options.cssNamespace+'_top'});

                $(this.options.id+'_'+this.options.cssNamespace+'_top').style.cursor = 'move';
            }
            else
            {
                new Draggable(this.options.id+(this.options.shadow ? '_shadow' : ''));
                $(this.options.id).style.cursor = 'move';
            }
        }
    },

    _createShadowDiv: function()
    {
        //try to create the element with html for IE
        try
        {
            //IE hack
            element = document.createElement('<div id="'+this.options.id+'_shadow" class="'+this.options.cssNamespace+'_shadow" style="display:none;">');
        }
        catch(err)
        {
            element = document.createElement('div');
            element.setAttribute('id', this.options.id+'_shadow');
            element.setAttribute('class', this.options.cssNamespace+'_shadow');
            //the display to none has to be set as an attribute, else IE will not render it good
            element.setAttribute('style', 'display:none;');
        }

        //set some styles in the DOM for rendering the window container
        element.style.position  = 'absolute';
        element.style.top       = '50%';
        element.style.left      = '50%';
        element.style.zIndex    = '1000';
        element.style.width     = this.options.width+this.options.sizeUnit;
        element.style.height    = this.options.height+this.options.sizeUnit;
        element.style.margin    = '-'+this.marginTop+this.options.sizeUnit+' 0 0 -'+this.marginLeft+this.options.sizeUnit;
        //IE cannot assign the !important operator, so don't do it
        if(this._getBrowserName() == 'Microsoft Internet Explorer')
        {
            element.style.background = 'url(/images/scriptaculous/shadow-alpha.png) no-repeat bottom right';
        }
        else
        {
            element.style.background = 'url(/images/scriptaculous/shadow-alpha.png) no-repeat bottom right !important';
        }

        //element.style.background = 'url(/images/scriptaculous/shadow.gif) no-repeat bottom right';

        //append the element to the last child of the document body element
        document.body.appendChild(element);
    },

    _createContainerDiv: function()
    {
        //try to create the element with html for IE
        try
        {
            //IE hack
            element = document.createElement('<div id="'+this.options.id+'" class="'+this.options.cssNamespace+'" style="display:none;">');
        }
        catch(err)
        {
            element = document.createElement('div');
            element.setAttribute('id', this.options.id);
            element.setAttribute('class', this.options.cssNamespace);
            //the display to none has to be set as an attribute, else IE will not render it good
            element.setAttribute('style', 'display:none;');
        }

        //set some styles in the DOM for rendering the window container
        if(this.options.shadow)
        {
            element.style.position  = 'relative';
        }
        else
        {
            element.style.position  = 'absolute';
            element.style.top       = '50%';
            element.style.left      = '50%';
        }

        element.style.zIndex    = '1000';
        element.style.backgroundColor = 'white';
        element.style.width     = this.options.width+this.options.sizeUnit;
        element.style.height    = this.options.height+this.options.sizeUnit;


        if(this.options.shadow)
        {

            if(this._getBrowserName() != 'Microsoft Internet Explorer')
            {
                element.style.margin    = '-8px 0 0 -8px'
            }
            //set different margins for IE
            else
            {
                element.style.margin    = '-6px 0 0 -6px';
            }
        }
        else
        {
            element.style.margin    = '-'+this.marginTop+this.options.sizeUnit+' 0 0 -'+this.marginLeft+this.options.sizeUnit;
        }

        //apply as a child if the shadow is configured
        if(this.options.shadow)
        {
            $(this.options.id+'_shadow').appendChild(element);
        }
        else
        {
            //append the element to the last child of the document body element
            document.body.appendChild(element);
        }
    },

    _createTitlebar: function()
    {
        //try to create the element with html for IE
        try
        {
            //IE hack
            element = document.createElement('<div id="'+this.options.id+'_'+this.options.cssNamespace+'_top" class="'+this.options.cssNamespace+'_top" style="display:none;text-align:left;">');
        }
        catch(err)
        {
            element = document.createElement('div');
            element.setAttribute('id', this.options.id+'_'+this.options.cssNamespace+'_top');
            element.setAttribute('class', this.options.cssNamespace+'_top');
            //the display to none has to be set as an attribute, else IE will not render it good
            element.setAttribute('style', 'display:none;');
        }

        //set the font weight of the titlebar text
        element.style.fontWeight = 'bold';
        //set the width and height
        element.style.width      = '100%';
        element.style.height     = '20px';
        element.style.padding    = '0px';
        element.style.textAlign  = 'left';
        if(this.options.closeButton)
        {
            //append the html to the element
            element.innerHTML = '<a style="cursor:pointer;" title="Close this window" id="'+this.options.id+'_closeBtn"><img class="'+this.options.cssNamespace+'_button_close" src="'+this.options.imgDir+this.options.closeImg+'" alt="Close" /></a><a name="'+this.options.id+'"></a><span class="'+this.options.cssNamespace+'_top_titlebar">'+this.options.title+'</span>';
        }
        else
        {
            element.innerHTML = '<a name="'+this.options.id+'"></a><span class="'+this.options.cssNamespace+'_top_titlebar">'+this.options.title+'</span>';
        }

        //append this element to the parent window element
        $(this.options.id).appendChild(element);
        
        //add the event to the close button
        if(this.options.closeButton)
        {
            Event.observe(this.options.id+'_closeBtn', 'click', this.close.bindAsEventListener(this));
        }
    },

    _createContentContainer: function()
    {
        //try to create the element with html for IE
        try
        {
            //IE hack
            element = document.createElement('<div id="'+this.options.id+'_'+this.options.cssNamespace+'_content" class="'+this.options.cssNamespace+'_content">');
        }
        catch(err)
        {
            element = document.createElement('div');
            element.setAttribute('class', this.options.cssNamespace+'_content');
            element.setAttribute('id', this.options.id+'_'+this.options.cssNamespace+'_content');
        }

        element.style.textAlign = 'left';
        $(this.options.id).appendChild(element);

        //scroll the window back to the top
        window.scrollTo(0,0);
    },

    _createBackground:   function()
    {
        //try the IE hack first
        try {
            var Overlay = document.createElement('<div id="'+this.options.id+'_'+this.options.cssNamespace+'_background" style="display:none;"></div>');
        }
        catch(err)
        {
            var Overlay = document.createElement('div');
                Overlay.setAttribute('id', this.options.id+'_'+this.options.cssNamespace+'_background');
                Overlay.setAttribute('style', 'display:none;');
        }

        //set some styles that are needed to show the background.
        Overlay.style.position          = 'absolute';
        Overlay.style.top               = '0%';
        Overlay.style.left              = '0%';
        Overlay.style.zIndex            = '999';
        Overlay.style.backgroundColor   = 'black';
        //do not use percentages because IE 6 cant handle them.
        CurrentPageSize                 = this._getPageSize();
        Overlay.style.height            = CurrentPageSize[1]+'px';
        Overlay.style.width             = CurrentPageSize[0]+'px';
        Overlay.style.margin            = '0px';
        Overlay.style.padding           = '0px';


        //append the element as the last child of the body element to the DOM
        document.body.appendChild(Overlay);
    },

    //function to display the created elements
    _show: function()
    {
        if(this.options.effect)
        {
            //appear with effect
            if(this.options.shadow)
            {
                new Effect.Appear(this.options.id+'_shadow', {from:0.0, to:1.0});
            }

            new Effect.Appear(this.options.id, {from:0.0, to:1.0});

            if(this.options.titleBar)
            {
                new Effect.Appear(this.options.id+'_'+this.options.cssNamespace+'_top', {from:0.0, to:1.0});
            }

            if(this.options.background !=false)
            {
                new Effect.Appear(this.options.id+'_'+this.options.cssNamespace+'_background', {from:0.0, to:0.6});
            }
        }
        else
        {
            //appear without effect
            if(this.options.shadow)
            {
                $(this.options.id+'_shadow').show();
            }
            $(this.options.id).show();
            if(this.options.titleBar)
            {
                $(this.options.id+'_'+this.options.cssNamespace+'_top').show();
            }

            if(this.options.background !=false)
            {
                new Element.setOpacity(this.options.id+'_'+this.options.cssNamespace+'_background', 0.6);
                $(this.options.id+'_'+this.options.cssNamespace+'_background').show();
            }
        }
    },

    //function to set an html string or object collection or just some text in the content element
    setContent: function(content)
    {
        //if the content is an html object then append it
        if(typeof(content) == 'object')
        {
            $(this.options.id+'_'+this.options.cssNamespace+'_content').appendChild(content);
        }
        else
        {
            //set some html or text to the content division of the window
            $(this.options.id+'_'+this.options.cssNamespace+'_content').innerHTML = content;
        }
    },


    //function to get the value of a specific option
    getOptionValue: function(option)
    {
        //return the value of an option
        return this.options[option];
    },

    //function to close the window
    close: function()
    {
        if(this.options.effect)
        {
            new Effect.Fade(this.options.id+(this.options.shadow ? '_shadow' : ''));
            setTimeout('document.body.removeChild($(\''+this.options.id+(this.options.shadow ? '_shadow' : '')+'\'));', 1500);
        }
        else
        {
            document.body.removeChild($(this.options.id+(this.options.shadow ? '_shadow' : '')));
        }
        if(this.options.background !=false)
        {
            if(this.options.effect)
            {
                new Effect.Fade(this.options.id+'_'+this.options.cssNamespace+'_background');
                setTimeout('document.body.removeChild($(\''+this.options.id+'_'+this.options.cssNamespace+'_background\'));', 1500);
            }
            else
            {
                document.body.removeChild($(this.options.id+'_'+this.options.cssNamespace+'_background'));
            }
        }
        this._showSelectBoxes();
        this._showFlash();
    },

    getCloseScript: function()
    {
        //create the js string for closing the window
        if(this.options.effect)
        {
            jsClose = 'new Effect.Fade(\''+this.options.id+(this.options.shadow ? '_shadow' : '')+'\');setTimeout(\'document.body.removeChild($(\\\''+this.options.id+(this.options.shadow ? '_shadow' : '')+'\\\'));\', 1500);';
        }
        else
        {
            jsClose = 'document.body.removeChild($(\''+this.options.id+(this.options.shadow ? '_shadow' : '')+'\'));';
        }
        if(this.options.background != false)
        {
            if(this.options.effect)
            {
                jsClose = jsClose+'new Effect.Fade(\''+this.options.id+'_'+this.options.cssNamespace+'_background\');setTimeout(\'document.body.removeChild($(\\\''+this.options.id+'_'+this.options.cssNamespace+'_background\\\'));\', 1500);';

            }
            else
            {
                jsClose = jsClose+'document.body.removeChild($(\''+this.options.id+'_'+this.options.cssNamespace+'_background\'));';
            }
        }
        return jsClose;
    },

    _getBrowserName: function()
    {
        return navigator.appName;
    },
    
    _showSelectBoxes: function()
    {
    	selects = document.getElementsByTagName("select");
    	for (i = 0; i != selects.length; i++) {
    		selects[i].style.visibility = "visible";
    	}
    },

    _hideSelectBoxes: function()
    {
    	selects = document.getElementsByTagName("select");
    	for (i = 0; i != selects.length; i++) {
    		selects[i].style.visibility = "hidden";
    	}
    },

    _showFlash: function()
    {
    	flashObjects = document.getElementsByTagName("object");
    	for (i = 0; i < flashObjects.length; i++) {
    		flashObjects[i].style.visibility = "visible";
    	}

    	flashEmbeds = document.getElementsByTagName("embed");
    	for (i = 0; i < flashEmbeds.length; i++) {
    		flashEmbeds[i].style.visibility = "visible";
    	}
    },

    _hideFlash: function()
    {
    	flashObjects = document.getElementsByTagName("object");
    	for (i = 0; i < flashObjects.length; i++) {
    		flashObjects[i].style.visibility = "hidden";
    	}

    	flashEmbeds = document.getElementsByTagName("embed");
    	for (i = 0; i < flashEmbeds.length; i++) {
    		flashEmbeds[i].style.visibility = "hidden";
    	}
    },
    
    _getPageSize: function()
    {
        xScroll = null;
    	yScroll = null;
    	
    	if (window.innerHeight && window.scrollMaxY) {	
    		xScroll = window.innerWidth + window.scrollMaxX;
    		yScroll = window.innerHeight + window.scrollMaxY;
    	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
    		xScroll = document.body.scrollWidth;
    		yScroll = document.body.scrollHeight;
    	} else {
    		xScroll = document.body.offsetWidth;
    		yScroll = document.body.offsetHeight;
    	}
    	
    	windowWidth = null;
        windowHeight = null;
    	if (self.innerHeight) {	// all except Explorer
    		if(document.documentElement.clientWidth){
    			windowWidth = document.documentElement.clientWidth; 
    		} else {
    			windowWidth = self.innerWidth;
    		}
    		windowHeight = self.innerHeight;
    	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
    		windowWidth = document.documentElement.clientWidth;
    		windowHeight = document.documentElement.clientHeight;
    	} else if (document.body) { // other Explorers
    		windowWidth = document.body.clientWidth;
    		windowHeight = document.body.clientHeight;
    	}	
    	
    	if(yScroll < windowHeight){
    		pageHeight = windowHeight;
    	} else { 
    		pageHeight = yScroll;
    	}
    	if(xScroll < windowWidth){	
    		pageWidth = xScroll;		
    	} else {
    		pageWidth = windowWidth;
    	}

    	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
    	return arrayPageSize;
    }
};