/*
VisAD system for interactive analysis and visualization of numerical
data.	Copyright (C) 1996 - 2002 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
import visad.*;
import visad.data.text.TextAdapter;
import visad.bom.CurveManipulationRendererJ3D;
import visad.java3d.DisplayImplJ3D;
import visad.java2d.DisplayImplJ2D;
import visad.java3d.*;
import visad.util.*;
import visad.util.SelectRangeWidget;
import visad.data.BadFormException;
import visad.data.visad.VisADSerialForm;
import java.util.Hashtable;

import ij.*;
import ij.gui.*;
import ij.text.*;

import java.awt.*;
import javax.swing.JTabbedPane;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JComponent;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.rmi.*;
import java.util.Vector;
import java.util.Random;
import java.io.*;

public class test{
	
	Random rand = new Random();
	
	public test(String[] args) throws VisADException, RemoteException, 
		IOException {
		
		Heatplot[] hp = new Heatplot[2];
		Scatterplot[] sp= new Scatterplot[2];
						
		// create the window
		JFrame frame = new JFrame("Raft");
		
		hp[0] = new Heatplot(3,4);                           
		hp[1] = new Heatplot(10,10);                           
		sp[0] = new Scatterplot(5);                           
		sp[1] = new Scatterplot(10);                           

		// create the panes
        JPanel pane1 = sp[0].getPanel();
        JPanel pane2 = sp[1].getPanel();
        JPanel pane3 = hp[0].getPanel();
        JPanel pane4 = hp[1].getPanel();

        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.addTab("pane1", pane1);
        tabbedPane.addTab("pane2", pane2);
        tabbedPane.addTab("pane3", pane3);
        tabbedPane.addTab("pane4", pane4);
        int is = tabbedPane.indexOfTab("pane1");
		tabbedPane.setSelectedIndex(is);
		
        //display the window
        int WIDTH = 600;
		int HEIGHT = 600;
		frame.setSize(WIDTH, HEIGHT);
		frame.setLocation(0,50);
        frame.getContentPane().add(tabbedPane,BorderLayout.CENTER);
        frame.setVisible(true);
        
}
	// heatmap display
	class Heatplot {
		
		private JPanel panel;
			
		Heatplot(int ncols, int nitem) throws VisADException, RemoteException{
	
			RealType row = RealType.getRealType("item");
			RealType column = RealType.getRealType("variable");
			RealTupleType domain_tuple = new RealTupleType(row, column);
			RealType intensity = RealType.getRealType("intensity");
			RealType color = RealType.getRealType("class");
			RealTupleType pixclass = new RealTupleType(intensity,color);
			// create a FunctionType (domain_tuple -> intensity)
			// use FunctionType(MathType domain, MathType range)
			FunctionType func_dom_int = new FunctionType(domain_tuple, pixclass);
			// the domain set goes from 1 to nitem in the x-direction and 
			// from 1 to nvar in the y direction - the .5 centers it all
			Set domain_set = new Linear2DSet(domain_tuple,.5,nitem+.5,nitem,
				.5,ncols+.5,ncols);
			// we create another array, with the same number of elements of
			// intensity_vals[][], but organized as float[1][ number_of_samples ]
			float[][] flat_samples = new float[2][ncols*nitem];
			// fill the 'flat' array with the original values
			// the intensity values indicate the order in which these values
	 		// are stored in flat_samples
			int rr = Integer.MAX_VALUE / 3 * 2;
			for(int c = 0; c < ncols; c++){			
	  			for(int i = 0; i < nitem; i++){
	  				float runif = (float)rand.nextInt(rr)/(float)rr;				
					flat_samples[0][c*nitem+ i] = runif;
	  				runif = (float)rand.nextInt(rr)/(float)rr;				
					flat_samples[1][c*nitem+ i] = runif;
				}
			}
	 		// create a FlatField
	 		// use FlatField(FunctionType type, Set domain_set)
	 		FlatField vals_ff = new FlatField(func_dom_int, domain_set);
	  		// ...and put the intensity values above into it
	 		vals_ff.setSamples(flat_samples);
	 		
	 		// create 2D Display 
			final DisplayImplJ3D display = new DisplayImplJ3D("heat", 
				new TwoDDisplayRendererJ3D());
				
			// get display's graphics mode control and draw scales
			GraphicsModeControl dispGMC = 
				(GraphicsModeControl) display.getGraphicsModeControl();
			dispGMC.setScaleEnable(true);
			
			// the maps
			ScalarMap colmMap = new ScalarMap(column,Display.XAxis);
			ScalarMap rowMap = new ScalarMap(row,Display.YAxis);
			ScalarMap intMap = new ScalarMap(intensity,Display.Value);
			ScalarMap cMap = new ScalarMap(color,Display.RGB);
			
			// add maps to display
			display.addMap(colmMap);
			display.addMap(rowMap);
			display.addMap(intMap);
			display.addMap(cMap);
								
			// create a data reference 
			DataReference data_ref = new DataReferenceImpl("data_ref");
			// add the data to the data reference
			data_ref.setData(vals_ff);
			// add reference to display
			display.addReference(data_ref);
			
			panel = new JPanel();
			panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
			panel.setAlignmentY(JPanel.TOP_ALIGNMENT);
			panel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
			// add display to panel
			panel.add(display.getComponent());
	
		}
		private JPanel getPanel(){
			return(this.panel);
		}
		
	}
							
	class Scatterplot {
		
		private JPanel panel;
	
		Scatterplot(int nitem) throws VisADException, 
		RemoteException{
	
			// set up the new FlatField	
			RealType ind = RealType.getRealType("index");
			Set index_set = new Integer1DSet(ind, nitem);
			
			// initialize the display			
			final DisplayImpl display = new DisplayImplJ3D("display");
			// get rid of the 3d box
			DisplayRenderer displayRenderer = display.getDisplayRenderer();
			displayRenderer.setBoxOn(false);
			GraphicsModeControl mode = display.getGraphicsModeControl();
			// change point size
			mode.setPointSize(3.0f);
					
			RealType x = RealType.getRealType("x");
			RealType y = RealType.getRealType("y");
			RealType z = RealType.getRealType("z");
			RealType c = RealType.getRealType("c");
			RealTupleType tuple = new RealTupleType(x,y,z,c);
			FunctionType ftype = new FunctionType( ind, tuple);
			FlatField vals_ff = new FlatField( ftype, index_set);
			
			int rr = Integer.MAX_VALUE / 3 * 2;

			float[][] samples = new float[4][nitem];
			for(int i=0; i<nitem; i++){
				for(int j=0; j<4; j++){
					float runif = (float)rand.nextInt(rr)/(float)rr;	
					samples[j][i] = runif;
				}
			}

			vals_ff.setSamples( samples );
			
			// the maps
			ScalarMap xMap = new ScalarMap(x,Display.XAxis);
			ScalarMap yMap = new ScalarMap(y,Display.YAxis);
			ScalarMap zMap = new ScalarMap(z,Display.ZAxis);
			ScalarMap cMap = new ScalarMap(c,Display.RGB);
			
			// add maps to display
			display.addMap(xMap);
			display.addMap(yMap);
			display.addMap(zMap);
			display.addMap(cMap);
								
			// create the datareference and add to the display
			final DataReference data_ref = new DataReferenceImpl("sref");
			data_ref.setData(vals_ff);
			display.addReference(data_ref); 								
											
			panel = new JPanel();
			panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
			panel.setAlignmentY(JPanel.TOP_ALIGNMENT);
			panel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
			// add display to panel
			panel.add(display.getComponent());
			
		}
		private JPanel getPanel(){
			return(this.panel);
		}
		
	}

	public static void main(String[] args) throws VisADException, 
		RemoteException, IOException {
		new test(args);
	}

}
