/*
 * File:     GridEditor.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.grid;

import mpi.eudico.client.annotator.gui.InlineEditBox;

import mpi.eudico.client.annotator.viewer.AbstractViewer;

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

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.Component;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;


/**
 * CellEditor for editing annotations
 * Extracted from GridViewer on Jun 29, 2004
 * @version November 2004
 */
public class GridEditor extends DefaultCellEditor {
    final private AbstractViewer viewer;
    final private GridViewerTableModel tableModel;
    final private String EMPTY = "";
    private Annotation annotation;
    private InlineEditBox inlineEditBox;

    /**
     * Creates a new GridEditor instance
     */
    public GridEditor(AbstractViewer viewer, GridViewerTableModel dataModel) {
        super(new JTextField());
        getComponent().setEnabled(false);
        this.viewer = viewer;
        this.tableModel = dataModel;
    }

    /**
     * Configures a textediting component, possibly an inline editbox and
     * returns it.
     *
     * @param table the table containing the cell
     * @param value the current value of the table cell
     * @param isSelected the selected state of the cell
     * @param row the row index of the cell
     * @param column the column index of the cell
     *
     * @return a text editing component
     */
    public Component getTableCellEditorComponent(JTable table, Object value,
        boolean isSelected, int row, int column) {
        annotation = null;

        if (inlineEditBox == null) {
            inlineEditBox = new InlineEditBox(table);
        }

        if (table.getColumnName(column).equals(GridViewerTableModel.ANNOTATION)) {
            annotation = (Annotation) tableModel.getAnnotationCore(row);
            configureEditBox(table, row, column);
            inlineEditBox.startEdit();

            return inlineEditBox.getEditorComponent();
        } else if (value instanceof Annotation) {
            annotation = (Annotation) value;
            configureEditBox(table, row, column);
            inlineEditBox.startEdit();

            return inlineEditBox.getEditorComponent();
        } else if (value instanceof String) {
            try {
                String tierName = tableModel.getColumnName(column);
                AbstractAnnotation parentAnn = (AbstractAnnotation) tableModel.getAnnotationCore(row);

                if ((tierName != null) && (parentAnn != null)) {
                    Tier childTier = ((TranscriptionImpl) parentAnn.getTier()
                                                                   .getParent()).getTierWithId(tierName);

                    if (childTier != null) {
                        TierImpl parentTier = (TierImpl) ((TierImpl) childTier).getParentTier();
                        long time = (parentAnn.getBeginTimeBoundary() +
                            parentAnn.getEndTimeBoundary()) / 2;

                        if ((parentTier == parentAnn.getTier()) ||
                                (parentTier.getAnnotationAtTime(time) != null)) {
                            // make sure the next ACMEditEvent does not result in an update of the tablemodel
                            // and a repaint; this would cancel the inline edit box
                            //	GridViewer.this.isCreatingAnnotation = true;
                            annotation = ((TierImpl) childTier).createAnnotation(time,
                                    time);
                        }
                    }
                }

                if (annotation != null) {
                    tableModel.setValueAt(annotation, row, column);
                    configureEditBox(table, row, column);
                    SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                if (inlineEditBox != null) {
                                    inlineEditBox.startEdit();
                                }
                            }
                        });

                    return inlineEditBox.getEditorComponent();
                }
            } catch (Exception ex) {
                ex.printStackTrace();

                //	LOG.warning(LogUtil.formatStackTrace(ex));
                return getComponent();
            }
        }

        System.out.println("Warning: Cell (" + row + "," + column +
            ") not handled by editor. Should not be editable!");

        return getComponent();
    }

    private void configureEditBox(JTable table, int row, int column) {
        viewer.setActiveAnnotation(annotation);
        inlineEditBox.setAnnotation(annotation);
        table.setRowHeight(row, (int) (1.5 * table.getRowHeight()));

        if (inlineEditBox.isUsingControlledVocabulary()) {
            inlineEditBox.configureEditor(JComboBox.class, table.getFont(),
                table.getCellRect(row, column, true).getSize());
        } else {
            inlineEditBox.configureEditor(JScrollPane.class, table.getFont(),
                table.getCellRect(row, column, true).getSize());
        }
    }

    /**
     * Returns the value of the editor component
     *
     * @return the value of the editor component
     */
    public Object getCellEditorValue() {
        if (annotation != null) {
            return annotation.getValue();
        } else {
            return EMPTY;
        }
    }

    public void updateLocale() {
        if (inlineEditBox != null) {
            inlineEditBox.updateLocale();
        }
    }

    /**
     * Cancel the inline edit box.
     */
    public void cancelCellEditing() {
        //super.cancelCellEditing();
        if (inlineEditBox != null) {
            inlineEditBox.cancelEdit();
        }
    }
}
