/* 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
