package imagej.ops.slicer;

import imagej.ops.OpService;
import net.imglib2.FinalInterval;
import net.imglib2.Interval;
import net.imglib2.RandomAccessibleInterval;

import org.scijava.plugin.AbstractPTService;
import org.scijava.plugin.Parameter;
import org.scijava.plugin.Plugin;
import org.scijava.service.Service;

@Plugin(type = Service.class)
public class HyperSlicingService extends AbstractPTService<HyperSlicer> {

	@Parameter
	protected OpService opService;

	@Override
	public Class<HyperSlicer> getPluginType() {
		return HyperSlicer.class;
	}

	public RandomAccessibleInterval<?> hyperSlice(
			final RandomAccessibleInterval<?> rndAccessibleInterval,
			final Interval i) {
		return (RandomAccessibleInterval<?>) opService.run("hyperslicer",
				rndAccessibleInterval, i);
	}

	Interval[] resolveIntervals(final int[] selected, final Interval in) {

		final int totalSteps = getNumIterationSteps(selected, in);
		final Interval[] res = new Interval[totalSteps];

		final int offset = 0;

		final long[] min = new long[in.numDimensions()];
		final long[] pointCtr = new long[in.numDimensions()];
		final long[] srcDims = new long[in.numDimensions()];

		in.min(min);
		in.max(pointCtr);
		in.dimensions(srcDims);

		long[] max = pointCtr.clone();

		final int[] unselected = getUnselectedDimIndices(selected,
				srcDims.length);

		final long[] indicators = new long[unselected.length];
		final Interval interval = new FinalInterval(min, pointCtr);

		for (int j = indicators.length - 1; j > -1; j--) {
			indicators[j] = 1;
			if (j < indicators.length - 1)
				indicators[j] = (srcDims[unselected[j + 1]])
						* indicators[j + 1];
		}

		for (final int u : unselected) {
			pointCtr[u] = -1;
		}

		for (int n = 0; n < getNumIterationSteps(selected, in); n++) {
			max = pointCtr.clone();

			for (int j = 0; j < indicators.length; j++) {
				if (n % indicators[j] == 0)
					pointCtr[unselected[j]]++;

				if (srcDims[unselected[j]] == pointCtr[unselected[j]])
					pointCtr[unselected[j]] = 0;
			}

			for (final int u : unselected) {
				max[u] = pointCtr[u] + min[u];
				min[u] = max[u];
			}

			res[offset + n] = new FinalInterval(min, max);
			interval.min(min);
		}
		return res;
	}

	/**
	 * @param dims
	 * @return
	 */
	private final int getNumIterationSteps(final int[] selectedDims,
			final Interval interval) {

		final long[] dims = new long[interval.numDimensions()];
		interval.dimensions(dims);

		final int[] unselectedDims = getUnselectedDimIndices(selectedDims,
				dims.length);
		int steps = 1;
		for (int i = 0; i < unselectedDims.length; i++) {
			steps *= dims[unselectedDims[i]];
		}

		return steps;
	}

	/**
	 * @return
	 */
	private final int[] getUnselectedDimIndices(final int[] selectedDims,
			final int numDims) {
		final boolean[] tmp = new boolean[numDims];
		int i;
		for (i = 0; i < selectedDims.length; i++) {
			if (selectedDims[i] >= numDims) {
				break;
			}
			tmp[selectedDims[i]] = true;
		}

		final int[] res = new int[numDims - i];

		int j = 0;
		for (int k = 0; j < res.length; k++) {
			if (k >= tmp.length || !tmp[k]) {
				res[j++] = k;
			}
		}
		return res;

	}

}

@@ -46,24 +46,61 @@
 .OpService;%0A
+import imagej.service.ImageJService;%0A
 import net.i
@@ -200,53 +200,8 @@
 l;%0A%0A
-import org.scijava.plugin.AbstractPTService;%0A
 impo
@@ -267,16 +267,60 @@
 Plugin;%0A
+import org.scijava.service.AbstractService;%0A
 import o
@@ -431,30 +431,40 @@
 ract
-PT
 Service
-%3CHyperSl
+ implements ImageJServ
 ice
-r%3E
  %7B%0A%0A
@@ -512,96 +512,8 @@
 e;%0A%0A
-%09@Override%0A%09public Class%3CHyperSlicer%3E getPluginType() %7B%0A%09%09return HyperSlicer.class;%0A%09%7D%0A%0A
 %09pub

fix class hierarchy