/* Charset.java -- 
   Copyright (C) 2002, 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.nio.charset;

import gnu.java.nio.charset.Provider;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.spi.CharsetProvider;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * @author Jesse Rosenstock
 * @since 1.4
 */
public abstract class Charset implements Comparable
{
  private static CharsetEncoder cachedEncoder;
  private static CharsetDecoder cachedDecoder;
 
  static
  {
    synchronized (Charset.class)
      {
        cachedEncoder = null;
        cachedDecoder = null;
      }
  }

  private final String canonicalName;
  private final String[] aliases;
  
  protected Charset (String canonicalName, String[] aliases)
  {
    checkName (canonicalName);
    if (aliases != null)
      {
        int n = aliases.length;
        for (int i = 0; i < n; ++i)
            checkName (aliases[i]);
      }

    this.canonicalName = canonicalName;
    this.aliases = aliases;
  }

  /**
   * @throws IllegalCharsetNameException  if the name is illegal
   */
  private static void checkName (String name)
  {
    int n = name.length ();

    if (n == 0)
      throw new IllegalCharsetNameException (name);

    char ch = name.charAt (0);
    if (!(('A' <= ch && ch <= 'Z')
          || ('a' <= ch && ch <= 'z')
          || ('0' <= ch && ch <= '9')))
      throw new IllegalCharsetNameException (name);

    for (int i = 1; i < n; ++i)
      {
        ch = name.charAt (i);
        if (!(('A' <= ch && ch <= 'Z')
              || ('a' <= ch && ch <= 'z')
              || ('0' <= ch && ch <= '9')
              || ch == '-' || ch == '.' || ch == ':' || ch == '_'))
          throw new IllegalCharsetNameException (name);
      }
  }

  public static boolean isSupported (String charsetName)
  {
    return charsetForName (charsetName) != null;
  }

  /**
   * Returns the Charset instance for the charset of the given name.
   * 
   * @param charsetName
   * @return
   * @throws UnsupportedCharsetException if this VM does not support
   * the charset of the given name.
   * @throws IllegalCharsetNameException if the given charset name is
   * legal.
   * @throws IllegalArgumentException if <code>charsetName</code> is null.
   */
  public static Charset forName (String charsetName)
  {
    // Throws IllegalArgumentException as the JDK does.
    if(charsetName == null)
        throw new IllegalArgumentException("Charset name must not be null.");
    
    Charset cs = charsetForName (charsetName);
    if (cs == null)
      throw new UnsupportedCharsetException (charsetName);
    cachedDecoder = null;
    cachedEncoder = null;
    return cs;
  }

  /**
   * Retrieves a charset for the given charset name.
   *
   * @return A charset object for the charset with the specified name, or
   * <code>null</code> if no such charset exists.
   *
   * @throws IllegalCharsetNameException  if the name is illegal
   */
  private static Charset charsetForName(String charsetName)
  {
    checkName (charsetName);
    return provider ().charsetForName (charsetName);
  }

  public static SortedMap availableCharsets()
  {
    TreeMap charsets = new TreeMap(String.CASE_INSENSITIVE_ORDER);

    for (Iterator i = provider ().charsets (); i.hasNext (); )
      {
        Charset cs = (Charset) i.next ();
        charsets.put (cs.name (), cs);
      }

    return Collections.unmodifiableSortedMap(charsets);
  }

  // XXX: we need to support multiple providers, reading them from
  // java.nio.charset.spi.CharsetProvider in the resource directory
  // META-INF/services
  private static CharsetProvider provider()
  {
    return Provider.provider();
  }

  public final String name ()
  {
    return canonicalName;
  }

  public final Set aliases ()
  {
    if (aliases == null)
      return Collections.EMPTY_SET;

    // should we cache the aliasSet instead?
    int n = aliases.length;
    HashSet aliasSet = new HashSet (n);
    for (int i = 0; i < n; ++i)
        aliasSet.add (aliases[i]);
    return Collections.unmodifiableSet (aliasSet);
  }

  public String displayName ()
  {
    return canonicalName;
  }

  public String displayName (Locale locale)
  {
    return canonicalName;
  }

  public final boolean isRegistered ()
  {
    return (!canonicalName.startsWith ("x-")
            && !canonicalName.startsWith ("X-"));
  }

  public abstract boolean contains (Charset cs);

  public abstract CharsetDecoder newDecoder ();

  public abstract CharsetEncoder newEncoder ();

  public boolean canEncode ()
  {
    return true;
  }

  public final ByteBuffer encode (CharBuffer cb)
  {
    try
      {
	CharsetEncoder enc = newEncoder ()
	  .onMalformedInput (CodingErrorAction.REPLACE)
	  .onUnmappableCharacter (CodingErrorAction.REPLACE);
	return enc.encode (cb);
      }
    catch (CharacterCodingException e)
      {
        throw new AssertionError (e);
      }
  }
  
  public final ByteBuffer encode (String str)
  {
    return encode (CharBuffer.wrap (str));
  }

  public final CharBuffer decode (ByteBuffer bb)
  {
    try
      {
	CharsetDecoder dec = newDecoder ()
	  .onMalformedInput (CodingErrorAction.REPLACE)
	  .onUnmappableCharacter (CodingErrorAction.REPLACE);
	return dec.decode (bb);
      }
    catch (CharacterCodingException e)
      {
        throw new AssertionError (e);
      }
  }

  public final int compareTo (Object ob)
  {
    return canonicalName.compareToIgnoreCase (((Charset) ob).canonicalName);
  }

  public final int hashCode ()
  {
    return canonicalName.hashCode ();
  }

  public final boolean equals (Object ob)
  {
    if (ob instanceof Charset)
      return canonicalName.equalsIgnoreCase (((Charset) ob).canonicalName);
    else
      return false;
  }

  public final String toString ()
  {
    return canonicalName;
  }
}
