/*
 * File:     EditTierDialog.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.gui;

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

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

import mpi.eudico.client.im.ImUtil;

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

import mpi.eudico.server.corpora.clomimpl.abstr.TierImpl;
import mpi.eudico.server.corpora.clomimpl.abstr.TranscriptionImpl;
import mpi.eudico.server.corpora.clomimpl.type.Constraint;
import mpi.eudico.server.corpora.clomimpl.type.LinguisticType;

import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Locale;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;


/**
 * The DefineTierDialog is a custom dialog for adding an Tier resp. changing
 * the attributes of a Tier.
 *
 * @author Alexander Klassmann
 * @version 2.0 nov 03
 * @version Aug 2005 Identity removed
 */
public class EditTierDialog extends JDialog implements ActionListener,
    ItemListener {
    /** Holds value of property DOCUMENT ME! */
    public static final int ADD = 0;

    /** Holds value of property DOCUMENT ME! */
    public static final int CHANGE = 1;

    /** Holds value of property DOCUMENT ME! */
    public static final int DELETE = 2;
    private TierImpl tier = null;
    private TierImpl oldParentTier;
    private TranscriptionImpl transcription;
    private String oldTierName;
    private String oldParentTierName;
    private String oldParticipant;
    private LinguisticType oldLingType;
    private Locale oldLocale;
    private Locale[] langs;

    /** Holds value of property DOCUMENT ME! */
    final private String none = "none";
    private int mode = CHANGE;
    private boolean singleEditMode = false;
    private Vector tiers;

    //Components

    /** Holds value of property DOCUMENT ME! */
    final private JLabel titleLabel = new JLabel();

    /** Holds value of property DOCUMENT ME! */
    final private JLabel selectTierLabel = new JLabel();

    /** Holds value of property DOCUMENT ME! */
    final private JLabel tierNameLabel = new JLabel();

    /** Holds value of property DOCUMENT ME! */
    final private JLabel participantLabel = new JLabel();

    /** Holds value of property DOCUMENT ME! */
    final private JLabel lingTypeLabel = new JLabel();

    /** Holds value of property DOCUMENT ME! */
    final private JLabel parentLabel = new JLabel();

    /** Holds value of property DOCUMENT ME! */
    final private JLabel languageLabel = new JLabel();

    /** Holds value of property DOCUMENT ME! */
    final private JTextField tierNameTextField = new JTextField(30);

    /** Holds value of property DOCUMENT ME! */
    final private JTextField participantTextField = new JTextField(30);

    /** Holds value of property DOCUMENT ME! */
    final private JComboBox lingTypeChoice = new JComboBox();

    /** Holds value of property DOCUMENT ME! */
    final private JComboBox languageChoice = new JComboBox();

    /** Holds value of property DOCUMENT ME! */
    final private JComboBox parentChoice = new JComboBox();

    /** Holds value of property DOCUMENT ME! */
    final private JComboBox currentTiersComboBox = new JComboBox();

    /** Holds value of property DOCUMENT ME! */
    final private JButton changeButton = new JButton();

    /** Holds value of property DOCUMENT ME! */
    final private JButton cancelButton = new JButton();

    /** Holds value of property DOCUMENT ME! */
    final private JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 6, 2));

    /** Holds value of property DOCUMENT ME! */
    final private Frame frame;

    /**
     * A modal dialog for creating, changing or deleting a tier.
     *
     * @param parentFrame the parent or root frame
     * @param modal whether the dialog should be modal or not
     * @param theTranscription the Transcription containing the tiers
     * @param editMode the type of dialog, ADD, CHANGE or DELETE
     * @param tier the tier to initialise the dialog for
     */
    public EditTierDialog(Frame parentFrame, boolean modal,
        Transcription theTranscription, int editMode, TierImpl tier) {
        super(parentFrame, modal);
        frame = parentFrame;
        transcription = (TranscriptionImpl) theTranscription;

        if ((editMode == ADD) || (editMode == CHANGE) || (editMode == DELETE)) {
            mode = editMode;
        }

        extractCurrentTiers();
        createDialog();
        updateForModeAndLocale();

        if (tier != null) {
            this.tier = tier;

            String name = tier.getName();
            singleEditMode = true;

            if (currentTiersComboBox != null) {
                currentTiersComboBox.setSelectedItem(name);
            }
        }

        pack();
        setResizable(false);
        setLocationRelativeTo(frame);

        if (editMode == ADD) {
            tierNameTextField.requestFocus();
        }
    }

    /**
     * Fill the tiers combobox with the currently present tiers.
     */
    private void extractCurrentTiers() {
        currentTiersComboBox.removeItemListener(this);
        currentTiersComboBox.removeAllItems();
        tiers = transcription.getTiers();

        if (tiers == null) {
            tiers = new Vector();

            return;
        }

        Iterator tierIt = tiers.iterator();

        while (tierIt.hasNext()) {
            TierImpl t = (TierImpl) tierIt.next();
            currentTiersComboBox.addItem(t.getName());
        }

        if (currentTiersComboBox.getItemCount() > 0) {
            currentTiersComboBox.setSelectedIndex(0);
            tier = (TierImpl) tiers.get(0);
        }

        currentTiersComboBox.addItemListener(this);
    }

    /**
     * Again extract the tiers from the transcription after an add,  change or
     * delete operation.
     */
    private void reextractTiers() {
        extractCurrentTiers();

        if (currentTiersComboBox.getItemCount() > 0) {
            currentTiersComboBox.setSelectedIndex(0);
        } else {
            tierNameTextField.setText("");
            participantTextField.setText("");
        }

        if (mode == ADD) {
            tierNameTextField.setText("");
            participantTextField.setText("");
        }
    }

    /**
     * Update the UI elements according to the current Locale and the current
     * edit mode.
     */
    private void updateForModeAndLocale() {
        tierNameLabel.setText(ElanLocale.getString(
                "EditTierDialog.Label.TierName"));
        participantLabel.setText(ElanLocale.getString(
                "EditTierDialog.Label.Participant"));
        lingTypeLabel.setText(ElanLocale.getString(
                "EditTierDialog.Label.LinguisticType"));
        parentLabel.setText(ElanLocale.getString("EditTierDialog.Label.Parent"));
        languageLabel.setText(ElanLocale.getString(
                "EditTierDialog.Label.Language"));
        cancelButton.setText(ElanLocale.getString("Button.Close"));

        switch (mode) {
        case ADD:
            setTitle(ElanLocale.getString("EditTierDialog.Title.Add"));
            selectTierLabel.setText(ElanLocale.getString(
                    "EditTierDialog.Label.CurrentTiers"));
            changeButton.setText(ElanLocale.getString("Button.Add"));

            break;

        case CHANGE:
            setTitle(ElanLocale.getString("EditTierDialog.Title.Change"));
            selectTierLabel.setText(ElanLocale.getString(
                    "EditTierDialog.Label.ChangeTier"));
            changeButton.setText(ElanLocale.getString("Button.Change"));
            parentChoice.setEnabled(false);

            break;

        case DELETE:
            setTitle(ElanLocale.getString("EditTierDialog.Title.Delete"));
            selectTierLabel.setText(ElanLocale.getString(
                    "EditTierDialog.Label.DeleteTier"));
            changeButton.setText(ElanLocale.getString("Button.Delete"));
            tierNameTextField.setEditable(false);
            participantTextField.setEditable(false);
            parentChoice.setEnabled(false);
            lingTypeChoice.setEnabled(false);
            languageChoice.setEnabled(false);

            break;
        }

        titleLabel.setText(getTitle());
    }

    private void createDialog() {
        //Initialisation of the Components
        titleLabel.setFont(titleLabel.getFont().deriveFont((float) 16));
        currentTiersComboBox.addItemListener(this);
        fillParentComboBox();
        fillLingTypeMenu();

        langs = ImUtil.getLanguages(this);

        updateLanguageChoice();

        changeButton.addActionListener(this);
        cancelButton.addActionListener(this);

        buttonPanel.add(changeButton);
        buttonPanel.add(cancelButton);

        addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent event) {
                    dispose();
                }
            });

        //Dependencies
        //Put them into the dialog
        getContentPane().setLayout(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();

        c.anchor = GridBagConstraints.NORTH;
        c.gridwidth = GridBagConstraints.REMAINDER;
        getContentPane().add(titleLabel, c);

        c.anchor = GridBagConstraints.WEST;
        c.gridwidth = 1;
        c.insets = new Insets(2, 6, 2, 6);
        getContentPane().add(selectTierLabel, c);

        currentTiersComboBox.setMaximumRowCount(Constants.COMBOBOX_VISIBLE_ROWS);
        c.gridwidth = GridBagConstraints.REMAINDER;
        getContentPane().add(currentTiersComboBox, c);

        c.anchor = GridBagConstraints.WEST;
        c.gridwidth = 1;
        getContentPane().add(tierNameLabel, c);

        c.gridwidth = GridBagConstraints.REMAINDER;
        getContentPane().add(tierNameTextField, c);

        c.gridwidth = 1;
        getContentPane().add(participantLabel, c);

        c.gridwidth = GridBagConstraints.REMAINDER;
        getContentPane().add(participantTextField, c);

        c.gridwidth = 1;

        // add(lingTypeLabel,c);	// HB, 16 aug 02 change order LT and parent choices
        // HS 22-10-2002: the intention of the negative parameters is to get the same
        // vertical distances  between the textFields and the choice menus (the default
        // height of a textField is e.g. 23 pixel, but the one of a choice menu is 21
        getContentPane().add(parentLabel, c);

        parentChoice.setMaximumRowCount(Constants.COMBOBOX_VISIBLE_ROWS);
        c.gridwidth = GridBagConstraints.REMAINDER;
        getContentPane().add(parentChoice, c);

        c.gridwidth = 1;
        getContentPane().add(lingTypeLabel, c);

        lingTypeChoice.setMaximumRowCount(Constants.COMBOBOX_VISIBLE_ROWS);
        c.gridwidth = GridBagConstraints.REMAINDER;
        getContentPane().add(lingTypeChoice, c);

        c.gridwidth = 1;
        getContentPane().add(languageLabel, c);

        languageChoice.setMaximumRowCount(Constants.COMBOBOX_VISIBLE_ROWS);
        c.gridwidth = GridBagConstraints.REMAINDER;
        getContentPane().add(languageChoice, c);

        c.anchor = GridBagConstraints.SOUTH;
        c.fill = GridBagConstraints.NONE;
        getContentPane().add(buttonPanel, c);
        updateUIForTier((String) currentTiersComboBox.getSelectedItem());
        pack();
        setResizable(false);
        setLocationRelativeTo(frame);
    }

    /**
     * Empties and refills the Linguistic Type menu with types that are not
     * excluded by the current parent tier choice.
     */
    private void fillLingTypeMenu() {
        lingTypeChoice.removeItemListener(this);
        lingTypeChoice.removeAllItems();

        TierImpl parentTier = (TierImpl) (transcription.getTierWithId((String) parentChoice.getSelectedItem()));

        boolean excludeTimeSubDiv = false;

        Constraint parentConstraint = null;

        if (parentTier != null) {
            parentConstraint = parentTier.getLinguisticType().getConstraints();

            if (parentConstraint != null) {
                if ((parentConstraint.getStereoType() == Constraint.SYMBOLIC_SUBDIVISION) ||
                        (parentConstraint.getStereoType() == Constraint.SYMBOLIC_ASSOCIATION)) {
                    excludeTimeSubDiv = true;
                }
            }
        }

        Enumeration e = transcription.getLinguisticTypes().elements();

        while (e.hasMoreElements()) {
            LinguisticType lt = (LinguisticType) e.nextElement();
            String ltName = lt.getLinguisticTypeName();

            if (excludeTimeSubDiv && (lt.getConstraints() != null) &&
                    ((lt.getConstraints().getStereoType() == Constraint.TIME_SUBDIVISION) ||
                    (lt.getConstraints().getStereoType() == Constraint.INCLUDED_IN))) {
                continue;
            }

            if (parentTier == null) { // only unconstrained types

                if (lt.getConstraints() != null) {
                    continue;
                }
            }

            if (parentTier != null) { // only constrained types

                if (lt.getConstraints() == null) {
                    continue;
                }
            }

            lingTypeChoice.addItem(ltName);
        }

        // set selected the current type of the selected tier
        String tierName = (String) currentTiersComboBox.getSelectedItem();

        if (tierName != null) {
            TierImpl tier = (TierImpl) transcription.getTierWithId(tierName);

            if (tier != null) {
                LinguisticType type = tier.getLinguisticType();

                if (type != null) {
                    lingTypeChoice.setSelectedItem(type.getLinguisticTypeName());
                }
            }
        }

        lingTypeChoice.addItemListener(this);

        if (lingTypeChoice.getModel().getSize() <= 0) {
            changeButton.setEnabled(false);
        } else {
            changeButton.setEnabled(true);
        }
    }

    /**
     * Fills the parent tier combobox with the potential parent tiers for the
     * specified tier.
     */
    private void fillParentComboBox() {
        parentChoice.removeItemListener(this);
        parentChoice.removeAllItems();
        parentChoice.addItem(none);

        if ((tier != null) && (mode != ADD)) {
            Vector candidateParents = transcription.getCandidateParentTiers(tier);
            Iterator pIter = candidateParents.iterator();

            while (pIter.hasNext()) {
                parentChoice.addItem(((Tier) pIter.next()).getName());
            }

            if (tier.hasParentTier()) {
                parentChoice.setSelectedItem(tier.getParentTier().getName());
            }
        } else if (mode == ADD) {
            Iterator tierIt = tiers.iterator();

            while (tierIt.hasNext()) {
                TierImpl t = (TierImpl) tierIt.next();
                parentChoice.addItem(t.getName());
            }

            parentChoice.setSelectedItem(none);
        }

        parentChoice.addItemListener(this);
    }

    /**
     * Gets the Locale of the currently selected tier and tries to set this
     * Locale as the selected item in the language combo box.<br>
     * If the tier has a Locale that is not in the list, add it to the list.
     */
    private void updateLanguageChoice() {
        languageChoice.removeAllItems();

        if (langs != null) {
            for (int i = 0; i < langs.length; i++) {
                languageChoice.addItem(langs[i].getDisplayName());
            }
        }

        if (tier != null) {
            Locale l = tier.getDefaultLocale();

            if (l != null) {
                /*
                   List al = Arrays.asList(langs);
                   if (!al.contains(l)) {
                       languageChoice.addItem(l.getDisplayName());
                   }
                 */
                languageChoice.setSelectedItem(l.getDisplayName());
            } else {
                languageChoice.setSelectedIndex(0);
            }
        }
    }

    private void updateUIForTier(String name) {
        if (name != null) {
            tier = (TierImpl) transcription.getTierWithId(name);

            if (tier != null) {
                oldParentTier = (TierImpl) tier.getParentTier();

                if (oldParentTier != null) {
                    oldParentTierName = tier.getParentTier().getName();
                } else {
                    oldParentTierName = none;
                }

                oldLingType = tier.getLinguisticType();
                oldLocale = tier.getDefaultLocale();
                oldTierName = tier.getName();
                oldParticipant = tier.getParticipant();

                if (mode != ADD) {
                    tierNameTextField.setText(oldTierName);
                    participantTextField.setText(oldParticipant);
                }
            }

            fillParentComboBox();
            fillLingTypeMenu();
            updateLanguageChoice();
        }
    }

    //Various Listeners
    public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            if (e.getSource() == currentTiersComboBox) {
                String name = (String) currentTiersComboBox.getSelectedItem();
                updateUIForTier(name);
            } else if ((e.getSource() == lingTypeChoice) && (mode == CHANGE)) {
                if ((tier != null) && (tier.getNumberOfAnnotations() > 0)) {
                    // warn if more than 0 annotations and stereotype is different
                    String newTypeName = (String) e.getItem();
                    boolean stereoTypeChanged = false;
                    int newStereoType = getStereoTypeForTypeName(newTypeName);
                    int oldStereoType = getStereoTypeForType(oldLingType);

                    if (newStereoType != oldStereoType) {
                        stereoTypeChanged = true;
                    }

                    if (!oldLingType.getLinguisticTypeName().equals(newTypeName) &&
                            stereoTypeChanged) {
                        StringBuffer buf = new StringBuffer(ElanLocale.getString(
                                    "EditTierDialog.Message.RecommendType"));
                        buf.append("\n");
                        buf.append(ElanLocale.getString(
                                "EditTierDialog.Message.Corrupt"));

                        JOptionPane.showMessageDialog(this, buf.toString(),
                            ElanLocale.getString("Message.Warning"),
                            JOptionPane.WARNING_MESSAGE);

                        // HS sep-04 prevent changing the lin. type when there are annotations   
                        lingTypeChoice.setSelectedItem(oldLingType.getLinguisticTypeName());
                    }
                }
            } else if (e.getSource() == parentChoice) {
                if ((mode == CHANGE) && (tier != null) &&
                        (tier.getNumberOfAnnotations() > 0)) {
                    if (!(oldParentTierName.equals((String) e.getItem()))) {
                        StringBuffer buf = new StringBuffer(ElanLocale.getString(
                                    "EditTierDialog.Message.RecommendParent"));
                        buf.append("\n");
                        buf.append(ElanLocale.getString(
                                "EditTierDialog.Message.Corrupt"));
                        JOptionPane.showMessageDialog(this, buf.toString(),
                            ElanLocale.getString("Message.Warning"),
                            JOptionPane.WARNING_MESSAGE);

                        // HS sep-04 prevent changing the parent when there are annotations    
                        parentChoice.setSelectedItem(oldParentTierName);
                    }
                } else {
                    // suggest the participant name from the parent...
                    String partiName = participantTextField.getText();

                    if ((partiName == null) ||
                            (partiName.trim().length() == 0)) {
                        TierImpl parent = (TierImpl) transcription.getTierWithId((String) e.getItem());

                        if (parent != null) {
                            participantTextField.setText(parent.getParticipant());
                        }
                    }
                }

                fillLingTypeMenu();
            }
        }
    }

    /**
     * Adds a new tier to the transcription.
     *
     * @param tierName the name of the new tier
     * @param parentTier DOCUMENT ME!
     * @param lingType DOCUMENT ME!
     * @param participant DOCUMENT ME!
     * @param locale DOCUMENT ME!
     */
    private void doAdd(String tierName, Tier parentTier, String lingType,
        String participant, Locale locale) {
        Command c = ELANCommandFactory.createCommand(transcription,
                ELANCommandFactory.ADD_TIER);

        Object receiver = transcription;
        Object[] args = new Object[5];
        args[0] = tierName;
        args[1] = parentTier;
        args[2] = lingType;
        args[3] = participant;
        args[4] = locale;

        c.execute(receiver, args);

        // update the dialog ui
        reextractTiers();

        // warn if this is the first tier with a linguistic type 
        // allowing graphic refs.
        TierImpl tt = (TierImpl) transcription.getTierWithId(tierName);

        if ((tt != null) && tt.getLinguisticType().hasGraphicReferences()) {
            checkGraphics(tt);
        }
    }

    /**
     * Changes properties of a tier.
     *
     * @param tierName new name of the tier
     * @param parentTier the parent tier
     * @param lingType the linguistic type
     * @param participant the participant
     * @param locale the locale
     */
    private void doChange(String tierName, Tier parentTier, String lingType,
        String participant, Locale locale) {
        // double check on parent and type
        if (tier.getAnnotations().size() > 0) {
            if (((parentTier != null) && (oldParentTier == null)) ||
                    ((parentTier == null) && (oldParentTier != null)) ||
                    (parentTier != oldParentTier)) {
                parentTier = oldParentTier;
            }

            if (getStereoTypeForTypeName(lingType) != getStereoTypeForType(
                        oldLingType)) {
                lingType = oldLingType.getLinguisticTypeName();
            }
        }

        // check whether something has changed
        if (!tierName.equals(oldTierName) ||
                ((parentTier != null) && (oldParentTier != null) &&
                (parentTier != oldParentTier)) ||
                !lingType.equals(oldLingType.getLinguisticTypeName()) ||
                !participant.equals(oldParticipant) ||
                ((locale != null) && (locale != oldLocale))) {
            Command c = ELANCommandFactory.createCommand(transcription,
                    ELANCommandFactory.CHANGE_TIER);

            Object receiver = tier;
            Object[] args = new Object[5];
            args[0] = tierName;
            args[1] = parentTier;
            args[2] = lingType;
            args[3] = participant;
            args[4] = locale;

            c.execute(receiver, args);

            // notify if this is the first tier allowing graphic references
            if (tier.getLinguisticType().hasGraphicReferences() &&
                    !lingType.equals(oldLingType.getLinguisticTypeName())) {
                checkGraphics(tier);
            }

            if (singleEditMode) {
                // dispose
                dispose();
            } else {
                // update the dialog ui
                reextractTiers();
            }
        } else {
            //System.out.println("no change");
        }
    }

    /**
     * Actually deletes the tier.
     */
    private void doDelete() {
        if (tier != null) {
            Vector depTiers = tier.getDependentTiers();
            StringBuffer mesBuf = new StringBuffer();
            mesBuf.append(ElanLocale.getString(
                    "EditTierDialog.Message.ConfirmDelete"));
            mesBuf.append("  ");
            mesBuf.append(oldTierName);
            mesBuf.append(" ?\n");

            if ((depTiers != null) && (depTiers.size() > 0)) {
                mesBuf.append(ElanLocale.getString(
                        "EditTierDialog.Message.AlsoDeleted"));

                Iterator depIt = depTiers.iterator();

                while (depIt.hasNext()) {
                    Tier t = (Tier) depIt.next();
                    mesBuf.append("\n-   ");

                    mesBuf.append(t.getName());
                }
            }

            int option = JOptionPane.showConfirmDialog(this, mesBuf.toString(),
                    ElanLocale.getString("Message.Warning"),
                    JOptionPane.YES_NO_OPTION);

            if (option == JOptionPane.YES_OPTION) {
                Object[] args = new Object[] { tier };
                Command c = ELANCommandFactory.createCommand(transcription,
                        ELANCommandFactory.DELETE_TIER);
                c.execute(transcription, args);

                if (singleEditMode) {
                    // dispose
                    dispose();
                } else {
                    // update the dialog ui
                    reextractTiers();
                }
            }
        }
    }

    /**
     * Checks whether this is the first tier with a linguistic type that allows
     * graphic annotations. Shows a warning message if so.
     *
     * @param ti the changed or new tier
     */
    private void checkGraphics(TierImpl ti) {
        int numGraphicTiers = 1;

        Vector tiers = transcription.getTiers();
        Iterator tierIt = tiers.iterator();
        TierImpl t;

        while (tierIt.hasNext()) {
            t = (TierImpl) tierIt.next();

            if ((t != ti) && t.getLinguisticType().hasGraphicReferences()) {
                numGraphicTiers++;
            }
        }

        if ((numGraphicTiers == 1) &&
                ((transcription.getSVGFile() == null) ||
                (transcription.getSVGFile().length() == 0))) {
            JOptionPane.showMessageDialog(this,
                ElanLocale.getString("EditTierDialog.Message.Graphics"),
                ElanLocale.getString("Message.Warning"),
                JOptionPane.WARNING_MESSAGE);
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param event DOCUMENT ME!
     */
    public void actionPerformed(ActionEvent event) {
        if (event.getSource() == changeButton) {
            if (mode == DELETE) {
                doDelete();

                return;
            } else {
                String tierName = tierNameTextField.getText();
                tierName.replace('\n', ' ');
                tierName.trim();

                if (tierName.length() == 0) {
                    tierNameTextField.requestFocus();
                    JOptionPane.showMessageDialog(this,
                        ElanLocale.getString("EditTierDialog.Message.TierName"),
                        ElanLocale.getString("Message.Error"),
                        JOptionPane.ERROR_MESSAGE);

                    return;
                }

                if (transcription.getTierWithId(tierName) != null) {
                    if ((mode == ADD) ||
                            ((mode == CHANGE) && !tierName.equals(oldTierName))) {
                        tierNameTextField.requestFocus();
                        JOptionPane.showMessageDialog(this,
                            ElanLocale.getString(
                                "EditTierDialog.Message.Exists"),
                            ElanLocale.getString("Message.Error"),
                            JOptionPane.ERROR_MESSAGE);

                        return;
                    }
                }

                String participant = participantTextField.getText();
                String lingType = (String) lingTypeChoice.getSelectedItem();
                Tier parentTier = transcription.getTierWithId((String) parentChoice.getSelectedItem());

                String localeName = (String) languageChoice.getSelectedItem();
                Locale locale = null;

                if (langs != null) {
                    for (int i = 0; i < langs.length; i++) {
                        if (langs[i].getDisplayName().equals(localeName)) {
                            locale = langs[i];

                            break;
                        }
                    }
                }

                if (locale == null) {
                    locale = oldLocale;
                }

                switch (mode) {
                case ADD:
                    doAdd(tierName, parentTier, lingType, participant, locale);

                    break;

                case CHANGE:
                    doChange(tierName, parentTier, lingType, participant, locale);

                    break;
                }
            }

            //dispose();
        } else {
            dispose();
        }
    }

    /**
     * Returns the stereotype for a linguistic type. When the linguistic type
     * has no constraints -1 is returned.
     *
     * @param name type name
     *
     * @return the stereotype or -1
     */
    private int getStereoTypeForTypeName(String name) {
        LinguisticType type = null;

        Vector types = transcription.getLinguisticTypes();
        LinguisticType tempType = null;

        for (int i = 0; i < types.size(); i++) {
            tempType = (LinguisticType) types.get(i);

            if (tempType.getLinguisticTypeName().equals(name)) {
                type = tempType;

                break;
            }
        }

        return getStereoTypeForType(type);
    }

    /**
     * Returns the stereotype for a linguistic type. When the linguistic type
     * has no constraints -1 is returned.
     *
     * @param type type
     *
     * @return the stereotype or -1
     */
    private int getStereoTypeForType(LinguisticType type) {
        if ((type == null) || (type.getConstraints() == null)) {
            return -1;
        } else {
            return type.getConstraints().getStereoType();
        }
    }
}
