// Copyright 2000-2020 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.util;

import com.intellij.openapi.util.NlsSafe;
import com.intellij.util.ui.StartupUiUtil;
import org.jetbrains.annotations.NotNull;

import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.UIResource;
import java.awt.*;
import java.text.AttributedCharacterIterator.Attribute;
import java.util.Map;

import static java.awt.font.TextAttribute.KERNING;
import static java.awt.font.TextAttribute.KERNING_ON;
import static java.util.Collections.singletonMap;

public final class FontUtil {

  @NotNull
  public static String leftArrow(@NotNull Font font) {
    return canDisplay(font, '\u2190', "<-");
  }

  @NotNull
  @NlsSafe
  public static String rightArrow(@NotNull Font font) {
    return canDisplay(font, '\u2192', "->");
  }

  public static boolean isValidFont(@NotNull Font font) {
    try {
      return font.canDisplay('a') &&
             font.canDisplay('z') &&
             font.canDisplay('A') &&
             font.canDisplay('Z') &&
             font.canDisplay('0') &&
             font.canDisplay('1');
    }
    catch (Exception e) {
      // JRE has problems working with the font. Just skip.
      return false;
    }
  }

  @NotNull
  public static String upArrow(@NotNull Font font, @NotNull String defaultValue) {
    return canDisplay(font, '\u2191', defaultValue);
  }

  /**
   * The method checks whether the font can display the character.
   *
   * If the character should be shown in editor, the method might return incorrect result,
   * since the editor will try to use fallback fonts if the base one cannot display the character.
   * In this case use {@link com.intellij.openapi.editor.ex.util.EditorUtil#displayCharInEditor(char, com.intellij.openapi.editor.colors.TextAttributesKey, String)} instead.
   */
  @NotNull
  public static String canDisplay(@NotNull Font font, char value, @NotNull String defaultValue) {
    return font.canDisplay(value) ? String.valueOf(value) : defaultValue;
  }

  @NotNull
  public static @NlsSafe String spaceAndThinSpace() {
    return " " + thinSpace();
  }

  @NotNull
  public static String thinSpace() {
    return canDisplay(StartupUiUtil.getLabelFont(), '\u2009', " ");
  }

  @NotNull
  public static Font minusOne(@NotNull Font font) {
    return font.deriveFont(font.getSize() - 1f);
  }

  /**
   * @param oldFont    a base font to derive from
   * @param attributes a map of attributes to override in the given font
   * @return a new font that replicates the given font with the specified attributes
   */
  @NotNull
  public static Font deriveFont(@NotNull Font oldFont, @NotNull Map<? extends Attribute, ?> attributes) {
    Font newFont = oldFont.deriveFont(attributes);
    return oldFont instanceof UIResource ? new FontUIResource(newFont) : newFont;
  }

  /**
   * @param font a base font to derive from
   * @return a new font that replicates the given font without a kerning attribute
   */
  @NotNull
  public static Font disableKerning(@NotNull Font font) {
    return deriveFont(font, DisableKerning.LAZY);
  }

  private static final class DisableKerning {
    private static final Map<Attribute, Integer> LAZY = singletonMap(KERNING, null);
  }


  /**
   * @param font a base font to derive from
   * @return a new font that replicates the given font with a kerning attribute
   */
  @NotNull
  public static Font enableKerning(@NotNull Font font) {
    return deriveFont(font, EnableKerning.LAZY);
  }

  private static final class EnableKerning {
    private static final Map<Attribute, Integer> LAZY = singletonMap(KERNING, KERNING_ON);
  }
}

@@ -1535,16 +1535,20 @@
 er.%0A   *
+ %3Cp%3E
 %0A   * If
@@ -1758,12 +1758,12 @@
 e %7B@
-link
+code
  com
@@ -1904,16 +1904,26 @@
 nstead.%0A
+   * %3C/p%3E%0A
    */%0A  

fix javadoc refs