/* XFontPeer.java -- The font peer for X
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.awt.peer.x;

import java.awt.AWTError;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.LineMetrics;
import java.awt.font.TextAttribute;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.InputStream;
import java.text.CharacterIterator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import gnu.java.awt.peer.ClasspathFontPeer;
import gnu.x11.Display;
import gnu.x11.Fontable;

/**
 * The bridge from AWT to X fonts.
 *
 * @author Roman Kennke (kennke@aicas.com)
 */
public class XFontPeer
  extends ClasspathFontPeer
{

  /**
   * The font mapping as specified in the file fonts.properties.
   */
  private static Properties fontProperties;
  static
  {
    fontProperties = new Properties();
    InputStream in = XFontPeer.class.getResourceAsStream("fonts.properties");
    try
      {
        fontProperties.load(in);
      }
    catch (IOException e)
      {
        e.printStackTrace();
      }
  }

  /**
   * The FontMetrics implementation for XFontPeer.
   */
  private class XFontMetrics
    extends FontMetrics
  {
    /**
     * The ascent of the font.
     */ 
    int ascent;

    /**
     * The descent of the font.
     */ 
    int descent;

    /**
     * The maximum of the character advances.
     */
    private int maxAdvance;

    /**
     * The internal leading.
     */
    int leading;

    /**
     * Cached string metrics. This caches string metrics locally so that the
     * server doesn't have to be asked each time.
     */
    private HashMap metricsCache;

    /**
     * The widths of the characters indexed by the characters themselves.
     */
    private int[] charWidths;

    /**
     * Creates a new XFontMetrics for the specified font.
     *
     * @param font the font
     */
    protected XFontMetrics(Font font)
    {
      super(font);
      metricsCache = new HashMap();
      Fontable.FontReply info = getXFont().info();
      ascent = info.font_ascent();
      descent = info.font_descent();
      maxAdvance = info.max_bounds().character_width();
      leading = 0; // TODO: Not provided by X. Possible not needed.

      if (info.min_byte1() == 0 && info.max_byte1() == 0)
        readCharWidthsLinear(info);
      else
        readCharWidthsNonLinear(info);
    }

    /**
     * Reads the character widths when specified in a linear fashion. That is
     * when the min-byte1 and max-byte2 fields are both zero in the X protocol.
     *
     * @param info the font info reply
     */
    private void readCharWidthsLinear(Fontable.FontReply info)
    {
      int startIndex = info.min_char_or_byte2();
      int endIndex = info.max_char_or_byte2();
      charWidths = new int[endIndex + 1];
      // All the characters before startIndex are zero width.
      for (int i = 0; i < startIndex; i++)
        {
          charWidths[i] = 0;
        }
      // All the other character info is fetched from the font info.
      int index = startIndex;
      Iterator charInfos = info.char_infos().iterator();
      while (charInfos.hasNext())
        {
          Fontable.FontReply.CharInfo charInfo =
            (Fontable.FontReply.CharInfo) charInfos.next();
          charWidths[index] = charInfo.character_width();
          index++;
        }
    }

    private void readCharWidthsNonLinear(Fontable.FontReply info)
    {
      // TODO: Implement.
      throw new UnsupportedOperationException("Not yet implemented");
    }

    /**
     * Returns the ascent of the font.
     *
     * @return the ascent of the font
     */
    public int getAscent()
    {
      return ascent;
    }

    /**
     * Returns the descent of the font.
     *
     * @return the descent of the font
     */
    public int getDescent()
    {
      return descent;
    }

    /**
     * Returns the overall height of the font. This is the distance from
     * baseline to baseline (usually ascent + descent + leading).
     *
     * @return the overall height of the font
     */
    public int getHeight()
    {
      return ascent + descent;
    }

    /**
     * Returns the leading of the font.
     *
     * @return the leading of the font
     */
    public int getLeading()
    {
      return leading;
    }

    /**
     * Returns the maximum advance for this font.
     *
     * @return the maximum advance for this font
     */
    public int getMaxAdvance()
    {
      return maxAdvance;
    }

    /**
     * Determines the width of the specified character <code>c</code>.
     *
     * @param c the character
     *
     * @return the width of the character
     */
    public int charWidth(char c)
    {
      int width;
      if (c > charWidths.length)
        width = charWidths['?'];
      else
        width = charWidths[c];
      return width;
    }

    /**
     * Determines the overall width of the specified string.
     *
     * @param c the char buffer holding the string
     * @param offset the starting offset of the string in the buffer
     * @param length the number of characters in the string buffer 
     *
     * @return the overall width of the specified string
     */
    public int charsWidth(char[] c, int offset, int length)
    {
      int width = 0;
      if (c.length > 0 && length > 0)
        {
          String s = new String(c, offset, length);
          width = stringWidth(s);
        }
      return width;
    }

    /**
     * Determines the overall width of the specified string.
     *
     * @param s the string
     *
     * @return the overall width of the specified string
     */
    public int stringWidth(String s)
    {
      int width = 0;
      if (s.length() > 0)
        {
          if (metricsCache.containsKey(s))
            {
              width = ((Integer) metricsCache.get(s)).intValue();
            }
          else
            {
              Fontable.TextExtentReply extents = getXFont().text_extent(s);
              /*
               System.err.println("string: '" + s + "' : ");
               System.err.println("ascent: " + extents.getAscent());
               System.err.println("descent: " + extents.getDescent());
               System.err.println("overall ascent: " + extents.getOverallAscent());
               System.err.println("overall descent: " + extents.getOverallDescent());
               System.err.println("overall width: " + extents.getOverallWidth());
               System.err.println("overall left: " + extents.getOverallLeft());
               System.err.println("overall right: " + extents.getOverallRight());
               */
              width = extents.overall_width(); // + extents.overall_left();
              //System.err.println("String: " + s + ", width: " + width);
              metricsCache.put(s, new Integer(width));
            }
        }
      //System.err.print("stringWidth: '" + s + "': ");
      //System.err.println(width);
      return width;
    }
  }

  /**
   * The LineMetrics implementation for the XFontPeer.
   */
  private class XLineMetrics
    extends LineMetrics
  {

    /**
     * Returns the ascent of the font.
     *
     * @return the ascent of the font
     */
    public float getAscent()
    {
      return fontMetrics.ascent;
    }

    public int getBaselineIndex()
    {
      // FIXME: Implement this.
      throw new UnsupportedOperationException();
    }

    public float[] getBaselineOffsets()
    {
      // FIXME: Implement this.
      throw new UnsupportedOperationException();
    }

    /**
     * Returns the descent of the font.
     *
     * @return the descent of the font
     */
    public float getDescent()
    {
      return fontMetrics.descent;
    }

    /**
     * Returns the overall height of the font. This is the distance from
     * baseline to baseline (usually ascent + descent + leading).
     *
     * @return the overall height of the font
     */
    public float getHeight()
    {
      return fontMetrics.ascent + fontMetrics.descent;
    }

    /**
     * Returns the leading of the font.
     *
     * @return the leading of the font
     */
    public float getLeading()
    {
      return fontMetrics.leading;
    }

    public int getNumChars()
    {
      // FIXME: Implement this.
      throw new UnsupportedOperationException();
    }

    public float getStrikethroughOffset()
    {
      return 0.F; // TODO: Provided by X??
    }

    public float getStrikethroughThickness()
    {
      return 1.F; // TODO: Provided by X??
    }

    public float getUnderlineOffset()
    {
      return 0.F; // TODO: Provided by X??
    }

    public float getUnderlineThickness()
    {
      return 1.F; // TODO: Provided by X??
    }
      
  }

  /**
   * The X font.
   */
  private gnu.x11.Font xfont;

  private String name;

  private int style;

  private int size;

  /**
   * The font metrics for this font.
   */
  XFontMetrics fontMetrics; 

  /**
   * Creates a new XFontPeer for the specified font name, style and size.
   *
   * @param name the font name
   * @param style the font style (bold / italic / normal)
   * @param size the size of the font
   */
  public XFontPeer(String name, int style, int size)
  {
    super(name, style, size);
    this.name = name;
    this.style = style;
    this.size = size;
  }

  /**
   * Creates a new XFontPeer for the specified font name and style
   * attributes.
   *
   * @param name the font name
   * @param atts the font attributes
   */
  public XFontPeer(String name, Map atts)
  {
    super(name, atts);
    String family = name;
    if (family == null || family.equals(""))
      family = (String) atts.get(TextAttribute.FAMILY);
    if (family == null)
      family = "SansSerif";

    int size = 12;
    Float sizeFl = (Float) atts.get(TextAttribute.SIZE);
    if (sizeFl != null)
      size = sizeFl.intValue();

    int style = 0;
    // Detect italic attribute.
    Float posture = (Float) atts.get(TextAttribute.POSTURE);
    if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
      style |= Font.ITALIC;

    // Detect bold attribute.
    Float weight = (Float) atts.get(TextAttribute.WEIGHT);
    if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
      style |= Font.BOLD;

    this.name = name;
    this.style = style;
    this.size = size;
  }

  /**
   * Initializes the font peer with the specified attributes. This method is
   * called from both constructors.
   *
   * @param name the font name
   * @param style the font style
   * @param size the font size
   */
  private void init(String name, int style, int size)
  {
    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice dev = env.getDefaultScreenDevice();
    if (dev instanceof XGraphicsDevice)
      {
        Display display = ((XGraphicsDevice) dev).getDisplay();
        String fontDescr = encodeFont(name, style, size);
        if (XToolkit.DEBUG)
          System.err.println("XLFD font description: " + fontDescr);
        xfont = new gnu.x11.Font(display, fontDescr);
      }
    else
      {
        throw new AWTError("Local GraphicsEnvironment is not XWindowGraphicsEnvironment");
      }
  }

  public boolean canDisplay(Font font, char c)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public String getSubFamilyName(Font font, Locale locale)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public String getPostScriptName(Font font)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public int getNumGlyphs(Font font)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public int getMissingGlyphCode(Font font)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public byte getBaselineFor(Font font, char c)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public String getGlyphName(Font font, int glyphIndex)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public GlyphVector createGlyphVector(Font font, FontRenderContext frc,
                                       CharacterIterator ci)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public GlyphVector createGlyphVector(Font font, FontRenderContext ctx,
                                       int[] glyphCodes)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc,
                                       char[] chars, int start, int limit,
                                       int flags)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  /**
   * Returns the font metrics for the specified font.
   *
   * @param font the font for which to fetch the font metrics
   *
   * @return the font metrics for the specified font
   */
  public FontMetrics getFontMetrics(Font font)
  {
    if (font.getPeer() != this)
      throw new AWTError("The specified font has a different peer than this");

    if (fontMetrics == null)
      fontMetrics = new XFontMetrics(font);
    return fontMetrics;
  }

  /**
   * Frees the font in the X server.
   */
  protected void finalize()
  {
    if (xfont != null)
      xfont.close();
  }

  public boolean hasUniformLineMetrics(Font font)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  /**
   * Returns the line metrics for this font and the specified string and
   * font render context.
   */
  public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin,
                                    int limit, FontRenderContext rc)
  {
    return new XLineMetrics();
  }

  public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  public Rectangle2D getStringBounds(Font font, CharacterIterator ci,
                                     int begin, int limit, FontRenderContext frc)
  {
    // TODO: Implement this.
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  /**
   * Encodes a font name + style + size specification into a X logical font
   * description (XLFD) as described here:
   *
   * http://www.meretrx.com/e93/docs/xlfd.html
   *
   * This is implemented to look up the font description in the
   * fonts.properties of this package.
   *
   * @param name the font name
   * @param atts the text attributes
   *
   * @return the encoded font description
   */
  static String encodeFont(String name, Map atts)
  {
    String family = name;
    if (family == null || family.equals(""))
      family = (String) atts.get(TextAttribute.FAMILY);
    if (family == null)
      family = "SansSerif";

    int size = 12;
    Float sizeFl = (Float) atts.get(TextAttribute.SIZE);
    if (sizeFl != null)
      size = sizeFl.intValue();

    int style = 0;
    // Detect italic attribute.
    Float posture = (Float) atts.get(TextAttribute.POSTURE);
    if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
      style |= Font.ITALIC;

    // Detect bold attribute.
    Float weight = (Float) atts.get(TextAttribute.WEIGHT);
    if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
      style |= Font.BOLD;

    return encodeFont(name, style, size);
  }

  /**
   * Encodes a font name + style + size specification into a X logical font
   * description (XLFD) as described here:
   *
   * http://www.meretrx.com/e93/docs/xlfd.html
   *
   * This is implemented to look up the font description in the
   * fonts.properties of this package.
   *
   * @param name the font name
   * @param style the font style
   * @param size the font size
   *
   * @return the encoded font description
   */
  static String encodeFont(String name, int style, int size)
  {
    StringBuilder key = new StringBuilder();
    key.append(validName(name));
    key.append('.');
    switch (style)
    {
      case Font.BOLD:
        key.append("bold");
        break;
      case Font.ITALIC:
        key.append("italic");
        break;
      case (Font.BOLD | Font.ITALIC):
        key.append("bolditalic");
        break;
      case Font.PLAIN:
      default:
        key.append("plain");
      
    }

    String protoType = fontProperties.getProperty(key.toString());
    int s = validSize(size);
    return protoType.replaceFirst("%d", String.valueOf(s * 10));
  }

  /**
   * Checks the specified font name for a valid font name. If the font name
   * is not known, then this returns 'sansserif' as fallback.
   *
   * @param name the font name to check
   *
   * @return a valid font name
   */
  static String validName(String name)
  {
    String retVal;
    if (name.equalsIgnoreCase("sansserif")
        || name.equalsIgnoreCase("serif")
        || name.equalsIgnoreCase("monospaced")
        || name.equalsIgnoreCase("dialog")
        || name.equalsIgnoreCase("dialoginput"))
      {
        retVal = name.toLowerCase();
      }
    else
      {
        retVal = "sansserif";
      }
    return retVal;
  }

  /**
   * Translates an arbitrary point size to a size that is typically available
   * on an X server. These are the sizes 8, 10, 12, 14, 18 and 24.
   *
   * @param size the queried size
   * @return the real available size
   */
  private static final int validSize(int size)
  {
    int val;
    if (size <= 9)
      val = 8;
    else if (size <= 11)
      val = 10;
    else if (size <= 13)
      val = 12;
    else if (size <= 17)
      val = 14;
    else if (size <= 23)
      val = 18;
    else
      val = 24;
    return val;
  }

  /**
   * Returns the X Font reference. This lazily loads the font when first
   * requested.
   *
   * @return the X Font reference
   */
  gnu.x11.Font getXFont()
  {
    if (xfont == null)
      {
        init(name, style, size);
      }
    return xfont;
  }
}
