#!/usr/bin/env jython

# VisAD Tutorial
# Copyright (C) 2000 Ugo Taddei
#
# Jython translation
# Copyright (C) 2002 Frank Gibbons.

import java
from visad import *
from visad.python.JPythonMethods import *
from visad.java2d import DisplayImplJ2D
import java.rmi.RemoteException
from java.awt import *
from javax.swing import *

true = 1; false = not true

# VisAD Tutorial example 2_05
# Combine examples 2_03 and 2_04, to display the continuous function
# height = 45 - 5 * time^2 as a green line and the point of
# example 2_04 as red dots. The line values are generated with a for-loop
# Add a ScalarMap with SelectRange as DisplayRealType, in order to
# select a range in which the RealTypes can be displayed.
# This will cut the parabola and prevent the first data point to be
# dislayed , that is, data ouside the range don't get drawn


# Create the quantities
# x and y are measured in SI meters
# Use RealType(String name, Unit u, Set set), set is null
time = getRealType("time")
height = getRealType("height")

# Code for setting POINT data
# Organize time and height in a Tuple
t_h_tuple = RealTupleType(time, height)

# Index has no unit, just a name
index = RealType("index")

# Create a FunctionType (index -> (time, height)), for points
# Use FunctionType(MathType domain, MathType range)
func_i_tuple = FunctionType(index, t_h_tuple)

# Create index_set, but this time using a Integer1DSet(MathType type, int length)
index_set = Integer1DSet(index, 5)

# These are our actual data values for time and height
# Note that these values correspond to the parabola of the
# previous examples. The y (height) values are the same, but the x (time)
# values are explicitely given.
point_vals = [ [-3.0, -1.5, 0.0, 1.5, 3.0],
               [0.0, 33.75, 45.0, 33.75, 0.0] ]


# Create a FlatField, that is the Data class for the samples
# Use FlatField(FunctionType type, Set domain_set)
# for the (time, height) points
points_ff = FlatField(func_i_tuple, index_set)

# and finally put the points and height values above into the points FlatField
points_ff.setSamples(point_vals)

# Code for setting LINE data
# the FunctionType for the line, function (time -> height)
func_time_height = FunctionType(time, height)

# Create a time_set, with LENGTH = 25 values, for continuous line
LENGTH = 25
time_set = Linear1DSet(time, -3.0, 3.0, LENGTH)

# Generate some (25) points with a for-loop for the line
# Note that we have the parabola height = 45 - 5 * time^2
# But first we create a float array for the values
h_vals = []; h_vals.append([])

# ...then we use a method of Set to get the samples from time_set
# this call will get the time values
# "true" means we get a copy from the samples

d_vals = time_set.getSamples(true)

for i in range(LENGTH):
    h_vals[0].append(45.0 - 5.0 * (d_vals[0][i]*d_vals[0][i]))
    
# Create a FlatField, that is the Data class for the samples
# Use FlatField(FunctionType type, Set domain_set)
# for the line
line_ff = FlatField(func_time_height, time_set)

# and finally put the points and height values into the line FlatField
line_ff.setSamples(h_vals)

# Create Display and its maps
display = DisplayImplJ2D("display1")

# Get display's graphics mode control and draw scales
dispGMC = display.getGraphicsModeControl()
dispGMC.setScaleEnable(true)

# Create the ScalarMaps: quantity time is to be displayed along XAxis
# and height along YAxis
# Use ScalarMap(ScalarType scalar, DisplayRealType display_scalar)

timeMap = ScalarMap(time, Display.XAxis)
heightMap = ScalarMap(height, Display.YAxis)

# We create a ScalarMap, with time as RealType and SelectRange as DisplayRealType
timeRangeMap = ScalarMap(time, Display.SelectRange)

display.addMap(timeMap)
display.addMap(heightMap)
display.addMap(timeRangeMap)

# Scale heightMap. This will scale the y-axis, because heightMap has DisplayRealType YAXIS
# We simply choose the range from -4 to 4 for the x-axis
# and -10.0 to 50.0 for
timeMap.setRange(-4.0, 4.0)
heightMap.setRange(-10.0, 50.0)

# Select the range of RealType time
timeRangeControl = timeRangeMap.getControl()

timeRange = [ -2.0, 4.0 ]
timeRangeControl.setRange(timeRange)

# Create a data reference and set the FlatField as our data
points_ref = DataReferenceImpl("points_ref")
line_ref = DataReferenceImpl("line_ref")
points_ref.setData(points_ff)
line_ref.setData(line_ff)


# Only change from the previous version
# Define a ConstantMap to draw large red points
pointsCMap = [ ConstantMap(1.0, Display.Red),
               ConstantMap(0.0, Display.Green),
               ConstantMap(0.0, Display.Blue),
               ConstantMap(0.5, Display.PointSize)]

lineCMap = [ ConstantMap(0.0, Display.Red),
             ConstantMap(0.8, Display.Green),
             ConstantMap(0.0, Display.Blue),
             ConstantMap(0.0, Display.LineWidth)]


# Add reference to display, and link DataReference to ConstantMap
display.addReference(points_ref, pointsCMap)
#display.addReference(line_ref, lineCMap)


# Create application window, put display into it
jframe = JFrame("VisAD Tutorial example 2_05")
jframe.getContentPane().add(display.getComponent())
jframe.setSize(300, 300)
jframe.setVisible(true)
