/*
 * Copyright
 *   2007 axYus - www.axyus.com
 *   2005 C.Marchand - christophe.marchand@axyus.com
 *
 * This file is part of XEMELIOS.
 *
 * XEMELIOS 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.
 *
 * XEMELIOS 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 XEMELIOS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package fr.gouv.finances.cp.xemelios.plugins;

import java.awt.Cursor;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

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

import org.apache.log4j.Logger;

import fr.gouv.finances.cp.utils.ui.DisplayExceptionDlg;


/**
 * Defines contract to make export plugins.
 * An implementation must provide a constructor with no parameters
 * @author chm
 */
public abstract class ExportPlugin extends XemeliosPlugin {
    private static Logger logger = Logger.getLogger(ExportPlugin.class);

    private BufferedWriter bw;
    public BufferedWriter getWriter() { return bw; }
    private Throwable exceptionDuringProcess = null;
    private String fileName=null;
    @Override
	public int getPluginType() {
        return TYPE_SEARCH;
    }
    @Override
	public Long doInBackground() throws Exception {
        Long nbExport = new Long(0);
        try {
            nbExport = doExport();
        } catch(Throwable t) {
            logger.error("in doExport:",t);
            exceptionDuringProcess = t;
        }
        return nbExport;
    }
//    protected char getSeparator() { return getPluginModel().getSeparatorChar(); }
    /**
     * This method is called by doInBackground. It must return the buffer to export
     * @return The buffer to write in output file.
     * @throws Exception
     */
    public abstract Long doExport() throws Exception;
    /**
     * This method is called by doInBackground to let you read parameters
     * @throws Exception
     */
    public abstract void computeParameters() throws Exception;
    
    public StringBuffer getBuffer() throws Exception {
        return (StringBuffer)get();
    }
    @Override
    public void done() {
        super.done();
        terminate();
    }
    public void terminate() {
        try {
            if(getWriter()!=null) {
	            getWriter().flush();
	            getWriter().close();
            }
        } catch(IOException ioEx) {
            logger.error("closing writer",ioEx);
        }
        setProgressVisible(false);
        if(exceptionDuringProcess!=null) new DisplayExceptionDlg(getSearchWindow().getParentFrame(),exceptionDuringProcess);
        getSearchWindow().setSearchEnabled(true);
        try { logger.debug("finished: "+get().toString()); } catch(Throwable t) {logger.fatal("interrupted"); }
    }
    public void startExport() throws Exception {
        computeParameters();
        File f = getFileToExportTo(getDefaultFileExtension());
        
        if(f!=null) {
            fileName = f.toURL().toExternalForm();
            if(f.getName().indexOf(".")<0) {
                f = new File(f.getParent(),f.getName()+"."+getDefaultFileExtension());
                fileName = f.toURL().toExternalForm();
            }
            bw = new BufferedWriter(new FileWriter(f));
            execute();
        } else {
            setProgressVisible(false);
            getSearchWindow().setSearchEnabled(true);
            getSearchWindow().setCursor(Cursor.getDefaultCursor());
            getSearchWindow().getParentFrame().stopWaiter();
        }
    }
    /**
     * Returns the file filter to use. This method does not return anything by default, but it can be overriden.
     * If no file filter is returned, a default file filter based on default file extension is provided.
     */
    public FileFilter getFileFilter() { return null; }
    protected File getFileToExportTo(String defaultExtension) throws IOException {
        File ret = null;
        FileFilter ff = null;
        ff = getFileFilter();
        if(ff==null) ff = new MyFileFilter(defaultExtension);
        JFileChooser fc = new JFileChooser();
//        if(defaultExtension!=null) {
            fc.addChoosableFileFilter(ff);
//        }
        if(fc.showSaveDialog(getOwner())==JFileChooser.APPROVE_OPTION) {
            ret = fc.getSelectedFile();
            if(ret.exists()) {
                int response = JOptionPane.showConfirmDialog(getOwner(),"Ce fichier existe déjà. Voulez-vous l'écraser ?","Confirmation",JOptionPane.YES_NO_CANCEL_OPTION);
                switch(response) {
                    case JOptionPane.CANCEL_OPTION: {
                        ret = null;
                        break;
                    }
                    case JOptionPane.NO_OPTION: {
                        ret = getFileToExportTo(defaultExtension);
                        break;
                    }
                    case JOptionPane.YES_OPTION: {
                        ret.delete();
                    }
                }
            }
        }
        return ret;
    }
    protected String getFileName() { return fileName; }
    public abstract String getDefaultFileExtension();
    public static class MyFileFilter extends FileFilter {
        private String ext;
        public MyFileFilter(String extension) {
            super();
            if(extension!=null) {
                if(extension.startsWith(".")) {
                    this.ext=extension;
                } else {
                    this.ext = "."+extension;
                }
            } else {
                ext = "  ";
            }
        }
        @Override
		public boolean accept(File f) {
            return f.getName().endsWith(ext);
        }
        @Override
		public String getDescription() {
            return "Fichiers "+ext.substring(1);
        }
    }
}
