/*
 * File:     ElanFileFilter.java
 * Project:  MPI Linguistic Application
 * Date:     03 April 2006
 *
 * Copyright (C) 2001-2006  Max Planck Institute for Psycholinguistics
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package mpi.eudico.client.annotator.util;

import mpi.eudico.client.annotator.ElanLocale;

import java.io.File;

import java.util.Enumeration;
import java.util.Hashtable;

import javax.swing.filechooser.FileFilter;


/**
 * A FileFilter class especially for Elan.
 * Based on Sun's ExampleFileFilter.
 *
 * @author Han Sloetjes
 */
public class ElanFileFilter extends FileFilter {
    private static String TYPE_UNKNOWN = "Type Unknown";
    private static String HIDDEN_FILE = "Hidden File";

    /** Constant for mpeg file filter */
    public static final int MPEG_TYPE = 0;

    /** Constant for wav file filter */
    public static final int WAV_TYPE = 1;

    /** Constant for media file filter */
    public static final int MEDIA_TYPE = 2;

    /** Constant for eaf file filter */
    public static final int EAF_TYPE = 3;

    /** Constant for etf file filter */
    public static final int TEMPLATE_TYPE = 4;

    /** Constant for chat file filter */
    public static final int CHAT_TYPE = 5;

    /** Constant for wac file filter */
    public static final int WAC_TYPE = 6;

    /** Constant for shoebox text file filter */
    public static final int SHOEBOX_TEXT_TYPE = 7;

    /** Constant for shoebox typ file filter */
    public static final int SHOEBOX_TYP_TYPE = 8;

    /** Constant for shoebox marker file filter */
    public static final int SHOEBOX_MKR_TYPE = 9;

    /** Constant for image file filter */
    public static final int IMAGE_TYPE = 10;

    /** Constant for text file filter */
    public static final int TEXT_TYPE = 11;

    /** Constant for transcriber file filter */
    public static final int TRANSCRIBER_TYPE = 12;

    /** Constant for SMIL file filter */
    public static final int SMIL_TYPE = 13;

    /** Constant for Tiger filter */
    public static final int TIGER_TYPE = 14;
    private Hashtable filters = null;
    private String description = null;
    private String fullDescription = null;
    private boolean useExtensionsInDescription = true;

    /**
     * No-arg constructor.
     */
    public ElanFileFilter() {
        super();
        this.filters = new Hashtable();
    }

    /**
     * Creates a new ElanFileFilter instance
     *
     * @param extension DOCUMENT ME!
     */
    public ElanFileFilter(String extension) {
        this(extension, null);
    }

    /**
     * Creates a new ElanFileFilter instance
     *
     * @param extension DOCUMENT ME!
     * @param description DOCUMENT ME!
     */
    public ElanFileFilter(String extension, String description) {
        this();

        if (extension != null) {
            addExtension(extension);
        }

        if (description != null) {
            setDescription(description);
        }
    }

    /**
     * Creates a new ElanFileFilter instance
     *
     * @param filters DOCUMENT ME!
     */
    public ElanFileFilter(String[] filters) {
        this(filters, null);
    }

    /**
     * Creates a new ElanFileFilter instance
     *
     * @param filters DOCUMENT ME!
     * @param description DOCUMENT ME!
     */
    public ElanFileFilter(String[] filters, String description) {
        this();

        for (int i = 0; i < filters.length; i++) {
            // add filters one by one
            addExtension(filters[i]);
        }

        if (description != null) {
            setDescription(description);
        }
    }

    /**
     * Returns true if the File f should be visible in the view.
     *
     * @param f the File
     *
     * @return true if f should be visible, false otherwise
     */
    public boolean accept(File f) {
        if (f != null) {
            if (f.isDirectory()) {
                return true;
            }

            String extension = getExtension(f);

            if ((extension != null) && (filters.get(extension) != null)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Returns the file extension for the given file.
     *
     * @param f the file
     *
     * @return the file extension
     */
    public String getExtension(File f) {
        if (f != null) {
            String filename = f.getName();
            int i = filename.lastIndexOf('.');

            if ((i > 0) && (i < (filename.length() - 1))) {
                return filename.substring(i + 1).toLowerCase();
            }
        }

        return null;
    }

    /**
     * Add an extension to the list of extensions.
     *
     * @param extension the file extension
     */
    public void addExtension(String extension) {
        if (filters == null) {
            filters = new Hashtable(5);
        }

        filters.put(extension.toLowerCase(), this);
        fullDescription = null;
    }

    /**
     * Returns the description of the file filter.
     *
     * @return the description
     */
    public String getDescription() {
        if (fullDescription == null) {
            if ((description == null) || isExtensionListInDescription()) {
                fullDescription = (description == null) ? "(" : (description +
                    " (");

                // build the description from the extension list
                Enumeration extensions = filters.keys();

                if (extensions != null) {
                    fullDescription += ("*." +
                    (String) extensions.nextElement());

                    while (extensions.hasMoreElements()) {
                        fullDescription += (", *." +
                        (String) extensions.nextElement());
                    }
                }

                fullDescription += ")";
            } else {
                fullDescription = description;
            }
        }

        return fullDescription;
    }

    /**
     * Sets the description for this file filter.
     *
     * @param description the new description
     */
    public void setDescription(String description) {
        this.description = description;
        fullDescription = null;
    }

    /**
     * Sets the extension list in description flag.
     *
     * @param b the new value for the flag
     */
    public void setExtensionListInDescription(boolean b) {
        useExtensionsInDescription = b;
        fullDescription = null;
    }

    /**
     * Returns the value of the extension list in description flag.
     *
     * @return the value of the extension list in description flag
     */
    public boolean isExtensionListInDescription() {
        return useExtensionsInDescription;
    }

    /**
     * Returns a FilterFilter of the specified type.
     *
     * @param filterType the requested filter type
     *
     * @return a customized FileFilter
     */
    public static FileFilter createFileFilter(int filterType) {
        ElanFileFilter eff = null;

        switch (filterType) {
        case MPEG_TYPE:
            eff = new ElanFileFilter(FileExtension.MPEG_EXT,
                    ElanLocale.getString("Frame.ElanFrame.FileDescription.MPEG"));

            break;

        case WAV_TYPE:
            eff = new ElanFileFilter(FileExtension.WAV_EXT,
                    ElanLocale.getString("Frame.ElanFrame.FileDescription.WAV"));

            break;

        case MEDIA_TYPE:
            eff = new ElanFileFilter(FileExtension.MEDIA_EXT,
                    ElanLocale.getString(
                        "Frame.ElanFrame.NewDialog.MediaFilterDescription"));

            break;

        case EAF_TYPE:
            eff = new ElanFileFilter(FileExtension.EAF_EXT,
                    ElanLocale.getString(
                        "Frame.ElanFrame.OpenDialog.FileDescription"));

            break;

        case TEMPLATE_TYPE:
            eff = new ElanFileFilter(FileExtension.TEMPLATE_EXT,
                    ElanLocale.getString(
                        "Frame.ElanFrame.NewDialog.TemplateFilterDescription"));

            break;

        case CHAT_TYPE:
            eff = new ElanFileFilter(FileExtension.CHAT_EXT,
                    ElanLocale.getString(
                        "Frame.ElanFrame.OpenDialog.CHATFileDescription"));

            break;

        case WAC_TYPE:
            eff = new ElanFileFilter(FileExtension.WAC_EXT,
                    ElanLocale.getString("ImportDialog.FileDescription.WAC"));

            break;

        case SHOEBOX_TEXT_TYPE:
            eff = new ElanFileFilter(FileExtension.TEXT_EXT,
                    ElanLocale.getString("ImportDialog.FileDescription.Shoebox"));

            break;

        case SHOEBOX_TYP_TYPE:
            eff = new ElanFileFilter(FileExtension.SHOEBOX_TYP_EXT,
                    ElanLocale.getString(
                        "ImportDialog.FileDescription.ShoeboxType"));

            break;

        case SHOEBOX_MKR_TYPE:
            eff = new ElanFileFilter(FileExtension.SHOEBOX_MKR_EXT,
                    ElanLocale.getString(
                        "ShoeboxMarkerDialog.FileDescription.ShoeboxMarker"));

            break;

        case TRANSCRIBER_TYPE:
            eff = new ElanFileFilter(FileExtension.TRANSCRIBER_EXT,
                    ElanLocale.getString(
                        "ImportDialog.FileDescription.Transcriber"));

            break;

        case IMAGE_TYPE:
            eff = new ElanFileFilter(FileExtension.IMAGE_EXT, "");

            break;

        case TEXT_TYPE:
            eff = new ElanFileFilter(FileExtension.TEXT_EXT,
                    ElanLocale.getString("ExportDialog.FileDescription"));

            break;

        case TIGER_TYPE:
            eff = new ElanFileFilter(FileExtension.TIGER_EXT,
                    ElanLocale.getString("ExportDialog.FileDescription"));

            break;

        case SMIL_TYPE:
            eff = new ElanFileFilter(FileExtension.SMIL_EXT, "");
        }

        return eff;
    }
}
