/*
 * File:     ExportSmilDialog.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.Selection;

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

import mpi.eudico.client.util.CheckBoxTableCellRenderer;
import mpi.eudico.client.util.EAF2SMIL;

import mpi.eudico.server.corpora.clom.Transcription;

import mpi.eudico.server.corpora.clomimpl.abstr.MediaDescriptor;
import mpi.eudico.server.corpora.clomimpl.abstr.TierImpl;
import mpi.eudico.server.corpora.clomimpl.abstr.TranscriptionImpl;

import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.io.File;
import java.io.IOException;

import java.util.ArrayList;
import java.util.Vector;

import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileFilter;

import javax.xml.transform.TransformerException;


public class ExportSmilDialog extends AbstractTierExportDialog
    implements ListSelectionListener {
    private Transcription transcription;
    private Selection selection;
    private JCheckBox restrictCheckBox;

    /**
     *
     * @param parent
     * @param modal
     * @param transcription
     * @param selection
     */
    public ExportSmilDialog(Frame parent, boolean modal,
        Transcription transcription, Selection selection) {
        super(parent, modal);
        this.transcription = transcription;
        this.selection = selection;
        this.initComponents();
        extractTiers();
        postInit();
    }

    /**
     * Initializes UI elements.
     */
    protected void initComponents() {
        super.initComponents();

        restrictCheckBox = new JCheckBox();

        model.setColumnIdentifiers(new String[] { EXPORT_COLUMN, TIER_NAME_COLUMN });
        tierTable.getColumn(EXPORT_COLUMN).setCellEditor(new DefaultCellEditor(
                new JCheckBox()));
        tierTable.getColumn(EXPORT_COLUMN).setCellRenderer(new CheckBoxTableCellRenderer());
        tierTable.getColumn(EXPORT_COLUMN).setMaxWidth(30);
        tierTable.setShowVerticalLines(false);
        tierTable.setTableHeader(null);
        tierTable.getSelectionModel().addListSelectionListener(this);

        // options
        GridBagConstraints gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;

        //gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.anchor = GridBagConstraints.WEST;
        gridBagConstraints.insets = insets;
        optionsPanel.add(restrictCheckBox, gridBagConstraints);

        updateLocale();
    }

    /**
     * Extract candidate tiers for export.
     */
    protected void extractTiers() {
        if (model != null) {
            for (int i = model.getRowCount() - 1; i >= 0; i--) {
                model.removeRow(i);
            }

            if (transcription != null) {
                Vector v = transcription.getTiers();
                TierImpl t;

                for (int i = 0; i < v.size(); i++) {
                    t = (TierImpl) v.get(i);

                    // add all
                    if (i == 0) {
                        model.addRow(new Object[] { Boolean.TRUE, t.getName() });
                    } else {
                        model.addRow(new Object[] { Boolean.FALSE, t.getName() });
                    }
                }
            }
        }
    }

    /**
     * Pack, size and set location.
     */
    protected void postInit() {
        pack();

        int w = 550;
        int h = 400;
        setSize((getSize().width < w) ? w : getSize().width,
            (getSize().height < h) ? h : getSize().height);
        setLocationRelativeTo(getParent());

        //setResizable(false);
    }

    /**
     * @see mpi.eudico.client.annotator.export.AbstractTierExportDialog#updateLocale()
     */
    protected void updateLocale() {
        setTitle(ElanLocale.getString("ExportSmilDialog.Title"));
        titleLabel.setText(ElanLocale.getString("ExportSmilDialog.TitleLabel"));
        tierSelectionPanel.setBorder(new TitledBorder(ElanLocale.getString(
                    "ExportDialog.Label.SelectTiers")));
        optionsPanel.setBorder(new TitledBorder(ElanLocale.getString(
                    "ExportDialog.Label.Options")));
        restrictCheckBox.setText(ElanLocale.getString("ExportDialog.Restrict"));
        startButton.setText(ElanLocale.getString("Button.OK"));
        closeButton.setText(ElanLocale.getString("Button.Close"));
    }

    /**
     * @see mpi.eudico.client.annotator.export.AbstractTierExportDialog#startExport()
     */
    protected boolean startExport() throws IOException {
        if ((model == null) || (tierTable == null)) {
            throw new NullPointerException("The tier table is null");
        }

        int includeCol = model.findColumn(EXPORT_COLUMN);
        int nameCol = model.findColumn(TIER_NAME_COLUMN);

        // check if there is anything to export
        boolean atLeastOneTier = false;

        for (int i = 0; i < model.getRowCount(); i++) {
            Boolean include = (Boolean) model.getValueAt(i, includeCol);

            if (include.booleanValue()) {
                atLeastOneTier = true;

                break;
            }
        }

        if (!atLeastOneTier) {
            JOptionPane.showMessageDialog(this,
                ElanLocale.getString("ExportTradTranscript.Message.NoTiers"),
                ElanLocale.getString("Message.Warning"),
                JOptionPane.WARNING_MESSAGE);

            return false;
        }

        // prompt for file name and location
        String fileName = promptForFileName();

        if (fileName == null) {
            throw new IOException("No valid output file specified");
        }

        // export....
        ArrayList exportTiers = new ArrayList();

        // add selected tiers in the right order
        for (int i = 0; i < model.getRowCount(); i++) {
            Boolean include = (Boolean) model.getValueAt(i, includeCol);

            if (include.booleanValue()) {
                exportTiers.add(model.getValueAt(i, nameCol));
            }
        }

        String[] tierNames = (String[]) exportTiers.toArray(new String[] {  });
        String mediaURL = "";

        if (((TranscriptionImpl) transcription).getMediaDescriptors().size() > 0) {
            mediaURL = ((MediaDescriptor) ((TranscriptionImpl) transcription).getMediaDescriptors()
                                           .get(0)).mediaURL;
        }

        try {
            if ((selection != null) && restrictCheckBox.isSelected()) {
                EAF2SMIL.export2SMIL(new File(
                        ((TranscriptionImpl) transcription).getPathName()),
                    new File(fileName), tierNames, mediaURL,
                    selection.getBeginTime(), selection.getEndTime());
            } else {
                EAF2SMIL.export2SMIL(new File(
                        ((TranscriptionImpl) transcription).getPathName()),
                    new File(fileName), tierNames, mediaURL);
            }
        } catch (TransformerException te) {
            // this is ugly
            throw new IOException("TransformerException: " + te.getMessage());
        }

        return true;
    }

    /**
     * Prompts the user for a file name and location.
     *
     * @return a file (unique) path
     */
    private String promptForFileName() {
        String exportDir = (String) Preferences.get("LastUsedExportDir", null);

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

        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory(new File(exportDir));
        chooser.setDialogTitle(ElanLocale.getString("ExportSmilDialog.Title"));

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

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

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

            exportFile = chooser.getSelectedFile();

            if (exportFile != null) {
                String name = exportFile.getAbsolutePath();
                String lowerPathName = name.toLowerCase();

                String[] exts = FileExtension.SMIL_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) {
                        return promptForFileName();
                    } else {
                        return name;
                    }
                } else {
                    return name;
                }
            } else {
                return null;
            }
        } else {
            // save dialog canceled
            return null;
        }
    }

    /**
     * Updates the checked state of the export checkboxes.
     *
     * @param lse the list selection event
     */
    public void valueChanged(ListSelectionEvent lse) {
        if ((model != null) && lse.getValueIsAdjusting()) {
            int b = lse.getFirstIndex();
            int e = lse.getLastIndex();
            int col = model.findColumn(EXPORT_COLUMN);

            for (int i = b; i <= e; i++) {
                if (tierTable.isRowSelected(i)) {
                    model.setValueAt(Boolean.TRUE, i, col);
                }
            }
        }
    }
}
