/*
* Created on Apr 13, 2003
*/
package de.renew.ioontology;

import java.io.File;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;



/**
 * ExtensionFileFilters can be combined into new combinations of FileFilters.
 * This allows to filter for multiple file types.
 *
 * @author Lawrence Cabac, Konstantin Moellers (1kmoelle)
 */
public class MultiExtensionFileFilterImpl extends javax.swing.filechooser.FileFilter
    implements MultiExtensionFileFilter
{
    private final HashSet<ExtensionFileFilter> _filterList;
    private ExtensionFileFilter _preferredFileFilter;
    private String _description;

    /**
     * Constructs a new multi extension file filter with a description and sets up a list to add or remove filters from.
     *
     * @param description a text that describes the multi extension file filter
     */
    public MultiExtensionFileFilterImpl(String description) {
        _filterList = new HashSet<>();
        _description = description;
    }

    /**
     * Constructs a new multi extension file filter with a description and a given collection of filters
     *
     * @param description a text that describes the multi extension file filter
     * @param filters the filters
     */
    public MultiExtensionFileFilterImpl(
        String description, Collection<ExtensionFileFilter> filters)
    {
        _filterList = new HashSet<>();
        _description = description;
        addAll(filters);
    }

    @Override
    public final void setDescription(String description) {
        this._description = description;
    }

    @Override
    public final boolean add(ExtensionFileFilter ff) {
        if (ff != null && _filterList.contains(ff)) {
            return false;
        }
        if (_filterList.isEmpty()) {
            _preferredFileFilter = ff;
        }
        return _filterList.add(ff);
    }

    @Override
    public final boolean addAll(Collection<? extends ExtensionFileFilter> filters) {
        boolean result = false;
        for (ExtensionFileFilter ff : filters) {
            result = add(ff) || result;
        }
        return result;
    }

    @Override
    public final void remove(ExtensionFileFilter ff) {
        _filterList.remove(ff);
    }

    @Override
    public final Set<ExtensionFileFilter> getFileFilters() {
        return _filterList;
    }

    @Override
    public boolean accept(File f) {
        // Never accept null files or hidden files
        if (f == null || f.isHidden() || f.getName().startsWith(".")) {
            return false;
        }

        // Always accept directories.
        if (f.isDirectory()) {
            return true;
        }

        // Check if one of the contained filters accepts the file.
        for (ExtensionFileFilter filter : _filterList) {
            if (filter.accept(f)) {
                return true;
            }
        }

        return false;
    }

    @Override
    public final ExtensionFileFilter getPreferredFileFilter() {
        return _preferredFileFilter;
    }

    @Override
    public final void setPreferredFileFilter(ExtensionFileFilter filter) {
        _preferredFileFilter = filter;
    }

    @Override
    public final String getDescription() {
        return _description;
    }

    @Override
    public final boolean equals(Object o) {
        if (o instanceof MultiExtensionFileFilterImpl other) {
            return getDescription().equals(other.getDescription())
                && getFileFilters().equals(other.getFileFilters());
        }

        return false;
    }

    @Override
    public final int hashCode() {
        return MultiExtensionFileFilterImpl.class.hashCode() ^ getDescription().hashCode()
            ^ getFileFilters().hashCode();
    }
}