package hep.aida.ref.tuple;

import hep.aida.ref.*;
import hep.aida.*;

/**
 * Base class for Tuple, ChainedTuple etc.
 * This implements all methods which modify the tuple to throw exceptions.
 *
 * @author The AIDA team @ SLAC.
 *
 */

public abstract class AbstractTuple extends ManagedObject implements ITuple {

    private String title;
    private IAnnotation annotation = new Annotation();

    public AbstractTuple(String name) {
        super(name);
    }
    public String[] columnNames() {
       String[] result = new String[columns()];
       for (int i=0; i<result.length; i++) result[i] = columnName(i);
       return result;
    }
    public Class[] columnTypes() {
        Class[] result = new Class[columns()];
        for (int i=0; i<result.length; i++) result[i] = columnType(i);
        return result;
    }
    public String getAIDAType() {
        return "ITuple";
    }

    public String title() {
        return title == null ? name() : title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public hep.aida.IAnnotation annotation() {
        return annotation;
    }

    public void setAnnotation( IAnnotation annotation ) {
        this.annotation = annotation;
    }

    public int getRow() {
        throw new ReadOnlyException();
    }

    public void addRow() throws hep.aida.OutOfStorageException {
        throw new ReadOnlyException();
    }
    public void fill(double[] values) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(float[] values) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(int param, int param1) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(int param, double param1) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(int param, float param1) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(int param, long param1) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(int param, Object obj) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(int param, char param1) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(int param, byte param1) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(int param, short param1) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(int param, String str) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }

    public void fill(int param, boolean param1) throws java.lang.IllegalArgumentException {
        throw new ReadOnlyException();
    }
    public void reset() {
        throw new ReadOnlyException();
    }

    public void resetRow() {
        throw new ReadOnlyException();
    }

        // Projections on IHistogram1D

    public void project(IHistogram1D histogram, IEvaluator evaluator) {
        start();
        evaluator.initialize(this);
        while ( next() )
            histogram.fill( evaluator.evaluateDouble() );
    }


    public void project(IHistogram1D histogram, IEvaluator evaluator, IEvaluator weightEvaluator) {
        start();
        evaluator.initialize(this);
        weightEvaluator.initialize(this);
        while ( next() )
            histogram.fill( evaluator.evaluateDouble(), weightEvaluator.evaluateDouble() );
    }

    public void project(IHistogram1D histogram, IEvaluator evaluator, IFilter filter, IEvaluator weightEvaluator) {
        start();
        filter.initialize(this);
        evaluator.initialize(this);
        weightEvaluator.initialize(this);
        while ( next() )
            if ( filter.accept() )
                histogram.fill( evaluator.evaluateDouble(), weightEvaluator.evaluateDouble() );
    }

    public void project(IHistogram1D histogram, IEvaluator evaluator, IFilter filter) {
        start();
        evaluator.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                histogram.fill( evaluator.evaluateDouble() );
    }

    // Projections on IHistogram2D

    public void project(IHistogram2D histogram, IEvaluator evaluatorX, IEvaluator evaluatorY, IFilter filter) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                histogram.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble());
    }

    public void project(IHistogram2D histogram, IEvaluator evaluatorX, IEvaluator evaluatorY) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        while ( next() )
            histogram.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble());
    }
    public void project(IHistogram2D histogram, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        weightEvaluator.initialize(this);
        while ( next() )
            histogram.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), weightEvaluator.evaluateDouble());
    }
    public void project(IHistogram2D histogram, IEvaluator evaluatorX, IEvaluator evaluatorY, IFilter filter, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        weightEvaluator.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                histogram.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), weightEvaluator.evaluateDouble());
    }

    // Projections on IHistogram3D

    public void project(IHistogram3D histogram, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ, IFilter filter) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                histogram.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble());
    }

    public void project(IHistogram3D histogram, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        while ( next() )
            histogram.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble());
    }

    public void project(IHistogram3D histogram, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        weightEvaluator.initialize(this);
        while ( next() )
            histogram.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble(), weightEvaluator.evaluateDouble());
    }

    public void project(IHistogram3D histogram, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ, IFilter filter, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        weightEvaluator.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                histogram.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble(), weightEvaluator.evaluateDouble());
    }

    // Projections on ICloud1D

    public void project(ICloud1D cloud, IEvaluator evaluator) {
        start();
        evaluator.initialize(this);
        while ( next() )
            cloud.fill( evaluator.evaluateDouble() );
    }

    public void project(ICloud1D cloud, IEvaluator evaluator, IFilter filter) {
        start();
        evaluator.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                cloud.fill( evaluator.evaluateDouble() );
    }

    public void project(ICloud1D cloud, IEvaluator evaluator, IEvaluator weightEvaluator) {
        start();
        evaluator.initialize(this);
        weightEvaluator.initialize(this);
        while ( next() )
            cloud.fill( evaluator.evaluateDouble(), weightEvaluator.evaluateDouble() );
    }

    public void project(ICloud1D cloud, IEvaluator evaluator, IFilter filter, IEvaluator weightEvaluator) {
        start();
        filter.initialize(this);
        evaluator.initialize(this);
        weightEvaluator.initialize(this);
        while ( next() )
            if ( filter.accept() )
                cloud.fill( evaluator.evaluateDouble(), weightEvaluator.evaluateDouble() );
    }

    // Projections on ICloud2D

    public void project(ICloud2D cloud, IEvaluator evaluatorX, IEvaluator evaluatorY) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        while ( next() )
            cloud.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble());
    }

    public void project(ICloud2D cloud, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        weightEvaluator.initialize(this);
        while ( next() )
            cloud.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), weightEvaluator.evaluateDouble());
    }

    public void project(ICloud2D cloud, IEvaluator evaluatorX, IEvaluator evaluatorY, IFilter filter) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                cloud.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble());
    }

    public void project(ICloud2D cloud, IEvaluator evaluatorX, IEvaluator evaluatorY, IFilter filter, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        weightEvaluator.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                cloud.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), weightEvaluator.evaluateDouble());
    }

    // Projections on ICloud3D

    public void project(ICloud3D cloud, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        while ( next() )
            cloud.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble());
    }

    public void project(ICloud3D cloud, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ, IFilter filter) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                cloud.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble());
    }

    public void project(ICloud3D cloud, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        weightEvaluator.initialize(this);
        while ( next() )
            cloud.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble(), weightEvaluator.evaluateDouble());
    }

    public void project(ICloud3D cloud, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ, IFilter filter, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        weightEvaluator.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                cloud.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble(), weightEvaluator.evaluateDouble());
    }

    // Projections on IProfile1D

    public void project(IProfile1D profile, IEvaluator evaluatorX, IEvaluator evaluatorY) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        while ( next() )
            profile.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble());
    }

    public void project(IProfile1D profile, IEvaluator evaluatorX, IEvaluator evaluatorY, IFilter filter) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                profile.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble());
    }

    public void project(IProfile1D profile, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        weightEvaluator.initialize(this);
        while ( next() )
            profile.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), weightEvaluator.evaluateDouble());
    }

    public void project(IProfile1D profile, IEvaluator evaluatorX, IEvaluator evaluatorY, IFilter filter, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        weightEvaluator.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                profile.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), weightEvaluator.evaluateDouble());
    }

    // Projections on IProfile1D

    public void project(IProfile2D profile, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        while ( next() )
            profile.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble());
    }

    public void project(IProfile2D profile, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        weightEvaluator.initialize(this);
        while ( next() )
            profile.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble(), weightEvaluator.evaluateDouble());
    }

    public void project(IProfile2D profile, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ, IFilter filter) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                profile.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble());
    }

    public void project(IProfile2D profile, IEvaluator evaluatorX, IEvaluator evaluatorY, IEvaluator evaluatorZ, IFilter filter, IEvaluator weightEvaluator) {
        start();
        evaluatorX.initialize(this);
        evaluatorY.initialize(this);
        evaluatorZ.initialize(this);
        weightEvaluator.initialize(this);
        filter.initialize(this);
        while ( next() )
            if ( filter.accept() )
                profile.fill( evaluatorX.evaluateDouble(), evaluatorY.evaluateDouble(), evaluatorZ.evaluateDouble(), weightEvaluator.evaluateDouble());
    }
    
    public String columnDefaultString( int column ) {
        return null;
    }
    
}
