/* ParameterBlock.java -- 
   Copyright (C) 2002 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.awt.image.renderable;

import java.awt.image.RenderedImage;
import java.io.Serializable;
import java.util.Vector;

public class ParameterBlock implements Cloneable, Serializable
{
  private static final long serialVersionUID = -7577115551785240750L;
  protected Vector sources;
  protected Vector parameters;

  public ParameterBlock()
  {
    this(new Vector(), new Vector());
  }

  public ParameterBlock(Vector sources)
  {
    this(sources, new Vector());
  }

  public ParameterBlock(Vector sources, Vector parameters)
  {
    this.sources = sources;
    this.parameters = parameters;
  }

  public Object shallowClone()
  {
    try
      {
        return super.clone();
      }
    catch (CloneNotSupportedException e)
      {
        throw (Error) new InternalError().initCause(e); // impossible
      }
  }

  public Object clone()
  {
    ParameterBlock pb = (ParameterBlock) shallowClone();
    if (sources != null)
      pb.sources = (Vector) sources.clone();
    if (parameters != null)
      pb.parameters = (Vector) parameters.clone();
    return pb;
  }

  public ParameterBlock addSource(Object source)
  {
    sources.add(source);
    return this;
  }

  public Object getSource(int index)
  {
    return sources.get(index);
  }

  public ParameterBlock setSource(Object source, int index)
  {
    sources.ensureCapacity(index);
    sources.set(index, source);
    return this;
  }

  public RenderedImage getRenderedSource(int index)
  {
    return (RenderedImage) sources.get(index);
  }

  public RenderableImage getRenderableSource(int index)
  {
    return (RenderableImage) sources.get(index);
  }

  public int getNumSources()
  {
    return sources.size();
  }

  public Vector getSources()
  {
    return sources;
  }

  public void setSources(Vector sources)
  {
    this.sources = sources;
  }

  public void removeSources()
  {
    if (sources != null)
      sources.clear();
  }

  public int getNumParameters()
  {
    return parameters.size();
  }

  public Vector getParameters()
  {
    return parameters;
  }

  public void setParameters(Vector parameters)
  {
    this.parameters = parameters;
  }

  public void removeParameters()
  {
    if (parameters != null)
      parameters.clear();
  }

  public ParameterBlock add(Object o)
  {
    parameters.add(o);
    return this;
  }

  public ParameterBlock add(byte b)
  {
    return add(new Byte(b));
  }

  public ParameterBlock add(char c)
  {
    return add(new Character(c));
  }

  public ParameterBlock add(short s)
  {
    return add(new Short(s));
  }

  public ParameterBlock add(int i)
  {
    return add(new Integer(i));
  }

  public ParameterBlock add(long l)
  {
    return add(new Long(l));
  }

  public ParameterBlock add(float f)
  {
    return add(new Float(f));
  }

  public ParameterBlock add(double d)
  {
    return add(new Double(d));
  }

  public ParameterBlock set(Object o, int index)
  {
    parameters.ensureCapacity(index);
    parameters.set(index, o);
    return this;
  }

  public ParameterBlock set(byte b, int index)
  {
    return set(new Byte(b), index);
  }

  public ParameterBlock set(char c, int index)
  {
    return set(new Character(c), index);
  }

  public ParameterBlock set(short s, int index)
  {
    return set(new Short(s), index);
  }

  public ParameterBlock set(int i, int index)
  {
    return set(new Integer(i), index);
  }

  public ParameterBlock set(long l, int index)
  {
    return set(new Long(l), index);
  }

  public ParameterBlock set(float f, int index)
  {
    return set(new Float(f), index);
  }

  public ParameterBlock set(double d, int index)
  {
    return set(new Double(d), index);
  }

  public Object getObjectParameter(int index)
  {
    return parameters.get(index);
  }

  public byte getByteParameter(int index)
  {
    return ((Byte) parameters.get(index)).byteValue();
  }

  public char getCharParameter(int index)
  {
    return ((Character) parameters.get(index)).charValue();
  }

  public short getShortParameter(int index)
  {
    return ((Short) parameters.get(index)).shortValue();
  }

  public int getIntParameter(int index)
  {
    return ((Integer) parameters.get(index)).intValue();
  }

  public long getLongParameter(int index)
  {
    return ((Long) parameters.get(index)).longValue();
  }

  public float getFloatParameter(int index)
  {
    return ((Float) parameters.get(index)).floatValue();
  }

  public double getDoubleParameter(int index)
  {
    return ((Double) parameters.get(index)).doubleValue();
  }

  public Class[] getParamClasses()
  {
    int i = parameters.size();
    Class[] result = new Class[i];
    while (--i >= 0)
      {
        Class c = parameters.get(i).getClass();
        if (c == Byte.class)
          result[i] = byte.class;
        else if (c == Character.class)
          result[i] = char.class;
        else if (c == Short.class)
          result[i] = short.class;
        else if (c == Integer.class)
          result[i] = int.class;
        else if (c == Long.class)
          result[i] = long.class;
        else if (c == Float.class)
          result[i] = float.class;
        else if (c == Double.class)
          result[i] = double.class;
        else
          result[i] = c;
      }
    return result;
  }
} // class ParameterBlock
