/*
 * Zorbage: an Algebraic data hierarchy for use in numeric processing.
 *
 * Copyright (C) 2016-2019 Barry DeZonia
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package nom.bdezonia.zorbage.multidim;

import nom.bdezonia.zorbage.type.algebra.Algebra;
import nom.bdezonia.zorbage.type.storage.IndexedDataSource;
import nom.bdezonia.zorbage.type.storage.SequencedDataSource;

/**
 * 
 * @author Barry DeZonia
 *
 */
public class PipedDataSource <X extends Algebra<X,Y>,Y> implements IndexedDataSource<PipedDataSource<X,Y>,Y> {

	private MultiDimDataSource<X,Y> d;
	private int dim;
	private long[] parentDims;
	private long[] coords;
	private IndexedDataSource<?,Y> data;
	
	/**
	 * 
	 * @param d
	 * @param dim
	 * @param coords
	 */
	public PipedDataSource(MultiDimDataSource<X,Y> d, int dim, long[] coords) {
		this.d = d;
		this.dim = dim;
		this.coords = coords;
		if (coords.length != d.numDimensions())
			throw new IllegalArgumentException("coordinate does not match dimensionality of multidim data");
		if (dim < 0 || dim >= coords.length)
			throw new IllegalArgumentException("ranging dim is not within dimensionality of multidim data");
		for (int i = 0; i < coords.length; i++) {
			if (i != dim) {
				if (coords[i] < 0 || coords[i] >= d.dimension(i))
					throw new IllegalArgumentException("coordinate is outside bounds of multidim data");
			}
		}
		this.parentDims = new long[d.numDimensions()];
		for (int i = 0; i < d.numDimensions(); i++) {
			this.parentDims[i] = d.dimension(i);
		}
		this.data = findSubset();
	}
	
	@Override
	public PipedDataSource<X,Y> duplicate() {
		// shallow copy
		return new PipedDataSource<X,Y>(d,dim,coords);
	}

	@Override
	public void set(long index, Y value) {
		data.set(index, value);
	}

	@Override
	public void get(long index, Y value) {
		data.get(index, value);
	}

	@Override
	public long size() {
		return data.size();
	}

	private IndexedDataSource<?,Y> findSubset() {
		long[] start = coords.clone();
		long[] stop = coords.clone();
		start[dim] = 0;
		stop[dim] = d.dimension(dim)-1;
		long count = d.dimension(dim);
		long offset = IndexUtils.indexToLong(parentDims,start);
		long stride;
		if (count <= 1) {
			stride = 1;
		}
		else {
			stride = (IndexUtils.indexToLong(parentDims,stop) - offset) / (count - 1);
		}
		return new SequencedDataSource<>(d.rawData(), offset, stride, count);
	}
	
}

@@ -1673,16 +1673,144 @@
 onia%0A *%0A
+ * A %7B@link DataSource%7D that is a one dimensional column within a %7B@link MultiDimDataSource%7D.%0A * Pronounced as %22pie%22 %22ped%22.%0A * %0A
  */%0Apubl
@@ -1835,17 +1835,17 @@
 Source %3C
-X
+T
  extends
@@ -1853,22 +1853,22 @@
 Algebra%3C
-X,Y%3E,Y
+T,U%3E,U
 %3E implem
@@ -1910,14 +1910,14 @@
 rce%3C
-X,Y%3E,Y
+T,U%3E,U
 %3E %7B%0A
@@ -1945,19 +1945,19 @@
 aSource%3C
-X,Y
+T,U
 %3E d;%0A%09pr
@@ -2052,17 +2052,17 @@
 ource%3C?,
-Y
+U
 %3E data;%0A
@@ -2167,19 +2167,19 @@
 aSource%3C
-X,Y
+T,U
 %3E d, int
@@ -2963,19 +2963,19 @@
 aSource%3C
-X,Y
+T,U
 %3E duplic
@@ -3033,11 +3033,11 @@
 rce%3C
-X,Y
+T,U
 %3E(d,
@@ -3085,33 +3085,33 @@
 set(long index, 
-Y
+U
  value) %7B%0A%09%09data
@@ -3174,17 +3174,17 @@
  index, 
-Y
+U
  value) 
@@ -3303,17 +3303,17 @@
 ource%3C?,
-Y
+U
 %3E findSu

Make class more closely follow project conventions and add javadoc