/*
 * File:     DeleteTierCommand.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.util.AnnotationRecreator;

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

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

import java.awt.Cursor;

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

import javax.swing.tree.DefaultMutableTreeNode;


/**
 * Removes a tier from the transcription.
 *
 * @author Han Sloetjes
 */
public class DeleteTierCommand implements UndoableCommand {
    private String commandName;

    //state 
    private TierImpl tier;
    private Vector depTiers;
    private ArrayList annotationsNodes;

    // receiver
    private TranscriptionImpl transcription;

    /**
     * A command to delete a tier (and depending tiers) from a transcription.
     *
     * @param name the name of the command
     */
    public DeleteTierCommand(String name) {
        commandName = name;
    }

    /**
     * Adds the removed tier to the transcription.
     */
    public void undo() {
        if ((transcription != null) && (tier != null)) {
            int curPropMode = 0;

            curPropMode = transcription.getTimeChangePropagationMode();

            if (curPropMode != Transcription.NORMAL) {
                transcription.setTimeChangePropagationMode(Transcription.NORMAL);
            }

            setWaitCursor(true);

            TierImpl deptier;

            if (transcription.getTierWithId(tier.getName()) == null) {
                transcription.addTier(tier);
            }

            if (depTiers != null) {
                for (int i = 0; i < depTiers.size(); i++) {
                    deptier = (TierImpl) depTiers.get(i);

                    if (transcription.getTierWithId(deptier.getName()) == null) {
                        transcription.addTier(deptier);
                    }
                }
            }

            if (annotationsNodes.size() > 0) {
                transcription.setNotifying(false);

                DefaultMutableTreeNode node;

                if (tier.hasParentTier()) {
                    AnnotationRecreator.createAnnotationsSequentially(transcription,
                        annotationsNodes);
                } else {
                    for (int i = 0; i < annotationsNodes.size(); i++) {
                        node = (DefaultMutableTreeNode) annotationsNodes.get(i);
                        AnnotationRecreator.createAnnotationFromTree(transcription,
                            node);
                    }
                }

                transcription.setNotifying(true);
            }

            setWaitCursor(false);

            // restore the time propagation mode
            transcription.setTimeChangePropagationMode(curPropMode);
        }
    }

    /**
     * Again removes the tier from the transcription.
     */
    public void redo() {
        if ((transcription == null) || (tier == null)) {
            return;
        }

        transcription.removeTier(tier);

        if (depTiers != null) {
            for (int i = 0; i < depTiers.size(); i++) {
                transcription.removeTier((TierImpl) depTiers.get(i));
            }
        }
    }

    /**
     * <b>Note: </b>it is assumed the types and order of the arguments are
     * correct.
     *
     * @param receiver the transcription
     * @param arguments the arguments:  <ul><li>arg[0] = the tier to remove
     *        (TierImpl)</li> </ul>
     */
    public void execute(Object receiver, Object[] arguments) {
        if (receiver instanceof TranscriptionImpl) {
            transcription = (TranscriptionImpl) receiver;
        } else {
            return;
        }

        tier = (TierImpl) arguments[0];

        if (tier == null) {
            return;
        }

        depTiers = tier.getDependentTiers();

        // first store all annotations
        annotationsNodes = new ArrayList();

        Vector annos = tier.getAnnotations();
        Iterator anIter = annos.iterator();
        AbstractAnnotation ann;

        while (anIter.hasNext()) {
            ann = (AbstractAnnotation) anIter.next();
            annotationsNodes.add(AnnotationRecreator.createTreeForAnnotation(
                    ann));
        }

        // then remove the tiers			
        if (depTiers != null) {
            for (int i = 0; i < depTiers.size(); i++) {
                transcription.removeTier((TierImpl) depTiers.get(i));
            }
        }

        transcription.removeTier(tier);
    }

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

    /**
     * Changes the cursor to either a 'busy' cursor or the default cursor.
     *
     * @param showWaitCursor when <code>true</code> show the 'busy' cursor
     */
    private void setWaitCursor(boolean showWaitCursor) {
        if (showWaitCursor) {
            ELANCommandFactory.getRootFrame(transcription).getRootPane()
                              .setCursor(Cursor.getPredefinedCursor(
                    Cursor.WAIT_CURSOR));
        } else {
            ELANCommandFactory.getRootFrame(transcription).getRootPane()
                              .setCursor(Cursor.getDefaultCursor());
        }
    }
}
