/*
 * Copyright (C) 2007  Almost Realism Software Group
 *
 *  All rights reserved.
 *  This document may not be reused without
 *  express written permission from Mike Murray.
 */

package net.sf.j3d.physics.pfield.util.buffers;

/**
 * @author  Mike Murray
 */
public class AveragedVectorMap2D96Bit implements AveragedVectorMap2D {
	private static double shortmax = Short.MAX_VALUE;
	
	private double vector[];
	private int w, h;
	private int count[][];
	private int xBuf[], yBuf[], zBuf[];
	
	public AveragedVectorMap2D96Bit(int w, int h) {
		this.count = new int[w][h];
		this.w = w;
		this.h = h;
		int tot = w * h;
		this.xBuf = new int[tot];
		this.yBuf = new int[tot];
		this.zBuf = new int[tot];
	}
	
	public void setVector(double x, double y, double z) {
		this.vector = new double[] {x, y, z};
		this.xBuf = null;
		this.yBuf = null;
		this.zBuf = null;
	}
	
	public void addVector(double u, double v, double x, double y, double z) {
		if (u >= 1.0 || v >= 1.0 || u < 0.0 || v < 0.0) {
			System.out.println("AveragedVectorMap2D96Bit: Invalid UV " + u + ", " + v);
			return;
		}
		
		int px = (int) (u * w);
		int py = (int) (v * h);
		int t = px + py * w;
		
		this.count[px][py]++;
		if (this.count[px][py] >= Short.MAX_VALUE)
			System.out.print("AveragedVectorMap2D96Bit: Overflow.");
		
		if (this.vector != null) return;
		
		this.xBuf[t] += x * Short.MAX_VALUE;
		this.yBuf[t] += y * Short.MAX_VALUE;
		this.zBuf[t] += z * Short.MAX_VALUE;
	}
	
	public double[] getVector(double u, double v) {
		if (this.vector != null) return this.vector;
		
		int px = (int) (u * w);
		int py = (int) (v * h);
		int t = px + py * w;
		
		double xyz[] = {(this.xBuf[t] / shortmax) / this.count[px][py],
						(this.yBuf[t] / shortmax) / this.count[px][py],
						(this.zBuf[t] / shortmax) / this.count[px][py]};
		
		return xyz;
	}
	
	public int getSampleCount(double u, double v) {
		int px = (int) (u * w);
		int py = (int) (v * h);
		return this.count[px][py];
	}
}
