/*
 * 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.ui;

import javax.swing.*;
import javax.swing.plaf.basic.BasicGraphicsUtils;
import javax.swing.plaf.basic.BasicLabelUI;
import java.awt.*;

public class RightAlignedLabelUI extends BasicLabelUI {

  @Override
  protected String layoutCL(
    JLabel label,
    FontMetrics fontMetrics,
    String text,
    Icon icon,
    Rectangle viewR,
    Rectangle iconR,
    Rectangle textR) {
    String s = layoutCompoundLabel(
            label,
      fontMetrics,
      text,
      icon,
      label.getVerticalAlignment(),
      label.getHorizontalAlignment(),
      label.getVerticalTextPosition(),
      label.getHorizontalTextPosition(),
      viewR,
      iconR,
      textR,
      label.getIconTextGap());

    if (s.equals(""))
      return text;
    return s;
  }

  static final int LEADING = SwingConstants.LEADING;
  static final int TRAILING = SwingConstants.TRAILING;
  static final int LEFT = SwingConstants.LEFT;
  static final int RIGHT = SwingConstants.RIGHT;
  static final int TOP = SwingConstants.TOP;
  static final int CENTER = SwingConstants.CENTER;

  /**
   * Compute and return the location of the icons origin, the
   * location of origin of the text baseline, and a possibly clipped
   * version of the compound labels string.  Locations are computed
   * relative to the viewR rectangle.
   * The JComponents orientation (LEADING/TRAILING) will also be taken
   * into account and translated into LEFT/RIGHT values accordingly.
   */
  public static String layoutCompoundLabel(JComponent c,
    FontMetrics fm,
    String text,
    Icon icon,
    int verticalAlignment,
    int horizontalAlignment,
    int verticalTextPosition,
    int horizontalTextPosition,
    Rectangle viewR,
    Rectangle iconR,
    Rectangle textR,
    int textIconGap) {
    boolean orientationIsLeftToRight = true;
    int hAlign = horizontalAlignment;
    int hTextPos = horizontalTextPosition;


    if (c != null) {
      if (!(c.getComponentOrientation().isLeftToRight())) {
        orientationIsLeftToRight = false;
      }
    }


    // Translate LEADING/TRAILING values in horizontalAlignment
    // to LEFT/RIGHT values depending on the components orientation
    switch (horizontalAlignment) {
    case LEADING:
      hAlign = (orientationIsLeftToRight) ? LEFT : RIGHT;
      break;
    case TRAILING:
      hAlign = (orientationIsLeftToRight) ? RIGHT : LEFT;
      break;
    }

    // Translate LEADING/TRAILING values in horizontalTextPosition
    // to LEFT/RIGHT values depending on the components orientation
    switch (horizontalTextPosition) {
    case LEADING:
      hTextPos = (orientationIsLeftToRight) ? LEFT : RIGHT;
      break;
    case TRAILING:
      hTextPos = (orientationIsLeftToRight) ? RIGHT : LEFT;
      break;
    }

    return layoutCompoundLabel(fm,
      text,
      icon,
      verticalAlignment,
      hAlign,
      verticalTextPosition,
      hTextPos,
      viewR,
      iconR,
      textR,
      textIconGap);
  }

  /**
   * Compute and return the location of the icons origin, the
   * location of origin of the text baseline, and a possibly clipped
   * version of the compound labels string.  Locations are computed
   * relative to the viewR rectangle.
   * This layoutCompoundLabel() does not know how to handle LEADING/TRAILING
   * values in horizontalTextPosition (they will default to RIGHT) and in
   * horizontalAlignment (they will default to CENTER).
   * Use the other version of layoutCompoundLabel() instead.
   */
  public static String layoutCompoundLabel(
    FontMetrics fm,
    String text,
    Icon icon,
    int verticalAlignment,
    int horizontalAlignment,
    int verticalTextPosition,
    int horizontalTextPosition,
    Rectangle viewR,
    Rectangle iconR,
    Rectangle textR,
    int textIconGap) {
    /* Initialize the icon bounds rectangle iconR.
     */

    if (icon != null) {
      iconR.width = icon.getIconWidth();
      iconR.height = icon.getIconHeight();
    }
    else {
      iconR.width = iconR.height = 0;
    }

    /* Initialize the text bounds rectangle textR.  If a null
     * or and empty String was specified we substitute "" here
     * and use 0,0,0,0 for textR.
     */

    // Fix for textIsEmpty sent by Paulo Santos
    boolean textIsEmpty = (text == null) || (text.equals(""));

    String rettext = "";
    if (textIsEmpty) {
      textR.width = textR.height = 0;
    }
    else {
      Dimension dim = new Dimension(SwingUtilities.computeStringWidth(fm, text), fm.getHeight());
      textR.width = dim.width;
      textR.height = dim.height;
    }

    /* Unless both text and icon are non-null, we effectively ignore
     * the value of textIconGap.  The code that follows uses the
     * value of gap instead of textIconGap.
     */

    int gap = (textIsEmpty || (icon == null)) ? 0 : textIconGap;

    if (!textIsEmpty) {

      /* If the label text string is too wide to fit within the available
       * space "..." and as many characters as will fit will be
       * displayed instead.
       */

      int availTextWidth;

      if (horizontalTextPosition == CENTER) {
        availTextWidth = viewR.width;
      }
      else {
        availTextWidth = viewR.width - (iconR.width + gap);
      }


      if (textR.width > availTextWidth) {
        String clipString = "...";
        int totalWidth = SwingUtilities.computeStringWidth(fm, clipString);
        int nChars;
        rettext = "";
        for (nChars = text.length() - 1; nChars >= 0; nChars--) {
          totalWidth += fm.charWidth(text.charAt(nChars));
          if (totalWidth > availTextWidth) {
            break;
          }
          rettext = text.charAt(nChars) + rettext;
        }
        rettext = clipString + rettext;
        textR.width = SwingUtilities.computeStringWidth(fm, rettext);
      }
    }


    /* Compute textR.x,y given the verticalTextPosition and
     * horizontalTextPosition properties
     */

    if (verticalTextPosition == TOP) {
      if (horizontalTextPosition != CENTER) {
        textR.y = 0;
      }
      else {
        textR.y = -(textR.height + gap);
      }
    }
    else if (verticalTextPosition == CENTER) {
      textR.y = (iconR.height / 2) - (textR.height / 2);
    }
    else {
      // (verticalTextPosition == BOTTOM)
      if (horizontalTextPosition != CENTER) {
        textR.y = iconR.height - textR.height;
      }
      else {
        textR.y = (iconR.height + gap);
      }
    }

    if (horizontalTextPosition == LEFT) {
      textR.x = -(textR.width + gap);
    }
    else if (horizontalTextPosition == CENTER) {
      textR.x = (iconR.width / 2) - (textR.width / 2);
    }
    else {
      // (horizontalTextPosition == RIGHT)
      textR.x = (iconR.width + gap);
    }

    /* labelR is the rectangle that contains iconR and textR.
     * Move it to its proper position given the labelAlignment
     * properties.
     *
     * To avoid actually allocating a Rectangle, Rectangle.union
     * has been inlined below.
     */
    int labelR_x = Math.min(iconR.x, textR.x);
    int labelR_width = Math.max(iconR.x + iconR.width, textR.x + textR.width) - labelR_x;
    int labelR_y = Math.min(iconR.y, textR.y);
    int labelR_height = Math.max(iconR.y + iconR.height, textR.y + textR.height) - labelR_y;

    int dx, dy;

    if (verticalAlignment == TOP) {
      dy = viewR.y - labelR_y;
    }
    else if (verticalAlignment == CENTER) {
      dy = (viewR.y + (viewR.height / 2)) - (labelR_y + (labelR_height / 2));
    }
    else {
      // (verticalAlignment == BOTTOM)
      dy = (viewR.y + viewR.height) - (labelR_y + labelR_height);
    }

    if (horizontalAlignment == LEFT) {
      dx = viewR.x - labelR_x;
    }
    else if (horizontalAlignment == RIGHT) {
      dx = (viewR.x + viewR.width) - (labelR_x + labelR_width);
    }
    else {
      // (horizontalAlignment == CENTER)
      dx = (viewR.x + (viewR.width / 2)) -
        (labelR_x + (labelR_width / 2));
    }

    /* Translate textR and glypyR by dx,dy.
     */

    textR.x += dx;
    textR.y += dy;

    iconR.x += dx;
    iconR.y += dy;

    return rettext;
  }

  @Override
  protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) {
    int accChar = l.getDisplayedMnemonic();
    g.setColor(l.getForeground());
    BasicGraphicsUtils.drawString(g, s, accChar, textX, textY);
  }

  @Override
  protected void paintDisabledText(JLabel l, Graphics g, String s, int textX, int textY) {
    int accChar = l.getDisplayedMnemonic();
    g.setColor(l.getBackground());
    BasicGraphicsUtils.drawString(g, s, accChar, textX, textY);
  }

}
