/* GtkToolkit.java -- Implements an AWT Toolkit using GTK for peers
   Copyright (C) 1998, 1999, 2002, 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.peer.gtk;

import gnu.java.awt.EmbeddedWindow;
import gnu.java.awt.dnd.GtkMouseDragGestureRecognizer;
import gnu.java.awt.dnd.peer.gtk.GtkDragSourceContextPeer;
import gnu.java.awt.peer.ClasspathFontPeer;
import gnu.java.awt.peer.EmbeddedWindowPeer;

import java.awt.AWTException;
import java.awt.Button;
import java.awt.Canvas;
import java.awt.Checkbox;
import java.awt.CheckboxMenuItem;
import java.awt.Choice;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Label;
import java.awt.List;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Panel;
import java.awt.Point;
import java.awt.PopupMenu;
import java.awt.PrintJob;
import java.awt.Rectangle;
import java.awt.ScrollPane;
import java.awt.Scrollbar;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Window;
import java.awt.datatransfer.Clipboard;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.im.InputMethodHighlight;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.peer.ButtonPeer;
import java.awt.peer.CanvasPeer;
import java.awt.peer.CheckboxMenuItemPeer;
import java.awt.peer.CheckboxPeer;
import java.awt.peer.ChoicePeer;
import java.awt.peer.DialogPeer;
import java.awt.peer.FileDialogPeer;
import java.awt.peer.FontPeer;
import java.awt.peer.FramePeer;
import java.awt.peer.LabelPeer;
import java.awt.peer.ListPeer;
import java.awt.peer.MenuBarPeer;
import java.awt.peer.MenuItemPeer;
import java.awt.peer.MouseInfoPeer;
import java.awt.peer.MenuPeer;
import java.awt.peer.PanelPeer;
import java.awt.peer.PopupMenuPeer;
import java.awt.peer.RobotPeer;
import java.awt.peer.ScrollPanePeer;
import java.awt.peer.ScrollbarPeer;
import java.awt.peer.TextAreaPeer;
import java.awt.peer.TextFieldPeer;
import java.awt.peer.WindowPeer;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

import javax.imageio.spi.IIORegistry;

/* This class uses a deprecated method java.awt.peer.ComponentPeer.getPeer().
   This merits comment.  We are basically calling Sun's bluff on this one.
   We think Sun has deprecated it simply to discourage its use as it is
   bad programming style.  However, we need to get at a component's peer in
   this class.  If getPeer() ever goes away, we can implement a hash table
   that will keep up with every window's peer, but for now this is faster. */

public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
{
  Hashtable containers = new Hashtable();
  static EventQueue q;
  static Thread mainThread;

  static native void gtkInit(int portableNativeSync);

  static
  {
    System.loadLibrary("gtkpeer");

    int portableNativeSync;     
    String portNatSyncProp = 
      System.getProperty("gnu.classpath.awt.gtk.portable.native.sync");
    
    if (portNatSyncProp == null)
      portableNativeSync = -1;  // unset
    else if (Boolean.valueOf(portNatSyncProp).booleanValue())
      portableNativeSync = 1;   // true
    else
      portableNativeSync = 0;   // false

    gtkInit(portableNativeSync);

    mainThread = new Thread ("GTK main thread")
      {
        public void run ()
        {
          gtkMain ();
        }
      };
    mainThread.start ();
  }

  public GtkToolkit ()
  {
  }

  public native void beep();
  private native void getScreenSizeDimensions(int[] xy);
  
  public int checkImage (Image image, int width, int height, 
			 ImageObserver observer) 
  {
    int status = ImageObserver.ALLBITS 
      | ImageObserver.WIDTH 
      | ImageObserver.HEIGHT;

    if (image instanceof GtkImage)
	return ((GtkImage) image).checkImage (observer);

    if (observer != null)
      observer.imageUpdate (image, status,
                            -1, -1,
                            image.getWidth (observer),
                            image.getHeight (observer));
    
    return status;
  }

  /** 
   * Helper to return either a Image -- the argument -- or a
   * GtkImage with the errorLoading flag set if the argument is null.
   */
  private Image imageOrError(Image b)
  {
    if (b == null) 
      return GtkImage.getErrorImage();
    else
      return b;
  }

  public Image createImage (String filename)
  {
    if (filename.length() == 0)
      return new GtkImage ();
    
    Image image;
    try
      {
	image = CairoSurface.getBufferedImage( new GtkImage( filename ) );
      }
    catch (IllegalArgumentException iae)
      {
	image = null;
      }
    return imageOrError(image);
  }

  public Image createImage (URL url)
  {
    Image image;
    try
      {
	image = CairoSurface.getBufferedImage( new GtkImage( url ) );
      }
    catch (IllegalArgumentException iae)
      {
	image = null;
      }
    return imageOrError(image);
  }

  public Image createImage (ImageProducer producer) 
  {
    if (producer == null)
      return null;
      
    Image image;
    try
      {
	image = CairoSurface.getBufferedImage( new GtkImage( producer ) );
      }
    catch (IllegalArgumentException iae)
      {
	image = null;
      }
    return imageOrError(image);
  }

  public Image createImage (byte[] imagedata, int imageoffset,
			    int imagelength)
  {
    Image image;
    try
      {
	byte[] data = new byte[ imagelength ];
	System.arraycopy(imagedata, imageoffset, data, 0, imagelength);
	image = CairoSurface.getBufferedImage( new GtkImage( data ) );
      }
    catch (IllegalArgumentException iae)
      {
	image = null;
      }
    return imageOrError(image);
  }
  
  /**
   * Creates an ImageProducer from the specified URL. The image is assumed
   * to be in a recognised format. 
   *
   * @param url URL to read image data from.
   */  
  public ImageProducer createImageProducer(URL url)
  {
    return createImage( url ).getSource();
  }

  /**
   * Returns the native color model (which isn't the same as the default
   * ARGB color model, but doesn't have to be). 
   */
  public ColorModel getColorModel () 
  {
    /* Return the GDK-native ABGR format */
    return new DirectColorModel(32, 
				0x000000FF,
				0x0000FF00,
				0x00FF0000,
				0xFF000000);
  }

  public String[] getFontList () 
  {
    return (new String[] { "Dialog", 
			   "DialogInput", 
			   "Monospaced", 
			   "Serif", 
			   "SansSerif" });
  }

  private class LRUCache extends LinkedHashMap
  {    
    int max_entries;
    public LRUCache(int max)
    {
      super(max, 0.75f, true);
      max_entries = max;
    }
    protected boolean removeEldestEntry(Map.Entry eldest)
    {
      return size() > max_entries;
    }
  }

  private LRUCache fontCache = new LRUCache(50);
  private LRUCache metricsCache = new LRUCache(50);
  private LRUCache imageCache = new LRUCache(50);

  public FontMetrics getFontMetrics (Font font) 
  {
    synchronized (metricsCache)
      {
        if (metricsCache.containsKey(font))
          return (FontMetrics) metricsCache.get(font);
      }

    FontMetrics m = new GdkFontMetrics (font);
    synchronized (metricsCache)
      {
        metricsCache.put(font, m);
      }
    return m;
  }

  public Image getImage (String filename) 
  {
    if (imageCache.containsKey(filename))
      return (Image) imageCache.get(filename);
    else
      {
        Image im = createImage(filename);
        imageCache.put(filename, im);
        return im;
      }
  }

  public Image getImage (URL url) 
  {
    if (imageCache.containsKey(url))
      return (Image) imageCache.get(url);
    else
      {
        Image im = createImage(url);
        imageCache.put(url, im);
        return im;
      }
  }

  public PrintJob getPrintJob (Frame frame, String jobtitle, Properties props) 
  {
    SecurityManager sm;
    sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPrintJobAccess();

    return null;
  }

  public native int getScreenResolution();

  public Dimension getScreenSize ()
  {
    int dim[] = new int[2];
    getScreenSizeDimensions(dim);
    return new Dimension(dim[0], dim[1]);
  }

  public Clipboard getSystemClipboard() 
  {
    SecurityManager secman = System.getSecurityManager();
    if (secman != null)
      secman.checkSystemClipboardAccess();

    return GtkClipboard.getClipboardInstance();
  }

  public Clipboard getSystemSelection()
  {
    SecurityManager secman = System.getSecurityManager();
    if (secman != null)
      secman.checkSystemClipboardAccess();
    
    return GtkClipboard.getSelectionInstance();
  }

  /**
   * Prepares a GtkImage. For every other kind of Image it just
   * assumes the image is already prepared for rendering.
   */
  public boolean prepareImage (Image image, int width, int height, 
			       ImageObserver observer) 
  {
    /* GtkImages are always prepared, as long as they're loaded. */
    if (image instanceof GtkImage)
      return ((((GtkImage)image).checkImage (observer) & 
	       ImageObserver.ALLBITS) != 0);

    /* Assume anything else is too */
    return true;
  }

  public native void sync();

  protected void setComponentState (Component c, GtkComponentPeer cp)
  {
    /* Make the Component reflect Peer defaults */
    if (c.getForeground () == null)
      c.setForeground (cp.getForeground ());
    if (c.getBackground () == null)
      c.setBackground (cp.getBackground ());
    //        if (c.getFont () == null)
    //  	c.setFont (cp.getFont ());
      
    /* Make the Peer reflect the state of the Component */
    if (! (c instanceof Window))
      {
	cp.setCursor (c.getCursor ());
	
	Rectangle bounds = c.getBounds ();
	cp.setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
	cp.setVisible (c.isVisible ());
      }
  }

  protected ButtonPeer createButton (Button b)
  {
    return new GtkButtonPeer (b);
  }

  protected CanvasPeer createCanvas (Canvas c) 
  {
    return new GtkCanvasPeer (c);
  }

  protected CheckboxPeer createCheckbox (Checkbox cb) 
  {
    return new GtkCheckboxPeer (cb);
  }

  protected CheckboxMenuItemPeer createCheckboxMenuItem (CheckboxMenuItem cmi)
  {
    return new GtkCheckboxMenuItemPeer (cmi);
  }

  protected ChoicePeer createChoice (Choice c) 
  {
    return new GtkChoicePeer (c);
  }

  protected DialogPeer createDialog (Dialog d)
  {
    return new GtkDialogPeer (d);
  }

  protected FileDialogPeer createFileDialog (FileDialog fd)
  {
    return new GtkFileDialogPeer (fd);
  }

  protected FramePeer createFrame (Frame f)
  {
    return new GtkFramePeer (f);
  }

  protected LabelPeer createLabel (Label label) 
  {
    return new GtkLabelPeer (label);
  }

  protected ListPeer createList (List list)
  {
    return new GtkListPeer (list);
  }

  protected MenuPeer createMenu (Menu m) 
  {
    return new GtkMenuPeer (m);
  }

  protected MenuBarPeer createMenuBar (MenuBar mb) 
  {
    return new GtkMenuBarPeer (mb);
  }

  protected MenuItemPeer createMenuItem (MenuItem mi) 
  {
    return new GtkMenuItemPeer (mi);
  }

  protected PanelPeer createPanel (Panel p) 
  {
    return new GtkPanelPeer (p);
  }

  protected PopupMenuPeer createPopupMenu (PopupMenu target) 
  {
    return new GtkPopupMenuPeer (target);
  }

  protected ScrollPanePeer createScrollPane (ScrollPane sp) 
  {
    return new GtkScrollPanePeer (sp);
  }

  protected ScrollbarPeer createScrollbar (Scrollbar sb) 
  {
    return new GtkScrollbarPeer (sb);
  }

  protected TextAreaPeer createTextArea (TextArea ta) 
  {
    return new GtkTextAreaPeer (ta);
  }

  protected TextFieldPeer createTextField (TextField tf) 
  {
    return new GtkTextFieldPeer (tf);
  }

  protected WindowPeer createWindow (Window w)
  {
    return new GtkWindowPeer (w);
  }

  public EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w)
  {
    return new GtkEmbeddedWindowPeer (w);
  }

  /** 
   * @deprecated part of the older "logical font" system in earlier AWT
   * implementations. Our newer Font class uses getClasspathFontPeer.
   */
  protected FontPeer getFontPeer (String name, int style) {
    // All fonts get a default size of 12 if size is not specified.
    return getFontPeer(name, style, 12);
  }

  /**
   * Private method that allows size to be set at initialization time.
   */
  private FontPeer getFontPeer (String name, int style, int size) 
  {
    Map attrs = new HashMap ();
    ClasspathFontPeer.copyStyleToAttrs (style, attrs);
    ClasspathFontPeer.copySizeToAttrs (size, attrs);
    return getClasspathFontPeer (name, attrs);
  }

  /**
   * Newer method to produce a peer for a Font object, even though Sun's
   * design claims Font should now be peerless, we do not agree with this
   * model, hence "ClasspathFontPeer". 
   */

  public ClasspathFontPeer getClasspathFontPeer (String name, Map attrs)
  {
    Map keyMap = new HashMap (attrs);
    // We don't know what kind of "name" the user requested (logical, face,
    // family), and we don't actually *need* to know here. The worst case
    // involves failure to consolidate fonts with the same backend in our
    // cache. This is harmless.
    keyMap.put ("GtkToolkit.RequestedFontName", name);
    if (fontCache.containsKey (keyMap))
      return (ClasspathFontPeer) fontCache.get (keyMap);
    else
      {
        ClasspathFontPeer newPeer = new GdkFontPeer (name, attrs);
        fontCache.put (keyMap, newPeer);
        return newPeer;
      }
  }

  protected EventQueue getSystemEventQueueImpl() 
  {
    synchronized (GtkToolkit.class)
      {
        if (q == null)
          {
            q = new EventQueue();
          }
      }    
    return q;
  }

  public Cursor createCustomCursor(Image image, Point hotspot, String name)
  {
    return new GtkCursor(image, hotspot, name);
  }

  protected native void loadSystemColors (int[] systemColors);

  public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e)
  {
    return new GtkDragSourceContextPeer(e);
  }
  
  public DragGestureRecognizer createDragGestureRecognizer(Class recognizer,
                                                           DragSource ds,
                                                           Component comp,
                                                           int actions,
                                                           DragGestureListener l)
  {
    if (recognizer.getName().equals("java.awt.dnd.MouseDragGestureRecognizer"))
      {
        GtkMouseDragGestureRecognizer gestureRecognizer
          = new GtkMouseDragGestureRecognizer(ds, comp, actions, l);
        gestureRecognizer.registerListeners();
        return gestureRecognizer;
      }
    else
      {
        return null;
      }
  }

  public Map mapInputMethodHighlight(InputMethodHighlight highlight)
  {
    throw new Error("not implemented");
  }

  public Rectangle getBounds()
  {
    int[] dims = new int[2];
    getScreenSizeDimensions(dims);
    return new Rectangle(0, 0, dims[0], dims[1]);
  }
  
  // ClasspathToolkit methods

  public GraphicsEnvironment getLocalGraphicsEnvironment()
  {
    return new GdkGraphicsEnvironment();
  }

  public Font createFont(int format, InputStream stream)
  {
    throw new UnsupportedOperationException();
  }

  public RobotPeer createRobot (GraphicsDevice screen) throws AWTException
  {
    return new GdkRobotPeer (screen);
  }

  public void registerImageIOSpis(IIORegistry reg)
  {
    GdkPixbufDecoder.registerSpis(reg);
  }

  public static native void gtkMain();

  protected MouseInfoPeer getMouseInfoPeer()
  {
    return new GtkMouseInfoPeer();
  }

  public native int getMouseNumberOfButtons();

} // class GtkToolkit
