/*
 * File:     ExportGridTable.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.export;

import mpi.eudico.client.annotator.ElanLocale;
import mpi.eudico.client.annotator.Preferences;

import mpi.eudico.client.annotator.grid.AnnotationTable;
import mpi.eudico.client.annotator.grid.GridViewerTableModel;

import mpi.eudico.client.annotator.gui.TextExportFileChooser;

import mpi.eudico.client.annotator.util.ElanFileFilter;
import mpi.eudico.client.annotator.util.FileExtension;

import mpi.eudico.server.corpora.clom.Annotation;
import mpi.eudico.server.corpora.clom.AnnotationCore;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

import java.nio.charset.UnsupportedCharsetException;

import java.util.ArrayList;

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


/**
 * A class for exporting the contents of the Annotation table in the
 * GridViewer or a search result frame.
 *
 * @author Han Sloetjes
 * @version 1.0, feb 2005
 */
public class ExportGridTable {
    /**
     * Constructor.
     */
    public ExportGridTable() {
    }

    /**
     * Exports the contents of hte table to a tab delimited text file.
     *
     * @param table the annotationtable
     */
    public void exportTableAsTabDelimitedText(AnnotationTable table) {
        if (table == null) {
            return;
        }

        String encoding = "UTF-8";

        String exportDir = (String) Preferences.get("LastUsedExportDir", null);

        if (exportDir == null) {
            exportDir = System.getProperty("user.dir");
        }

        TextExportFileChooser chooser = new TextExportFileChooser();
        chooser.setCurrentDirectory(new File(exportDir));
        chooser.setDialogTitle(ElanLocale.getString("ExportTabDialog.Title"));

        File exportFile = null;
        FileFilter filter = ElanFileFilter.createFileFilter(ElanFileFilter.TEXT_TYPE);
        chooser.setFileFilter(filter);

        if (chooser.showSaveDialog(null, null) == JFileChooser.APPROVE_OPTION) {
            File curDir = chooser.getCurrentDirectory();

            if (curDir != null) {
                Preferences.set("LastUsedExportDir", curDir.getAbsolutePath(),
                    null);
            }

            exportFile = chooser.getSelectedFile();

            if (exportFile != null) {
                encoding = chooser.getSelectedEncoding();

                String name = exportFile.getAbsolutePath();
                String lowerPathName = name.toLowerCase();

                String[] exts = FileExtension.TEXT_EXT;
                boolean validExt = false;

                for (int i = 0; i < exts.length; i++) {
                    if (lowerPathName.endsWith("." + exts[i])) {
                        validExt = true;

                        break;
                    }
                }

                if (!validExt) {
                    name += ("." + exts[0]);
                    exportFile = new File(name);
                }

                if (exportFile.exists()) {
                    int answer = JOptionPane.showConfirmDialog(null,
                            ElanLocale.getString("Message.Overwrite"),
                            ElanLocale.getString("SaveDialog.Message.Title"),
                            JOptionPane.YES_NO_OPTION);

                    if (answer == JOptionPane.NO_OPTION) {
                        // ask again??
                        exportTableAsTabDelimitedText(table);

                        //return;
                    }
                }
            }
        } else {
            // save dialog canceled
            return;
        }

        // exportFile should not be null here
        BufferedWriter writer = null;

        GridViewerTableModel dataModel = null;
        boolean filtering = false;

        try {
            FileOutputStream out = new FileOutputStream(exportFile);
            OutputStreamWriter osw = null;

            try {
                osw = new OutputStreamWriter(out, encoding);
            } catch (UnsupportedCharsetException uce) {
                osw = new OutputStreamWriter(out, "UTF-8");
            }

            writer = new BufferedWriter(osw);

            dataModel = (GridViewerTableModel) table.getModel();
            filtering = dataModel.isFiltering();
            dataModel.setFiltering(false);

            ArrayList visColumns = new ArrayList();
            boolean tierNameColumnPresent = false;

            for (int i = 0; i < dataModel.getColumnCount(); i++) {
                String columnName = dataModel.getColumnName(i);

                if (table.isColumnVisible(columnName)) {
                    visColumns.add(columnName);

                    if (columnName.equals(GridViewerTableModel.TIERNAME)) {
                        tierNameColumnPresent = true;
                    }
                }
            }

            String tierName = "";

            if (!tierNameColumnPresent && (dataModel.getRowCount() > 0)) {
                for (int i = 0; i < dataModel.getColumnCount(); i++) {
                    if (visColumns.contains(dataModel.getColumnName(i))) {
                        Object o = dataModel.getValueAt(0, i);

                        if (o instanceof Annotation) {
                            tierName = ((Annotation) o).getTier().getName();

                            break;
                        }
                    }
                }
            }

            // first row are the table header values
            for (int i = 1; i < dataModel.getColumnCount(); i++) {
                if (visColumns.contains(dataModel.getColumnName(i))) {
                    String header = (String) table.getColumnModel().getColumn(i)
                                                  .getHeaderValue();

                    // replace 'Annotation' by the tier's name
                    if (!tierNameColumnPresent &&
                            dataModel.getColumnName(i).equals(GridViewerTableModel.ANNOTATION) &&
                            (tierName.length() > 0)) {
                        header = tierName;
                    }

                    writer.write(header + "\t");
                }
            }

            writer.write("\n");

            // loop over rows and columns
            for (int i = 0; i < dataModel.getRowCount(); i++) {
                // the first column is the crosshair time indicator column, skip
                for (int j = 1; j < dataModel.getColumnCount(); j++) {
                    if (visColumns.contains(dataModel.getColumnName(j))) {
                        Object o = dataModel.getValueAt(i, j);

                        if (o instanceof Annotation) {
                            writer.write(((Annotation) o).getValue().replace('\n',
                                    ' '));
                        } else if (o instanceof AnnotationCore) {
                            writer.write(((AnnotationCore) o).getValue()
                                          .replace('\n', ' '));
                        } else if (o != null) {
                            writer.write(o.toString());
                        } else {
                            writer.write("");
                        }

                        writer.write("\t");
                    }
                }

                writer.write("\n");
            }

            writer.flush();
            writer.close();
        } catch (Exception ex) {
            // FileNotFound, IO, Security, Null etc
            JOptionPane.showMessageDialog(null,
                ElanLocale.getString("ExportDialog.Message.Error"),
                ElanLocale.getString("Message.Warning"),
                JOptionPane.WARNING_MESSAGE);
        } finally {
            if (dataModel != null) {
                dataModel.setFiltering(filtering);
            }

            try {
                writer.close();
            } catch (Exception ee) {
            }
        }
    }
}
