/* ClasspathToolkit.java -- Abstract superclass for Classpath toolkits.
   Copyright (C) 2003, 2004, 2005, 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;

import gnu.java.awt.EmbeddedWindow;
import gnu.java.awt.peer.ClasspathFontPeer;
import gnu.java.awt.peer.EmbeddedWindowPeer;
import gnu.java.security.action.SetAccessibleAction;

import java.awt.AWTException;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.image.ColorModel;
import java.awt.image.ImageProducer;
import java.awt.peer.RobotPeer;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.AttributedString;
import java.util.HashMap;
import java.util.Map;
import java.security.AccessController;

import javax.imageio.spi.IIORegistry;

/**
 * An abstract superclass for Classpath toolkits.
 *
 * <p>There exist some parts of AWT and Java2D that are specific to
 * the underlying platform, but for which the {@link Toolkit} class
 * does not provide suitable abstractions. Examples include some
 * methods of {@link Font} or {@link GraphicsEnvironment}. Those
 * methods use ClasspathToolkit as a central place for obtaining
 * platform-specific functionality.
 *
 * <p>In addition, ClasspathToolkit implements some abstract methods
 * of {@link java.awt.Toolkit} that are not really platform-specific,
 * such as the maintenance of a cache of loaded images.
 *
 * <p><b>Thread Safety:</b> The methods of this class may safely be
 * called without external synchronization. This also hold for any
 * inherited {@link Toolkit} methods. Subclasses are responsible for
 * the necessary synchronization.
 *
 * @author Sascha Brawer (brawer@dandelis.ch)
 */
public abstract class ClasspathToolkit
  extends Toolkit
{
  /**
   * Returns a shared instance of the local, platform-specific
   * graphics environment.
   *
   * <p>This method is specific to GNU Classpath. It gets called by
   * the Classpath implementation of {@link
   * GraphicsEnvironment.getLocalGraphcisEnvironment()}.
   */
  public abstract GraphicsEnvironment getLocalGraphicsEnvironment();

  /**
   * Acquires an appropriate {@link ClasspathFontPeer}, for use in
   * classpath's implementation of {@link java.awt.Font}.
   *
   * @param name The logical name of the font. This may be either a face
   * name or a logical font name, or may even be null. A default
   * implementation of name decoding is provided in 
   * {@link ClasspathFontPeer}, but may be overridden in other toolkits.
   *
   * @param attrs Any extra {@link java.awt.font.TextAttribute} attributes
   * this font peer should have, such as size, weight, family name, or
   * transformation.
   */
  public abstract ClasspathFontPeer getClasspathFontPeer (String name, Map attrs); 

  /** 
   * Creates a {@link Font}, in a platform-specific manner.
   * 
   * The default implementation simply constructs a {@link Font}, but some
   * toolkits may wish to override this, to return {@link Font} subclasses 
   * which implement {@link java.awt.font.OpenType} or
   * {@link java.awt.font.MultipleMaster}.
   */
  public Font getFont (String name, Map attrs) 
  {
    Font f = null;

    // Circumvent the package-privateness of the
    // java.awt.Font.Font(String,Map) constructor.
    try
      {
        Constructor fontConstructor = Font.class.getDeclaredConstructor
          (new Class[] { String.class, Map.class });
        AccessController.doPrivileged
          (new SetAccessibleAction(fontConstructor));
        f = (Font) fontConstructor.newInstance(new Object[] { name, attrs });
      }
    catch (IllegalAccessException e)
      {
        throw new AssertionError(e);
      }
    catch (NoSuchMethodException e)
      {
        throw new AssertionError(e);
      }
    catch (InstantiationException e)
      {
        throw new AssertionError(e);
      }
    catch (InvocationTargetException e)
      {
        throw new AssertionError(e);
      }
    return f;
  }

  /**
   * Creates a font, reading the glyph definitions from a stream.
   *
   * <p>This method provides the platform-specific implementation for
   * the static factory method {@link Font#createFont(int,
   * java.io.InputStream)}.
   *
   * @param format the format of the font data, such as {@link
   * Font#TRUETYPE_FONT}. An implementation may ignore this argument
   * if it is able to automatically recognize the font format from the
   * provided data.
   *
   * @param stream an input stream from where the font data is read
   * in. The stream will be advanced to the position after the font
   * data, but not closed.
   *
   * @throws IllegalArgumentException if <code>format</code> is
   * not supported.
   * 
   * @throws FontFormatException if <code>stream</code> does not
   * contain data in the expected format, or if required tables are
   * missing from a font.
   *
   * @throws IOException if a problem occurs while reading in the
   * contents of <code>stream</code>.
   */
  public abstract Font createFont(int format, InputStream stream);

  /**
   * Creates a RobotPeer on a given GraphicsDevice.
   */
  public abstract RobotPeer createRobot (GraphicsDevice screen)
    throws AWTException;

  /**
   * Creates an embedded window peer, and associates it with an
   * EmbeddedWindow object.
   *
   * @param w The embedded window with which to associate a peer.
   */
  public abstract EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w);

  /**
   * Used to register ImageIO SPIs provided by the toolkit.
   *
   * Our default implementation does nothing.
   */
   public void registerImageIOSpis(IIORegistry reg)
   {
   }

   /**
    * Returns the number of mouse buttons.
    * (used by java.awt.MouseInfo).
    *
    * This dummy implementation returns -1 (no mouse).
    * toolkit implementors should overload this method if possible.
    * @since 1.5
    */
   public int getMouseNumberOfButtons() 
   {
     return -1;
   }
}

