// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ui.components;

import com.intellij.ui.ComponentUtil;
import com.intellij.ui.DocumentAdapter;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.text.Document;
import java.awt.*;

public class JBTextArea extends JTextArea {
  //private final DefaultBoundedRangeModel visibility;

  public JBTextArea() {
    this(null, null, 0, 0);
  }

  public JBTextArea(String text) {
    this(null, text, 0, 0);
  }

  public JBTextArea(int rows, int columns) {
    this(null, null, rows, columns);
  }

  public JBTextArea(String text, int rows, int columns) {
    this(null, text, rows, columns);
  }

  public JBTextArea(Document doc) {
    this(doc, null, 0, 0);
  }

  public JBTextArea(Document doc, String text, int rows, int columns) {
    super(doc, text, rows, columns);
    getDocument().addDocumentListener(new DocumentAdapter() {
      @Override
      protected void textChanged(@NotNull DocumentEvent e) {
        invalidate();
        revalidate();
        repaint();
      }
    });
  }

  @Override
  public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    Insets insets = getInsets();
    String[] lines = getText().split("\n");
    int columns = 0;
    int rows = lines.length;
    for (String line : lines) {
      columns = Math.max(columns, line.length());
    }
    if (columns != 0) {
      d.width = Math.max(d.width, columns * getColumnWidth() +
                                  insets.left + insets.right);
    }
    if (rows != 0) {
      d.height = Math.max(d.height, rows * getRowHeight() +
                                    insets.top + insets.bottom);
    }
    return d;
  }

  @Override
  public void scrollRectToVisible(Rectangle r) {
    JViewport viewport = ComponentUtil.getParentOfType((Class<? extends JViewport>)JViewport.class, (Component)this);
    if (viewport != null) {
      r = SwingUtilities.convertRectangle(this, r, viewport);
      viewport.scrollRectToVisible(r);
    }
  }


}

@@ -249,16 +249,260 @@
 dapter;%0A
+import com.intellij.util.BooleanFunction;%0Aimport com.intellij.util.ObjectUtils;%0Aimport com.intellij.util.ui.ComponentWithEmptyText;%0Aimport com.intellij.util.ui.JBInsets;%0Aimport com.intellij.util.ui.JBUI;%0Aimport com.intellij.util.ui.StatusText;%0A
 import o
@@ -628,24 +628,64 @@
 t.Document;%0A
+import javax.swing.text.JTextComponent;%0A
 import java.
@@ -734,16 +734,50 @@
 extArea 
+implements ComponentWithEmptyText 
 %7B%0A  //pr
@@ -826,16 +826,69 @@
 ility;%0A%0A
+  private final TextComponentEmptyText myEmptyText;%0A%0A
   public
@@ -1364,24 +1364,947 @@
 , columns);%0A
+%0A    myEmptyText = new TextComponentEmptyText(this) %7B%0A      @Override%0A      protected boolean isStatusVisible() %7B%0A        Object function = getClientProperty(%22StatusVisibleFunction%22);%0A        if (function instanceof BooleanFunction) %7B%0A          //noinspection unchecked%0A          return ((BooleanFunction%3CJTextComponent%3E)function).fun(JBTextArea.this);%0A        %7D%0A        return super.isStatusVisible();%0A      %7D%0A%0A      @Override%0A      protected Rectangle getTextComponentBound() %7B%0A        Insets insets = ObjectUtils.notNull(getInsets(), JBUI.emptyInsets());%0A        Insets margin = ObjectUtils.notNull(getMargin(), JBUI.emptyInsets());%0A        Insets ipad = getComponent().getIpad();%0A        Dimension size = getPreferredSize();%0A        int left = insets.left + margin.left - ipad.left;%0A        int top = insets.top + margin.top - ipad.top;%0A        return new Rectangle(left, top, size.width, size.height);%0A      %7D%0A    %7D;%0A%0A
     getDocum
@@ -3471,11 +3471,569 @@
  %7D%0A  %7D%0A%0A
+  @NotNull%0A  @Override%0A  public StatusText getEmptyText() %7B%0A    return myEmptyText;%0A  %7D%0A%0A  @Override%0A  protected void paintComponent(Graphics g) %7B%0A    super.paintComponent(g);%0A    if (!myEmptyText.getStatusTriggerText().isEmpty() && myEmptyText.isStatusVisible()) %7B%0A      g.setColor(getBackground());%0A%0A      Rectangle rect = new Rectangle(getSize());%0A      JBInsets.removeFrom(rect, getInsets());%0A      JBInsets.removeFrom(rect, getMargin());%0A      ((Graphics2D)g).fill(rect);%0A%0A      g.setColor(getForeground());%0A    %7D%0A    myEmptyText.paintStatusText(g);%0A  %7D
 %0A%7D%0A

implement ComponentWithEmptyText