from visad.python.JPythonMethods import *
"""
Sim3DAudioLite extends Tom Whittaker's 'Evolution of an application'
VisADJython example
to include the 'squashing' of the image in the left panel.  When
executed with the pinna
image, it becomes an educational (or proof-of-concept) application that
illustrates the
effect the shape of the outer ear(pinna) and the direction of a sound
source have on the
acoustic pressure response within the ear.

As the generation of the 'squashed image' is rather memory intensive,
only one transformation
is included in this 'lite' version of Sim3DAudio.

Controls:
Use the buttons to 'squash' the pinna and the slider to choose sound
source direction.
SHIFT + Drag the Left Mouse Button to zoom. Drag the LMB to rotate the
red, 3D wire frame.

Sim3DAudioLite v1.0 by Chi-chi Ekweozor.  MEng Project - Part I, May
2003.
Powered by VisAD.

"""


from visad import *
from visad.python.JPythonMethods import *
import graph, subs
from java.lang import Boolean, System
from visad.util import VisADSlider
from visad.java2d import *
from visad.java3d import *
from javax.swing import JPanel, JFrame, JButton, JLabel, BorderFactory,
border
from java.awt import *
from java.awt import BorderLayout, GridLayout, FlowLayout, Font

img=load("pinnaimage.jpg")
set = img.getDomainSet()
lengths = set.getLengths()
width = lengths[0]
height = lengths[1]

print "image loaded and domain set extracted"

LINES = 360
NELE = 280

# Display data for making an overall display...starting with the
original image
imgdom = getDomainType(img)
imgrng = getRangeType(img)
maps = subs.makeMaps(imgdom[0],'x', imgdom[1],'y',
                imgrng[0],'red',imgrng[1],'green',imgrng[2],'blue')

# subs for Psuedo-plot panel
m2 = subs.makeMaps(imgdom[0],"x",imgrng[0],"y", imgrng[1],"z",
imgdom[1],"selectvalue")
plotd = subs.makeDisplay3D(m2)
plotd.setBoxSize(.5)
#subs.setBoxSize(plotd, 0.6)
subs.setBoxColor(plotd, "red")
subs.setCursorColor(plotd, "red")
#subs.addTitle("Simulated Acoustic Pressure Response", 1) doesn't
work...

# change the scale label on x axis
xscale=AxisScale(m2[0],label="Simulated Acoustic Pressure response")
showAxesScales(plotd,1)

"""
 Psuedo-Acoustic Pressure Response Plot (Brightness line) set up
"""
#extract desired format of the line plot (line->(element->value))
brightline = domainFactor(img, imgdom[1])
#add line reference to plot
ref2 = subs.addData("imageline", brightline, plotd)

#Source image put into a grid so that it is now displayed like the rest
twist_grid0 = [ [w for h in xrange(height) for w in xrange(width)],
[(w-h) for h in xrange(height) for w in xrange(width)]]
twist_set0 = Gridded2DSet(set.getType(), twist_grid0, width, height,
None,
None, None, 0)
twist0 = FlatField(img.getType(), twist_set0)
twist0.setSamples(img.getValues(Boolean(0)),0)
print "done making grid0"

#define twist grids for stretching image in pre-defined amounts (y
direction only)
#Twist_Grid 1
twist_grid1 = [ [w for h in xrange(height) for w in xrange(width)],
[(w-(h*0.4)) for h in xrange(height) for w in xrange(width)]]
twist_set1 = Gridded2DSet(set.getType(), twist_grid1, width, height,
None,
None, None, 0)
twist1 = FlatField(img.getType(), twist_set1)
twist1.setSamples(img.getValues(Boolean(0)),0)
print "done making grid2"
print "done making all grids!"

#define twist events for stretching image in y direction
def twist_0(event):
    sf.showIt(0)
    #reset plot display to upright position if it was displaced
    plotd.setBoxSize(.5, 1, 1, 1)

#twist event 1
def twist_1(event):
    sf.showIt(1)
    #reset plot display to upright position if it was displaced
    plotd.setBoxSize(.5, 1, 1, 1)

sf = subs.SelectField('img_index',[twist0, twist1])
print "now 'selecting Fields'"

# include the ScalarMap for the selectValue from SelectField.
maps.append(sf.getScalarMap())

print "appended ScalarMaps for images in SelectField"

disp = subs.makeDisplay(maps)

ref=disp.addData("images",sf.getSelectField())
disp.setBoxSize(.5)
print "just added images from SelectField to Display"
print "next bit, adding line's dummy reference takes a while"

# also, set up a dummy reference so we can put the invisible line onto
the display
usref = subs.addData("line", None, disp)

print "dummy reference added"

# define an inner-type CellImpl class to handle changes
class MyCell(CellImpl):
    def doAction(this):
        line = (LINES-1) - (userline.getData()).getValue()
        pts = subs.makeLine( (imgdom[1], imgdom[0]),
((line,line),(0,NELE)))
#        usref.setData(pts) this comment makes the line invisible
        ff = brightline.evaluate(Real(line))
        ref2.setData(ff)

print "Cell class defined"

# make a DataReference that we can use later to change the value of
"line"
userline = DataReferenceImpl("userline")
slide = VisADSlider("Sound Source Direction
(°)",0,LINES,0,1.0,userline,imgdom[1])

cell = MyCell()
cell.addReference(userline)

print "GUI creation begins"


#some program calls to add stretched image when buttons are clicked
#Stretch controls
buttonPanel = JPanel(border=border.TitledBorder(" Pinna 'Squash'
Controls "),
layout=FlowLayout())

originalButton=JButton("Image", preferredSize=(100,20),
actionPerformed=twist_0)
squashButton=JButton("Image x 0.4", preferredSize=(100,20),
actionPerformed=twist_1)
exitButton=JButton("Exit", preferredSize=(100,20),
actionPerformed=lambda event: System.exit(0))


buttonPanel.add(originalButton)
buttonPanel.add(squashButton)
buttonPanel.add(exitButton)

print "GUI 90% created"

# make JPanels for the graph and slide...and put the slide in its Panel
graph_panel = JPanel()
slide_panel = JPanel()
slide_panel.add(slide)

#add slide and graph to display
plotd.showDisplay(width=400, height=400, panel=graph_panel,
bottom=slide_panel)

print "now starting to render"

# now show all three panels in one frame.
disp.showDisplay(width=400, height=400, title="Sim3DAudioLite",
right=graph_panel, bottom=buttonPanel)

sf.showIt(0)
print "Done!"
