/*
 * File:     ExtractStep3.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.timeseries;

import mpi.eudico.client.annotator.ElanLocale;

import mpi.eudico.client.annotator.commands.Command;
import mpi.eudico.client.annotator.commands.ELANCommandFactory;
import mpi.eudico.client.annotator.commands.ExtractTrackDataCommand;

import mpi.eudico.client.annotator.gui.multistep.MultiStepPane;
import mpi.eudico.client.annotator.gui.multistep.StepPane;

import mpi.eudico.client.annotator.util.ClientLogger;
import mpi.eudico.client.annotator.util.ProgressListener;

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

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.border.EmptyBorder;


/**
 * The final step of the extraction process.  Closes the wizard when finished.
 *
 * @author Han Sloetjes
 * @version 1.0
 */
public class ExtractStep3 extends StepPane implements ClientLogger,
    ProgressListener {
    private TranscriptionImpl transcription;
    private TSTrackManager manager;
    private JProgressBar progressBar;
    private JLabel progressLabel;
    private Command command;

    /**
     * Creates a new ExtractStep3 instance, the final step.
     *
     * @param multiPane the container multistep pane
     * @param transcription the transcription containing source and destination
     *        tier
     * @param manager the track manager containing the time series tracks
     */
    public ExtractStep3(MultiStepPane multiPane,
        TranscriptionImpl transcription, TSTrackManager manager) {
        super(multiPane);
        this.transcription = transcription;
        this.manager = manager;
        initComponents();
    }

    /**
     * Initialize ui components etc. a label and a progressbar.
     */
    public void initComponents() {
        // setPreferredSize
        setLayout(new GridBagLayout());
        setBorder(new EmptyBorder(12, 12, 12, 12));

        Insets insets = new Insets(4, 6, 4, 6);

        progressLabel = new JLabel(ElanLocale.getString(
                    "TimeSeriesViewer.Extract.Extracting"));
        progressBar = new JProgressBar(JProgressBar.HORIZONTAL, 0, 100);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.insets = insets;
        add(progressLabel, gbc);

        progressBar = new JProgressBar(JProgressBar.HORIZONTAL, 0, 100);
        progressBar.setValue(0);

        gbc = new GridBagConstraints();
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.insets = insets;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1.0;
        add(progressBar, gbc);
    }

    /**
     * Returns the title of this step.
     *
     * @return the title
     */
    public String getStepTitle() {
        return ElanLocale.getString("TimeSeriesViewer.Extract.Extracting");
    }

    /**
     * Starts the actual extraction progress in a separate thread. Closes the
     * dialog on finish.
     *
     * @return false
     */
    public boolean doFinish() {
        multiPane.setButtonEnabled(MultiStepPane.ALL_BUTTONS, false);

        String sourceTierName = (String) multiPane.getStepProperty("SourceTier");
        String destTierName = (String) multiPane.getStepProperty("DestTier");
        String trackName = (String) multiPane.getStepProperty("TrackName");
        String method = (String) multiPane.getStepProperty("Calc");

        if (method == null) {
            LOG.warning("Unknown calculation method.");
            notifyCancel(ElanLocale.getString(
                    "TimeSeriesViewer.Extract.NoMethod"));

            return false;
        }

        String overwr = (String) multiPane.getStepProperty("Overwrite");
        boolean overwrite = true;

        if ("false".equals(overwr)) {
            overwrite = false;
        }

        TierImpl sourceTier = (TierImpl) transcription.getTierWithId(sourceTierName);

        if (sourceTier == null) {
            LOG.warning("Source tier is null: " + sourceTierName);
            notifyCancel(ElanLocale.getString(
                    "TimeSeriesViewer.Extract.NotFound") + " " +
                sourceTierName);

            return false;
        }

        TierImpl destTier = (TierImpl) transcription.getTierWithId(destTierName);

        if (destTier == null) {
            LOG.warning("Destination tier is null: " + destTierName);
            notifyCancel(ElanLocale.getString(
                    "TimeSeriesViewer.Extract.NotFound") + " " + destTierName);

            return false;
        }

        AbstractTSTrack track = manager.getTrack(trackName);

        if (track == null) {
            LOG.warning("Track is null: " + trackName);
            notifyCancel(ElanLocale.getString(
                    "TimeSeriesViewer.Extract.NotFound") + " " + trackName);

            return false;
        }

        command = ELANCommandFactory.createCommand(transcription,
                ELANCommandFactory.EXT_TRACK_DATA);
        ((ExtractTrackDataCommand) command).addProgressListener(this);

        command.execute(transcription,
            new Object[] {
                sourceTierName, destTierName, track, method,
                new Boolean(overwrite)
            });

        // the action is performed on a separate thread, don't close
        return false;
    }

    /**
     * This is a "finish only" step, no user interaction required. Delegates to
     * doFinish().
     */
    public void enterStepForward() {
        doFinish();
    }

    private void notifyCancel(String message) {
        JOptionPane.showMessageDialog(this, message,
            ElanLocale.getString("Message.Warning"), JOptionPane.WARNING_MESSAGE);
        multiPane.setButtonEnabled(MultiStepPane.CANCEL_BUTTON, true);
        multiPane.setButtonEnabled(MultiStepPane.PREVIOUS_BUTTON, true);
    }

    /**
     * @see mpi.eudico.client.annotator.util.ProgressListener#progressUpdated(java.lang.Object,
     *      int, java.lang.String)
     */
    public void progressUpdated(Object source, int percent, String message) {
        if ((progressLabel != null) && (message != null)) {
            progressLabel.setText(message);
        }

        if (percent < 0) {
            percent = 0;
        } else if (percent > 100) {
            percent = 100;
        }

        progressBar.setValue(percent);

        if (percent >= 100) {
            showMessageDialog("Operation completed");

            if (command != null) {
                ((ExtractTrackDataCommand) command).removeProgressListener(this);
            }

            multiPane.close();
        }
    }

    /**
     * @see mpi.eudico.client.annotator.util.ProgressListener#progressCompleted(java.lang.Object,
     *      java.lang.String)
     */
    public void progressCompleted(Object source, String message) {
        if (progressLabel != null) {
            progressLabel.setText(message);
        }

        showMessageDialog("Operation completed");

        if (command != null) {
            ((ExtractTrackDataCommand) command).removeProgressListener(this);
        }

        multiPane.close();
    }

    /**
     * @see mpi.eudico.client.annotator.util.ProgressListener#progressInterrupted(java.lang.Object,
     *      java.lang.String)
     */
    public void progressInterrupted(Object source, String message) {
        if (progressLabel != null) {
            progressLabel.setText(message);
        }

        // message dialog
        showWarningDialog("Operation interrupted: " + message);

        if (command != null) {
            ((ExtractTrackDataCommand) command).removeProgressListener(this);
        }

        multiPane.close();
    }

    /**
     * Shows a warning/error dialog with the specified message string.
     *
     * @param message the message to display
     */
    private void showWarningDialog(String message) {
        JOptionPane.showMessageDialog(this, message,
            ElanLocale.getString("Message.Warning"), JOptionPane.WARNING_MESSAGE);
    }

    /**
     * Shows a message dialog with the specified message string.
     *
     * @param message the message to display
     */
    private void showMessageDialog(String message) {
        JOptionPane.showMessageDialog(this, message, null,
            JOptionPane.INFORMATION_MESSAGE);
    }
}
