/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jetbrains.plugins.groovy.annotator.intentions.dynamic;

import com.intellij.ide.DeleteProvider;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.listeners.RefactoringElementListenerProvider;
import com.intellij.refactoring.listeners.RefactoringListenerManager;
import com.intellij.ui.*;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
import com.intellij.ui.treeStructure.treetable.TreeTable;
import com.intellij.ui.treeStructure.treetable.TreeTableModel;
import com.intellij.ui.treeStructure.treetable.TreeTableTree;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.AbstractTableCellEditor;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import icons.JetgroovyIcons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.annotator.intentions.QuickfixUtil;
import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.elements.*;
import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment;

import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.TableCellRenderer;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * User: Dmitry.Krasilschikov
 * Date: 09.01.2008
 */
public class DynamicToolWindowWrapper {
  private static final Logger LOG = Logger.getInstance(DynamicToolWindowWrapper.class);

  private static final int CLASS_OR_ELEMENT_NAME_COLUMN = 0;
  private static final int TYPE_COLUMN = 1;

  private static final String[] myColumnNames = {"Dynamic Element", "Type"};

  private final Project myProject;
  private ToolWindow myToolWindow = null;

  private JPanel myTreeTablePanel;
  private SimpleToolWindowPanel myBigPanel;
  private ListTreeTableModelOnColumns myTreeTableModel;
  private MyTreeTable myTreeTable;

  public DynamicToolWindowWrapper(Project project) {
    myProject = project;
  }

  public static DynamicToolWindowWrapper getInstance(Project project) {
    return ServiceManager.getService(project, DynamicToolWindowWrapper.class);
  }

  public TreeTable getTreeTable() {
    getToolWindow();

    return myTreeTable;
  }

  public ToolWindow getToolWindow() {
    if (myToolWindow == null) {
      myToolWindow = ToolWindowManager.getInstance(myProject).registerToolWindow(GroovyBundle.message("dynamic.tool.window.id"), true, ToolWindowAnchor.RIGHT);
      myToolWindow.setIcon(JetgroovyIcons.Groovy.DynamicProperty_13);
      myToolWindow.setTitle(GroovyBundle.message("dynamic.window"));
      myToolWindow.setToHideOnEmptyContent(true);

      final JPanel panel = buildBigPanel();
      final ContentManager contentManager = myToolWindow.getContentManager();
      final Content content = contentManager.getFactory().createContent(panel, "", false);
      content.setPreferredFocusableComponent(myTreeTable);
      contentManager.addContent(content);
    }

    return myToolWindow;
  }

  private JPanel buildBigPanel() {
    myBigPanel = new SimpleToolWindowPanel(true);

    final ActionManager actionManager = ActionManager.getInstance();
    final ActionGroup actionGroup = (ActionGroup)actionManager.getAction("Groovy.Dynamic.Toolbar");
    ActionToolbar actionToolbar = actionManager.createActionToolbar("Groovy.Dynamic.Toolbar", actionGroup, true);
    myBigPanel.setToolbar(actionToolbar.getComponent());

    myBigPanel.setBackground(UIUtil.getFieldForegroundColor());

    final JPanel panel = new JPanel(new BorderLayout());
    myBigPanel.add(panel, BorderLayout.CENTER);

    myTreeTablePanel = new JPanel(new BorderLayout());
    rebuildTreePanel();

    panel.add(myTreeTablePanel);
    myBigPanel.setPreferredSize(new Dimension(200, myBigPanel.getHeight()));

    myBigPanel.revalidate();
    return myBigPanel;
  }

  public void rebuildTreePanel() {
    DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
    buildTree(rootNode);

    rebuildTreeView(rootNode, false);
  }

  private void rebuildTreeView(DefaultMutableTreeNode root, boolean expandAll) {
    PsiDocumentManager.getInstance(myProject).commitAllDocuments();

    myTreeTablePanel.removeAll();

    final JScrollPane treeTable = createTable(root);

    if (expandAll) {
      TreeUtil.expandAll(myTreeTable.getTree());
    }

    myTreeTablePanel.add(treeTable);
    myTreeTablePanel.revalidate();
  }

  private DefaultMutableTreeNode buildTree(DefaultMutableTreeNode rootNode) {
    final Collection<DClassElement> containingClasses = DynamicManager.getInstance(myProject).getAllContainingClasses();

    DefaultMutableTreeNode containingClassNode;
    for (DClassElement containingClassElement : containingClasses) {
      containingClassNode = new DefaultMutableTreeNode(containingClassElement);

      final Collection<DPropertyElement> properties =
        DynamicManager.getInstance(myProject).findDynamicPropertiesOfClass(containingClassElement.getName());

//      if (properties.length == 0) continue;

      DefaultMutableTreeNode propertyTreeNode;
      for (DPropertyElement property : properties) {

        propertyTreeNode = new DefaultMutableTreeNode(property);
        containingClassNode.add(propertyTreeNode);
      }

      DefaultMutableTreeNode methodTreeNode;
      final Set<DMethodElement> methods = containingClassElement.getMethods();

      for (DMethodElement methodElement : methods) {
        final String[] psiTypes = QuickfixUtil.getArgumentsTypes(methodElement.getPairs());

        final DMethodElement method = DynamicManager.getInstance(myProject)
          .findConcreteDynamicMethod(containingClassElement.getName(), methodElement.getName(), psiTypes);

        methodTreeNode = new DefaultMutableTreeNode(method);
        containingClassNode.add(methodTreeNode);
      }

      rootNode.add(containingClassNode);
    }
    return rootNode;
  }

  private JScrollPane createTable(final MutableTreeNode myTreeRoot) {
    ColumnInfo[] columnInfos =
      {new ClassColumnInfo(myColumnNames[CLASS_OR_ELEMENT_NAME_COLUMN]), new PropertyTypeColumnInfo(myColumnNames[TYPE_COLUMN])};

    myTreeTableModel = new ListTreeTableModelOnColumns(myTreeRoot, columnInfos);

    myTreeTable = new MyTreeTable(myTreeTableModel);

    new TreeTableSpeedSearch(myTreeTable, new Convertor<TreePath, String>() {
      @Override
      public String convert(TreePath o) {
        final Object node = o.getLastPathComponent();
        if (node instanceof DefaultMutableTreeNode) {
          final Object object = ((DefaultMutableTreeNode)node).getUserObject();
          if (object instanceof DNamedElement) {
            return ((DNamedElement)object).getName();
          }
        }
        return "";
      }
    });

    DefaultActionGroup group = new DefaultActionGroup();
    group.add(ActionManager.getInstance().getAction(RemoveDynamicAction.GROOVY_DYNAMIC_REMOVE));
    PopupHandler.installUnknownPopupHandler(myTreeTable, group, ActionManager.getInstance());

    final MyColoredTreeCellRenderer treeCellRenderer = new MyColoredTreeCellRenderer();

    myTreeTable.setDefaultRenderer(String.class, new TableCellRenderer() {
      @Override
      public Component getTableCellRendererComponent(JTable table,
                                                     Object value,
                                                     boolean isSelected,
                                                     boolean hasFocus,
                                                     int row,
                                                     int column) {
        if (value instanceof String) {
          try {
            final PsiType type = JavaPsiFacade.getElementFactory(myProject).createTypeFromText((String)value, null);
            String shortName = type.getPresentableText();
            return new JLabel(shortName);
          }
          catch (IncorrectOperationException e) {
            LOG.debug("Type cannot be created", e);
          }
          return new JLabel(QuickfixUtil.shortenType((String)value));
        }

        return new JLabel();
      }
    });

    myTreeTable.setTreeCellRenderer(treeCellRenderer);

    myTreeTable.setRootVisible(false);
    myTreeTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

    final MyPropertyTypeCellEditor typeCellEditor = new MyPropertyTypeCellEditor();

    typeCellEditor.addCellEditorListener(new CellEditorListener() {
      @Override
      public void editingStopped(ChangeEvent e) {
        final TreeTableTree tree = getTree();

        String newTypeValue = ((MyPropertyTypeCellEditor)e.getSource()).getCellEditorValue();

        if (newTypeValue == null || tree == null) {
          myTreeTable.editingStopped(e);
          return;
        }

        try {
          final PsiType type = JavaPsiFacade.getElementFactory(myProject).createTypeFromText(newTypeValue, null);
          String canonical = type.getCanonicalText();
          if (canonical != null) newTypeValue = canonical;
        }
        catch (IncorrectOperationException ex) {
          //do nothing in case bad string is entered
        }

        final TreePath editingTypePath = tree.getSelectionPath();
        if (editingTypePath == null) return;

        final TreePath editingClassPath = editingTypePath.getParentPath();

        Object oldTypeValue = myTreeTable.getValueAt(tree.getRowForPath(editingTypePath), TYPE_COLUMN);

        if (!(oldTypeValue instanceof String)) {
          myTreeTable.editingStopped(e);
          return;
        }

        final Object editingPropertyObject = myTreeTable.getValueAt(tree.getRowForPath(editingTypePath), CLASS_OR_ELEMENT_NAME_COLUMN);
        final Object editingClassObject = myTreeTable.getValueAt(tree.getRowForPath(editingClassPath), CLASS_OR_ELEMENT_NAME_COLUMN);

        if (!(editingPropertyObject instanceof DItemElement) || !(editingClassObject instanceof DClassElement)) {
          myTreeTable.editingStopped(e);
          return;
        }

        final DItemElement dynamicElement = (DItemElement)editingPropertyObject;
        final String name = dynamicElement.getName();
        final String className = ((DClassElement)editingClassObject).getName();

        if (dynamicElement instanceof DPropertyElement) {
          DynamicManager.getInstance(myProject).replaceDynamicPropertyType(className, name, (String)oldTypeValue, newTypeValue);
        }
        else if (dynamicElement instanceof DMethodElement) {
          final List<ParamInfo> myPairList = ((DMethodElement)dynamicElement).getPairs();
          DynamicManager.getInstance(myProject).replaceDynamicMethodType(className, name, myPairList, (String)oldTypeValue, newTypeValue);
        }
      }

      @Override
      public void editingCanceled(ChangeEvent e) {
        myTreeTable.editingCanceled(e);
      }
    });

    RefactoringListenerManager.getInstance(myProject).addListenerProvider(new RefactoringElementListenerProvider() {
      @Override
      @Nullable
      public RefactoringElementListener getListener(final PsiElement element) {
        if (element instanceof PsiClass) {
          final String qualifiedName = ((PsiClass)element).getQualifiedName();

          return new RefactoringElementListener() {
            @Override
            public void elementMoved(@NotNull PsiElement newElement) {
              renameElement(qualifiedName, newElement);
            }

            @Override
            public void elementRenamed(@NotNull PsiElement newElement) {
              renameElement(qualifiedName, newElement);
            }

            private void renameElement(String oldClassName, PsiElement newElement) {
              if (newElement instanceof PsiClass) {
                final String newClassName = ((PsiClass)newElement).getQualifiedName();

                final DRootElement rootElement = DynamicManager.getInstance(myProject).getRootElement();
                final DClassElement oldClassElement = rootElement.getClassElement(oldClassName);
                final TreeNode oldClassNode = TreeUtil.findNodeWithObject((DefaultMutableTreeNode)myTreeRoot, oldClassElement);

                DynamicManager.getInstance(myProject).replaceClassName(oldClassElement, newClassName);
                myTreeTableModel.nodeChanged(oldClassNode);
              }
            }
          };
        }
        return null;
      }
    });

    myTreeTable.setDefaultEditor(String.class, typeCellEditor);

    myTreeTable.registerKeyboardAction(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent event) {
        final int selectionRow = myTreeTable.getTree().getLeadSelectionRow();
        myTreeTable.editCellAt(selectionRow, CLASS_OR_ELEMENT_NAME_COLUMN, event);
      }
    }, KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), JComponent.WHEN_FOCUSED);

    myTreeTable.registerKeyboardAction(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent event) {
        final int selectionRow = myTreeTable.getTree().getLeadSelectionRow();
        myTreeTable.editCellAt(selectionRow, TYPE_COLUMN, event);
      }
    }, KeyStroke.getKeyStroke(KeyEvent.VK_F2, InputEvent.CTRL_MASK), JComponent.WHEN_FOCUSED);

    myTreeTable.getTree().setShowsRootHandles(true);
    myTreeTable.getTableHeader().setReorderingAllowed(false);

    myTreeTable.setPreferredScrollableViewportSize(new Dimension(300, myTreeTable.getRowHeight() * 10));
    myTreeTable.getColumn(myColumnNames[CLASS_OR_ELEMENT_NAME_COLUMN]).setPreferredWidth(200);
    myTreeTable.getColumn(myColumnNames[TYPE_COLUMN]).setPreferredWidth(160);

    JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTreeTable);

    scrollPane.setPreferredSize(new Dimension(600, 400));
    return scrollPane;
  }

  void deleteRow() {

    boolean isShowDialog = true;
    final int rowsCount = myTreeTable.getSelectedRows().length;
    int i = 0;

    final TreePath[] paths = myTreeTable.getTree().getSelectionPaths();
    if (paths == null) return;

    for (TreePath selectionPath : paths) {
      if (rowsCount > 1) isShowDialog = false;
      if (i == 0) isShowDialog = true;
      i++;

      //class
      final TreePath parent = selectionPath.getParentPath();

      if (parent.getParentPath() == null) {
        //selectionPath is class

        final Object classRow = selectionPath.getLastPathComponent();
        if (!(classRow instanceof DefaultMutableTreeNode)) return;

        if (!removeClass(((DefaultMutableTreeNode)classRow), isShowDialog, rowsCount)) return;

      } else {
        //selectionPath is dynamic item
        final Object classRow = parent.getLastPathComponent();
        final Object dynamicRow = selectionPath.getLastPathComponent();

        if (!(classRow instanceof DefaultMutableTreeNode)) return;
        if (!(dynamicRow instanceof DefaultMutableTreeNode)) return;

        final DefaultMutableTreeNode dynamicItemNode = (DefaultMutableTreeNode)dynamicRow;
        final DefaultMutableTreeNode classNode = (DefaultMutableTreeNode)classRow;

        final boolean removeClass = classNode.getChildCount() == 1;
        if (!removeDynamicElement(dynamicItemNode, isShowDialog, rowsCount)) return;
        if (removeClass) {
          removeNamedElement((DNamedElement)classNode.getUserObject());
        }
      }
    }
    DynamicManager.getInstance(myProject).fireChange();
  }

  private boolean removeClass(DefaultMutableTreeNode classNode, boolean isShowDialog, int rowsCount) {
    final TreeNode rootObject = classNode.getParent();
    return rootObject instanceof DefaultMutableTreeNode && removeDynamicElement(classNode, isShowDialog, rowsCount);

  }

  private boolean removeDynamicElement(DefaultMutableTreeNode child, boolean isShowDialog, int rowsCount) {
    Object namedElement = child.getUserObject();

    if (!(namedElement instanceof DNamedElement)) return false;

    if (isShowDialog) {
      int result;
      if (rowsCount > 1) {
        result = Messages.showOkCancelDialog(myBigPanel, GroovyBundle.message("are.you.sure.to.delete.elements", String.valueOf(rowsCount)),
                                             GroovyBundle.message("dynamic.element.deletion"), Messages.getQuestionIcon());

      } else {
        result = Messages.showOkCancelDialog(myBigPanel, GroovyBundle.message("are.you.sure.to.delete.dynamic.property",
                                                                              ((DNamedElement)namedElement).getName()),
                                             GroovyBundle.message("dynamic.property.deletion"), Messages.getQuestionIcon());
      }

      if (result != Messages.OK) return false;
    }

    removeNamedElement(((DNamedElement)namedElement));

    return true;
  }

  private void removeNamedElement(DNamedElement namedElement) {
    if (namedElement instanceof DClassElement) {
      DynamicManager.getInstance(myProject).removeClassElement((DClassElement)namedElement);
    } else if (namedElement instanceof DItemElement) {
      DynamicManager.getInstance(myProject).removeItemElement((DItemElement)namedElement);
    }
  }

  public void setSelectedNode(DefaultMutableTreeNode node) {
    JTree tree = myTreeTable.getTree();
    TreePath path = new TreePath(node.getPath());
    tree.expandPath(path.getParentPath());
    int row = tree.getRowForPath(path);
    myTreeTable.getSelectionModel().setSelectionInterval(row, row);
    myTreeTable.scrollRectToVisible(myTreeTable.getCellRect(row, 0, true));
    IdeFocusManager.getInstance(myProject).requestFocus(myTreeTable, true);
  }

  public void removeFromParent(DefaultMutableTreeNode parent, DefaultMutableTreeNode child) {
    int idx = myTreeTableModel.getIndexOfChild(parent, child);
    child.removeFromParent();
    myTreeTableModel.nodesWereRemoved(parent, new int[]{idx}, new TreeNode[]{child});
  }

  @Nullable
  private TreeTableTree getTree() {
    return myTreeTable != null ? myTreeTable.getTree() : null;
  }

  private static class PropertyTypeColumnInfo extends ColumnInfo<DefaultMutableTreeNode, String> {
    public PropertyTypeColumnInfo(String name) {
      super(name);
    }

    @Override
    public boolean isCellEditable(DefaultMutableTreeNode node) {
      final Object value = node.getUserObject();

      return !(value instanceof DClassElement);
    }

    @Override
    public String valueOf(DefaultMutableTreeNode treeNode) {
      Object userObject = treeNode.getUserObject();

      if (userObject instanceof DItemElement) return ((DItemElement)userObject).getType();

      return null;
    }
  }

  private static class ClassColumnInfo extends ColumnInfo<DefaultMutableTreeNode, DNamedElement> {
    public ClassColumnInfo(String name) {
      super(name);
    }

    @Override
    public boolean isCellEditable(DefaultMutableTreeNode treeNode) {
      final Object userObject = treeNode.getUserObject();

      return userObject instanceof DPropertyElement;
    }

    @Override
    public Class getColumnClass() {
      return TreeTableModel.class;
    }

    @Override
    public DNamedElement valueOf(DefaultMutableTreeNode treeNode) {
      Object userObject = treeNode.getUserObject();
      if (userObject instanceof DClassElement) return ((DClassElement)userObject);
      if (userObject instanceof DPropertyElement) return ((DPropertyElement)userObject);
      if (userObject instanceof DMethodElement) return ((DMethodElement)userObject);

      return null;
    }
  }

  public ListTreeTableModelOnColumns getTreeTableModel() {
    getToolWindow();

    return myTreeTableModel;
  }

  private static class MyColoredTreeCellRenderer extends ColoredTreeCellRenderer {
    @Override
    public void customizeCellRenderer(JTree tree,
                                      Object value,
                                      boolean selected,
                                      boolean expanded,
                                      boolean leaf,
                                      int row,
                                      boolean hasFocus) {
      value = ((DefaultMutableTreeNode)value).getUserObject();

      setPaintFocusBorder(false);

      if (!(value instanceof DNamedElement)) return;

      if (value instanceof DClassElement) {
        final String containingClassName = ((DClassElement)value).getName();
        //        append(className, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
        final String classShortName = QuickfixUtil.shortenType(containingClassName);
        append(classShortName, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
      }

      if (value instanceof DItemElement) {
        final DItemElement itemElement = ((DItemElement)value);
        final String substringToHighlight = itemElement.getHighlightedText();
        final String name = itemElement.getName();

        if (substringToHighlight != null) {
          appendHighlightName(substringToHighlight, name);
        } else {
          appendName(name);
        }

        if (value instanceof DMethodElement) {
          appendMethodParameters((DMethodElement)value);
        }
      }
    }

    private void appendHighlightName(String substringToHighlight, String name) {
      final int begin = name.indexOf(substringToHighlight);
//          if (name.length() <= begin) return;
      final String first = name.substring(0, begin);
      append(first, SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES);
      final TextAttributes textAttributes = new TextAttributes();
      textAttributes.setBackgroundColor(UIUtil.getListSelectionBackground());
      append(substringToHighlight, SimpleTextAttributes.fromTextAttributes(textAttributes));
      append(name.substring(first.length() + substringToHighlight.length()), SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES);
    }

    private void appendName(String name) {
      append(name, SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES);
    }

    private void appendMethodParameters(DMethodElement value) {
      StringBuilder buffer = new StringBuilder();
      buffer.append("(");

      final String[] types = mapToUnqualified(QuickfixUtil.getArgumentsNames(value.getPairs()));
      for (int i = 0; i < types.length; i++) {
        if (i != 0) buffer.append(", ");

        String type = types[i];
        buffer.append(type);
      }
      buffer.append(")");

      append(buffer.toString(), SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES);
    }

    private static String[] mapToUnqualified(final String[] argumentsNames) {
      return ContainerUtil.map2Array(argumentsNames, String.class, new NullableFunction<String, String>() {
        @Override
        @Nullable
        public String fun(final String s) {
          if (s == null) return null;
          int index = s.lastIndexOf(".");
          if (index > 0 && index < s.length() - 1) return s.substring(index + 1);
          return s;
        }
      });
    }
  }

  private class MyPropertyTypeCellEditor extends AbstractTableCellEditor {
    final EditorTextField field;

    public MyPropertyTypeCellEditor() {
      final Document document = PsiDocumentManager.getInstance(myProject).getDocument(new GroovyCodeFragment(myProject, ""));
      field = new EditorTextField(document, myProject, GroovyFileType.GROOVY_FILE_TYPE);
    }

    @Override
    public String getCellEditorValue() {
      return field.getText();
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
      if (value instanceof String) {
        field.setText(((String)value));
      }

      return field;
    }
  }

  private class MyTreeTable extends TreeTable implements DataProvider {
    public MyTreeTable(TreeTableModel treeTableModel) {
      super(treeTableModel);
    }

    @Override
    @Nullable
    public Object getData(@NonNls String dataId) {
      if (CommonDataKeys.PSI_ELEMENT.is(dataId)) {
        return getSelectedElement();
      }
      else if (CommonDataKeys.PSI_FILE.is(dataId)) {
        final PsiElement element = getSelectedElement();

        if (element == null) return null;
        return element.getContainingFile();
      }
      else if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
        return new DeleteProvider() {
          @Override
          public void deleteElement(@NotNull DataContext dataContext) {
            deleteRow();
          }

          @Override
          public boolean canDeleteElement(@NotNull DataContext dataContext) {
            return myTreeTable.getTree().getSelectionPaths() != null;
          }
        };
      }

      return null;
    }

    private PsiElement getSelectedElement() {
      final TreePath path = getTree().getSelectionPath();

      if (path == null) return null;
      final Object selectedObject = path.getLastPathComponent();
      if (!(selectedObject instanceof DefaultMutableTreeNode)) return null;

      final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)selectedObject;
      final Object userObject = selectedNode.getUserObject();
      if (!(userObject instanceof DNamedElement)) return null;

      if (userObject instanceof DClassElement) {
        final DClassElement classElement = (DClassElement)userObject;

        try {
          PsiType type  = JavaPsiFacade.getElementFactory(myProject).createTypeFromText(classElement.getName(), null);

          if (type instanceof PsiPrimitiveType) {
            type = ((PsiPrimitiveType)type).getBoxedType(PsiManager.getInstance(myProject), GlobalSearchScope.allScope(myProject));
          }

          if (!(type instanceof PsiClassType)) return null;
          return ((PsiClassType)type).resolve();

        }
        catch (IncorrectOperationException e) {
          return null;
        }
      } else if (userObject instanceof DItemElement) {
        final DItemElement itemElement = (DItemElement)userObject;

        final TreeNode parentNode = selectedNode.getParent();
        if (!(parentNode instanceof DefaultMutableTreeNode)) return null;

        final Object classObject = ((DefaultMutableTreeNode)parentNode).getUserObject();
        if (!(classObject instanceof DClassElement)) return null;

        final String className = ((DClassElement)classObject).getName();

        return itemElement.getPsi(PsiManager.getInstance(myProject), className);
      }
      return null;
    }
  }
}
