/*
 * 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 com.intellij.xdebugger.impl.ui.tree.nodes;

import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.frame.WatchInplaceEditor;
import com.intellij.xdebugger.impl.frame.XWatchesView;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.tree.TreeNode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @author nik
 */
public class WatchesRootNode extends XDebuggerTreeNode {
  private final XDebugSession mySession;
  private final XWatchesView myWatchesView;
  private List<WatchNode> myChildren;
  private List<XDebuggerTreeNode> myLoadedChildren;
  private XDebuggerEvaluator myCurrentEvaluator;

  public WatchesRootNode(final @NotNull XDebuggerTree tree,
                         @NotNull XDebugSession session,
                         @NotNull XWatchesView watchesView,
                         @NotNull String[] watchExpressions) {
    super(tree, null, false);
    mySession = session;
    myWatchesView = watchesView;
    myChildren = new ArrayList<WatchNode>();
    for (String watchExpression : watchExpressions) {
      myChildren.add(WatchMessageNode.createMessageNode(tree, this, watchExpression));
    }
  }

  public void updateWatches(@Nullable XDebuggerEvaluator evaluator) {
    myCurrentEvaluator = evaluator;
    List<WatchNode> newChildren = new ArrayList<WatchNode>();
    if (evaluator != null) {
      for (WatchNode child : myChildren) {
        final String expression = child.getExpression();
        final WatchMessageNode evaluatingNode = WatchMessageNode.createEvaluatingNode(myTree, this, expression);
        newChildren.add(evaluatingNode);
        evaluator.evaluate(expression, new MyEvaluationCallback(evaluatingNode), null);
      }
    }
    else {
      for (WatchNode child : myChildren) {
        final String expression = child.getExpression();
        newChildren.add(WatchMessageNode.createMessageNode(myTree, this, expression));
      }
    }
    myChildren = newChildren;
    myLoadedChildren = null;
    fireNodeStructureChanged();
  }

  @NotNull
  @Override
  public List<? extends TreeNode> getChildren() {
    return myChildren;
  }

  @Nullable
  public List<? extends WatchNode> getAllChildren() {
    return myChildren;
  }

  @Override
  public List<? extends XDebuggerTreeNode> getLoadedChildren() {
    if (myLoadedChildren == null) {
      myLoadedChildren = new ArrayList<XDebuggerTreeNode>();
      for (WatchNode child : myChildren) {
        if (child instanceof WatchNodeImpl) {
          myLoadedChildren.add((WatchNodeImpl)child);
        }
      }
    }
    return myLoadedChildren;
  }

  @Override
  public void clearChildren() {
    updateWatches(myCurrentEvaluator);
  }

  private void replaceNode(final WatchNode oldNode, final WatchNode newNode) {
    for (int i = 0; i < myChildren.size(); i++) {
      WatchNode child = myChildren.get(i);
      if (child == oldNode) {
        myChildren.set(i, newNode);
        if (newNode instanceof XValueContainerNode<?>) {
          myLoadedChildren = null;
          fireNodeStructureChanged(newNode);
          myTree.childrenLoaded(this, Collections.<XValueContainerNode<?>>singletonList((XValueContainerNode<?>)newNode), false);
        }
        else {
          fireNodeStructureChanged(newNode);
        }
        return;
      }
    }
  }

  public void addWatchExpression(final @Nullable XDebuggerEvaluator evaluator,
                                 final @NotNull String expression,
                                 int index, final boolean navigateToWatchNode) {
    WatchMessageNode message = evaluator != null ? WatchMessageNode.createEvaluatingNode(myTree, this, expression) : WatchMessageNode.createMessageNode(myTree, this, expression);
    if (index == -1) {
      myChildren.add(message);
      index = myChildren.size() - 1;
    }
    else {
      myChildren.add(index, message);
    }
    fireNodeInserted(index);
    if (navigateToWatchNode) {
      myTree.scrollPathToVisible(message.getPath());
    }
    if (evaluator != null) {
      evaluator.evaluate(expression, new MyEvaluationCallback(message), null);
    }
  }

  private void fireNodeInserted(int index) {
    myTree.getTreeModel().nodesWereInserted(this, new int[]{index});
  }

  @SuppressWarnings("SuspiciousMethodCalls")
  public int removeChildNode(XDebuggerTreeNode node) {
    int index = myChildren.indexOf(node);
    if (index != -1) {
      myChildren.remove(node);
      myLoadedChildren = null;
      fireNodesRemoved(new int[]{index}, new TreeNode[]{node});
    }
    return index;
  }

  public void removeChildren(Collection<? extends XDebuggerTreeNode> nodes) {
    final int[] indices = getNodesIndices(nodes);
    final TreeNode[] removed = getChildNodes(indices);
    myChildren.removeAll(nodes);
    myLoadedChildren = null;
    fireNodesRemoved(indices, removed);
  }

  public void removeAllChildren() {
    myChildren.clear();
    myLoadedChildren = null;
    fireNodeStructureChanged();
  }

  public void addNewWatch() {
    editWatch(null);
  }

  public void editWatch(@Nullable WatchNode node) {
    WatchNode messageNode = WatchMessageNode.createMessageNode(myTree, this, "");
    int index = node != null ? myChildren.indexOf(node) : -1;
    if (index == -1) {
      myChildren.add(messageNode);
      fireNodeInserted(myChildren.size() - 1);
    }
    else {
      myChildren.set(index, messageNode);
      fireNodeStructureChanged(messageNode);
    }
    WatchInplaceEditor editor = new WatchInplaceEditor(this, mySession, myWatchesView, messageNode, "watch", node);
    editor.show();
  }

  private class MyEvaluationCallback extends XEvaluationCallbackBase {
    private final WatchNode myResultPlace;

    public MyEvaluationCallback(final @NotNull WatchNode resultPlace) {
      myResultPlace = resultPlace;
    }

    @Override
    public void evaluated(@NotNull final XValue result) {
      DebuggerUIUtil.invokeLater(new Runnable() {
        @Override
        public void run() {
          replaceNode(myResultPlace, new WatchNodeImpl(myTree, WatchesRootNode.this, result, myResultPlace.getExpression()));
        }
      });
    }

    @Override
    public void errorOccurred(@NotNull final String errorMessage) {
      DebuggerUIUtil.invokeLater(new Runnable() {
        @Override
        public void run() {
          replaceNode(myResultPlace, WatchMessageNode.createErrorNode(myTree, WatchesRootNode.this, myResultPlace.getExpression(), errorMessage));
        }
      });
    }
  }
}
