package org.biomoby.shared.data;

import java.util.Collection;
import java.util.Iterator;

import org.biomoby.registry.meta.Registry;
import org.biomoby.shared.*;

/**
 * A convenience class that just associates a set of possible services to run with a data 
 * collection.  It shadows all of the normal MobyDataObjectSet methods, passing them through 
 * to the data instance given in the constructor.  This is done rather than unnecessarily 
 * cloning potentially large objects.  NOTA BENE: This object does not clone the MOBY
 * data passed in, therefore any changes you make to the original MOBY data collection later
 * will be reflected here!  If you want this object to retain its own copy (e.g. in an
 * intialization loop) call the constructor like this: new MobyDataObjectSetSAI((MobyDataObjectSet) data.clone(), ...) 
 */

public class MobyDataObjectSetSAI extends MobyDataObjectSet implements MobyDataServiceAssocInstance{

    protected MobyDataObjectSet dataInstance;
    protected MobyService[] mobyServices;

    /**
     * Constructor for base Objects.
     */
    public MobyDataObjectSetSAI(String name, MobyService[] services){
	this(name, services, null);
    }

    public MobyDataObjectSetSAI(String name, MobyService[] services, Registry registry){
	super("", registry);  // Not using c-tor(namespace, id), then assigning "this" to
	                      // dataInstance, because that would cause recursion in the shadowed calls
	dataInstance = new MobyDataObjectSet(name, registry);
	mobyServices = services;
    }

    /**
     * Constructor that takes an existing object and associates services with it.
     */
    public MobyDataObjectSetSAI(MobyDataObjectSet collection, MobyService[] services){
	super(collection.getName(), collection.getDataType().getRegistry());
	dataInstance = collection;
	mobyServices = services;
    }

    public MobyService[] getServices(){
	return mobyServices;
    }

    public MobyDataType getDataType(){
	return dataInstance.getDataType();
    }

    public void setServices(MobyService[] services){
        mobyServices = services;
    }

    public int getXmlMode(){
	return dataInstance.getXmlMode();
    }

    public void setXmlMode(int mode) throws IllegalArgumentException{
	dataInstance.setXmlMode(mode);
    }

    public void setId(String value){
	dataInstance.setId(value);
    }

    public String getId(){
	return dataInstance.getId();
    }

    public void addNamespace(MobyNamespace ns){
	dataInstance.addNamespace(ns);
    }

    public MobyNamespace[] getNamespaces(){
	return dataInstance.getNamespaces();
    }

    public void setNamespaces(MobyNamespace[] values) {
	dataInstance.setNamespaces(values);
    }

    public void removeNamespace(String namespaceName) {
	dataInstance.removeNamespace(namespaceName);
    }

    public void setElements(MobyDataObject[] values) throws NullPointerException{
	dataInstance.setElements(values);
    }

    public MobyPrimaryDataSimple[] getElements(){
	return dataInstance.getElements();
    }

    public Object getUserData(){
	return dataInstance.getUserData();
    }

    public void setUserData(Object data){
        dataInstance.setUserData(data);
    }

    public Object getObject(){
	return dataInstance.getObject();
    }

    public boolean add(MobyDataObject mdsi) throws ClassCastException, NullPointerException{
	return dataInstance.add(mdsi);
    }

    public boolean addAll(Collection<? extends MobyDataObject> c) throws ClassCastException, NullPointerException{
	return dataInstance.addAll(c);
    }

    public boolean contains(Object mdsi) throws ClassCastException, NullPointerException{
	return dataInstance.contains(mdsi);
    }    
    
    public boolean containsAll(Collection c) throws ClassCastException, NullPointerException{
	return dataInstance.containsAll(c);
    }

    public boolean equals(Object set) throws ClassCastException, NullPointerException{
	return dataInstance.equals(set);
    }

    public int hashCode(){
	return dataInstance == null ? super.hashCode() : dataInstance.hashCode();
    }

    public void clear(){
	dataInstance.clear();
    }

    public boolean isEmpty(){
	return dataInstance.isEmpty();
    }

    public Iterator<org.biomoby.shared.data.MobyDataObject> iterator(){
	return dataInstance.iterator();
    }

    public boolean remove(Object mdsi) throws ClassCastException, NullPointerException{
	return dataInstance.remove(mdsi);
    }

    public boolean removeAll(Collection c) throws ClassCastException, NullPointerException{
	return dataInstance.removeAll(c);
    }

    public boolean retainAll(Collection c){
	return dataInstance.retainAll(c);
    }

    public Object[] toArray(){
	return dataInstance.toArray();
    }

    public <T extends Object>T[] toArray(T[] classArray) throws ArrayStoreException, NullPointerException{
	return dataInstance.toArray(classArray);
    }

    public MobyDataObject[] getElementInstances(){
	return dataInstance.getElementInstances();
    }

    public int size(){
	return dataInstance.size();
    }

    public String toString(){
	return dataInstance.toString();
    }

    public String toXML(){
	// We have to temporarily rename the data instance, because it's XML
	// representation in service mode should include the article name set
	// for this object instance, not the data instance
	String oldName = dataInstance.getName();
	dataInstance.setName(getName());
	String result = dataInstance.toXML();
	dataInstance.setName(oldName);
	return result;
    }
}
