//FillTest.java
import visad.VisADException;
import visad.MathType;
import visad.TupleType;
import visad.FunctionType;
import visad.RealType;
import visad.RealTupleType;
import visad.SetType;
import visad.Tuple;
import visad.DataImpl;
import visad.FieldImpl;
import visad.ScalarMap;
import visad.DelaunayCustom;
import visad.Integer1DSet;
import visad.Gridded2DSet;
import visad.Irregular2DSet;
import visad.DataReferenceImpl;
import visad.Display;
import visad.java3d.DisplayImplJ3D;

import java.rmi.RemoteException;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BoxLayout;

/**
 * This class shows how DelaunayCustom.fill() returns null
 * for certain Gridded2DSet's representing ellipses ????
 */
public class FillTest
{
	private static final int NE = 32;
	private static final int numPointsInSet = 33;
	private float[][] samples;
	
	public FillTest() throws VisADException, RemoteException
	{
		//setup display
		DisplayImplJ3D display = new DisplayImplJ3D("fill test");
		ScalarMap latMap = new ScalarMap(RealType.Latitude
		, Display.YAxis);
		ScalarMap lonMap = new ScalarMap(RealType.Longitude
		, Display.XAxis);
		display.addMap(latMap);
		display.addMap(lonMap);
		
		SetType settype = new
			  SetType(RealTupleType.LatitudeLongitudeTuple);
		
		// 1st ellipse
		samples = new float[2][NE+1];
		fillSamples1(); // this ellipse works
		Gridded2DSet outlineset = new Gridded2DSet(settype, samples,
					NE+1);
		Irregular2DSet filledset = DelaunayCustom.fill(outlineset);
		
		// 2nd ellipse
		samples = new float[2][numPointsInSet];
		// get samples for one of the ellipses that doesn't work
		fillSamples2();
		
		Gridded2DSet outlineset2 = new Gridded2DSet(settype, samples,
					numPointsInSet);
		Irregular2DSet filledset2 = DelaunayCustom.fill(outlineset2);
		
		if (filledset2 == null) {
			System.out.println("filledset2 is null!");
			System.out.println("DelaunayCustom.fill() returned null"+
			" on the second ellipse's Gridded2DSet");
		}
		
		
		// 1st ellipse
		DataReferenceImpl outlineRef1 = new
			DataReferenceImpl("outline1");
		DataReferenceImpl filledRef1 = new
			DataReferenceImpl("filled1");
		outlineRef1.setData(outlineset);
		filledRef1.setData(filledset);
		display.addReference(outlineRef1);
		display.addReference(filledRef1);
		
		// 2nd ellipse
		if (filledset2 != null) {
			DataReferenceImpl filledRef2 = new
				DataReferenceImpl("filled2");
			filledRef2.setData(filledset2);
			display.addReference(filledRef2);
		}
		DataReferenceImpl outlineRef2 = new
			DataReferenceImpl("outline2");
		outlineRef2.setData(outlineset2);
		display.addReference(outlineRef2);

		// Swing stuff
		JFrame jframe = new JFrame("Fill Test");
		jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JPanel panel = new JPanel();
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		panel.add(display.getComponent());
		jframe.getContentPane().add(panel);
		jframe.setSize(600,600);
		jframe.setVisible(true);
	}
	
	private void fillSamples1()
	{
		// this ellipse gets filled fine
		samples[0][0] = -33.686817f;
		samples[1][0] = 151.1839f;
		samples[0][1] = -33.685886f;
		samples[1][1] = 151.18857f;
		samples[0][2] = -33.683445f;
		samples[1][2] = 151.19301f;
		samples[0][3] = -33.679592f;
		samples[1][3] = 151.19705f;
		samples[0][4] = -33.67447f;
		samples[1][4] = 151.20053f;
		samples[0][5] = -33.668278f;
		samples[1][5] = 151.20332f;
		samples[0][6] = -33.66126f;
		samples[1][6] = 151.2053f;
		samples[0][7] = -33.653675f;
		samples[1][7] = 151.20642f;
		samples[0][8] = -33.64582f;
		samples[1][8] = 151.20662f;
		samples[0][9] = -33.637997f;
		samples[1][9] = 151.20589f;
		samples[0][10] = -33.63051f;
		samples[1][10] = 151.20425f;
		samples[0][11] = -33.62364f;
		samples[1][11] = 151.20178f;
		samples[0][12] = -33.617653f;
		samples[1][12] = 151.19858f;
		samples[0][13] = -33.61278f;
		samples[1][13] = 151.19476f;
		samples[0][14] = -33.609215f;
		samples[1][14] = 151.19048f;
		samples[0][15] = -33.607082f;
		samples[1][15] = 151.18588f;
		samples[0][16] = -33.606472f;
		samples[1][16] = 151.18115f;
		samples[0][17] = -33.607403f;
		samples[1][17] = 151.17648f;
		samples[0][18] = -33.609844f;
		samples[1][18] = 151.17204f;
		samples[0][19] = -33.613697f;
		samples[1][19] = 151.168f;
		samples[0][20] = -33.61882f;
		samples[1][20] = 151.16452f;
		samples[0][21] = -33.62501f;
		samples[1][21] = 151.16173f;
		samples[0][22] = -33.63203f;
		samples[1][22] = 151.15974f;
		samples[0][23] = -33.639614f;
		samples[1][23] = 151.15863f;
		samples[0][24] = -33.64747f;
		samples[1][24] = 151.15843f;
		samples[0][25] = -33.655293f;
		samples[1][25] = 151.15916f;
		samples[0][26] = -33.66278f;
		samples[1][26] = 151.1608f;
		samples[0][27] = -33.66965f;
		samples[1][27] = 151.16327f;
		samples[0][28] = -33.675636f;
		samples[1][28] = 151.16647f;
		samples[0][29] = -33.680508f;
		samples[1][29] = 151.17029f;
		samples[0][30] = -33.684074f;
		samples[1][30] = 151.17458f;
		samples[0][31] = -33.686207f;
		samples[1][31] = 151.17917f;
		samples[0][32] = -33.686817f;
		samples[1][32] = 151.1839f;
	}
	
	private void fillSamples2()
	{
		// this ellipse doesn't get filled if all points are plotted
		// if you set numPointsInSet to less than 32 and greater than 6 
		// then the fill works for this ellipse   ??????
		float[][] samples2 = new float[2][NE+1];
		samples2[0][0] = -34.110367f;
		samples2[1][0] = 151.09294f;
		samples2[0][1] = -34.107662f;
		samples2[1][1] = 151.09367f;
		samples2[0][2] = -34.10448f;
		samples2[1][2] = 151.09329f;
		samples2[0][3] = -34.100945f;
		samples2[1][3] = 151.09181f;
		samples2[0][4] = -34.097195f;
		samples2[1][4] = 151.0893f;
		samples2[0][5] = -34.09337f; 
		samples2[1][5] = 151.08582f;
		samples2[0][6] = -34.08962f;
		samples2[1][6] = 151.08153f;
		samples2[0][7] = -34.086086f;
		samples2[1][7] = 151.07658f;
		samples2[0][8] = -34.08291f;
		samples2[1][8] = 151.07118f;
		samples2[0][9] = -34.080204f;
		samples2[1][9] = 151.06552f;
		samples2[0][10] = -34.078083f;
		samples2[1][10] = 151.05983f;
		samples2[0][11] = -34.076622f;
		samples2[1][11] = 151.05432f;
		samples2[0][12] = -34.07588f;
		samples2[1][12] = 151.04921f;
		samples2[0][13] = -34.075882f;
		samples2[1][13] = 151.04468f;
		samples2[0][14] = -34.07663f;
		samples2[1][14] = 151.04092f;
		samples2[0][15] = -34.078094f;
		samples2[1][15] = 151.03807f;
		samples2[0][16] = -34.080223f;
		samples2[1][16] = 151.03624f;
		samples2[0][17] = -34.082928f;
		samples2[1][17] = 151.0355f;
		samples2[0][18] = -34.08611f;
		samples2[1][18] = 151.03589f;
		samples2[0][19] = -34.089645f;
		samples2[1][19] = 151.03737f;
		samples2[0][20] = -34.093395f;
		samples2[1][20] = 151.03989f;
		samples2[0][21] = -34.09722f;
		samples2[1][21] = 151.04337f;
		samples2[0][22] = -34.10097f;
		samples2[1][22] = 151.04765f;
		samples2[0][23] = -34.104504f;
		samples2[1][23] = 151.0526f;
		samples2[0][24] = -34.10768f;
		samples2[1][24] = 151.058f;
		samples2[0][25] = -34.110386f;
		samples2[1][25] = 151.06366f;
		samples2[0][26] = -34.112507f;
		samples2[1][26] = 151.06935f;
		samples2[0][27] = -34.113968f;
		samples2[1][27] = 151.07486f;
		samples2[0][28] = -34.11471f;
		samples2[1][28] = 151.07997f;
		samples2[0][29] = -34.114708f;
		samples2[1][29] = 151.0845f;
		samples2[0][30] = -34.11396f;
		samples2[1][30] = 151.08826f;
		samples2[0][31] = -34.112495f;
		samples2[1][31] = 151.09111f;
		samples2[0][32] = -34.110367f;
		samples2[1][32] = 151.09294f;
		
		for (int i = 0; i < numPointsInSet; i++) {
			samples[0][i] = samples2[0][i];
			samples[1][i] = samples2[1][i];
		}
	}
	
	public static void main(String[] args)
	{
		try {
			FillTest test = new FillTest();
		} catch(VisADException ve) {
			System.err.println(ve);
		} catch(RemoteException re) {
			System.err.println(re);
		}
	}
}

