package osa.attribute.atgrammar.gui.tables.assignments_table;

import java.util.*;

import javax.swing.table.TableCellEditor;
import java.awt.Component;
import javax.swing.*;
import javax.swing.event.*;
import java.util.EventObject;
import javax.swing.event.CellEditorListener;

import java.awt.*;
import java.awt.event.*;


import osa.attribute.atgrammar.grammar.*;
import osa.attribute.atgrammar.grammar.symbols.*;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2005</p>
 * <p>Company: </p>
 * @author not attributable
 * @version 1.0
 */

public class AssignmentsTCE
  implements TableCellEditor
  {
  protected static final int SOURCE_SYMBOL_WAS_EDITED=0;
  protected static final int SOURCE_ATTRIBUTE_WAS_EDITED=1;
  protected static final int RECIPIENT_SYMBOL_WAS_EDITED=2;
  protected static final int RECIPIENT_ATTRIBUTE_WAS_EDITED=3;


  protected class EditorComboActionListener
    implements ActionListener
    {
    public void actionPerformed(ActionEvent e)
      {
      stopCellEditing();
      }
    }

  protected class EditorsKeyListener
    implements KeyListener
    {
    public void keyTyped(KeyEvent e)
      {
      }

    public void keyPressed(KeyEvent e)
      {
      switch(e.getKeyCode())
            {
            case KeyEvent.VK_ESCAPE:
              cancelCellEditing();
              break;
            default:
            }
      }

    public void keyReleased(KeyEvent e)
      {
      }
    }

  protected class EditorsActionListener
    implements ActionListener
    {
    public void actionPerformed(ActionEvent e)
      {
      stopCellEditing();
      }
    }



  protected class EditorsFocusListener
    implements FocusListener
    {
    public void focusGained(FocusEvent e)
      {
      }

    public void focusLost(FocusEvent e)
      {
      cancelCellEditing();
      }
    }

  public AssignmentsTCE()
    {
    }


  protected class EditorComboBoxModel
    extends DefaultComboBoxModel
    {
    ArrayList values;

    public EditorComboBoxModel(ArrayList values)
      {
      super();
      this.values=values;
      }

    public int getSize()
      {
      return values.size();
      }

    public Object getElementAt(int index)
      {
      return values.get(index).toString();
      }

    }


  protected ArrayList listeners=new ArrayList();

  protected SimpleAssignment editor_value; // since we edit assignments
  protected JComboBox current_editor_component;
  protected int current_editor_descriptor;

  public Component getTableCellEditorComponent
    (JTable table,
     Object value,
     boolean isSelected,
     int row,
     int column
    )
    {
    Component cell_editor=null;

    if(value instanceof SimpleAssignment)
      {
      SimpleAssignment assignment=(SimpleAssignment)value;
      editor_value=assignment;

      switch(column)
            {
            case 0:
               // impossible
              break;
            case 1:
               // recipient symbol
              current_editor_component=getRecipientSymbolEditor();
              cell_editor=current_editor_component;
              current_editor_descriptor=this.RECIPIENT_SYMBOL_WAS_EDITED;
              break;
            case 2:
               // impossible
              break;
            case 3:
               // recipient attribute
               current_editor_component=getRecipientAttributeEditor();
               cell_editor=current_editor_component;
               current_editor_descriptor=this.RECIPIENT_ATTRIBUTE_WAS_EDITED;
              break;
            case 4:
               // impossible
              break;
            case 5:
               // source symbol
               current_editor_component=getSourceSymbolEditor();
               cell_editor=current_editor_component;
               current_editor_descriptor=this.SOURCE_SYMBOL_WAS_EDITED;
               break;
            case 6:
               // impossible
              break;
            case 7:
               // source attribute
               current_editor_component=getSourceAttributeEditor();
               cell_editor=current_editor_component;
               current_editor_descriptor=this.SOURCE_ATTRIBUTE_WAS_EDITED;
              break;
            default:
            }
      }

    if(cell_editor==null)
      {
      cell_editor=new JLabel("Error!");
      }

    return cell_editor;
    }

  public Object getCellEditorValue()
    {
    return editor_value;
    }

  public boolean isCellEditable(EventObject anEvent)
    {
    return true;
    }

  public boolean shouldSelectCell(EventObject anEvent)
    {
    return true;
    }

  public boolean stopCellEditing()
    {
    String label=(String)current_editor_component.getSelectedItem();

//    System.err.println("Label!! "+label);

    switch(current_editor_descriptor)
          {
          case RECIPIENT_SYMBOL_WAS_EDITED:
            editor_value.setRecipientSymbolLabel(label);
            editor_value.setRecipientAttributeLabel("");

            System.err.println("Label!! "+editor_value.getRecipientSymbolLabel());
            break;
          case RECIPIENT_ATTRIBUTE_WAS_EDITED:
            editor_value.setRecipientAttributeLabel(label);
            break;
          case SOURCE_SYMBOL_WAS_EDITED:
            editor_value.setSourceSymbolLabel(label);
            editor_value.setSourceAttributeLabel("");
            break;
          case SOURCE_ATTRIBUTE_WAS_EDITED:
            editor_value.setSourceAttributeLabel(label);
            break;
          default:
          }
    editor_value.updateIndexes();

    int size=listeners.size();
    CellEditorListener temp_listener;

    ChangeEvent event=new ChangeEvent(this);

    for(int i=0;i<size;i++)
       {
       temp_listener=(CellEditorListener)listeners.get(i);
       temp_listener.editingStopped(event);
       }
    System.err.println("Stop edit!");

    return true;
    }

  public void cancelCellEditing()
    {
    int size=listeners.size();
    CellEditorListener temp_listener;

    ChangeEvent event=new ChangeEvent(this);

    for(int i=0;i<size;i++)
       {
       temp_listener=(CellEditorListener)listeners.get(i);
       temp_listener.editingCanceled(event);
       }
    System.err.println("Chancel edit!");
    }

  public void addCellEditorListener(CellEditorListener l)
    {
    listeners.add(l);
    }

  public void removeCellEditorListener(CellEditorListener l)
    {
    listeners.remove(l);
    }

  protected JComboBox getProductionSymbolsCombo()
    {
    ArrayList symbols_names=new ArrayList();
    GrammarProduction production=editor_value.getOwner();
    SymbolsString string=production.getRightPart();
    int string_len=string.getLength();

    symbols_names.add("");
    symbols_names.add(production.getLeftPart().toString());
    for(int i=0;i<string_len;i++)
       {
       symbols_names.add(string.getSymbolAt(i).toString());
       }

    JComboBox symbols_combo;
    EditorComboBoxModel editor_model=new EditorComboBoxModel(symbols_names);
    symbols_combo=new JComboBox(editor_model);
    return symbols_combo;
    }

  protected JComboBox getSymbolAttributesCombo(Symbol symbol, AttributeType type)
    {
    ArrayList attributes_names=new ArrayList();
    int attributes_count=symbol.getAttrubutesCount();
    System.err.println("Attrs count "+attributes_count);
    Attribute temp_attribute;
    attributes_names.add("");
    for(int i=0;i<attributes_count;i++)
       {
       temp_attribute=symbol.getAttributeAt(i);
//       if(type==null || temp_attribute.getType()==type)   // correct in redisign
//         {
         attributes_names.add(temp_attribute.getName());
     System.err.println("ATTTTRS! "+ temp_attribute.getName());
//         }
       }

    EditorComboBoxModel attributes_combo_model=new EditorComboBoxModel(attributes_names);

    return new JComboBox(attributes_combo_model);
    }


  protected JComboBox getSourceSymbolEditor()
    {
    Symbol source_symbol=editor_value.getSourceSymbol();
    JComboBox editor=getProductionSymbolsCombo();
    if(source_symbol==null)
      {
      editor.setSelectedItem("");
      }
    else
      {
      editor.setSelectedItem(source_symbol.toString());
      }

    editor.addActionListener(new EditorsActionListener());
    editor.addFocusListener(new EditorsFocusListener());
    editor.addKeyListener(new EditorsKeyListener());

    return editor;
    }

  protected JComboBox getSourceAttributeEditor()
    {
    JComboBox editor;
    Attribute recipient_attribute=editor_value.getRecipientAttribute();
    Symbol source_symbol=editor_value.getSourceSymbol();

    AttributeType recipient_type;
    if(recipient_attribute==null)
      {
      recipient_type=null;
      }
    else
      {
      recipient_type=recipient_attribute.getType();
      }

    editor=this.getSymbolAttributesCombo(source_symbol,recipient_type);

    String label=editor_value.getSourceAttributeLabel();
    editor.setSelectedItem(label);

    editor.addActionListener(new EditorsActionListener());
    editor.addFocusListener(new EditorsFocusListener());
    editor.addKeyListener(new EditorsKeyListener());

    return editor;
    }

  protected JComboBox getRecipientSymbolEditor()
    {
    Symbol recipient_symbol=editor_value.getRecipientSymbol();
    JComboBox editor=getProductionSymbolsCombo();
    if(recipient_symbol==null)
      {
      editor.setSelectedItem("");
      }
    else
      {
      editor.setSelectedItem(recipient_symbol.toString());
      }

    editor.addActionListener(new EditorsActionListener());
    editor.addFocusListener(new EditorsFocusListener());
    editor.addKeyListener(new EditorsKeyListener());

    return editor;
    }

  protected JComboBox getRecipientAttributeEditor()
    {
    JComboBox editor;
    Attribute source_attribute=editor_value.getSourceAttribute();
    Symbol recipient_symbol=editor_value.getRecipientSymbol();

    AttributeType source_type;
    if(source_attribute==null)
      {
      source_type=null;
      }
    else
      {
      source_type=source_attribute.getType();
      }

    editor=this.getSymbolAttributesCombo(recipient_symbol,source_type);

    String label=editor_value.getRecipientAttributeLabel();
    editor.setSelectedItem(label);

    editor.addActionListener(new EditorsActionListener());
    editor.addFocusListener(new EditorsFocusListener());
    editor.addKeyListener(new EditorsKeyListener());

    return editor;
    }

  }