/* FreetypeGlyphVector.java
   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.gtk;

import java.awt.Font;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.GeneralPath;
import java.awt.font.GlyphJustificationInfo;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.font.FontRenderContext;

public class FreetypeGlyphVector extends GlyphVector
{
  /**
   * The associated font and its peer.
   */
  private Font font;
  private GdkFontPeer peer; // ATTN: Accessed from native code.

  private Rectangle2D logicalBounds;

  private float[] glyphPositions;
  /**
   * The string represented by this GlyphVector.
   */
  private String s;

  /**
   * The font render context
   */
  private FontRenderContext frc;

  /**
   * The total # of glyphs.
   */
  private int nGlyphs;

  /**
   * The glyph codes
   */
  private int[] glyphCodes;

  /**
   * Glyph transforms. (de facto only the translation is used)
   */
  private AffineTransform[] glyphTransforms;

  private GlyphMetrics[] metricsCache;

  /**
   * Create a glyphvector from a given (Freetype) font and a String.
   */
  public FreetypeGlyphVector(Font f, String s, FontRenderContext frc)
  {
    this(f, s, frc, Font.LAYOUT_LEFT_TO_RIGHT);
  }

  /**
   * Create a glyphvector from a given (Freetype) font and a String.
   */
  public FreetypeGlyphVector(Font f, String s, FontRenderContext frc,
			     int flags)
  {
    this.s = s;
    this.font = f;
    this.frc = frc;
    if( !(font.getPeer() instanceof GdkFontPeer ) )
      throw new IllegalArgumentException("Not a valid font.");
    peer = (GdkFontPeer)font.getPeer();

    getGlyphs();
    if( flags == Font.LAYOUT_RIGHT_TO_LEFT )
      {
	// reverse the glyph ordering.
	int[] temp = new int[ nGlyphs ];
	for(int i = 0; i < nGlyphs; i++)
	  temp[ i ] = glyphCodes[ nGlyphs - i - 1];
	glyphCodes = temp;
      }
    performDefaultLayout();
  }

  /**
   * Create a glyphvector from a given set of glyph codes.
   */
  public FreetypeGlyphVector(Font f, int[] codes, FontRenderContext frc)
  {
    this.font = f;
    this.frc = frc;
    if( !(font.getPeer() instanceof GdkFontPeer ) )
      throw new IllegalArgumentException("Not a valid font.");
    peer = (GdkFontPeer)font.getPeer();

    glyphCodes = new int[ codes.length ];
    System.arraycopy(codes, 0, glyphCodes, 0, codes.length);
    nGlyphs = glyphCodes.length;
    performDefaultLayout();
  }

  /**
   * Cloning constructor
   */  
  private FreetypeGlyphVector( FreetypeGlyphVector gv )
  {
    font = gv.font;
    peer = gv.peer;
    frc = gv.frc;
    s = gv.s;
    nGlyphs = gv.nGlyphs;
    logicalBounds = gv.logicalBounds.getBounds2D();

    if( gv.metricsCache != null )
      {
	metricsCache = new GlyphMetrics[ nGlyphs ];
	System.arraycopy(gv.metricsCache, 0, metricsCache, 0, nGlyphs);
      }

    glyphCodes = new int[ nGlyphs ];
    glyphPositions = new float[ nGlyphs ];
    glyphTransforms = new AffineTransform[ nGlyphs ];
    for(int i = 0; i < nGlyphs; i++ )
      {
	glyphTransforms[ i ] = new AffineTransform( gv.glyphTransforms[ i ] );
	glyphCodes[i] = gv.glyphCodes[ i ];
	glyphPositions[i] = gv.glyphPositions[ i ];
      }
  }

  /**
   * Create the array of glyph codes.
   */
  private void getGlyphs()
  {
    nGlyphs = s.codePointCount( 0, s.length() );
    glyphCodes = new int[ nGlyphs ];
    int[] codePoints = new int[ nGlyphs ];
    int stringIndex = 0;

    for(int i = 0; i < nGlyphs; i++)
      {
	codePoints[i] = s.codePointAt( stringIndex );
	// UTF32 surrogate handling
	if( codePoints[i] != (int)s.charAt( stringIndex ) )
	  stringIndex ++;
	stringIndex ++;
      }

   glyphCodes = getGlyphs( codePoints );
  }

  /**
   * Returns the glyph code within the font for a given character
   */
  public native int[] getGlyphs(int[] codepoints);

  /**
   * Returns the kerning of a glyph pair
   */
  private native Point2D getKerning(int leftGlyph, int rightGlyph);

  private native double[] getMetricsNative( int glyphCode );

  private native GeneralPath getGlyphOutlineNative(int glyphIndex);


  public Object clone()
  {
    return new FreetypeGlyphVector( this );
  }

  /**
   * Duh, compares two instances.
   */
  public boolean equals(GlyphVector gv)
  {
    if( ! (gv instanceof FreetypeGlyphVector) )
      return false;

    return (((FreetypeGlyphVector)gv).font.equals(font) && 
	    ((FreetypeGlyphVector)gv).frc.equals(frc)
	    && ((FreetypeGlyphVector)gv).s.equals(s));
  }

  /**
   * Returns the associated Font
   */
  public Font getFont()
  {
    return font;
  }

  /**
   * Returns the associated FontRenderContext
   */
  public FontRenderContext getFontRenderContext()
  {
    return frc;
  }

  /**
   * Layout the glyphs.
   */
  public void performDefaultLayout()
  {
    logicalBounds = null; // invalidate caches.
    glyphPositions = null;

    glyphTransforms = new AffineTransform[ nGlyphs ]; 
    double x = 0;

    for(int i = 0; i < nGlyphs; i++)
      {
	GlyphMetrics gm = getGlyphMetrics( i );
	glyphTransforms[ i ] = AffineTransform.getTranslateInstance(x, 0);
	x += gm.getAdvanceX();
	if( i > 0 )
	  {
	    Point2D p = getKerning( glyphCodes[ i - 1 ], glyphCodes[ i ] );
	    x += p.getX();
	  }
      }
  }

  /**
   * Returns the code of the glyph at glyphIndex;
   */
  public int getGlyphCode(int glyphIndex)
  {
    return glyphCodes[ glyphIndex ];
  }

  /**
   * Returns multiple glyphcodes.
   */
  public int[] getGlyphCodes(int beginGlyphIndex, int numEntries, 
			     int[] codeReturn)
  {
    int[] rval;

    if( codeReturn == null )
      rval = new int[ numEntries ];
    else
      rval = codeReturn;
    
    System.arraycopy(glyphCodes, beginGlyphIndex, rval, 0, numEntries);

    return rval;
  }

  /**
   * FIXME: Implement me.
   */
  public Shape getGlyphLogicalBounds(int glyphIndex)
  {
    GlyphMetrics gm = getGlyphMetrics( glyphIndex );
    if( gm == null )
      return null; 
    Rectangle2D r = gm.getBounds2D();
    Point2D p = getGlyphPosition( glyphIndex );
    return new Rectangle2D.Double( p.getX() + r.getX() - gm.getLSB(), 
				   p.getY() + r.getY(),
				   gm.getAdvanceX(), 
				   r.getHeight() );
  }

  /*
   * FIXME: Not all glyph types are supported.
   * (The JDK doesn't really seem to do so either)
   */
  public void setupGlyphMetrics()
  {
    metricsCache = new GlyphMetrics[ nGlyphs ];

    for(int i = 0; i < nGlyphs; i++)
      {
	GlyphMetrics gm = (GlyphMetrics)
	  peer.getGlyphMetrics( glyphCodes[ i ] );
	if( gm == null )
	  {
	    double[] val = getMetricsNative( glyphCodes[ i ] );
	    if( val == null )
	      gm = null;
	    else
	      {
		gm = new GlyphMetrics( true, 
				       (float)val[1], 
				       (float)val[2], 
				       new Rectangle2D.Double
				       ( val[3], val[4], 
					 val[5], val[6] ),
				       GlyphMetrics.STANDARD );
		peer.putGlyphMetrics( glyphCodes[ i ], gm );
	      }
	  }
	metricsCache[ i ] = gm;
      }
  }

  /**
   * Returns the metrics of a single glyph.
   */
  public GlyphMetrics getGlyphMetrics(int glyphIndex)
  {
    if( metricsCache == null )
      setupGlyphMetrics();

    return metricsCache[ glyphIndex ];
  }

  /**
   * Returns the outline of a single glyph.
   */
  public Shape getGlyphOutline(int glyphIndex)
  {
    GeneralPath gp = getGlyphOutlineNative( glyphCodes[ glyphIndex ] );
    gp.transform( glyphTransforms[ glyphIndex ] );
    return gp;
  }

  /**
   * Returns the position of a single glyph.
   */
  public Point2D getGlyphPosition(int glyphIndex)
  {
    return glyphTransforms[ glyphIndex ].transform( new Point2D.Double(0, 0),
						   null );
  }

  /**
   * Returns the positions of multiple glyphs.
   */
  public float[] getGlyphPositions(int beginGlyphIndex, int numEntries, 
				   float[] positionReturn)
  {
    if( glyphPositions != null )
      return glyphPositions;

    float[] rval;

    if( positionReturn == null )
      rval = new float[2 * numEntries];
    else
      rval = positionReturn;

    for( int i = beginGlyphIndex; i < numEntries; i++ )
      {
	Point2D p = getGlyphPosition( i );
	rval[i * 2] = (float)p.getX();
	rval[i * 2 + 1] = (float)p.getY();
      }

    glyphPositions = rval;
    return rval;
  }

  /**
   * Returns the transform of a glyph.
   */
  public AffineTransform getGlyphTransform(int glyphIndex)
  {
    return new AffineTransform( glyphTransforms[ glyphIndex ] );
  }

  /**
   * Returns the visual bounds of a glyph
   * May be off by a pixel or two due to hinting/rasterization.
   */
  public Shape getGlyphVisualBounds(int glyphIndex)
  {
    return getGlyphOutline( glyphIndex ).getBounds2D();
  }

  /**
   * Return the logical bounds of the whole thing.
   */
  public Rectangle2D getLogicalBounds()
  {
    if( nGlyphs == 0 )
      return new Rectangle2D.Double(0, 0, 0, 0);
    if( logicalBounds != null )
      return logicalBounds;

    Rectangle2D rect = (Rectangle2D)getGlyphLogicalBounds( 0 );
    for( int i = 1; i < nGlyphs; i++ )
      {
	Rectangle2D r2 = (Rectangle2D)getGlyphLogicalBounds( i );
	rect = rect.createUnion( r2 );
      }

    logicalBounds = rect;
    return rect;
  }

  /**
   * Returns the number of glyphs.
   */
  public int getNumGlyphs()
  {
    return glyphCodes.length;
  }

  /**
   * Returns the outline of the entire GlyphVector.
   */
  public Shape getOutline()
  {
    GeneralPath path = new GeneralPath();
    for( int i = 0; i < getNumGlyphs(); i++ )
      path.append( getGlyphOutline( i ), false );
    return path;
  }

  /**
   * TODO: 
   * FreeType does not currently have an API for the JSTF table. We should 
   * probably get the table ourselves from FT and pass it to some parser 
   * which the native font peers will need.
   */
  public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex)
  {
    return null;
  }

  /**
   * Returns the outline of the entire vector, drawn at (x,y).
   */
  public Shape getOutline(float x, float y)
  {
    AffineTransform tx = AffineTransform.getTranslateInstance( x, y );
    GeneralPath gp = (GeneralPath)getOutline();
    gp.transform( tx );
    return gp;
  }

  /**
   * Returns the visual bounds of the entire GlyphVector.
   * May be off by a pixel or two due to hinting/rasterization.
   */
  public Rectangle2D getVisualBounds()
  {
    return getOutline().getBounds2D();
  }

  /**
   * Sets the position of a glyph.
   */
  public void setGlyphPosition(int glyphIndex, Point2D newPos)
  {
    // FIXME: Scaling, etc.?
    glyphTransforms[ glyphIndex ].setToTranslation( newPos.getX(), 
						    newPos.getY() );
    logicalBounds = null;
    glyphPositions = null;
  }

  /**
   * Sets the transform of a single glyph.
   */
  public void setGlyphTransform(int glyphIndex, AffineTransform newTX)
  {
    glyphTransforms[ glyphIndex ].setTransform( newTX );
    logicalBounds = null;
    glyphPositions = null;
  }
}
