package com.FitBank.common;

import java.io.File;

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

import javax.swing.filechooser.FileFilter;

/**
 * Crea un filtro para ser usado en los dialogos de abrir y/o guardar archivos en el Generador.
 * 
 * @author FitBank
 */
public class Filtro extends FileFilter {

	private static String TYPE_UNKNOWN = "Type Unknown";
    private static String HIDDEN_FILE  = "Hidden File";

    private Hashtable filters = null;

    private String description     = null;
    private String fullDescription = null;

    private boolean useExtensionsInDescription = true;

    /**
     * Constructor por defecto.
     */
    public Filtro() {
        this.filters = new Hashtable();
    }

    /**
     * Constructor con un parametro tipo String.
     * 
     * @param extension Extension de los archivos que van a ser mostrados
     */
    public Filtro(String extension) {
        this(extension, null);
    }

    /**
     * Constructor con dos parametros.
     * 
     * @param extension Extension de los archivos que van a ser mostrados
     * @param description Descripcion de esta extension
     */
    public Filtro(String extension, String description) {
        this();

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

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

    /**
     * Constructor con un parametro, arreglo de Strings.
     * 
     * @param filters Arreglo de las extensiones
     */
    public Filtro(String[] filters) {
        this(filters, null);
    }

    /**
     * Constructor con 2 parametros, un arreglo de Strings, y una descripcion.
     * 
     * @param filters Arreglo de las extensiones
     * @param description Descripcion de las extensiones
     */
    public Filtro(String[] filters, String description) {
        this();

        for (String filter : filters) {
            addExtension(filter);
        }

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

    /**
     * Define si un archivo es aceptado o no.
     * 
     * @param f Archivo
     * 
     * @return true si es aceptado, o false si no
     */
    @Override
    public boolean accept(File f) {
        if (f != null) {
            if (f.isDirectory()) {
                return true;
            }

            String extension = getExtension(f);

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

        return false;
    }

    /**
     * Obtiene la extension del archivo.
     * 
     * @param f Archivo
     * 
     * @return String de la extension sin punto
     */
    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;
    }

    /**
     * Agrega una extension al filtro.
     * 
     * @param extension Extension sin punto
     */
    public void addExtension(String extension) {
        if (filters == null) {
            filters = new Hashtable(5);
        }

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

    /**
     * Obtiene la descripcion del filtro.
     * 
     * @return String de la descripcion
     */
    @Override
    public String getDescription() {
        if (fullDescription == null) {
            if (description == null || isExtensionListInDescription()) {
                fullDescription = description == null ?  "("  : description + " (";

                Enumeration extensions = filters.keys();

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

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

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

        return fullDescription;
    }

    /**
     * Asigna una descripcion al filtro.
     * 
     * @param newDescription String de la descripcion
     */
    public void setDescription(String newDescription) {
        description     = newDescription;
        fullDescription = null;
    }

    /**
     * Asigna si se va a incluir la lista de extensiones en la descripcion.
     * 
     * @param b true si se va a incluir, false si no.
     */
    public void setExtensionListInDescription(boolean b) {
        useExtensionsInDescription = b;
        fullDescription            = null;
    }

    /**
     * Determina si se va a incluir la lista de extensiones en la descripcion.
     * 
     * @return true si es verdad, false si no
     */
    public boolean isExtensionListInDescription() {
        return useExtensionsInDescription;
    }

}
