package imagej.dataset;

import imagej.Dimensions;
import imagej.data.Type;
import imagej.function.NAryFunction;
import imagej.iterator.SynchronizedIterator;
import imagej.operation.RegionCopyOperation;
import imagej.process.Index;
import imagej.process.Span;

public class DatasetDuplicator
{
	// *************** public interface ****************************************************
	
	/** constructor that allows subclass/override mechanism if needed */
	public DatasetDuplicator()
	{
	}
	
	/** creates a Dataset according to given factory's style but whose shape and data values are copied from a given Dataset */ 
	public Dataset createDataset(DatasetFactory factory, Dataset inputDataset)
	{
		Type type = inputDataset.getType();
		
		return createTypeConvertedDataset(factory, type, inputDataset);
	}
	
	// newer way - minimizes subset lookups using primitive access so faster but not yet working
	
	/** create a Dataset according to given factory's style and a specified type but whose shape and data values are copied from a given Dataset */
	public Dataset createTypeConvertedDataset(DatasetFactory factory, Type type, Dataset inputDataset)
	{
		int[] dimensions = inputDataset.getDimensions();
		
		Dataset newDataset = factory.createDataset(type, dimensions);
		
		int[] origin = Index.create(dimensions.length);
		
		RegionCopyOperation copier = new RegionCopyOperation(inputDataset, origin, newDataset, origin, dimensions, inputDataset.getType().isFloat());

		copier.execute();
		
		// TODO - SOMETHING NEEDS TO BE DONE HERE ABOUT PRESERVING METADATA
		// newDataset.setMetaData(inputDataset.getMetaData().clone());  // something like this???
		
		return newDataset;
	}
	
	
	// *************** private interface ****************************************************
	
	private class CopyRightmostNaryFunction implements NAryFunction
	{
		private int numValues;
		private boolean firstTime;
		
		public CopyRightmostNaryFunction(int numValues)
		{
			this.numValues = numValues;
			this.firstTime = false;
		}

		
		@Override
		public int getValueCount()
		{
			return this.numValues;
		}

		@Override
		public double compute(double[] inputs)
		{
			if (this.firstTime)
			{
				if (inputs.length != this.numValues)
					throw new IllegalArgumentException("nary function not given correct number of inputs");
			}
			return inputs[this.numValues-1];
		}
		
	}
}

@@ -36,125 +36,17 @@
 gej.
-Dimensions;%0Aimport imagej.data.Type;%0Aimport imagej.function.NAryFunction;%0Aimport imagej.iterator.SynchronizedIterator
+data.Type
 ;%0Aim
@@ -120,36 +120,8 @@
 dex;
-%0Aimport imagej.process.Span;
 %0A%0Apu
@@ -1545,694 +1545,6 @@
 %0A%09%7D%0A
-%09%0A%09%0A%09// *************** private interface ****************************************************%0A%09%0A%09private class CopyRightmostNaryFunction implements NAryFunction%0A%09%7B%0A%09%09private int numValues;%0A%09%09private boolean firstTime;%0A%09%09%0A%09%09public CopyRightmostNaryFunction(int numValues)%0A%09%09%7B%0A%09%09%09this.numValues = numValues;%0A%09%09%09this.firstTime = false;%0A%09%09%7D%0A%0A%09%09%0A%09%09@Override%0A%09%09public int getValueCount()%0A%09%09%7B%0A%09%09%09return this.numValues;%0A%09%09%7D%0A%0A%09%09@Override%0A%09%09public double compute(double%5B%5D inputs)%0A%09%09%7B%0A%09%09%09if (this.firstTime)%0A%09%09%09%7B%0A%09%09%09%09if (inputs.length != this.numValues)%0A%09%09%09%09%09throw new IllegalArgumentException(%22nary function not given correct number of inputs%22);%0A%09%09%09%7D%0A%09%09%09return inputs%5Bthis.numValues-1%5D;%0A%09%09%7D%0A%09%09%0A%09%7D%0A
 %7D%0A

remove unused code