/*
 * SSFileChooser.java  $Revision: 1.6 $  $Date: 2007/10/03 04:39:40 $
 *
 * Copyright (C) 2007 Meldcraft Corporation
 *
 * This file is part of Scaffold.
 * 
 * Scaffold is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Scaffold 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Scaffold.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.meldcraft.application.guis;

import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Level;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import com.meldcraft.application.ApplicationContext;
import com.meldcraft.application.ApplicationElementContext;
import com.meldcraft.application.swing.SwingApplicationContext;
import com.meldcraft.util.PropertiesHelper;
import com.meldcraft.util.ReflectUtil;

/**
 * @version $Revision: 1.6 $ $Date: 2007/10/03 04:39:40 $
 * @author Rob Richards
 */
public class SSFileChooser extends JFileChooser
{
    protected ApplicationElementContext mApplicationElementContext;
    protected SwingApplicationContext   mApplicationContext;
    protected String                    mElementId;

    public SSFileChooser(ApplicationElementContext context)
    {
        mApplicationElementContext = context;
        mApplicationContext = (SwingApplicationContext)context.getApplicationContext();
        mElementId = context.getElementId();
        initialize();
    }

    public Object showOpenDialog()
    {
        Object ret = null;
        setSelectedFile(null);
        int opt = showOpenDialog(mApplicationContext.getUIRoot());
        if (opt == JFileChooser.APPROVE_OPTION)
        {
            if (isMultiSelectionEnabled())
            {
                File[] files = getSelectedFiles();
                if ((files != null) && (files.length > 0))
                {
                    ret = files;
                }
            }
            else
            {
                ret = getSelectedFile();
            }
        }
        return ret;
    }

    protected Object getKeyPrefix()
    {
        return mElementId;
    }

    protected void initialize()
    {
        addPropertyChangeListener(new FilterListener(mApplicationContext));

        Map config = mApplicationElementContext.getConfiguration();
        String mode = PropertiesHelper.getString(config, "fileSelectionMode", "files");
        if (mode.equals("directories"))
        {
            this.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        }
        else if (mode.equals("filesAndDirectories"))
        {
            this.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        }
        else
        {
            this.setFileSelectionMode(JFileChooser.FILES_ONLY);
        }
                
        FileFilter[] filters = getFileFilters();
        if (filters != null)
        {
            for (int i=0 ; i < filters.length ; i++)
            {
                addChoosableFileFilter(filters[i]);
            }
        }
    }

    protected FileFilter[] getFileFilters()
    {
        FileFilter[] ret = null;

        Map config = PropertiesHelper.getSubset(mApplicationContext.getConfiguration(), mElementId + ".");
        String filters = PropertiesHelper.getString(config, "fileFilters", null);

        if (filters != null)
        {
            boolean acceptAll = false;

            ArrayList list = new ArrayList();
            StringTokenizer tok = new StringTokenizer(filters, ", ");
            while (tok.hasMoreTokens())
            {
                String cls = tok.nextToken();
                try
                {
                    if (cls.equals("AcceptAllFileFilter"))
                    {
                        acceptAll = true;
                    }
                    else
                    {
                        FileFilter filter = (FileFilter)mApplicationContext.getElementManager().getApplicationElement(cls);

                        if (filter != null)
                        {
                            list.add(filter);
                        }
                    }
                }
                catch (Exception e)
                {
                    mApplicationContext.getLogger().warning("Skipping file filter " + cls + ": " + e);
                }
            }

            if (list.size() > 0)
            {
                setAcceptAllFileFilterUsed(acceptAll);
                ret = (FileFilter[])list.toArray(new FileFilter[list.size()]);
            }
        }

        return ret;
    }

    public static class FilterListener implements PropertyChangeListener
    {
        private ApplicationContext  mApplicationContext;
        
        public FilterListener(ApplicationContext applicationContext)
        {
            mApplicationContext = applicationContext;
        }

        public void propertyChange(java.beans.PropertyChangeEvent event)
        {
            if (event.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
            {
                JFileChooser chooser = (JFileChooser)event.getSource();
                FileFilter filter = (FileFilter)event.getNewValue();

                int mode = JFileChooser.FILES_ONLY;
                boolean multi = false;

                try
                {
                    Boolean val = (Boolean)ReflectUtil.invokeMethod(filter, "isMultiSelectionEnabled");
                    multi = val.booleanValue();
                }
                catch (Throwable e)
                {
                    // ignored
                }

                try
                {
                    Integer val = (Integer)ReflectUtil.invokeMethod(filter, "getFileSelectionMode");
                    mode = val.intValue();
                }
                catch (Throwable e)
                {
                    // ignored
                }

                chooser.setMultiSelectionEnabled(multi);

                try
                {
                    chooser.setFileSelectionMode(mode);
                }
                catch (IllegalArgumentException e)
                {
                    mApplicationContext.getLogger().log(Level.SEVERE, "Could not set file selection mode.", e);
                }
            }
        }
    }
}



