/*
 * File:     StoreCommand.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.svg.SVGParserAndStore;

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

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

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

import java.io.File;

import java.util.Vector;

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


/**
 * DOCUMENT ME!
 *
 * @author Hennie Brugman
 */
public class StoreCommand implements Command {
    private String commandName;

    /**
     * Creates a new StoreCommand instance
     *
     * @param name DOCUMENT ME!
     */
    public StoreCommand(String name) {
        commandName = name;
    }

    //arguments:
    //[0]: ACM23TranscriptionStore eafTranscriptionStore
    //[1]: Boolean saveAsTemplate
    //[2]: Boolean saveNewCopy
    //[3]: Vector visibleTiers
    public void execute(Object receiver, Object[] arguments) {
        Transcription tr = (Transcription) receiver;
        ACM23TranscriptionStore eafTranscriptionStore = (ACM23TranscriptionStore) arguments[0];
        boolean saveAsTemplate = ((Boolean) arguments[1]).booleanValue();
        boolean saveNewCopy = ((Boolean) arguments[2]).booleanValue();
        Vector visibleTiers;

        if (arguments[3] != null) {
            visibleTiers = (Vector) arguments[3];
        } else {
            visibleTiers = ELANCommandFactory.getViewerManager(tr)
                                             .getMultiTierControlPanel()
                                             .getVisibleTiers();
        }

        if (saveNewCopy) {
            // prompt for new file name
            String saveDir = (String) Preferences.get("LastUsedEAFDir", null);

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

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

            // open dialog at directory of original eaf file
            JFileChooser chooser = new JFileChooser(saveDir);

            if (saveAsTemplate) {
                chooser.setFileFilter(ElanFileFilter.createFileFilter(
                        ElanFileFilter.TEMPLATE_TYPE));
                chooser.setDialogTitle(ElanLocale.getString(
                        "SaveDialog.Template.Title"));
            } else {
                chooser.setFileFilter(ElanFileFilter.createFileFilter(
                        ElanFileFilter.EAF_TYPE));
                chooser.setDialogTitle(ElanLocale.getString("SaveDialog.Title"));
            }

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

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

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

                File f = chooser.getSelectedFile();

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

                    if (!lowerPathName.endsWith(".eaf") &&
                            !lowerPathName.endsWith(".etf")) {
                        if (saveAsTemplate) {
                            pathName += ".etf";
                        } else {
                            pathName += ".eaf";
                        }
                    }

                    if ((new File(pathName)).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;
                        }
                    }

                    if (saveAsTemplate) {
                        eafTranscriptionStore.storeTranscriptionAsTemplateIn(tr,
                            visibleTiers, pathName);
                    } else {
                        eafTranscriptionStore.storeTranscriptionIn(tr, null,
                            visibleTiers, pathName, TranscriptionStore.EAF);

                        String name = pathName;
                        int lastSlashPos = name.lastIndexOf(System.getProperty(
                                    "file.separator"));

                        if (lastSlashPos >= 0) {
                            name = name.substring(lastSlashPos + 1);
                        }

                        //System.out.println("nm " + name);
                        tr.setName(name);

                        //tr.setName(pathName);
                        if (tr instanceof TranscriptionImpl) {
                            ((TranscriptionImpl) tr).setPathName(pathName);
                            ELANCommandFactory.getRootFrame(tr).setTitle("Elan - " +
                                tr.getName());
                        } else {
                            ELANCommandFactory.getRootFrame(tr).setTitle("Elan - " +
                                name);
                        }

                        tr.setUnchanged();

                        // check and update linked files, svg should be handled here too in the future
                        Vector linkedFiles = tr.getLinkedFileDescriptors();

                        if (linkedFiles.size() > 0) {
                            LinkedFileDescriptor lfd;

                            for (int i = 0; i < linkedFiles.size(); i++) {
                                lfd = (LinkedFileDescriptor) linkedFiles.get(i);

                                if (lfd.linkURL.endsWith("_tsconf.xml")) {
                                    // ELAN generated configuration file, copy
                                    String url = pathName.substring(0,
                                            pathName.length() - 4) +
                                        "_tsconf.xml";
                                    System.out.println("New conf: " + url);

                                    // copy conf
                                    try {
                                        File source = null;
                                        File dest = null;

                                        if (lfd.linkURL.startsWith("file:")) {
                                            source = new File(lfd.linkURL.substring(
                                                        5));
                                        } else {
                                            source = new File(lfd.linkURL);
                                        }

                                        if (url.startsWith("file:")) {
                                            dest = new File(url.substring(5));
                                        } else {
                                            dest = new File(url);
                                        }

                                        FileUtility.copyToFile(source, dest);
                                    } catch (Exception ex) {
                                        System.out.println(
                                            "Could not copy the configuration file.");
                                    }

                                    lfd.linkURL = url;
                                    tr.setChanged();
                                }
                            }
                        }

                        // save svg
                        // checks if there are any tiers allowing graphical annotations...
                        boolean saveSVG = false;

                        if (!saveSVG) {
                            Vector tiers = tr.getTiers();
                            TierImpl tier;

                            for (int i = 0; i < tiers.size(); i++) {
                                tier = (TierImpl) tiers.get(i);

                                if (tier.getLinguisticType()
                                            .hasGraphicReferences()) {
                                    saveSVG = true;

                                    break;
                                }
                            }
                        }

                        /*
                           if (!saveSVG) {
                               ((TranscriptionImpl) tr).setSVGFile(null);
                           }
                         */
                        if (!saveAsTemplate && /*SVGPrefs.getUseSVG()*/
                                saveSVG) {
                            int index = pathName.lastIndexOf(".eaf");
                            String svgFileName = pathName.substring(0, index) +
                                ".svg";
                            ((TranscriptionImpl) tr).setSVGFile(svgFileName);
                            SVGParserAndStore.storeSVG(tr);
                        }

                        // create a new backup timer
                        if (tr instanceof TranscriptionImpl) {
                            ((BackupCA) ELANCommandFactory.getCommandAction(tr,
                                ELANCommandFactory.BACKUP)).setFilePath(pathName);
                        }
                    }
                }
            }
        } else if (tr.isChanged()) {
            // check svg
            boolean saveSVG = false;
            Vector tiers = tr.getTiers();
            TierImpl tier;

            for (int i = 0; i < tiers.size(); i++) {
                tier = (TierImpl) tiers.get(i);

                if (tier.getLinguisticType().hasGraphicReferences()) {
                    saveSVG = true;

                    break;
                }
            }

            eafTranscriptionStore.storeTranscription(tr, null, visibleTiers, 0);

            /*
               if (!saveSVG) {
                   ((TranscriptionImpl) tr).setSVGFile(null);
               }
             */
            String svgFileName = ((TranscriptionImpl) tr).getSVGFile();

            if ((svgFileName == null) && saveSVG) {
                String pathName = ((TranscriptionImpl) tr).getPathName();
                int index = pathName.lastIndexOf(".eaf");
                String newSvgFileName = pathName.substring(0, index) + ".svg";
                ((TranscriptionImpl) tr).setSVGFile(newSvgFileName);
            }

            if ((svgFileName != null) || saveSVG) {
                SVGParserAndStore.storeSVG(tr);
            }

            //SVGParserAndStore.storeSVG(tr, null);    
            tr.setUnchanged();
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getName() {
        return commandName;
    }
}
