/* ExplicitBeanInfo.java --
   Copyright (C) 1998, 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., 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 gnu.java.beans;

import java.awt.Image;
import java.beans.BeanDescriptor;
import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;

/**
 ** ExplicitBeanInfo lets you specify in the constructor
 ** all the various parts of the BeanInfo.
 **
 ** @author John Keiser
 ** @version 1.1.0, 30 Jul 1998
 ** @see java.beans.BeanInfo
 **/

public class ExplicitBeanInfo implements BeanInfo {
	/** The BeanDescriptor returned by getBeanDescriptor. **/
	protected BeanDescriptor beanDescriptor;

	/** The EventSetDescriptor array returned by
	 ** getEventSetDescriptors().
	 **/
	protected EventSetDescriptor[] eventSetDescriptors = new EventSetDescriptor[0];

	/** The PropertyDescriptor array returned by
	 ** getPropertyDescriptors().
	 **/
	protected PropertyDescriptor[] propertyDescriptors = new PropertyDescriptor[0];

	/** The MethodDescriptor array returned by
	 ** getMethodDescriptors().
	 **/
	protected MethodDescriptor[]   methodDescriptors;

	/** The default property index. **/
	protected int defaultPropertyIndex;

	/** The default event index. **/
	protected int defaultEventIndex;

	/** The BeanInfo array returned by
	 ** getAdditionalBeanInfo().
	 **/
	protected BeanInfo[] additionalBeanInfo;

	/** The set of icons. **/
	protected Image[] icons;

	public ExplicitBeanInfo(BeanDescriptor beanDescriptor,
	                        BeanInfo[] additionalBeanInfo,
	                        PropertyDescriptor[] propertyDescriptors,
				int defaultPropertyIndex,
	                        EventSetDescriptor[] eventSetDescriptors,
				int defaultEventIndex,
	                        MethodDescriptor[] methodDescriptors,
				Image[] icons) {
		this.beanDescriptor = beanDescriptor;
		this.additionalBeanInfo = additionalBeanInfo;
		this.propertyDescriptors = propertyDescriptors;
		this.defaultPropertyIndex = defaultPropertyIndex;
		this.eventSetDescriptors = eventSetDescriptors;
		this.defaultEventIndex = defaultEventIndex;
		this.methodDescriptors = methodDescriptors;
		this.icons = icons;
	}

	/** Get Bean descriptor. **/
	public BeanDescriptor getBeanDescriptor() {
		return beanDescriptor;
	}

	/** Get Bean events. **/
	public EventSetDescriptor[] getEventSetDescriptors() {
		return eventSetDescriptors;
	}

	/** Get default event set. **/
	public int getDefaultEventIndex() {
		return defaultEventIndex;
	}

	/** Get Bean properties. **/
	public PropertyDescriptor[] getPropertyDescriptors() {
		return propertyDescriptors;
	}

	/** Get "default" property. **/
	public int getDefaultPropertyIndex() {
		return defaultPropertyIndex;
	}

	/** Get Bean methods. **/
	public MethodDescriptor[] getMethodDescriptors() {
		return methodDescriptors;
	}

	/** Get additional Bean info. **/
	public BeanInfo[] getAdditionalBeanInfo() {
		return additionalBeanInfo;
	}

	/** Get Bean icons.
	 ** @param iconType the type of icon
	 **/
	public Image getIcon(int iconType) {
		return icons != null ? icons[iconType - 1] : null;
	}
}
