/* InputContext.java -- provides the context for text input
   Copyright (C) 2002, 2003, 2004, 2005 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 java.awt.im;

import gnu.java.util.EmptyEnumeration;

import java.awt.AWTEvent;
import java.awt.AWTException;
import java.awt.Component;
import java.awt.im.spi.InputMethod;
import java.awt.im.spi.InputMethodDescriptor;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.AttributedCharacterIterator.Attribute;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;

/**
 * Provides a context for controlling input methods and keyboard layouts.
 * This class provides the communication layer between the client component,
 * and the various locale-dependent text entry input methods that can be used
 * for the client. By default, there is one instance per Window, shared among
 * all components, but this limits text entry to one component at a time.
 * Thus, text components can create their own instance to allow text entry
 * in multiple components at a time.
 *
 * <p>By using the interfaces of {@link java.awt.im.spi}, you can install
 * extensions which allow additional input methods. Some of these may use
 * platform native input methods, or keyboard layouts provided by the platform.
 * Input methods are unavailable if none have been installed and the platform
 * has no underlying native input methods. Extensions are installed as jar
 * files, usually accessed in the default extension location or specified by
 * the -extdir VM flag. The jar must contain a file named
 * "META_INF/services/java.awt.im.spi.InputMethodDescriptor" which lists,
 * one entry per line in UTF-8 encoding, each class in the jar that implements
 * java.awt.im.spi.InputMethodDescriptor.
 *
 * @author Eric Blake (ebb9@email.byu.edu)
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @see Component#getInputContext()
 * @see Component#enableInputMethods(boolean)
 * @since 1.2
 * @status updated to 1.4, but unverified
 */
public class InputContext
{
  /**
   * The list of installed input method descriptors.
   */
  private static final ArrayList<InputMethodDescriptor> descriptors
    = new ArrayList<InputMethodDescriptor>();

  static
  {
    Enumeration e;
    try
      {
        e = ClassLoader.getSystemResources
          ("META_INF/services/java.awt.im.spi.InputMethodDescriptor");
      }
    catch (IOException ex)
      {
        // XXX Should we do something else?
        e = EmptyEnumeration.getInstance();
      }
    while (e.hasMoreElements())
      {
        URL url = (URL) e.nextElement();
        BufferedReader in;
        String line;
        try
          {
            in = new BufferedReader
              (new InputStreamReader(url.openConnection().getInputStream(),
                                     "UTF-8"));
            line = in.readLine().trim();
          }
        catch (IOException ignored)
          {
            continue;
          }
      outer:
        while (line != null)
          {
            try
              {
                if (line.charAt(0) != '#')
                  {
                    Class<?> c = Class.forName(line);
                    descriptors.add((InputMethodDescriptor) c.newInstance());
                  }
                line = in.readLine().trim();
              }
            catch (IOException ex)
              {
                continue outer;
              }
            catch (Exception ignored)
              {
              }
          }
      }
  }

  /** The current input method; null if no input methods are installed. */
  private InputMethod im;

  /** Map of locales to the most recently selected input method. */
  private final HashMap<Locale,InputMethod> recent 
    = new HashMap<Locale,InputMethod>();

  /** The list of acceptable character subsets. */
  private Character.Subset[] subsets;

  /**
   * Construct an InputContext. This is protected, so clients must use
   * {@link #getInstance()} instead.
   */
  protected InputContext()
  {
  }

  /**
   * Returns a new InputContext.
   *
   * @return a new instance, initialized to the default locale if available
   */
  public static InputContext getInstance()
  {
    InputContext ic = new InputContext();
    ic.selectInputMethod(Locale.getDefault());
    return ic;
  }

  /**
   * Attempts to select an input method or keyboard layout which supports the
   * given locale. This returns true if a locale is available and was selected.
   * The following steps are taken in choosing an input method:<ul>
   * <li>If the currently selected input method or keyboard layout supports
   * the requested locale, it remains selected.</li>
   * <li>If there is no input method or keyboard layout available that
   * supports the requested locale, the current input method or keyboard
   * layout remains selected.</li>
   * <li>If the user has previously selected an input method or keyboard
   * layout for the requested locale from the user interface, then the most
   * recently selected such input method or keyboard layout is reselected.</li>
   * <li>Otherwise, an input method or keyboard layout that supports the
   * requested locale is selected in an implementation dependent way. This
   * implementation chooses the first input method which supports the requested
   * locale based on the InputMethodDescriptors loaded from the extensions
   * installed on the CLASSPATH.</li>
   * </ul>
   *
   * <p>Before switching away from an input method, any currently uncommitted
   * text is committed. Not all host operating systems provide API to
   * determine the locale of the currently selected native input method or
   * keyboard layout, and to select a native input method or keyboard layout
   * by locale. For host operating systems that don't provide such API,
   * selectInputMethod assumes that native input methods or keyboard layouts
   * provided by the host operating system support only the system's default
   * locale.
   *
   * <p>An example of where this may be called is in a multi-language document,
   * when moving the insertion point between sections of different locale, so
   * that the user may use the input method appropriate to that section of the
   * document.
   *
   * @param locale the desired new locale
   * @return true if the new locale is active
   * @throws NullPointerException if locale is null
   */
  public boolean selectInputMethod(Locale locale)
  {
    if (im != null && im.setLocale(locale))
      {
        recent.put(locale, im);
        return true;
      }
    InputMethod next = recent.get(locale);
    if (next != null)
      for (int i = 0, limit = descriptors.size(); i < limit; i++)
        {
          InputMethodDescriptor d = descriptors.get(i);
          Locale[] list;
          try
            {
              list = d.getAvailableLocales();
            }
          catch (AWTException ignored)
            {
              continue;
            }
          for (int j = list.length; --j >= 0; )
            if (locale.equals(list[j]))
              {
                try
                  {
                    next = d.createInputMethod();
                    recent.put(locale, next);
                  }
                catch (Exception ignored)
                  {
                    continue;
                  }
              }
        }
    if (next == null)
      return false;
    // XXX I'm not sure if this does all the necessary steps in the switch.
    if (im != null)
      {
        try
          {
            next.setCompositionEnabled(im.isCompositionEnabled());
          }
        catch (UnsupportedOperationException ignored)
          {
          }
        im.endComposition();
        im.deactivate(false);
        im.hideWindows();
      }
    im = next;
    im.setLocale(locale);
    im.setCharacterSubsets(subsets);
    return true;
  }

  /**
   * Returns the current locale of the current input method or keyboard
   * layout. Returns null if the input context does not have a current input
   * method or keyboard layout or if the current input method's
   * {@link InputMethod#getLocale()} method returns null. Not all host
   * operating systems provide API to determine the locale of the currently
   * selected native input method or keyboard layout. For host operating
   * systems that don't provide such API, getLocale assumes that the current
   * locale of all native input methods or keyboard layouts provided by the
   * host operating system is the system's default locale.
   *
   * @return the locale of the current input method, or null
   * @since 1.3
   */
  public Locale getLocale()
  {
    return im == null ? null : im.getLocale();
  }

  /**
   * Sets the subsets of Unicode characters allowed to be input by the current
   * input method, as well as subsequent input methods. The value of null
   * implies all characters are legal. Applications should not rely on this
   * behavior, since native host input methods may not allow restrictions.
   * If no current input method is available, this has no immediate effect.
   *
   * @param subsets the set of Unicode subsets to accept, or null
   */
  public void setCharacterSubsets(Character.Subset[] subsets)
  {
    this.subsets = subsets;
    if (im != null)
      im.setCharacterSubsets(subsets);
  }

  /**
   * Changes the enabled status of the current input method. An input method
   * that is enabled for composition interprets incoming events for both
   * composition and control purposes, while a disabled input method only
   * interprets control commands (including commands to enable itself).
   *
   * @param enable whether to enable the input method
   * @throws UnsupportedOperationException if there is no current input method,
   *         or the input method does not support enabling
   * @see #isCompositionEnabled()
   * @since 1.3
   */
  public void setCompositionEnabled(boolean enable)
  {
    if (im == null)
      throw new UnsupportedOperationException();
    im.setCompositionEnabled(enable);
  }

  /**
   * Find out if the current input method is enabled.
   *
   * @return true if the current input method is enabled
   * @throws UnsupportedOperationException if there is no current input method,
   *         or the input method does not support enabling
   * @see #setCompositionEnabled(boolean)
   * @since 1.3
   */
  public boolean isCompositionEnabled()
  {
    if (im == null)
      throw new UnsupportedOperationException();
    return im.isCompositionEnabled();
  }

  /**
   * Starts a reconversion operation in the current input method. The input
   * method gets the text to reconvert from the client component, using
   * {@link InputMethodRequests#getSelectedText(Attribute[])}. Then the
   * composed and committed text produced by the operation is sent back to
   * the client using a sequence of InputMethodRequests.
   *
   * @throws UnsupportedOperationException if there is no current input method,
   *         or the input method does not support reconversion
   * @since 1.3
   */
  public void reconvert()
  {
    if (im == null)
      throw new UnsupportedOperationException();
    im.reconvert();
  }

  /**
   * Dispatches an event to the current input method. This is called
   * automatically by AWT. If no input method is available, then the event
   * will never be consumed.
   *
   * @param event the event to dispatch
   * @throws NullPointerException if event is null
   */
  public void dispatchEvent(AWTEvent event)
  {
    if (im != null)
      im.dispatchEvent(event);
  }

  /**
   * Notifies the input context that a client component has been removed from
   * its containment hierarchy, or that input method support has been disabled
   * for the component. This method is usually called from the client
   * component's {@link Component#removeNotify()} method. Potentially pending
   * input from input methods for this component is discarded. If no input
   * methods are available, then this method has no effect.
   *
   * @param client the client component
   * @throws NullPointerException if client is null
   */
  public void removeNotify(Component client)
  {
    // XXX What to do with client information?
    if (im != null)
      {
        im.deactivate(false);
        im.removeNotify();
      }
  }

  /**
   * Ends any input composition that may currently be going on in this
   * context. Depending on the platform and possibly user preferences, this
   * may commit or delete uncommitted text. Any changes to the text are
   * communicated to the active component using an input method event. If no
   * input methods are available, then this method has no effect. This may
   * be called for a variety of reasons, such as when the user moves the
   * insertion point in the client text outside the range of the composed text,
   * or when text is saved to file.
   */
  public void endComposition()
  {
    if (im != null)
      im.endComposition();
  }

  /**
   * Disposes of the input context and release the resources used by it.
   * Called automatically by AWT for the default input context of each
   * Window. If no input methods are available, then this method has no
   * effect.
   */
  public void dispose()
  {
    if (im != null)
      {
        im.deactivate(false);
        im.dispose();
      }
  }

  /**
   * Returns a control object from the current input method, or null. A
   * control object provides implementation-dependent methods that control
   * the behavior of the input method or obtain information from the input
   * method. Clients have to compare the result against known input method
   * control object types. If no input methods are available or the current
   * input method does not provide an input method control object, then null
   * is returned. 
   *
   * @return the control object, or null
   */
  public Object getInputMethodControlObject()
  {
    return im == null ? null : im.getControlObject();
  }
} // class InputContext
