/*
 * File:     CHATExportDlg.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
 */

/*
 * Options dialog to set all parameters for CHAT Export.
 *
 * @author Hennie Brugman
 */
package mpi.eudico.client.annotator.export;

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

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

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

import mpi.eudico.server.corpora.clomimpl.abstr.TierImpl;
import mpi.eudico.server.corpora.clomimpl.abstr.TranscriptionImpl;
import mpi.eudico.server.corpora.clomimpl.chat.CHATEncoderInfo;
import mpi.eudico.server.corpora.clomimpl.dobes.ACM23TranscriptionStore;

import mpi.eudico.util.TranscriptionUtil;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.io.File;

import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileFilter;


/**
 * DOCUMENT ME!
 *
 * @author hennie
 */
public class CHATExportDlg extends JDialog implements ActionListener {
    private static int NUM_OF_COLUMNS = 7;
    private static int NUM_OF_DEP_COLUMNS = 3;
    private static String MAIN_TIER = "Main Tier";
    private static String DEPENDENT_TIER = "Dependent Tier";
    private static String LABEL = "Label";
    private static String FULL_NAME = "Full Name";
    private static String ROLE = "Role";
    private static String ID = "ID";
    private static String LANGUAGE = "Language";
    private JFrame frame;
    private TranscriptionImpl transcription;
    private ACM23TranscriptionStore acmTranscriptionStore;
    private Vector visibleTiers;
    private JComponent[][] mainTierTable;
    private JComponent[][] dependentTierTable;
    private JPanel mainTiersPanel;
    private JPanel dependentTiersPanel;
    private JPanel buttonPanel;
    private JButton exportButton;
    private TitledBorder mainTiersBorder;
    private TitledBorder dependentTiersBorder;

    /**
     * Creates a new CHATExportDlg instance
     *
     * @param frame DOCUMENT ME!
     * @param modal DOCUMENT ME!
     * @param tr DOCUMENT ME!
     * @param acmTranscriptionStore DOCUMENT ME!
     * @param visibleTiers DOCUMENT ME!
     */
    public CHATExportDlg(JFrame frame, boolean modal, Transcription tr,
        ACM23TranscriptionStore acmTranscriptionStore, Vector visibleTiers) {
        super(frame, modal);

        this.frame = frame;
        transcription = (TranscriptionImpl) tr;
        this.acmTranscriptionStore = acmTranscriptionStore;
        this.visibleTiers = visibleTiers;

        // create main tier table (num of root tier records, NUM_OF_COLUMNS columns each)
        Vector topTiers = TranscriptionUtil.getTopTiers(transcription);

        if (topTiers != null) {
            int numOfTiers = transcription.getTiers().size();
            mainTierTable = new JComponent[NUM_OF_COLUMNS][topTiers.size() + 1];
            dependentTierTable = new JComponent[NUM_OF_DEP_COLUMNS][numOfTiers -
                topTiers.size() + 1];
        }

        mainTiersPanel = new JPanel();
        dependentTiersPanel = new JPanel();
        buttonPanel = new JPanel();

        exportButton = new JButton();

        mainTiersBorder = new TitledBorder("Main tiers");
        dependentTiersBorder = new TitledBorder("Dependent tiers");

        createDialog();
        updateForLocale();
        setDefaultValues();
        pack();

        //setResizable(false);
    }

    private void createDialog() {
        getContentPane().setLayout(new GridBagLayout());
        mainTiersPanel.setLayout(new GridBagLayout());
        dependentTiersPanel.setLayout(new GridBagLayout());
        buttonPanel.setLayout(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();
        Insets insets = new Insets(2, 2, 2, 2);

        // main tiers panel
        JComponent tableComponent = null;

        JPanel mtPanel = new JPanel(new GridBagLayout());
        JScrollPane scrollPane = new JScrollPane(mtPanel);
        scrollPane.setBorder(null);
        mainTiersPanel.setBorder(mainTiersBorder);

        c.gridx = 0;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 1.0;
        c.weighty = 1.0;
        c.insets = insets;

        //getContentPane().add(mainTiersPanel, c);
        mtPanel.add(mainTiersPanel, c);

        // header row
        c = new GridBagConstraints();
        tableComponent = new JLabel(MAIN_TIER);
        mainTierTable[1][0] = tableComponent;
        c.gridx = 1;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;
        c.insets = insets;
        mainTiersPanel.add(tableComponent, c);

        tableComponent = new JLabel(LABEL);
        mainTierTable[2][0] = tableComponent;
        c.gridx = 2;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;
        c.insets = insets;
        mainTiersPanel.add(tableComponent, c);

        tableComponent = new JLabel(FULL_NAME);
        mainTierTable[3][0] = tableComponent;
        c.gridx = 3;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;
        c.insets = insets;
        mainTiersPanel.add(tableComponent, c);

        tableComponent = new JLabel(ROLE);
        mainTierTable[4][0] = tableComponent;
        c.gridx = 4;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;
        c.insets = insets;
        mainTiersPanel.add(tableComponent, c);

        tableComponent = new JLabel(ID);
        mainTierTable[5][0] = tableComponent;
        c.gridx = 5;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;
        c.insets = insets;
        mainTiersPanel.add(tableComponent, c);

        tableComponent = new JLabel(LANGUAGE);
        mainTierTable[5][0] = tableComponent;
        c.gridx = 6;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;
        c.insets = insets;
        mainTiersPanel.add(tableComponent, c);

        // row for each top level tier
        Vector topTiers = TranscriptionUtil.getTopTiers(transcription);

        if (topTiers != null) {
            for (int i = 0; i < topTiers.size(); i++) {
                String tName = ((Tier) topTiers.elementAt(i)).getName();

                tableComponent = new JCheckBox();
                ((JCheckBox) tableComponent).setSelected(true);
                mainTierTable[0][i + 1] = tableComponent;
                c.gridx = 0;
                c.gridy = i + 1;
                c.anchor = GridBagConstraints.WEST;
                c.insets = insets;
                mainTiersPanel.add(tableComponent, c);

                tableComponent = new JLabel(tName);
                mainTierTable[1][i + 1] = tableComponent;
                c.gridx = 1;
                c.gridy = i + 1;
                c.anchor = GridBagConstraints.WEST;
                c.insets = insets;
                mainTiersPanel.add(tableComponent, c);

                tableComponent = new JTextField(3);

                String defaultName = "*";

                if (tName.startsWith("*") && (tName.length() == 4)) {
                    defaultName = tName;
                }

                ((JTextField) tableComponent).setText(defaultName);
                mainTierTable[2][i + 1] = tableComponent;
                c.gridx = 2;
                c.gridy = i + 1;
                c.anchor = GridBagConstraints.WEST;
                c.insets = insets;
                mainTiersPanel.add(tableComponent, c);

                tableComponent = new JTextField(15);
                mainTierTable[3][i + 1] = tableComponent;
                c.gridx = 3;
                c.gridy = i + 1;
                c.anchor = GridBagConstraints.WEST;
                c.insets = insets;
                mainTiersPanel.add(tableComponent, c);

                tableComponent = new JTextField(10);
                mainTierTable[4][i + 1] = tableComponent;
                c.gridx = 4;
                c.gridy = i + 1;
                c.anchor = GridBagConstraints.WEST;
                c.insets = insets;
                mainTiersPanel.add(tableComponent, c);

                tableComponent = new JTextField(25);
                mainTierTable[5][i + 1] = tableComponent;
                c.gridx = 5;
                c.gridy = i + 1;
                c.anchor = GridBagConstraints.WEST;
                c.insets = insets;
                mainTiersPanel.add(tableComponent, c);

                tableComponent = new JTextField(10);

                String language = ((TierImpl) topTiers.elementAt(i)).getDefaultLocale()
                                   .getLanguage();

                if ((language != null) && !language.equals("")) {
                    ((JTextField) tableComponent).setText(language);
                }

                mainTierTable[6][i + 1] = tableComponent;
                c.gridx = 6;
                c.gridy = i + 1;
                c.anchor = GridBagConstraints.WEST;
                c.insets = insets;
                mainTiersPanel.add(tableComponent, c);
            }
        }

        // dependent tiers panel
        dependentTiersPanel.setBorder(dependentTiersBorder);

        c.gridx = 0;
        c.gridy = 1;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.anchor = GridBagConstraints.NORTH;
        c.insets = insets;

        //getContentPane().add(dependentTiersPanel, c);
        mtPanel.add(dependentTiersPanel, c);

        // header row
        tableComponent = new JLabel(DEPENDENT_TIER);
        dependentTierTable[1][0] = tableComponent;
        c.gridx = 1;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;
        c.insets = insets;
        dependentTiersPanel.add(tableComponent, c);

        tableComponent = new JLabel(LABEL);
        dependentTierTable[1][0] = tableComponent;
        c.gridx = 2;
        c.gridy = 0;
        c.anchor = GridBagConstraints.WEST;
        c.insets = insets;
        dependentTiersPanel.add(tableComponent, c);

        // row for each dependent tier
        Vector tiers = null;

        int rowIndex = 1;

        tiers = transcription.getTiers();

        if (tiers != null) {
            for (int i = 0; i < tiers.size(); i++) {
                TierImpl t = (TierImpl) tiers.elementAt(i);

                if (t.hasParentTier()) {
                    tableComponent = new JCheckBox();
                    ((JCheckBox) tableComponent).setSelected(true);
                    dependentTierTable[0][rowIndex] = tableComponent;
                    c.gridx = 0;
                    c.gridy = rowIndex;
                    c.anchor = GridBagConstraints.WEST;
                    c.insets = insets;
                    dependentTiersPanel.add(tableComponent, c);

                    tableComponent = new JLabel(t.getName());
                    dependentTierTable[1][rowIndex] = tableComponent;
                    c.gridx = 1;
                    c.gridy = rowIndex;
                    c.anchor = GridBagConstraints.WEST;
                    c.insets = insets;
                    dependentTiersPanel.add(tableComponent, c);

                    String defaultName = "%";

                    if (t.getName().startsWith("%") &&
                            (t.getName().length() > 4) &&
                            (t.getName().charAt(4) == '@')) {
                        defaultName = t.getName().substring(0, 4);
                    }

                    tableComponent = new JTextField(3);
                    ((JTextField) tableComponent).setText(defaultName);
                    dependentTierTable[2][rowIndex] = tableComponent;
                    c.gridx = 2;
                    c.gridy = rowIndex;
                    c.anchor = GridBagConstraints.WEST;
                    c.insets = insets;
                    dependentTiersPanel.add(tableComponent, c);

                    rowIndex++;
                }
            }
        }

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.insets = insets;
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 1.0;
        c.weighty = 100.0;
        getContentPane().add(scrollPane, c);

        c.gridx = 0;
        c.gridy = 1;
        c.fill = GridBagConstraints.NONE;
        c.anchor = GridBagConstraints.SOUTH;
        c.weightx = 0.0;
        c.weighty = 0.0;
        c.insets = insets;
        getContentPane().add(buttonPanel, c);

        c.gridx = 0;
        c.gridy = 0;
        c.fill = GridBagConstraints.NONE;
        c.anchor = GridBagConstraints.NORTH;
        c.insets = insets;
        buttonPanel.add(exportButton, c);
    }

    private void setDefaultValues() {
        //		selectionOnlyCheckBox.setSelected(false);
        //		selectionOnlyCheckBox.setEnabled(false);
        //		selectionOnlyLabel.setEnabled(false);
        //		showTierLabelCheckBox.setSelected(interlinearizer.isTierLabelsShown());		
        //		widthTextField.setText(new Integer(initialWidth).toString());
    }

    /**
     * Update the UI elements according to the current Locale and the current
     * edit mode.
     */
    private void updateForLocale() {
        setTitle(ElanLocale.getString("ExportCHATDialog.Title"));

        mainTiersBorder.setTitle(ElanLocale.getString(
                "ExportCHATDialog.MainTiers"));
        dependentTiersBorder.setTitle(ElanLocale.getString(
                "ExportCHATDialog.DependentTiers"));

        exportButton.setText(ElanLocale.getString("ExportCHATDialog.Export"));
        exportButton.addActionListener(this);
    }

    //listeners
    public void actionPerformed(ActionEvent event) {
        if (event.getSource() == exportButton) {
            if (fieldsOK()) {
                showDialogAndSave();
            }
        }
    }

    private boolean fieldsOK() {
        boolean ok = true;

        // main tier table: all fields have to start with * and have length 4
        for (int i = 1; i < mainTierTable[2].length; i++) {
            if (((JCheckBox) mainTierTable[0][i]).isSelected()) {
                String text = ((JTextField) mainTierTable[2][i]).getText();

                if ((text.length() != 4) || !text.startsWith("*")) {
                    ok = false;

                    break;
                }
            }
        }

        // dependent tier table: all fields have to start with % and have length 4
        for (int i = 1; i < dependentTierTable[2].length; i++) {
            if (((JCheckBox) dependentTierTable[0][i]).isSelected()) {
                String text = ((JTextField) dependentTierTable[2][i]).getText();

                if ((text.length() != 4) || !text.startsWith("%")) {
                    ok = false;

                    break;
                }
            }
        }

        if (!ok) { // give error message
            JOptionPane.showMessageDialog(this,
                ElanLocale.getString("ExportCHATDlg.Message.WrongLabel"),
                ElanLocale.getString("Message.Error"), JOptionPane.ERROR_MESSAGE);
        }

        return ok;
    }

    private void showDialogAndSave() {
        // prompt for new file name
        String saveDir = (String) Preferences.get("LastUsedCHATDir", null);

        if (saveDir == null) {
            saveDir = (new File(transcription.getName())).getParent();

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

        // open dialog at directory of original eaf file
        JFileChooser chooser = new JFileChooser(saveDir);
        FileFilter filter = ElanFileFilter.createFileFilter(ElanFileFilter.CHAT_TYPE);

        chooser.setFileFilter(filter);
        chooser.setDialogTitle(ElanLocale.getString("ExportCHATDialog.Title"));

        //	int option = chooser.showSaveDialog(ELANCommandFactory.getRootFrame(
        //				tr));
        int option = chooser.showSaveDialog(this);

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

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

            File f = chooser.getSelectedFile();

            if (f != null) {
                // make sure pathname finishes with .cha extension
                String pathName = f.getAbsolutePath();
                String lowerPathName = pathName.toLowerCase();

                if (!lowerPathName.endsWith(".cha")) {
                    pathName += ".cha";
                }

                if ((new File(pathName)).exists()) {
                    int answer = JOptionPane.showConfirmDialog(null,
                            ElanLocale.getString("Message.Overwrite"),
                            ElanLocale.getString(
                                "ExportCHATDialog.Message.Title"),
                            JOptionPane.YES_NO_OPTION);

                    if (answer == JOptionPane.NO_OPTION) {
                        return;
                    }
                }

                // collect encoder information to pass on
                String[][] mainTierInfo = new String[mainTierTable.length - 1][mainTierTable[0].length -
                    1];
                String[][] dependentTierInfo = new String[dependentTierTable.length -
                    1][dependentTierTable[0].length - 1];

                int index = 0;

                for (int i = 1; i < mainTierTable[1].length; i++) {
                    if (((JCheckBox) mainTierTable[0][i]).isSelected()) {
                        mainTierInfo[0][index] = ((JLabel) mainTierTable[1][i]).getText();
                        mainTierInfo[1][index] = ((JTextField) mainTierTable[2][i]).getText();
                        mainTierInfo[2][index] = ((JTextField) mainTierTable[3][i]).getText();
                        mainTierInfo[3][index] = ((JTextField) mainTierTable[4][i]).getText();
                        mainTierInfo[4][index] = ((JTextField) mainTierTable[5][i]).getText();
                        mainTierInfo[5][index] = ((JTextField) mainTierTable[6][i]).getText();

                        index++;
                    }
                }

                index = 0;

                for (int j = 1; j < dependentTierTable[1].length; j++) {
                    if (((JCheckBox) dependentTierTable[0][j]).isSelected()) {
                        dependentTierInfo[0][index] = ((JLabel) dependentTierTable[1][j]).getText();
                        dependentTierInfo[1][index] = ((JTextField) dependentTierTable[2][j]).getText();

                        index++;
                    }
                }

                CHATEncoderInfo encoderInfo = new CHATEncoderInfo(mainTierInfo,
                        dependentTierInfo);

                acmTranscriptionStore.storeTranscriptionIn(transcription,
                    encoderInfo, visibleTiers, pathName, TranscriptionStore.CHAT);
            }
        }
    }
}
