/*
 * File:     ExportImageFromWindowCommand.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.commands;

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

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

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

import mpi.library.util.LogUtil;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.image.BufferedImage;

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

import java.util.logging.Logger;

import javax.imageio.ImageIO;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;


/**
 * A Command for the export of an image of the Elan window.
 *
 * @author Han Sloetjes
 */
public class ExportImageFromWindowCommand implements Command {
    /** the Logger for this class */
    static final Logger LOG = Logger.getLogger(ExportImageFromWindowCommand.class.getName());
    private String commandName;

    /**
     * Creates a new Command for the export of an image of the Elan window.
     *
     * @param theName the name of the command
     */
    public ExportImageFromWindowCommand(String theName) {
        commandName = theName;
    }

    /**
     * <b>Note: </b>it is assumed the types and order of the arguments are
     * correct.
     *
     * @param receiver null
     * @param arguments the arguments:  <ul><li>arg[0] = the Transcription
     *        object (TranscriptionImpl)</li> </ul>
     */
    public void execute(Object receiver, Object[] arguments) {
        TranscriptionImpl transcription = (TranscriptionImpl) arguments[0];
        final JFrame frame = ELANCommandFactory.getRootFrame(transcription);

        // grab the frame and save
        String saveDir = (String) Preferences.get("MediaDir", null);

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

        JFileChooser chooser = new JFileChooser(saveDir);
        chooser.setFileFilter(ElanFileFilter.createFileFilter(
                ElanFileFilter.IMAGE_TYPE));

        int option = chooser.showSaveDialog(frame);

        if (option == JFileChooser.APPROVE_OPTION) {
            String imageIOType = "jpg";
            File curDir = chooser.getCurrentDirectory();

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

            File saveFile = chooser.getSelectedFile();

            if (saveFile != null) {
                String fileName = saveFile.getAbsolutePath();
                String lowerFileName = fileName.toLowerCase();

                if (lowerFileName.endsWith("png")) {
                    imageIOType = "png";
                } else if (!lowerFileName.endsWith("jpg") &&
                        !lowerFileName.endsWith("jpeg")) {
                    fileName += ".jpg";
                }

                final File newSaveFile = new File(fileName);

                if (newSaveFile.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;
                    }
                }

                // the actual saving is done on a seperate thread
                // this allows the UI to repaint after the disposal of the dialog
                new CaptureThread(frame, imageIOType, newSaveFile).start();
            }
        }
    }

    /**
     * Returns the name of the command
     *
     * @return the name of the command
     */
    public String getName() {
        return commandName;
    }

    /**
     * A Thread that uses the java.awt.Robot class to capture a part from the
     * screen and save it as a .jpg or .png file.
     *
     * @author Han Sloetjes
     */
    class CaptureThread extends Thread {
        private JFrame frame;
        private String imageType;
        private File saveFile;

        /**
         * Creates a new CaptureThread instance
         *
         * @param frame the Elan Frame to capture
         * @param imageType the image type as a String, either "jpg" or "png"
         * @param saveFile the File to save the image to
         */
        CaptureThread(JFrame frame, String imageType, File saveFile) {
            this.frame = frame;
            this.imageType = imageType;
            this.saveFile = saveFile;
        }

        /**
         * Creates a Robot, captures the part of the screen occupied by the frame
         * and writes the resulting image to file.
         */
        public void run() {
            try {
                Robot robot = new Robot();
                BufferedImage image = robot.createScreenCapture(frame.getBounds());

                //BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
                //Graphics2D g2d = image.createGraphics();
                //frame.paintAll(g2d);// does not receive the video image
                ImageIO.write(image, imageType, saveFile);
            } catch (AWTException ae) {
                LOG.warning(LogUtil.formatStackTrace(ae));
            } catch (IOException ioe) {
                LOG.warning(LogUtil.formatStackTrace(ioe));
            }
        }
    }
}
