Rtk.Shared.ObscureRenderedElements = function() {

    var HidableElements = $A();
    var HideShowStackCount = {};


    var Positioning = Rtk.Util.Positioning;

    function getHidableElementsInRegionOf(element)
    {
        var position = Positioning.GetPositionInDocument(element);

        var x = position.left;
        var y = position.top;
        var width = element.offsetWidth;
        var height = element.offsetHeight;

        return getHidableElementsInRegion(x,y,width,height);
    }

    function getHidableElementsInRegion(x,y,width,height)
    {
        var regional_hidable_elements = $A();

        for (var i = 0, len = HidableElements.length; i < len; ++i)
	    {
                var element = HidableElements[i];

                var dimensions = {};

                var position = Positioning.GetPositionInDocument(element);

                dimensions["x"] = position.left;
                dimensions["y"] = position.top;
                dimensions["width"] = element.offsetWidth;
                dimensions["height"] = element.offsetHeight;

	        if ( ((x + width) > dimensions["x"])
	             && ((y + height) > dimensions["y"])
	             && ((dimensions["x"] + dimensions["width"]) > x)
	             && ((dimensions["y"] + dimensions["height"]) > y))
                    {
                        regional_hidable_elements.push(element);
                    }
            }
        return regional_hidable_elements;
    }

    function getHidableElementsObscuredBy(element_id_or_region_key)
    {
        var obscured_elements = $A();

        for(hidable_element in HideShowStackCount)
        {
	    if (HideShowStackCount[hidable_element].indexOf(element_id_or_region_key) != -1)
	        obscured_elements.push($(hidable_element));
        }

      return obscured_elements;
    }

    return {
    	HideObscuredBy: function(element)
        {
	    if (!element)
	      return;

            var elements_to_hide = getHidableElementsInRegionOf(element);

            for (var i = 0, len = elements_to_hide.length; i < len; ++i)
                {
                    var hash_index = $(elements_to_hide[i]).identify();

                    if(HideShowStackCount[hash_index] == undefined)
  		        HideShowStackCount[hash_index] = $A();

		    if(HideShowStackCount[hash_index].indexOf(element.id) == -1)
                        HideShowStackCount[hash_index].push(element.id);

	    	    $(elements_to_hide[i]).style.visibility = "hidden";
                }
        },
        ShowObscuredBy: function(element)
        {
	    if (!element)
	        return;

            var elements_to_show = getHidableElementsObscuredBy(element.id);
            for (var i = 0, len = elements_to_show.length; i < len; ++i)
                {
                    var hash_index = $(elements_to_show[i]).identify();

                    if(HideShowStackCount[hash_index] == undefined)
                        HideShowStackCount[hash_index] = $A();

		    if(HideShowStackCount[hash_index].indexOf(element.id) != -1)
                        HideShowStackCount[hash_index] = HideShowStackCount[hash_index].without(element.id);

                    if (HideShowStackCount[hash_index].length == 0)
                        elements_to_show[i].style.visibility = "visible";
                }
        },
        HideInRegion: function(x,y,width,height,region_key)
        {
            var elements_to_hide = getHidableElementsInRegion(x,y,width,height);
            for (var i = 0, len = elements_to_hide.length; i < len; ++i)
                {
                    var hash_index =  $(elements_to_hide[i]).identify();

                    if(HideShowStackCount[hash_index] == undefined)
                        HideShowStackCount[hash_index] = $A();

		    if(HideShowStackCount[hash_index].indexOf(region_key) == -1)
                        HideShowStackCount[hash_index].push(region_key);

                    elements_to_hide[i].style.visibility = "hidden";
                }
        },
        ShowInRegion: function(region_key)
        {
	    var elements_to_show = getHidableElementsObscuredBy(region_key);
            for (var i = 0, len = elements_to_show.length; i < len; ++i)
                {
                    var hash_index = $(elements_to_show[i]).identify();

                    if(HideShowStackCount[hash_index] == undefined)
                        HideShowStackCount[hash_index] = $A();

		    if(HideShowStackCount[hash_index].indexOf(region_key) != -1)
                        HideShowStackCount[hash_index] = HideShowStackCount[hash_index].without(region_key);

                    if (HideShowStackCount[hash_index].length == 0)
                        elements_to_show[i].style.visibility = "visible";
                }
	},
        CollectHidableElements: function()
        {
	    $A(document.getElementsByTagName('applet'))
                .each(
                      function (e)
                      {
                          HidableElements.push(e);
                      }
            );

            if(Prototype.Browser.IE)
	    {
                $A(document.getElementsByTagName('select'))
                    .each(
                        function (e)
                        {
                            HidableElements.push(e);
                        }
                );
            }
        }
    };
}();

Event.observe(window,'load',Rtk.Shared.ObscureRenderedElements.CollectHidableElements);

