if (window.parent != null && window.parent.Filter != null)
{
    // use filter from parent
    Filter = window.parent.Filter;
} else 
{
    // create new filter
    var Filter = new Object();

    Filter.Types = ["invisible", "grayed"];
    Filter.DefaultType = Filter.Types[0];
    Filter.Active = false;

    /*
        Initialize filter for the first time
    */
    Filter.Init = function(htmlObject)
    {
        this.OnChange = new Event();
        this.FilterList = filterList;
        this.Style = "filter";
        this.Type = this.DefaultType;
        this.LoadFilterList();
        
        htmlObject.innerHTML = this.CreateEditor();
        this.Active = true;
    }
    
    Filter.LoadFilterList = function(){
        this.Properties = new Object();
        
        for (i = 0; i < filterList.length; i++)
        {
            var filter = filterList[i]
            var property = this.Properties[filter.Id];

            if (property == null)
            {
                property = new Object();
                property.Id = filter.Id;
                property.Name = filter.Name;
                property.Type = filter.Type;
                property.Values = new Object();
                property.Values[filter.Value] = false;
                this.Properties[filter.Id] = property;
            } else
            {
                property.Values[filter.Value] = false;
            }
        }    
    }
    
    /*
        Checks if 'properties' contains one or more properties that are filtered
    */
    Filter.IsFiltered = function(properties)
    {
        if (properties == null) return false;
        
        var i;
        var filtered = 0;

        for (i = 0; i < properties.length; i++)
        {
            var property = properties[i];
            //RR: check added, some properties do not exist
            if (this.Properties[property.Id] != null)
            {
                if (this.Properties[property.Id].Values[property.Value] == true)
                {
                    filtered++;
                }
            }
        }

        if (filtered == properties.length && filtered != 0) return true;
        else return false;        
    }
    
    //checks if menuitem needs to be filtered, used hierarchy
    Filter.IsMenuitemFiltered = function(menuitem)
    {
        //check if current needs filter, if not, go up in hierarchy till we find one that does
        var isFiltered = this.IsFiltered(menuitem.Properties);
        if (isFiltered != true)
        {
            if (menuitem.Parent != null)
            {
                isFiltered = this.IsMenuitemFiltered(menuitem.Parent);
            }
        }
        
        return isFiltered;
    }    
    
    // ==========================================
    // Create Html
    // ==========================================
    /*
        toggles the specified filter property
    */
    Filter.Toggle = function(name, value)
    {
        this.Properties[name].Values[value] = !this.Properties[name].Values[value];
        this.OnChange.Trigger();
    }
    
    /*
        Creates a filter property editor. 
            
        The following html structure will be generated:
            
        <fieldset id="filter_[property.Name]" class="[filter.Style]_property">
            <legend>[property.Name]</legend>
            <div class="[filter.Style]_value">
                <input type="checkbox" class="[filter.Style]_checkbox" id=filter_[property.Name]_[property.Value]"> 
                [property.value]
            </div>
            <div class="[filter.Id]_value">
                <input type="checkbox" id="filter_[property.Name]_[property.Value]"> 
                [property.value]
            </div>
            ...
        </fieldset>
    */
    Filter.CreateEditor = function()
    {
        var key;
        var result = '';
        var name;

        // close filter button
        result += '<div id="filter_header" class="menu_header">';
        result += '<a id="' + this.Style + '_close" onclick="ToggleFilter(); return false;" class="close_button"></a>';
        result += '</div>';
        
        for (name in this.Properties)
        {
            var property = this.Properties[name];
            result += '<div id="filter_' + property.Name + '" class="' + this.Style + '_property">';
            result += '<div class="' + this.Style + '_property_name">' + property.Name + '</div>';

            var value;
            for (value in property.Values)
            {
                result += '<div class="' + this.Style + '_property_option">';
                result += '<input type="checkbox" class="' + this.Style + '_property_checkbox" id="filter_' + name + '_' + value + '" onclick="Filter.Toggle(\'' + name + '\', \'' + value + '\');" checked="' + !property.Values[value] + '">';
                result += '<span class="' + this.Style + '_property_value">' + value + '</span>';
                result += '</div>';
            }

            result += '</div>';
        }
        
        result += this.CreateTypeEditor();
        
        return result;
    }
    
    //init the filtertype radiobuttons: check the one with default value
    Filter.CreateTypeEditor = function()
    {
        
        var result = '<div id="filter_types" class="' + this.Style + '_types">';
        result += '<div class="' + this.Style + '_type_header">Filter type</div>'
        
        for (var i = 0; i < this.Types.length; i++)
        {
            var type = this.Types[i];
            result += '<div class="' + this.Style + '_type_option">';
            if (this.Type == type) result += '<input class="' + this.Style + '_type_radio" onclick="Filter.ChangeType(' + i + ');" type="radio" name="filterType" value="' + i + '" checked="checked" />';
            else result += '<input class="' + this.Style + '_type_radio" onclick="Filter.ChangeType(' + i + ');" type="radio" name="filterType" value="' + i + '" />';
            result += '<span class="' + this.Style + '_type_name">' + type + '</span>';
            result += '</div>';
        }
        
        result += '</div>';
        return result;
    }

    //toggle the filtertype via radiobutton and update the notifyees
    Filter.ChangeType = function(index)
    {
        this.Type = this.Types[index];
        this.OnChange.Trigger();
    }    
    
    /*
        Filters menuitems
    */
    Filter.FilterMenuitems = function(menuitems)
    {
        if (menuitems == null) return;
        
        for (var key in menuitems){
            var menuitem = menuitems[key];
            
            menuitem.Filtered = this.IsFiltered(menuitem.Properties);
            if (menuitem.Filtered == true){
                this.MarkAsFiltered(menuitem.Children);
            } else {
                this.FilterMenuitems(menuitem.Children);
            }
        }
    }
    
    Filter.MarkAsFiltered = function(menuitems)
    {
        if (menuitems == null) return;
        
        for (var key in menuitems){
            var menuitem = menuitems[key];
            menuitem.Filtered = true;
            this.MarkAsFiltered(menuitem.Children);
        }
    }
    
    Filter.FilterDocument = function(win)
    {
        var paragraphProperties = win.ParagraphProperties;
    
        // find all paragraphs with properties and filter them
        for (paragraphId in paragraphProperties)
        {
            var properties = paragraphProperties[paragraphId];
        
            var object = win.document.getElementById("node_" + paragraphId);
            var isFiltered = this.IsFiltered(properties);
            
            if (isFiltered) object.className = "paragraph_" + this.Type;
            else object.className = "";
        }
    }
}