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

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

import osa.attribute.atgrammar.gui.panels.atgrammar_panels.*;

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


import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;



/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: </p>
 * <p>Company: </p>
 * @author not attributable
 * @version
 */

public class AttributesTCE
  implements TableCellEditor
  {

  protected class EditorsMouseListener
    implements MouseListener
    {
    public boolean is_in_component=true;
    public void mouseClicked(MouseEvent e)
      {
      System.err.println("click!");
      if(!is_in_component)
        {
        cancelCellEditing();
        }
      }

    public void mousePressed(MouseEvent e)
      {
      }

    public void mouseReleased(MouseEvent e)
      {
      }

    public void mouseEntered(MouseEvent e)
      {
      is_in_component=true;
      }

    public void mouseExited(MouseEvent e)
      {
      is_in_component=false;
      }
    }





  protected class TypesComboModel
    extends DefaultComboBoxModel
    {
    private ArrayList types;
    public TypesComboModel()
      {
      types=Grammar.getInstance().getAttributeTypeSystem().getTypesList();
      }

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

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

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

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

    public void keyReleased(KeyEvent e)
      {
      }
    }

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

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

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


  protected static final int NAME_WAS_EDITED=0;
  protected static final int TYPE_WAS_EDITED=1;

  protected Attribute editor_value=null; // Since we edit attribute ;)

  protected JTextField attribute_name_editor;
  protected JComboBox attribute_type_editor;

  protected int editor_descriptor;

  public AttributesTCE()
    {
    }

  protected ArrayList listeners=new ArrayList();

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

     if(value instanceof Attribute)
       {
       Attribute attribute=(Attribute)value;
       editor_value=attribute;

       switch(column)
             {
             case 0:
               // impossible
               break;
             case 1:
               attribute_name_editor=getNameEditor(attribute);
               cell_editor=attribute_name_editor;
               editor_descriptor=NAME_WAS_EDITED;
               break;
             case 2:
               attribute_type_editor=getTypeEditor(attribute);
               cell_editor=attribute_type_editor;
               editor_descriptor=TYPE_WAS_EDITED;
               break;
             case 3:
               // impossible
               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)
    {
    System.err.println(anEvent.getSource());
    AttributesTable source=(AttributesTable)anEvent.getSource();
    if(source.getEditingColumn()<0)
      {
      return true;
      }
    return false;
    }

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

  public boolean stopCellEditing()
    {
    boolean is_valid_value=false;

    switch(this.editor_descriptor)
          {
          case NAME_WAS_EDITED:
            // check if valid name entered
            String attribute_name=attribute_name_editor.getText();
            if(attribute_name!="")
              {
              if( ! editor_value.getName().equals(attribute_name))
                {
                if(editor_value.setName(attribute_name))
                  {
                  is_valid_value=true;
                  /// then need to refresh all
                  }
                else
                  {
                  JOptionPane.showMessageDialog(ATGrammarTabPane.getInstance(),
                                                "Атрибут с таким именем уже существует \n Введите другое имя, пожалуйста...",
                                                "Ошибка",
                                                JOptionPane.ERROR_MESSAGE);
                  }
                }
              else
                {
                is_valid_value=true;
                }
              }
            else
              {
              JOptionPane.showMessageDialog(ATGrammarTabPane.getInstance(),
                                            "Введите корректное значение, пожалуйста!",
                                            "Ошибка",
                                            JOptionPane.ERROR_MESSAGE);
              }

            break;
          case TYPE_WAS_EDITED:
            editor_value.setType((AttributeType)attribute_type_editor.getSelectedItem());
            // then needed to refresh all
            break;
          default:
          }

    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 JTextField getNameEditor(Attribute attr)
    {
    JTextField name_editing_field=new JTextField();
    name_editing_field.addKeyListener(new EditorsKeyListener());
    name_editing_field.addFocusListener(new EditorsFocusListener());
    name_editing_field.addMouseListener(new EditorsMouseListener());
    return name_editing_field;
    }

  protected JComboBox getTypeEditor(Attribute attr)
    {
    JComboBox type_editing_combo=new JComboBox(new TypesComboModel());
    type_editing_combo.setSelectedItem(attr.getType());
    type_editing_combo.setMaximumRowCount(5);
    type_editing_combo.addActionListener(new TypeComboActionListener());
    type_editing_combo.addFocusListener(new EditorsFocusListener());
    type_editing_combo.addKeyListener(new EditorsKeyListener());
    type_editing_combo.addMouseListener(new EditorsMouseListener());
    return type_editing_combo;
    }
  }