/*
 * Copyright 2000-2015 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.dvcs.push.ui;

import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.ui.popup.ComponentPopupBuilder;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.ui.HyperlinkAdapter;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.ui.UIUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.tree.TreePath;
import java.awt.*;

public class VcsCommitInfoBalloon {
  private static final String EMPTY_COMMIT_INFO = "<p style='font-style:italic;color:gray;'>No commit information found...</p>";

  @NotNull private final JTree myTree;
  @Nullable private JBPopup myBalloon;
  @NotNull private final JEditorPane myEditorPane;
  @NotNull private final ComponentPopupBuilder myPopupBuilder;

  public VcsCommitInfoBalloon(@NotNull JTree tree) {
    myTree = tree;
    myEditorPane = new JEditorPane(UIUtil.HTML_MIME, "");
    myEditorPane.setEditable(false);
    myEditorPane.setBackground(HintUtil.INFORMATION_COLOR);
    myEditorPane.setFont(UIUtil.getToolTipFont());
    myEditorPane.setBorder(HintUtil.createHintBorder());
    myEditorPane.addHyperlinkListener(new HyperlinkAdapter() {
      @Override
      protected void hyperlinkActivated(HyperlinkEvent e) {
        BrowserUtil.browse(e.getURL());
      }
    });
    myPopupBuilder = JBPopupFactory.getInstance().createComponentPopupBuilder(myEditorPane, null);
    myPopupBuilder.setCancelOnClickOutside(true).setResizable(true).setMovable(true).setRequestFocus(false)
      .setMinSize(new Dimension(200, 80));
  }

  public void updateCommitDetails() {
    if (myBalloon != null && myBalloon.isVisible()) {
      TreePath[] selectionPaths = myTree.getSelectionPaths();
      if (selectionPaths == null || selectionPaths.length != 1) {
        myBalloon.cancel();
      }
      else {
        Object node = selectionPaths[0].getLastPathComponent();
        myEditorPane.setText(
          XmlStringUtil.wrapInHtml(node instanceof TooltipNode ? ((TooltipNode)node).getTooltip().replaceAll("\n", "<br>") :
                                   EMPTY_COMMIT_INFO));
        myBalloon.setSize(myEditorPane.getPreferredSize());
        myBalloon.setLocation(calculateBestPopupLocation());
      }
    }
  }

  @NotNull
  private Point calculateBestPopupLocation() {
    Point defaultLocation = myTree.getLocationOnScreen();
    TreePath selectionPath = myTree.getSelectionPath();
    if (selectionPath == null) return defaultLocation;
    Rectangle rectangle = myTree.getPathBounds(selectionPath);
    if (rectangle == null) return defaultLocation;
    Point location = rectangle.getLocation();
    SwingUtilities.convertPointToScreen(location, myTree);
    return new Point(location.x, location.y + rectangle.height);
  }

  private void createNewCommitInfoBalloon() {
    myBalloon = myPopupBuilder.createPopup();
    myBalloon.setSize(myEditorPane.getPreferredSize());
  }

  public void showCommitDetails() {
    if (myBalloon == null || !myBalloon.isVisible()) {
      createNewCommitInfoBalloon();
      myBalloon.show(new RelativePoint(calculateBestPopupLocation()));
    }
    updateCommitDetails();
  }
}

@@ -952,24 +952,74 @@
 ativePoint;%0A
+import com.intellij.ui.components.panels.Wrapper;%0A
 import com.i
@@ -1194,16 +1194,131 @@
 wing.*;%0A
+import javax.swing.border.Border;%0Aimport javax.swing.border.CompoundBorder;%0Aimport javax.swing.border.EmptyBorder;%0A
 import j
@@ -1496,17 +1496,17 @@
 = %22%3C
-p
+i
  style='
 font
@@ -1505,26 +1505,8 @@
 le='
-font-style:italic;
 colo
@@ -1545,14 +1545,11 @@
 ound
-...
 %3C/
-p
+i
 %3E%22;%0A
@@ -1588,16 +1588,60 @@
 myTree;%0A
+  @NotNull private final Wrapper myWrapper;%0A
   @Nulla
@@ -1916,16 +1916,104 @@
 E, %22%22);%0A
+    myEditorPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);%0A
     myEd
@@ -2205,24 +2205,155 @@
 tBorder());%0A
+    Border margin = new EmptyBorder(3, 3, 3, 3);%0A    myEditorPane.setBorder(new CompoundBorder(myEditorPane.getBorder(), margin));%0A
     myEditor
@@ -2535,16 +2535,59 @@
     %7D);%0A
+    myWrapper = new Wrapper(myEditorPane);%0A
     myPo
@@ -2658,26 +2658,23 @@
 ilder(my
-EditorPane
+Wrapper
 , null);
@@ -2818,14 +2818,13 @@
 ion(
-200, 8
+80, 3
 0));
@@ -3385,38 +3385,292 @@
     
-myBalloon.setSize(myEditorPane
+//workaround: fix initial size for JEditorPane%0A        RepaintManager rp = RepaintManager.currentManager(myEditorPane);%0A        rp.markCompletelyDirty(myEditorPane);%0A        rp.validateInvalidComponents();%0A        rp.paintDirtyRegions();%0A        //%0A        myBalloon.setSize(myWrapper
 .get

update commit info popup ui