/* IIORegistry.java --
   Copyright (C) 2004  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 javax.imageio.spi;

import gnu.classpath.ServiceFactory;
import gnu.java.awt.ClasspathToolkit;

import java.awt.Toolkit;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

import gnu.javax.imageio.bmp.BMPImageReaderSpi;
import gnu.javax.imageio.bmp.BMPImageWriterSpi;
import gnu.javax.imageio.gif.GIFImageReaderSpi;
import gnu.javax.imageio.png.PNGImageReaderSpi;

public final class IIORegistry extends ServiceRegistry
{
  private static final HashSet defaultCategories = new HashSet();
  
  private static HashMap instances = new HashMap();

  static
  {
    defaultCategories.add(ImageReaderSpi.class);
    defaultCategories.add(ImageWriterSpi.class);
    defaultCategories.add(ImageTranscoderSpi.class);
    defaultCategories.add(ImageInputStreamSpi.class);
    defaultCategories.add(ImageOutputStreamSpi.class);
  }
  
  public static synchronized IIORegistry getDefaultInstance()
  {
    // XXX: This leaks memory if a ThreadGroup isn't available anymore.
    ThreadGroup group = Thread.currentThread().getThreadGroup();
    IIORegistry registry = (IIORegistry) instances.get(group);
    
    if (registry == null)
      {
        registry = new IIORegistry();
        instances.put(group, registry);
      }
    
    return registry;
  }

  private IIORegistry()
  {
    super(defaultCategories.iterator());

    // XXX: Register built-in Spis here.
    registerServiceProvider(new PNGImageReaderSpi()); // Register PNG decoder.
    registerServiceProvider(new GIFImageReaderSpi()); // Register GIF decoder.
    registerServiceProvider(new BMPImageReaderSpi());
    registerServiceProvider(new BMPImageWriterSpi());

    Toolkit toolkit = Toolkit.getDefaultToolkit();
    if (toolkit instanceof ClasspathToolkit)
      ((ClasspathToolkit)toolkit).registerImageIOSpis(this);
    
    registerApplicationClasspathSpis();
  }

  /**
   * Registers all available service providers found on the application
   * classpath.
   */
  public void registerApplicationClasspathSpis()
  {
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    Iterator categories = getCategories();

    while (categories.hasNext())
      {
	Class category = (Class) categories.next();
	Iterator providers = ServiceFactory.lookupProviders(category, loader);

	while (providers.hasNext())
	  registerServiceProvider((IIOServiceProvider) providers.next());
      }
  }
}
