/* QtToolkit.java --
   Copyright (C)  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.qt;

import gnu.java.awt.EmbeddedWindow;
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.Dialog;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Label;
import java.awt.List;
import java.awt.MenuBar;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.FileDialog;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.PopupMenu;
import java.awt.PrintJob;
import java.awt.Scrollbar;
import java.awt.ScrollPane;
import java.awt.Window;
import java.awt.datatransfer.Clipboard;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.event.AWTEventListener;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.im.InputMethodHighlight;
import java.awt.peer.ButtonPeer;
import java.awt.peer.FontPeer;
import java.awt.peer.PanelPeer;
import java.awt.peer.CanvasPeer;
import java.awt.peer.FramePeer;
import java.awt.peer.PopupMenuPeer;
import java.awt.peer.CheckboxMenuItemPeer;
import java.awt.peer.LabelPeer;
import java.awt.peer.RobotPeer;
import java.awt.peer.CheckboxPeer;
import java.awt.peer.ScrollPanePeer;
import java.awt.peer.ChoicePeer;
import java.awt.peer.ListPeer;
import java.awt.peer.ScrollbarPeer;
import java.awt.peer.MenuBarPeer;
import java.awt.peer.TextAreaPeer;
import java.awt.peer.DialogPeer;
import java.awt.peer.MenuItemPeer;
import java.awt.peer.TextFieldPeer;
import java.awt.peer.FileDialogPeer;
import java.awt.peer.MenuPeer;
import java.awt.peer.WindowPeer;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import gnu.java.awt.ClasspathToolkit;

public class QtToolkit extends ClasspathToolkit
{
  public static EventQueue eventQueue = null; // the native event queue
  public static QtRepaintThread repaintThread = null; 
  public static MainQtThread guiThread = null;
  public static QtGraphicsEnvironment graphicsEnv = null;

  private static void initToolkit()
  {
    eventQueue = new EventQueue();
    repaintThread = new QtRepaintThread();
    System.loadLibrary("qtpeer");

    String theme = null;
    try 
      {
	String style = System.getProperty("qtoptions.style");
	if(style != null)
	  theme = style;
      } 
    catch(SecurityException e)
      {
      }
    catch(IllegalArgumentException e)
      {
      }

    boolean doublebuffer = true;
    try 
      {
	String style = System.getProperty("qtoptions.nodoublebuffer");
	if(style != null)
	  doublebuffer = false;
      } 
    catch(SecurityException e)
      {
      }
    catch(IllegalArgumentException e)
      {
      }

    guiThread = new MainQtThread( theme, doublebuffer );
    guiThread.start();
    repaintThread.start();
  }

  /**
   * Construct the toolkit!
   */
  public QtToolkit()
  {
    if( guiThread == null )
      initToolkit();

    while (!guiThread.isRunning()); // make sure the GUI thread has started.

    if( graphicsEnv == null )
      graphicsEnv = new QtGraphicsEnvironment( this );
  }

  native String[] nativeFontFamilies();
  
  native int numScreens();

  native int defaultScreen();

  // ************ Public methods *********************

  public synchronized native void beep();

  public int checkImage(Image image, int w, int h, ImageObserver observer)
  {
    if(image instanceof QtImage)
      return ((QtImage)image).checkImage(observer);

    return ImageObserver.ERROR; // FIXME
  }

  protected ButtonPeer createButton( Button target )
  {
    return new QtButtonPeer( this, target );
  }

  protected CanvasPeer createCanvas(Canvas target)
  {
    return new QtCanvasPeer( this, target );
  }

  protected CheckboxPeer createCheckbox(Checkbox target)
  {
    return new QtCheckboxPeer( this, target );
  }

  protected  ChoicePeer createChoice(Choice target)
  {
    return new QtChoicePeer( this, target );
  }

  protected CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target)
  {
    return new QtMenuItemPeer( this, target );
  }

  public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) 
  {
    throw new RuntimeException("Not implemented");
  }

  protected FramePeer createFrame(Frame target)
  {
    return new QtFramePeer( this, target );
  }

  protected FileDialogPeer createFileDialog(FileDialog target)
  {
    return new QtFileDialogPeer( this, target );
  }

  public Image createImage(ImageProducer producer)
  {
    return new QtImage( producer );
  }
  
  public Image createImage(byte[] imageData,
			   int imageOffset,
			   int imageLength)
  {
    byte[] dataCopy = new byte[imageLength];
    System.arraycopy(imageData, imageOffset, dataCopy, 0, imageLength);
    return new QtImage( dataCopy );
  }
  
  public Image createImage(String filename)
  {
    return new QtImage( filename );
  }

  public Image createImage(URL url)
  {
    return new QtImage( url );
  }

  protected TextFieldPeer createTextField(TextField target)
  {
    return new QtTextFieldPeer(this,target);
  }
  
  protected LabelPeer createLabel(Label target)
  {
    return new QtLabelPeer( this, target );
  }

  protected ListPeer createList(List target)
  {
    return new QtListPeer( this, target );
  }

  protected ScrollbarPeer createScrollbar(Scrollbar target)
  {
    return new QtScrollbarPeer( this, target );
  }

  protected ScrollPanePeer createScrollPane(ScrollPane target)
  {
    return new QtScrollPanePeer( this, target );
  }

  protected TextAreaPeer createTextArea(TextArea target)
  {
    return new QtTextAreaPeer( this, target );
  }

  protected PanelPeer createPanel(Panel target)
  {
    return new QtPanelPeer( this, target);
  }

  protected WindowPeer createWindow(Window target)
  {
    return new QtWindowPeer( this, target );
  }

  protected DialogPeer createDialog(Dialog target)
  {
    return new QtDialogPeer( this, target );
  }

  protected MenuBarPeer createMenuBar(MenuBar target)
  {
    return new QtMenuBarPeer( this, target );
  }

  protected MenuPeer createMenu(Menu target)
  {
    return new QtMenuPeer( this, target );
  }

  protected PopupMenuPeer createPopupMenu(PopupMenu target)
  {
    return new QtPopupMenuPeer( this, target );
  }

  protected MenuItemPeer createMenuItem(MenuItem target)
  {
    return new QtMenuItemPeer( this, target );
  }

  /**
   * @since 1.4
   */
  public AWTEventListener[] getAWTEventListeners()
  {
    return null; // FIXME
  }

  /**
   * @since 1.4
   */
  public AWTEventListener[] getAWTEventListeners(long mask)
  {
    return null; // FIXME
  }

  public ColorModel getColorModel()
  {
    return new DirectColorModel(32, 
				0x00FF0000,
				0x0000FF00,
				0x000000FF,
				0xFF000000);
  }

  /**
   * Just return the defaults.
   */
  public String[] getFontList()
  {
    String[] builtIn = new String[] { "Dialog", 
				      "DialogInput", 
				      "Monospaced", 
				      "Serif", 
				      "SansSerif" };
    String[] nat = nativeFontFamilies();
    String[] allFonts = new String[ nat.length + 5 ];
    System.arraycopy(builtIn, 0, allFonts, 0, 5);
    System.arraycopy(nat, 0, allFonts, 5, nat.length);
    return allFonts;
  }

  public FontMetrics getFontMetrics(Font font)
  {
    return new QtFontMetrics(font);
  }

  protected FontPeer getFontPeer(String name,
				 int style)
  {
    Map attrs = new HashMap ();
    ClasspathFontPeer.copyStyleToAttrs(style, attrs);
    ClasspathFontPeer.copySizeToAttrs(12, attrs); // Default size is 12.
    return getClasspathFontPeer (name, attrs);
  }

  public Image getImage(String filename)
  {
    return new QtImage(filename);
  }

  public Image getImage(URL url)
  {
    return createImage( url );
  }

  public PrintJob getPrintJob(Frame frame,
			      String jobtitle,
			      Properties props)
  {
    SecurityManager sm;
    sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPrintJobAccess();
    
    throw new RuntimeException("Not implemented");
  }

  public Clipboard getSystemClipboard()
  {
    throw new RuntimeException("Not implemented");
  }

  protected EventQueue getSystemEventQueueImpl()
  {
    return eventQueue;
  }

  public native Dimension getScreenSize();

  public native int getScreenResolution();

  public Map mapInputMethodHighlight(InputMethodHighlight highlight)
  {
    return null; // FIXME
  }  
  
  public boolean prepareImage(Image image, int w, int h, ImageObserver observer)
  {
    if(image instanceof QtImage)
      return true;
    return false; // FIXME?
  }

  public native void sync();

  // ********************** ClasspathToolkit methods

  public GraphicsEnvironment getLocalGraphicsEnvironment()
  {
    return graphicsEnv;
  }

  public ClasspathFontPeer getClasspathFontPeer (String name, Map attrs)
  {  
    return new QtFontPeer (name, attrs);
  }

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

  // FIXME
  public RobotPeer createRobot (GraphicsDevice screen) throws AWTException
  {
    throw new UnsupportedOperationException();
  }

  public EmbeddedWindowPeer createEmbeddedWindow(EmbeddedWindow w)
  {
    //    return new QtEmbeddedWindowPeer( this, w );
    return null;
  }
}
