/*
 * Copyright 2000-2009 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.DialogWrapper;
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() {
      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() {
      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);
        }
      }

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

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

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

            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() {
      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() {
      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 != DialogWrapper.OK_EXIT_CODE) 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);
    }

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

      return !(value instanceof DClassElement);
    }

    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);
    }

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

      return userObject instanceof DPropertyElement;
    }

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

    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 {
    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>() {
        @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);
    }

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

    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);
    }

    @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;
    }
  }
}
