package org.biomoby.shared.data;

import java.util.Collection;

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 
 * instance.  It shadows all of the normal MobyDataObject 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 object 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 MobyDataObjectSAI((MobyDataObject) data.clone(), ...) 
 */

public class MobyDataObjectSAI extends MobyDataObject implements MobyDataServiceAssocInstance{

    protected MobyDataObject dataInstance;
    protected MobyService[] mobyServices;

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

    public MobyDataObjectSAI(String namespace, String id, 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 MobyDataObject(namespace, id, registry);
	// Note: in future maybe we should check that the services come from from the passed in registry, for consistency
	mobyServices = services;
    }

    /**
     * Constructor that takes an existing object and associates services with it.
     */
    public MobyDataObjectSAI(MobyDataObject mdsi, MobyService[] services){
	super(mdsi.getName(), mdsi.getDataType().getRegistry());
	// Note: in future maybe we should check that the data object and the services come from from the same registry
	dataInstance = mdsi;
	mobyServices = services;
    }

    public MobyDataObjectSAI clone(){
	// Clone according to the base instance's subclass specific methods
	return new MobyDataObjectSAI((MobyDataObject) dataInstance.clone(), 
				     mobyServices);
    }

    /**
     * Returns the underlying data instance we are shadowing
     */
    public MobyDataObject getDataInstance(){
	return dataInstance;
    }

    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 Object getUserData(){
	return dataInstance.getUserData();
    }

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

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

    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 Object getObject(){
	return dataInstance.getObject();
    }

    public void addCrossReference(MobyDataObject mobj){
	dataInstance.addCrossReference(mobj);
    }

    public Collection getCrossReferences(){
	return dataInstance.getCrossReferences();
    }

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

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

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