import jarray
import java
from javax.swing import *
from javax.swing.border import LineBorder, CompoundBorder, EmptyBorder
from java.awt import GridLayout, BorderLayout, FlowLayout, Color, Dimension, Canvas
from java.awt.event import InputEvent
import subs, graph
from subs import *
from graph import *
from visad.python.JPythonMethods import *
from visad import *
from visad.java3d import DirectManipulationRendererJ3D
from visad.bom import PickManipulationRendererJ3D, RubberBandBoxRendererJ3D, CurveManipulationRendererJ3D, ImageRendererJ3D
from visad.util import Delay
from ui.colorbar import ColorBarWidget
from java.util import StringTokenizer
from java.lang import Float, Thread, Integer, Math, Runtime
from util import Helper, ValueHistogram, OneDProbeRendererJ3D, MyRubberBandBoxRendererJ3D
from histostretch import linkHistLocation, dragHistLocation, dragHistLocationColorFunction
from DisplayViewSelect import DisplayViewSelectToolBar, HAction

import hydra_properties

#---------------------------------------
false = 0
true  = 1
lightWeightPopupEnabled = false
#---------------------------------------

selector_colors = [Color.magenta, Color(0.5, 0.5, 0.0), Color(0.0, 0.5, 0.5), Color(1.0, 0.0, 0.0), Color(0.0, 0.0, 1.0)]

runtime = Runtime.getRuntime()

import hydra_properties


class ChannelLinearCombo:
  def __init__(self, filereader, spectrum):
    self.filereader  = filereader
    self.operPair    = None
    self.spectrum    = spectrum  
    self.obs_valid_range = self.filereader.getObsValidRange()
    
    self.makeSelectDisplay()
    
    self.resultX            = None
    self.resultY            = None
    self.resultDisplayList  = [] 
    self.scatterDisplayList = []
    

  def windowClose(self, event):
    rlen = len(self.resultDisplayList)
    for i in range(rlen):
      self.resultDisplayList[0].windowClose(event)
    slen = len(self.scatterDisplayList)
    for i in range(slen):
      self.scatterDisplayList[0].windowClose(event)
          
  def getOperandData(self, value):
    spectralIndex = self.filereader.observationDomain.valueToIndex([[value]])[0]
    return self.filereader.getSameImageSegmentCopy(spectralIndex)
    
  def compute(self, event):
    result = self.operPair.evaluate()
    ResultDisplay(self, result)

  def scatter(self, event):
    if self.resultX != None and self.resultY != None:
      sc = Scatter(self)
      self.scatterDisplayList.append(sc)

  def unzoom(self, event):
    self.pcntrl.setMatrix(self.imtrx)
    self.xmap.setRange(self.lo[0], self.hi[0])
    if isinstance(self.filereader.spectrumRangeType, RealTupleType):
      self.ymap.setRange(self.obs_valid_range[0][0], self.obs_valid_range[0][1])
      self.ymap2.setRange(self.obs_valid_range[1][0], self.obs_valid_range[1][1])
    else:
      self.ymap.setRange(self.obs_valid_range[0], self.obs_valid_range[1])       
      
  def setX(self, x):
    if x == None:
      self.scatterButton.setEnabled(0)
    self.resultX = x
    if self.resultX != None and self.resultY != None:
      self.scatterButton.setEnabled(1)
   
    
  def setY(self, y):
    if y == None:
      self.scatterButton.setEnabled(0)
    self.resultY = y
    if self.resultX != None and self.resultY != None:
      self.scatterButton.setEnabled(1)
      
      
  def makeSelectDisplay(self):
    #-- VisAD displays are awt.Canvas -> Canvas3D, so mixing heavyweight/lightweight 
    #-- components causes problems with the popup menus always rendered beneath the Canvas
    JPopupMenu.setDefaultLightWeightPopupEnabled(lightWeightPopupEnabled)

    frame     = JFrame("Channel Combination Tool", windowClosing=self.windowClose)
    framePane = frame.getContentPane()
    framePane.setLayout(BorderLayout())
           
    #-- from Paolo's acViewer.py
    global spectrumDisplay
    obsElementInstrument, obsLineInstrument, obsChannelIndexInstrument, observationChannelsInstrument, observationsInstrument = self.filereader.getRealTypes()
    rtype = self.filereader.spectrumRangeType
    
    dset    = self.filereader.observationDomain
    self.lo = dset.getLow()
    self.hi = dset.getHi()
    lens    = dset.getLengths()
    spmps = None
    ylohi = None
    
    if isinstance(rtype, RealTupleType):
      spmps = makeMaps(observationChannelsInstrument,'x',rtype.getComponent(0),'y',rtype.getComponent(1),'y')
      spmps[0].setRange(self.lo[0], self.hi[0])
      spmps[1].setRange(self.obs_valid_range[0][0], self.obs_valid_range[0][1])
      spmps[2].setRange(self.obs_valid_range[1][0], self.obs_valid_range[1][1])
      as = spmps[2].getAxisScale()
      as.setVisible(1)
      as.setSide(1)
      as.setColor(Color.orange)
      ylohi = self.obs_valid_range[1]
      observationsInstrument = rtype.getComponent(1)
      self.ymap2 = spmps[2]
    else:
      spmps = makeMaps(observationChannelsInstrument,'x',observationsInstrument,'y')
      spmps[1].setRange(self.obs_valid_range[0], self.obs_valid_range[1])
      spmps[0].setRange(self.lo[0], self.hi[0])
      ylohi = self.obs_valid_range
    
    spectrumDisplay = makeDisplay(spmps)
    subs.setAspectRatio(spectrumDisplay,2)
    mode = spectrumDisplay.getGraphicsModeControl()
    mode.setPointSize(5)
    showAxesScales(spectrumDisplay,1)
    setBoxSize(spectrumDisplay,.6,clip=0)
    
    dsp_rdr = spectrumDisplay.getDisplayRenderer()
    dsp_rdr.setBackgroundColor(hydra_properties.background_color)
    dsp_rdr.setForegroundColor(hydra_properties.foreground_color)

    if isinstance(rtype, RealTupleType):
      addData('b',self.spectrum.getComponent(0),spectrumDisplay,subs.makeColorMap(hydra_properties.foreground_color),zlayer=-0.05) 
      addData('b',self.spectrum.getComponent(1),spectrumDisplay,subs.makeColorMap("orange"),zlayer=-0.05) 
    else:
      addData('b',self.spectrum,spectrumDisplay,subs.makeColorMap(hydra_properties.foreground_color), zlayer=-0.05) 
    #---------------------------
    
    self.pcntrl = spectrumDisplay.getProjectionControl()
    self.imtrx  = self.pcntrl.getMatrix()
    self.xmap   = spmps[0]
    self.ymap   = spmps[1]


    global lval, leftSelectRef, rval, rghtSelectRef
    
    lval     = int(lens[0]*0.33)
    leftInit = self.filereader.observationDomain.indexToValue([lval])[0]   
    leftSelectRef = spectrumDisplay.addData("left", Real(observationChannelsInstrument, leftInit[0]),
      constantMaps=[ConstantMap(-0.5, Display.YAxis)]+makeColorMap("red"), renderer=OneDProbeRendererJ3D(dset))
      
    rval     = int(lens[0]*0.66)
    rghtInit = self.filereader.observationDomain.indexToValue([rval])[0]          
    rghtSelectRef = spectrumDisplay.addData("rght", Real(observationChannelsInstrument, rghtInit[0]),
      constantMaps=[ConstantMap(-0.5, Display.YAxis)]+makeColorMap("green"), renderer=OneDProbeRendererJ3D(dset))
      
    global lval2, leftSelectRef2, rval2, rghtSelectRef2
    
    lval2 = -3000
    leftInit2 = self.filereader.observationDomain.indexToValue([lval2])[0]    
    leftSelectRef2 = spectrumDisplay.addData("left", Real(observationChannelsInstrument, lval2),
      constantMaps=[ConstantMap(-0.5, Display.YAxis)]+makeColorMap("blue"), renderer=OneDProbeRendererJ3D(dset))
      
    rval2 = -3000
    rghtInit2 = self.filereader.observationDomain.indexToValue([rval2])[0]          
    rghtSelectRef2 = spectrumDisplay.addData("rght", Real(observationChannelsInstrument, rval2),
      constantMaps=[ConstantMap(-0.5, Display.YAxis)]+makeColorMap("magenta"), renderer=OneDProbeRendererJ3D(dset))      

 
     
    global lpair, rpair
    if self.filereader.instrumentName == "MODIS" or self.filereader.instrumentName == "MSG":
      lpair = OperationPairPullDown(leftInit[0], leftSelectRef, rghtInit[0], rghtSelectRef, 1, 1, Color.red, Color.green, self)
      rpair = OperationPairPullDown(leftInit[0], leftSelectRef2, rghtInit[0], rghtSelectRef2, 0, 0, Color.blue, Color.magenta, self)
    else:
      lpair = OperationPair(leftInit[0], leftSelectRef, rghtInit[0], rghtSelectRef, 1, 1, Color.red, Color.green, self)
      rpair = OperationPair(leftInit[0], leftSelectRef2, rghtInit[0], rghtSelectRef2, 0, 0, Color.blue, Color.magenta, self)
      
    self.operPair = Operation(lpair, rpair)
    #self.operPair.getComponent().setMaximumSize(Dimension(600,50))
    self.operPair.getComponent().setMaximumSize(self.operPair.getComponent().getPreferredSize())
    
    computeButton = JButton("compute", actionPerformed=self.compute)      
    sp = JPanel()
    sp.setLayout(FlowLayout())
    sp.add(computeButton)
    self.scatterButton = JButton("scatter", actionPerformed=self.scatter)
    self.scatterButton.setEnabled(0)
    self.default_sb_back = self.scatterButton.getBackground()
    sp.add(self.scatterButton)
    sp.setMaximumSize(sp.getPreferredSize())
    
    
    tb = DisplayViewSelectToolBar([spectrumDisplay], [1], pickAction="grab")
    tb.add(sp)

    #framePane.add(sp, BorderLayout.NORTH)
    framePane.add(tb, BorderLayout.NORTH)
    framePane.add(spectrumDisplay.getComponent(), BorderLayout.CENTER)
    framePane.add(self.operPair.getComponent(), BorderLayout.SOUTH)

    class LeftCell(CellImpl):
      def __init__(self, operPair, obs_valid_range):
        self.operPair = operPair
        self.obs_valid_range = obs_valid_range
        self.lineRefL = spectrumDisplay.drawLine([[lval, lval], [self.obs_valid_range[0], self.obs_valid_range[1]]], color="red", width=2)
        
      def doAction(self):
        val = leftSelectRef.getData().getValue()
        spectrumDisplay.moveLine(self.lineRefL, [[val, val], [self.obs_valid_range[0], self.obs_valid_range[1]]])
        lpair.lockout(1)
        lpair.setLeft('%8.3f' % val)
        lpair.lockout(0)
    lcell = LeftCell(self.operPair, ylohi)
    lcell.addReference(leftSelectRef)

    class RightCell(CellImpl):
      def __init__(self, operPair, obs_valid_range):
        self.operPair = operPair
        self.obs_valid_range = obs_valid_range
        self.lineRefR = spectrumDisplay.drawLine([[rval, rval], [self.obs_valid_range[0], self.obs_valid_range[1]]], color="green", width=2)
        
      def doAction(self):
        val = rghtSelectRef.getData().getValue()
        spectrumDisplay.moveLine(self.lineRefR, [[val, val], [self.obs_valid_range[0], self.obs_valid_range[1]]])    
        lpair.lockout(1)
        if (val == -3000):
          lpair.setRight("--------")
        else:
          lpair.setRight('%8.3f' % val)
        lpair.lockout(0)
    rcell = RightCell(self.operPair, ylohi)
    rcell.addReference(rghtSelectRef)

    class LeftCell2(CellImpl):
      def __init__(self, operPair, obs_valid_range):
        self.operPair = operPair
        self.obs_valid_range = obs_valid_range
        self.lineRefL = spectrumDisplay.drawLine([[lval2, lval2], [self.obs_valid_range[0], self.obs_valid_range[1]]], color="blue", width=2)
        
      def doAction(self):
        val = leftSelectRef2.getData().getValue()
        spectrumDisplay.moveLine(self.lineRefL, [[val, val], [self.obs_valid_range[0], self.obs_valid_range[1]]]) 
        rpair.lockout(1)
        if (val == -3000):
          rpair.setLeft("--------")
        else:
          rpair.setLeft('%8.3f' % val)
        rpair.lockout(0)
    lcell2 = LeftCell2(self.operPair, ylohi)
    lcell2.addReference(leftSelectRef2)
    
    class RightCell2(CellImpl):
      def __init__(self, operPair, obs_valid_range):
        self.operPair = operPair
        self.obs_valid_range = obs_valid_range
        self.lineRefR = spectrumDisplay.drawLine([[rval2, rval2], [self.obs_valid_range[0], self.obs_valid_range[1]]], color="magenta", width=2) 
        
      def doAction(self):
        val = rghtSelectRef2.getData().getValue()
        spectrumDisplay.moveLine(self.lineRefR, [[val, val], [self.obs_valid_range[0], self.obs_valid_range[1]]])
        rpair.lockout(1)
        if (val == -3000):
          rpair.setRight("--------")
        else:
          rpair.setRight('%8.3f' % val)
        rpair.lockout(0)
    rcell2 = RightCell2(self.operPair, ylohi)
    rcell2.addReference(rghtSelectRef2)
    
    
      
    class ZoomBox(CellImpl):
      def __init__(self, zoomBoxRef, xmap, ymap, lref, rref, mom):
        self.first      = 1
        self.zoomBoxRef = zoomBoxRef
        self.xmap       = xmap
        self.ymap       = ymap
        self.lref       = lref
        self.rref       = rref
        self.mom        = mom
        
      def doAction(self):
        if self.first == 0:
          set = self.zoomBoxRef.getData()
          lo  = set.getLow()
          hi  = set.getHi()
          if ((hi[0] - lo[0]) < (hi[1] - lo[1])):
            slo = lo[0]
            shi = hi[0]
          else:
            slo = lo[1]
            shi = hi[1]
          if ((lo[0] == hi[0]) or (lo[1] == hi[1])):
            self.mom.unzoom(None)
          else:
            self.xmap.setRange(lo[0], hi[0])
            self.ymap.setRange(lo[1], hi[1])
          type = self.lref.getData().getType()
        else:
          self.first = 0
    #zcell = ZoomBox(zoomBoxRef, spmps[0], spmps[1], leftSelectRef, rghtSelectRef, self)
    #zcell.addReference(zoomBoxRef)

        
    frame.pack()
    frame.show()
   # frame.setSize(650, 400)
#---------------------------------------- makeSelectDisplay



class Scatter(ScalarMapListener):
  def __init__(self, clc):
    runtime.gc()
    self.clc     = clc
    self.resultX = clc.resultX
    self.resultY = clc.resultY
    
    self.n_selectors  = 5
    self.select_index = 0
    
    Xmask = self.resultX.vminmaxbig[2:7]
    Ymask = self.resultY.vminmaxbig[2:7]
    
    #--re-initialize ranges
    if self.resultX.dirty == true:
      self.resultX.result.setSamples(self.resultX.values,false)
    if self.resultY.dirty == true:
      self.resultY.result.setSamples(self.resultY.values,false)
    
    self.resultDim = self.resultX.result.getDomainSet().getLengths()
    

    mt  = self.resultX.result.getType()
    nmt = FunctionType(mt.getDomain(), makeType("X"))
    #new_resultX = self.resultX.result.changeMathType(nmt), extra memory issue: no copy=false for unary
    new_resultX = FlatField(nmt, self.resultX.result.getDomainSet())
    new_resultX.setSamples(self.resultX.values, false)

    mt  = self.resultY.result.getType()
    nmt = FunctionType(mt.getDomain(), makeType("Y"))
    #new_resultY = self.resultY.result.changeMathType(nmt)
    new_resultY = FlatField(nmt, self.resultY.result.getDomainSet())
    new_resultY.setSamples(self.resultY.values, false)

    self.xy_ttype  = RealTupleType(makeType("X"), makeType("Y"))
    

    self.histogram = ValueHistogram(self.resultX.result, self.resultX.values, self.resultY.result, self.resultY.values, 100, Xmask, Ymask)

    topPanel  = JPanel()
    textLabel = JLabel()
    textLabel.setForeground(hydra_properties.foreground_color)
    topPanel.setBackground(hydra_properties.background_color)
    textLabel.setText("X: "+self.resultX.resultStr+",  Y: "+self.resultY.resultStr)
    topPanel.add(textLabel)

    botPanel  = JPanel(GridLayout(2,1))
    textLabel = JLabel()
    textLabel.setForeground(hydra_properties.foreground_color)
    botPanel.setBackground(hydra_properties.background_color)
    textLabel.setText("X: "+self.resultX.chValStr+",   Y: "+self.resultY.chValStr)
    botPanel.add(textLabel)
  
    dsp = scatter(new_resultX, new_resultY, pointsize=3, bottom=botPanel, xlabel=self.resultX.resultStr, ylabel=self.resultY.resultStr, color=hydra_properties.foreground_color)
    dsp.my_frame.windowClosing=self.windowClose
    
    dsp_rdr = dsp.getDisplayRenderer()
    dsp_rdr.setBackgroundColor(hydra_properties.background_color)
    dsp_rdr.setForegroundColor(hydra_properties.foreground_color)
    
    #- menuBar
    menuBar     = JMenuBar()
    toolMenu    = JMenu("Tools")
    menuBar.add(toolMenu)
    item1 = JMenuItem("Capture Display", actionPerformed=self.captureDisplay)
    item1.setEnabled(1)
    toolMenu.add(item1)
    dsp.my_frame.setJMenuBar(menuBar)
    
    self.dsp = dsp
    self.boxRef = None
    dsp.displayChanged=self.subsetScatterByCurve
    mode = dsp.getGraphicsModeControl()
     

    dset       = Integer1DSet(1)
    self.empty = FlatField(FunctionType(dset.getType().getDomain(), self.xy_ttype), dset)
    self.markRef = dsp.addData("mark", self.empty, constantMaps=makeColorMap("magenta"), zlayer = 0.05)
    self.markRef_s = [dsp.addData("mark", self.empty, constantMaps=makeColorMap(selector_colors[x])) for x in xrange(self.n_selectors)]
    
    
    self.rbbRef_s = []
    self.crvRef_s = []
    self.boxRef_s = []
    self.last_crvRef_s = []
    
    mHelper = dsp.getDisplayRenderer().getMouseBehavior().getMouseHelper()
    mHelper.setFunctionMap([[[MouseHelper.DIRECT, MouseHelper.ZOOM],
                                   [MouseHelper.TRANSLATE, MouseHelper.NONE]],
                                  [[MouseHelper.CURSOR_TRANSLATE, MouseHelper.CURSOR_ZOOM],
                                   [MouseHelper.CURSOR_ROTATE, MouseHelper.NONE]],
                                  [[MouseHelper.DIRECT, MouseHelper.DIRECT],
                                   [MouseHelper.DIRECT, MouseHelper.DIRECT]]])
   
    for i in xrange(self.n_selectors):
      rbbRef = dsp.enableRubberBandBox(0, callback=self.subsetScatter, color=selector_colors[i])
    
      self.curveRef = DataReferenceImpl("curveRef")
      self.set1 = Gridded2DSet(self.xy_ttype, [[min(self.resultX.values[0])], [min(self.resultY.values[0])]], 1)
      self.curveRef.setData(UnionSet([self.set1]))
      dsp.addReferences(CurveManipulationRendererJ3D(0,0), self.curveRef, [makeLineStyleMap(None, 2)]+makeColorMap(selector_colors[i])+[ConstantMap(0.07, Display.ZAxis)])
      
      self.rbbRef_s.append(rbbRef)
      self.crvRef_s.append(self.curveRef)
      self.boxRef_s.append(None)
      
      last_cref = DataReferenceImpl("last_crvRef")
      dsp.addReference(last_cref, [makeLineStyleMap(None,2)]+makeColorMap(selector_colors[i]))
      last_cref.setData(UnionSet([self.set1]))
      self.last_crvRef_s.append(last_cref)
    
      if i == self.select_index:
        dsp.toggle(self.rbbRef_s[i], true)
        dsp.toggle(self.crvRef_s[i], true)
      else:
        dsp.toggle(self.rbbRef_s[i], false)
        dsp.toggle(self.crvRef_s[i], false)
          
    
    #-- selector widget --------------   
    toolbar = JToolBar()
    toolbar.setFloatable(0)
    bg = ButtonGroup()
    self.last_select_index = 0
    for i in xrange(self.n_selectors):
      tb = JToggleButton(ImageIcon("./ui/icons/rubber_band.gif"), actionPerformed=self.setSelectedIndex, actionCommand=str(i))
      #tb.setBorder(LineBorder(selector_colors[i],1))
      #tb.setBackground(selector_colors[i])
      #tb.setBorder(CompoundBorder(EmptyBorder(2,2,2,2), LineBorder(selector_colors[i],1)))
      tb.setToolTipText("select points")
      bg.add(tb)
      toolbar.add(tb)
      if i == 0:
        tb.setSelected(1)

    tb = JToggleButton(ImageIcon("./ui/icons/Home16.gif"), actionPerformed=self.resetZoom)
    tb.setToolTipText("unzoom")
    bg.add(tb)
    toolbar.add(tb)

    tb = JToggleButton(ImageIcon("./ui/icons/subset16.jpg"), actionPerformed=self.selectZoom)
    tb.setToolTipText("rubber-band zoom")
    bg.add(tb)
    toolbar.add(tb)

             
    xb = JRadioButton("box", actionPerformed=self.selectBox)
    xb.setSelected(true)
    dsp.toggle(self.crvRef_s[self.select_index], false)
    yb = JRadioButton("curve", actionPerformed=self.selectCurve)
    bg = ButtonGroup()
    bg.add(xb)
    bg.add(yb)
    sp = JPanel()
    sp.setLayout(FlowLayout())
    sp.add(xb)
    sp.add(yb)
    sp0 = JPanel()
    sp0.setLayout(FlowLayout())
    sp0.add(toolbar)
    sp0.add(sp)

    #botPanel.add(toolbar)
    botPanel.add(sp0)
    self.boxSelected   = true
    self.curveSelected = false
    
    self.rbbzSelected = false
    self.zoomRef = self.dsp.enableRubberBandBox(0, callback=self.zoom, color="green")
    self.dsp.toggle(self.zoomRef, false)
    self.smaps = subs.getDisplayScalarMapLists(self.dsp)
    self.xmap = self.smaps[0][0]
    self.ymap = self.smaps[1][0]
    subs.setBoxSize(self.dsp, clip=0)

    self.xmapEvent = false
    self.ymapEvent = false
    self.xmapRange = None
    self.ymapRange = None
    self.xmap.addScalarMapListener(self)
    self.ymap.addScalarMapListener(self)
    

  def mapChanged(self, event):
    if self.xmap == event.getScalarMap() and self.xmapEvent == false:
      self.xmapRange = self.xmap.getRange()
      self.xmapEvent = true

    if self.ymap == event.getScalarMap() and self.ymapEvent == false:
      self.ymapRange = self.ymap.getRange()
      self.ymapEvent = true
      

  def controlChanged(self, event):
    print event

  def resetZoom(self, event):
    rr = self.xmapRange
    self.xmap.setRange(rr[0], rr[1])
    rr = self.ymapRange
    self.ymap.setRange(rr[0], rr[1])

  def zoom(self, event):
    set = self.zoomRef.getData()
    lo  = set.getLow()
    hi  = set.getHi()
    if ((hi[0] - lo[0]) < (hi[1] - lo[1])):
      slo = lo[0]
      shi = hi[0]
    else:
      slo = lo[1]
      shi = hi[1]
    if ((lo[0] == hi[0]) or (lo[1] == hi[1])):
      pass
    else:
      self.dsp.disableAction()
      self.xmap.setRange(lo[0], hi[0])
      self.ymap.setRange(lo[1], hi[1])
      self.dsp.enableAction()

    
  def selectZoom(self, event):
    self.dsp.toggle(self.zoomRef, true)
    for i in xrange(self.n_selectors):
      self.dsp.toggle(self.rbbRef_s[i], false)
      self.dsp.toggle(self.crvRef_s[i], false)
    
    
  def selectBox(self, event):
    self.boxSelected = true
    self.curveSelected = false
    for i in xrange(self.n_selectors):
      self.dsp.toggle(self.crvRef_s[i], false)
    self.dsp.toggle(self.rbbRef_s[self.select_index], true)
    
  def selectCurve(self, event):
    self.boxSelected = false
    self.curveSelected = true
    for i in xrange(self.n_selectors):
      self.dsp.toggle(self.rbbRef_s[i], false)
    self.dsp.toggle(self.crvRef_s[self.select_index], true)
    
  def setSelectedIndex(self, event):
    cmd = event.getActionCommand()
    self.select_index = int(cmd)
    
    if self.select_index == self.last_select_index:
      self.clearScatter(self.select_index)
      self.histogram.clear(self.select_index)
      if self.boxRef_s[self.select_index] != None:
        self.boxRef_s[self.select_index].setData(self.empty)
      self.crvRef_s[self.select_index].setData(UnionSet([self.set1]))
      self.last_crvRef_s[self.select_index].setData(UnionSet([self.set1]))
    self.last_select_index = self.select_index

    for i in xrange(self.n_selectors):
      if i == self.select_index:
        if self.boxSelected == true:
          self.dsp.toggle(self.rbbRef_s[i], true)
          self.dsp.toggle(self.crvRef_s[i], false)
        if self.curveSelected == true:
          self.dsp.toggle(self.crvRef_s[i], true)
          self.dsp.toggle(self.rbbRef_s[i], false)
      else:
        self.dsp.toggle(self.rbbRef_s[i], false)
        self.dsp.toggle(self.crvRef_s[i], false)

    self.dsp.toggle(self.zoomRef, false)
          
  def subsetScatter(self, diagonal):
    self.boxRef_s[self.select_index] = self.dsp.drawBox(diagonal, boxref=self.boxRef_s[self.select_index], color=selector_colors[self.select_index])
    self.crvRef_s[self.select_index].setData(UnionSet([self.set1]))
    self.last_crvRef_s[self.select_index].setData(UnionSet([self.set1]))
    self.histogram.getIndexesByRange(diagonal[0], diagonal[1], self.select_index)
    self.resultX.dirty = true
    self.resultY.dirty = true
    
  def subsetScatterByCurve(self, event):
    ie = event.getInputEvent()
    if ((event.getId() == DisplayEvent.MOUSE_RELEASED_RIGHT or event.getId() == DisplayEvent.MOUSE_RELEASED_LEFT) and self.curveSelected == true):
      self.last_crvRef_s[self.select_index].setData(UnionSet([self.set1]))
      if self.boxRef_s[self.select_index] != None:
        self.boxRef_s[self.select_index].setData(self.empty)
      uset = self.crvRef_s[self.select_index].getData()
      sets = uset.getSets()
      s_idx = len(sets) - 1
      self.crvRef_s[self.select_index].setData(UnionSet([sets[s_idx]]))
      self.last_crvRef_s[self.select_index].setData(UnionSet([sets[s_idx]]))
      self.histogram.getIndexesByCurve(sets[s_idx].getSamples(), self.select_index)
      self.resultX.dirty = true
      self.resultY.dirty = true

      
  def markScatterPoints(self, line, elem, select_idx):
    ln_lo   = Math.round(Math.min(line[0], line[1]))
    el_lo   = Math.round(Math.min(elem[0], elem[1]))
    ln_hi   = Math.round(Math.max(line[0], line[1]))
    el_hi   = Math.round(Math.max(elem[0], elem[1]))

    ratio = self.clc.filereader.xlength/self.clc.filereader.gxlength
    ln_lo *= ratio
    el_lo *= ratio
    ln_hi *= ratio
    el_hi *= ratio

    n_lines = ln_hi - ln_lo
    n_elems = el_hi - el_lo

    len  = n_lines*n_elems
    if len > 0:
      dset = Integer1DSet(len)
      ff   = FlatField(FunctionType(dset.getType().getDomain(), self.xy_ttype), dset)
      new_vals = []
      new_vals.append(jarray.zeros(len, 'f'))
      new_vals.append(jarray.zeros(len, 'f'))
      for i in range(n_elems):
        for j in range(n_lines):
          idx = (i+el_lo)*self.resultDim[0] + (j+ln_lo)
          ii  = i*n_lines + j
          new_vals[0][ii] = self.resultX.values[0][idx]
          new_vals[1][ii] = self.resultY.values[0][idx]
      ff.setSamples(new_vals)
      self.markRef_s[select_idx].setData(ff)
    else:
      self.markRef_s[select_idx].setData(self.empty)
            
  def markScatterPointsByCurve(self, line_s, elem_s, select_index):
    n_pts = len(line_s)
    if n_pts > 0:
      dset = Integer1DSet(n_pts)
      ff   = FlatField(FunctionType(dset.getType().getDomain(), self.xy_ttype), dset)
      new_vals = []
      new_vals.append(jarray.zeros(n_pts, 'f'))
      new_vals.append(jarray.zeros(n_pts, 'f'))
      ratio = self.clc.filereader.xlength/self.clc.filereader.gxlength
      for k in range(n_pts):
        elem_s[k] *= ratio
        line_s[k] *= ratio
        idx = elem_s[k]*self.resultDim[0] + line_s[k]
        new_vals[0][k] = self.resultX.values[0][idx]
        new_vals[1][k] = self.resultY.values[0][idx]
      ff.setSamples(new_vals)
      self.markRef_s[select_index].setData(ff)
    else:
      self.markRef_s[select_index].setData(self.empty)   
      
  def clearScatter(self, select_index):
    self.markRef_s[select_index].setData(self.empty)
    
  def captureDisplay(self,event):
    Helper.saveDisplay(self.dsp, JFrame().getContentPane())
     
  def windowClose(self, event):
    frame = self.dsp.my_frame
    frame.dispose()
    self.clc.scatterDisplayList.remove(self)
    runtime.gc()



class ResultDisplay:
  displayLineType = None
  displayElemType = None
  displayAltType  = None
  dtt             = None
  count           = 0
  
  def __init__(self, caller, result):
    runtime.gc()
    
    self.dirty      = false
    self.caller     = caller
    self.result     = result
    #values = Helper.getValues(result,true)
    values = Helper.unpackFloats(result,true)
    self.resultCopy = FlatField(result.getType(), result.getDomainSet())
    self.resultCopy.setSamples(values, false)
    self.text = TextType.Generic
    self.n_selectors = 5
    self.select_index = 0
    self.boxSelected = true
    self.curveSelected = false
    
    #-- build result display, from Paolo's acViewer.py
    obsElementInstrument, obsLineInstrument, obsChannelIndexInstrument, observationChannelsInstrument, observationsInstrument = self.caller.filereader.getRealTypes()
    obsLatitudeInstrument, obsLongitudeInstrument = self.caller.filereader.getGeoRealTypes()
    obsLatMinMaxInstrument, obsLonMinMaxInstrument = self.caller.filereader.getGeoDomain()    
    observationChannelsInstrumentMX = self.caller.filereader.getObservationChannelRange()
    maps = makeMaps(obsLongitudeInstrument,'x', obsLatitudeInstrument, 'y', observationsInstrument, 'rgb','marker','shape', self.text, 'text')
    self.maps = maps
    dsp = makeDisplay(maps)
    self.dsp = dsp
    dsp.setAlwaysAutoScale(1)
    setBoxSize(dsp,.7,clip=0)
    
    dsp_rdr = self.dsp.getDisplayRenderer()
    dsp_rdr.setBackgroundColor(hydra_properties.background_color)
    dsp_rdr.setForegroundColor(hydra_properties.foreground_color)
    
    dsp_rdr.setCursorStringOn(false)
    self.mHelper = dsp_rdr.getMouseBehavior().getMouseHelper()
    self.mHelper.setFunctionMap([[[MouseHelper.DIRECT, MouseHelper.ZOOM],
                                   [MouseHelper.TRANSLATE, MouseHelper.NONE]],
                                  [[MouseHelper.CURSOR_TRANSLATE, MouseHelper.CURSOR_ZOOM],
                                   [MouseHelper.CURSOR_ROTATE, MouseHelper.NONE]],
                                  [[MouseHelper.DIRECT, MouseHelper.DIRECT],
                                   [MouseHelper.DIRECT, MouseHelper.DIRECT]]])
    
    self.shapes = None
    self.shapes = subs.Shapes(dsp,self.maps[3])
    self.shapeMarkerIndex = None
    self.shapeMarkerIndex = self.shapes.addShape("cross",scale=.03,color="cyan", autoScale=0)
    ll = self.caller.filereader.cs.toReference([[0], [0]])
    self.shapes.moveShape(self.shapeMarkerIndex, (ll[1][0], ll[0][0]))

    txtCntrl = self.maps[4].getControl()
    txtCntrl.setJustification(TextControl.Justification.LEFT)
    txtCntrl.setAutoSize(1)
    txtCntrl.setFont(Font("sansserif", Font.PLAIN, 16))

    
    #-- string label stuff
    operString = self.caller.operPair.toString()
    st = StringTokenizer(operString, "()+-/*")
    channelVals = []
    ns = operString
    chStr = ""
    for i in xrange(st.countTokens()):
      if chStr != "":
        chStr = chStr + ',  '
      tok = st.nextElement()
      channelVals.append(tok)
      tt = 'c%i' % (i+1)
      ns = ns.replace(tok, tt)
      chStr = chStr + tt
      chStr = chStr + ":"+tok

    roamText = Tuple(TupleType([obsLatitudeInstrument, obsLongitudeInstrument, self.text]), [Real(obsLatitudeInstrument,
Float.NaN), Real(obsLongitudeInstrument, Float.NaN), Text(self.text, '   %-6.2f' % Float.NaN)])
    self.roamTextRef = subs.addData('a', roamText, dsp, subs.makeColorMap(Color(1.0,0.0,1.0)),zlayer = 0.1)
    
    
    frame = JFrame(ns+"  "+chStr,windowClosing=self.windowClose)
    
    #- menuBar
    menuBar     = JMenuBar()
    toolMenu    = JMenu("Tools")
    settingMenu = JMenu("Settings")
    menuBar.add(toolMenu)
    menuBar.add(settingMenu)
    item1 = JMenuItem("Capture Display", actionPerformed=self.captureDisplay)
    item1.setEnabled(1)
    toolMenu.add(item1)
    item1 = JMenuItem("Set Color Range", actionPerformed=self.doSetColorRange)
    item1.setEnabled(1)
    settingMenu.add(item1)
    frame.setJMenuBar(menuBar)
       
    
    self.frame = frame
    framePane  = frame.getContentPane()
    framePane.setLayout(BorderLayout())
    framePane.add(dsp.getComponent(), BorderLayout.CENTER)
    textPanel = JPanel()
    textLabel = JLabel()
    textLabel.setForeground(hydra_properties.foreground_color)
    textPanel.setBackground(hydra_properties.background_color)
    dsp.setAlwaysAutoScale(false)
    
    textLabel.setText(chStr)
    textPanel.add(textLabel)
    
    #- Scatter axis controls
    southPanel = JPanel(GridLayout(4,1))
    xb = JRadioButton("XAxis", actionPerformed=self.selectX)
    yb = JRadioButton("YAxis", actionPerformed=self.selectY)
    sp = JPanel()
    sp.setLayout(FlowLayout())
    sp.add(xb)
    sp.add(yb)
    bg = ButtonGroup()
    self.xb = xb
    self.yb = yb
    southPanel.add(textPanel)
    southPanel.add(sp)
    
    #- mask toggle button 
    self.mask_on  = true
    self.togText  = ["mask on ", "mask off"]
    self.togIndex = 0
    self.lastTogIndex = 1
    tp = JPanel()
    tp.setLayout(FlowLayout())
    self.viewToolBar = DisplayViewSelectToolBar([dsp])
    tp.add(self.viewToolBar)
    self.mskToggleBttn = JButton(self.togText[self.togIndex], actionPerformed=self.toggleMask)
    #tp.add(self.mskToggleBttn)
    sp.add(self.mskToggleBttn)
    southPanel.add(tp)
    
    
    colorBar = ColorBarWidget(maps[2],hydra_properties.background_color, hydra_properties.foreground_color)
    colorBar.getSliderLabel().changeLabel(ns)
    framePane.add(colorBar, BorderLayout.NORTH)
    
    class Pick:
      def __init__(self, dsp, result, colorBar, shapes, shapeMarkerIndex):
        self.dsp      = dsp
        self.result   = result
        self.colorBar = colorBar
        self.shapes   = shapes
        self.shapeMarkerIndex = shapeMarkerIndex
        subs.HandlePickEvent(self.dsp, self.doAction)
      def doAction(self, lon, lat):
        self.shapes.moveShape(self.shapeMarkerIndex,(lon,lat))
        val = self.result.evaluate(RealTuple(self.result.getType().getDomain().getCoordinateSystem().getReference(), [lat, lon]), Data.NEAREST_NEIGHBOR, Data.NO_ERRORS)
        self.colorBar.getSlider().setValue(val.getValue())
    #- use the copy so we can get the non-masked field values
    pick = Pick(dsp, self.resultCopy, colorBar, self.shapes, self.shapeMarkerIndex)

    class roamProbe(DisplayListener):
      def __init__(self, display, result, toolbar, textRef, y, x, txt):
        self.display = display
        self.display.addDisplayListener(self)
        self.dr = display.getDisplayRenderer()
        self.result = result
        self.toolbar = toolbar
        self.textRef = textRef
        self.x = x
        self.y = y
        self.txt = txt
        self.last_lon = None
        self.last_lat = None

      def displayChanged(self, event):
        if event.getId() == 2 or event.getId() == 3:
          return
        lat = self.dr.getDirectAxisValue("Latitude")
        lon = self.dr.getDirectAxisValue("Longitude")
        if self.toolbar.pickAction.enabled == 1:
          val = self.result.evaluate(RealTuple(self.result.getType().getDomain().getCoordinateSystem().getReference(), [lat, lon]), Data.NEAREST_NEIGHBOR, Data.NO_ERRORS)
          self.textRef.setData(Tuple(TupleType([self.y, self.x, self.txt]), [Real(self.y, lat), Real(self.x, lon), Text(self.txt, '   %-6.2f' % val)]))
    roamProbe(dsp, self.resultCopy, self.viewToolBar, self.roamTextRef, obsLatitudeInstrument, obsLongitudeInstrument, self.text)
    
    
    #- set up curve selectors
    self.crvRef_s = []    
    self.last_crvRef_s = []
    point = self.result.getType().getDomain().getCoordinateSystem().toReference([[0],[0]])
    point = Set.doubleToFloat(point)
    self.noSet = Gridded2DSet(RealTupleType(obsLatitudeInstrument, obsLongitudeInstrument), point, 1)
    for i in xrange(self.n_selectors):
      curveRef = DataReferenceImpl("curveRef")
      curveRef.setData(UnionSet([self.noSet]))
      dsp.addReferences(CurveManipulationRendererJ3D(0,0), curveRef, [makeLineStyleMap(None, 2)]+makeColorMap(selector_colors[i])+[ConstantMap(0.07, Display.ZAxis)])
      dsp.toggle(curveRef, false)
      self.crvRef_s.append(curveRef)
      
      last_cref = DataReferenceImpl("last_crvRef")
      dsp.addReference(last_cref, [makeLineStyleMap(None,2)]+makeColorMap(selector_colors[i]))
      last_cref.setData(UnionSet([self.noSet]))
      self.last_crvRef_s.append(last_cref)
      
    dsp.displayChanged=self.subsetByCurve
    
        
    #--- color function stuff ----------------
    vmin, vmax = Helper.minmax(values[0])
    cc = maps[2].getControl()
    cc.initGreyWedge()
    ct = cc.getTable()
    self.ct = ct
    ct_len = len(ct[0])
        
    fsmpls = jarray.zeros(ct_len+6, 'f')
    vdiff = vmax - vmin
    vinc  = vdiff/(ct_len - 1)
    vminmaxbig = [vmin, vmax, vmax+vdiff*100, vmax+2*vdiff*100, vmax+3*vdiff*100, vmax+4*vdiff*100, vmax+5*vdiff*100]    
    fsmpls[0] = -10.0
    for i in xrange(ct_len-1): fsmpls[i+2] = fsmpls[i+1] + vinc/(vmax - vmin)
    fsmpls[ct_len+1] = (vminmaxbig[2] - vmin)/(vmax - vmin)
    fsmpls[ct_len+2] = (vminmaxbig[3] - vmin)/(vmax - vmin)
    fsmpls[ct_len+3] = (vminmaxbig[4] - vmin)/(vmax - vmin)
    fsmpls[ct_len+4] = (vminmaxbig[5] - vmin)/(vmax - vmin)
    fsmpls[ct_len+5] = (vminmaxbig[6] - vmin)/(vmax - vmin)
    clr_set = Gridded1DSet(RealType.Generic, [fsmpls], ct_len+6)
    new_ct  = [[], [], []]
    
    #-new_ct[0].append(0.0), new_ct[1].append(0.0), new_ct[2].append(1.0)
    #-for i in range(ct_len): new_ct[0].append(ct[0][i]), new_ct[1].append(ct[1][i]), new_ct[2].append(ct[2][i])
    
    new_ct[0].append(1.0), new_ct[1].append(1.0), new_ct[2].append(1.0)
    for i in range(ct_len): new_ct[0].append(ct[0][(ct_len-1)-i]), new_ct[1].append(ct[1][(ct_len-1)-i]), new_ct[2].append(ct[2][(ct_len-1)-i])
    
    new_ct[0].append(0.5), new_ct[1].append(0.0), new_ct[2].append(0.5)
    new_ct[0].append(0.5), new_ct[1].append(0.5), new_ct[2].append(0.0)
    new_ct[0].append(0.0), new_ct[1].append(0.5), new_ct[2].append(0.5)
    new_ct[0].append(1.0), new_ct[1].append(0.0), new_ct[2].append(0.0)
    new_ct[0].append(0.0), new_ct[1].append(0.0), new_ct[2].append(1.0)
    
    clr_fnc = FlatField(FunctionType(RealType.Generic, RealTupleType([makeType("cR"), makeType("cG"), makeType("cB")])), clr_set)
    clr_fnc.setSamples(new_ct)
    

    #-- do these steps together: enable/disable
    dsp.disableAction() 
    
    maps[2].setRange(vminmaxbig[0], vminmaxbig[1])
    cc.setFunction(clr_fnc)
    
    self.resultRef     = self.dsp.addData('b', result, renderer=ImageRendererJ3D(), zlayer=-0.1)   
    #self.resultCopy = result.clone()
    #self.resultCopyRef = self.dsp.addData('c', self.resultCopy, renderer=ImageRendererJ3D(), zlayer=-0.2)
    #self.dsp.toggle(self.resultCopyRef, false)
        
    from subsetImage import SubsetImage, Subset
    subsetRef        = [None]
    self.rbbrj3d_s   = []
    self.subsetRef_s = []
    
    for i in xrange(self.n_selectors):
      ss = SubsetImage(self.result, dsp, maps[0], maps[1], self.boxUpdate, subsetRef, color=selector_colors[i])
      self.rbbrj3d_s.append(ss.rbbrj3d)
      self.subsetRef_s.append(ss.boxRef)
      ss.rbbrj3d.active = false
      self.noBox = ss.noBox
    self.rbbrj3d = self.rbbrj3d_s[self.select_index]
    self.rbbrj3d.active = true
    
        
    dsp.enableAction()    
    
    from ColorScaleSelect import ColorScaleSelect
    self.colorMenu = ColorScaleSelect("set color scale", self.maps[2])
    settingMenu.add(self.colorMenu)
    
    
    #-- selector widget --------------   
    toolbar = JToolBar()
    toolbar.setFloatable(0)
    bg = ButtonGroup()
    
    class Toggle(HAction):
      def __init__(self, listeners, actionCommand, icon, tooltip, parent):
        HAction.__init__(self, listeners, actionCommand, icon, tooltip)
        self.parent = parent
       
          
      def selected(self, leftFunc):      
        self.parent.mHelper.setFunctionMap([[[MouseHelper.DIRECT, MouseHelper.ZOOM],
                                      [MouseHelper.TRANSLATE, MouseHelper.NONE]],
                                     [[MouseHelper.CURSOR_TRANSLATE, MouseHelper.CURSOR_ZOOM],
                                      [MouseHelper.CURSOR_ROTATE, MouseHelper.NONE]],
                                     [[MouseHelper.DIRECT, MouseHelper.DIRECT],
                                      [MouseHelper.DIRECT, MouseHelper.DIRECT]]])
        cmd = self.actionCommand
        select_index = int(cmd)
        self.parent.select_index = select_index
        if self.enabled == 1:
          for i in xrange(len(self.parent.caller.resultDisplayList)):
            self.parent.caller.resultDisplayList[i].clear(select_index)
          for i in xrange(len(self.parent.caller.scatterDisplayList)):
            self.parent.caller.scatterDisplayList[i].clearScatter(select_index)
        for i in xrange(self.parent.n_selectors):
          if i == select_index:
            if self.parent.boxSelected == true:
              self.parent.rbbrj3d_s[i].active = true
              self.parent.dsp.toggle(self.parent.crvRef_s[i], false)
            if self.parent.curveSelected == true:
              self.parent.dsp.toggle(self.parent.crvRef_s[i], true)
              self.parent.rbbrj3d_s[i].active = false
          else:
            self.parent.rbbrj3d_s[i].active = false
            self.parent.dsp.toggle(self.parent.crvRef_s[i], false)
        self.enabled = 1
        
      def deselected(self):
        self.enabled = 0
    
        
    for i in xrange(self.n_selectors):
      self.viewToolBar.addHAction(Toggle([self.dsp], str(i), "./ui/icons/rubber_band.gif", "select pixels", self))
             
    xb = JRadioButton("box", actionPerformed=self.selectBox)
    xb.setSelected(true)
    yb = JRadioButton("curve", actionPerformed=self.selectCurve)
    bg = ButtonGroup()
    bg.add(xb)
    bg.add(yb)
    sp = JPanel()
    sp.setLayout(FlowLayout())
    sp.add(xb)
    sp.add(yb)
    sp0 = JPanel()
    sp0.setLayout(FlowLayout())
    sp0.add(toolbar)
    sp0.add(sp)
    
    southPanel.add(sp0)
    
    
    framePane.add(southPanel, BorderLayout.SOUTH)
    
    frame.setSize(500,500)
    frame.pack()
    frame.show()
     
    
    self.resultStr  = ns
    self.chValStr   = chStr
    self.values     = values
    self.vminmaxbig = vminmaxbig
    
    self.caller.resultDisplayList.append(self)
    ResultDisplay.count += 1

    
  def setSelectedIndex(self,event):
    cmd = event.getActionCommand()
    self.select_index = int(cmd)
    for i in xrange(self.n_selectors):
      if i == self.select_index:
        if self.boxSelected == true:
          self.rbbrj3d_s[i].active = true
          self.dsp.toggle(self.crvRef_s[i], false)
        if self.curveSelected == true:
          self.dsp.toggle(self.crvRef_s[i], true)
          self.rbbrj3d_s[i].active = false
      else:
        self.rbbrj3d_s[i].active = false
        self.dsp.toggle(self.crvRef_s[i], false)
    
  def selectBox(self, event):
    self.boxSelected   = true
    self.curveSelected = false
    for i in xrange(self.n_selectors):
      self.dsp.toggle(self.crvRef_s[i], false)
    self.rbbrj3d_s[self.select_index].active = true
    
  def selectCurve(self, event):
    self.boxSelected   = false
    self.curveSelected = true
    for i in xrange(self.n_selectors):
      self.rbbrj3d_s[i].active = false
    self.dsp.toggle(self.crvRef_s[self.select_index], true)
  
  def selectX(self, event):
    self_idx = self.caller.resultDisplayList.index(self)
    for i in range(len(self.caller.resultDisplayList)):
      rr = self.caller.resultDisplayList[i]
      if (i != self_idx):        
        self.caller.resultDisplayList[i].xb.setSelected(false)
      else:
        if rr.yb.isSelected():
          rr.yb.setSelected(false)
          self.caller.setY(None)
    self.caller.setX(self)
    
  def selectY(self, event):
    self_idx = self.caller.resultDisplayList.index(self)
    for i in range(len(self.caller.resultDisplayList)):
      rr = self.caller.resultDisplayList[i]
      if (i != self_idx):
        self.caller.resultDisplayList[i].yb.setSelected(false)
      else:
        if rr.xb.isSelected():
          rr.xb.setSelected(false)
          self.caller.setX(None)
    self.caller.setY(self)
    
  def toggleMask(self, event):
    if (self.togIndex == 0):
      self.mask_vals = Helper.unpackFloats(self.result, false)
      self.result.setSamples(self.values, false)
    if (self.togIndex == 1):
      self.result.setSamples(self.mask_vals, false)
    self.mskToggleBttn.setText(self.togText[self.lastTogIndex])
    tmp = self.togIndex
    self.togIndex = self.lastTogIndex
    self.lastTogIndex = tmp
    
  def doSetColorRange(self,event):
    dragHistLocationColorFunction(self.maps[2], self.resultCopy, self.vminmaxbig, self.ct, self.colorMenu)
    
  def captureDisplay(self,event):
    Helper.saveDisplay(self.dsp, JFrame().getContentPane())
    
  def clear(self, select_index):
    self.crvRef_s[select_index].setData(UnionSet([self.noSet]))
    self.last_crvRef_s[select_index].setData(UnionSet([self.noSet]))
    self.rbbrj3d_s[select_index].removeLastBox()
  
  def boxUpdate(self,line,elem):
    for i in range(len(self.caller.scatterDisplayList)):
      self.caller.scatterDisplayList[i].markScatterPoints(line, elem, self.select_index)
      #--- keep last box stuff
      self_idx = self.caller.resultDisplayList.index(self)
      for i in range(len(self.caller.resultDisplayList)):
        self.caller.resultDisplayList[i].crvRef_s[self.select_index].setData(UnionSet([self.caller.resultDisplayList[i].noSet]))
        self.caller.resultDisplayList[i].last_crvRef_s[self.select_index].setData(UnionSet([self.caller.resultDisplayList[i].noSet]))
        if (i != self_idx):
          self.caller.resultDisplayList[i].rbbrj3d_s[self.select_index].setLastBox(self.caller.resultDisplayList[self_idx].rbbrj3d_s[self.select_index])  
                    
  def subsetByCurve(self, event):
    if ((event.getId() == DisplayEvent.MOUSE_RELEASED_RIGHT or event.getId() == DisplayEvent.MOUSE_RELEASED_LEFT) and self.curveSelected == true):
      uset  = self.crvRef_s[self.select_index].getData()
      sets  = uset.getSets()
      s_idx = len(sets) - 1
      self.crvRef_s[self.select_index].setData(UnionSet([sets[s_idx]]))
      self.last_crvRef_s[self.select_index].setData(UnionSet([sets[s_idx]]))
      cs   = self.result.getType().getDomain().getCoordinateSystem()
      crv  = cs.fromReference(sets[s_idx].getSamples())
      dset = self.result.getDomainSet()
      lens = dset.getLengths()
      onImage = [[], []]
      for i in range(len(crv[0])):
        if ((crv[0][i] >= 0 and crv[0][i] < lens[0]) and (crv[1][i] >= 0 and crv[1][i] < lens[1])):
          onImage[0].append(crv[0][i])
          onImage[1].append(crv[1][i])
      
      if (len(onImage[0]) == 0):
        return
        
      lineLo = int(round(min(onImage[0])))
      lineHi = int(round(max(onImage[0])))
      elemLo = int(round(min(onImage[1])))
      elemHi = int(round(max(onImage[1])))
      
      insideCurve = [[], []]
      for j in range(elemHi - elemLo):
        for i in range(lineHi - lineLo):
           x = i + lineLo
           y = j + elemLo
           if DelaunayCustom.inside(crv, x, y):
             insideCurve[0].append(x)
             insideCurve[1].append(y)
      sc_list = self.caller.scatterDisplayList
      for i in range(len(sc_list)):
        sc_list[i].markScatterPointsByCurve(insideCurve[0], insideCurve[1], self.select_index)

      #-- copy to other result displays
      rd_list = self.caller.resultDisplayList
      self_idx = rd_list.index(self)
      for i in range(len(rd_list)):
        rd_list[i].rbbrj3d_s[self.select_index].removeLastBox()
        if (i != self_idx):
          rd_list[i].crvRef_s[self.select_index].setData(UnionSet([sets[s_idx]]))       
          rd_list[i].last_crvRef_s[self.select_index].setData(UnionSet([sets[s_idx]]))
              
  def windowClose(self, event):
    if self.xb.isSelected():
      self.caller.setX(None)      
    if self.yb.isSelected():
      self.caller.setY(None)

    self.frame.dispose()
    self.caller.resultDisplayList.remove(self)
    runtime.gc()

    
#-------------------------------------------------------------------------------------    
    
class OperMenu(JComboBox):
  def __init__(self, pair):
    self.items = ["+","-","/","*"," "]
    JComboBox.__init__(self, self.items)
    self.pair = pair
    self.setSelectedIndex(self.items.index(self.pair.operator)) # do this before next line :)
    self.addActionListener(self)
       
  def actionPerformed(self, event):
    self.operator      = self.getSelectedItem()
    self.pair.operator = self.operator    
    if (self.operator != " "):
      self.pair.rightEnable(1)
    else:
      self.pair.rightEnable(0)
      
  def toString(self):
    return self.operator
    

"""             
class OperMenu:
  def __init__(self, pair):
    self.operMenu = JMenuBar()
    self.jm       = JMenu()
    self.operator = pair.operator
    self.jm.setLabel(self.operator)
    self.jm.add(JMenuItem("+", actionPerformed=self.operatorSelected))
    self.jm.add(JMenuItem("-", actionPerformed=self.operatorSelected))
    self.jm.add(JMenuItem("/", actionPerformed=self.operatorSelected))
    self.jm.add(JMenuItem("*", actionPerformed=self.operatorSelected))
    self.jm.add(JMenuItem(" ", actionPerformed=self.operatorSelected))
    self.operMenu.add(self.jm)
    self.pair = pair
   
  def operatorSelected(self,event):
    self.operator = event.getActionCommand()
    self.jm.setLabel(self.operator)   
    self.pair.operator = self.operator
    if (self.operator != " "):
      self.pair.rightEnable(1)
    else:
      self.pair.rightEnable(0)
      
  def getComponent(self):
    return self.operMenu
    
  def toString(self):
    return self.operator
"""    
   
class OperationPair:
  def __init__(self, leftInit, leftSelectRef, rghtInit, rghtSelectRef, leftOn ,rghtOn, lcolor, rcolor, clc):
    self.rghtValue        = '%7.1f' % rghtInit
    self.leftValue        = '%7.1f' % leftInit
    self.leftValueDefault = '%7.1f' % leftInit
    self.rghtValueDefault = '%7.1f' % rghtInit
    self.operMenu         = None
    self.leftTextField    = None
    self.rightTextField   = None
    self.operator         = "-"
    self.leftSelectRef    = leftSelectRef
    self.rghtSelectRef    = rghtSelectRef
    self.clc              = clc
    
    self.leftOn   = leftOn
    self.rghtOn   = rghtOn
    if (self.leftOn == 1 and self.rghtOn == 1):
      self.operator = "-"
    elif (self.rghtOn == 0 and self.leftOn == 0):
      self.operator = " "
      self.leftValue = "--------"
      self.rghtValue = "--------"
      
    self.mainPanel = JPanel()
    self.mainPanel.setLayout(FlowLayout())
    self.operMenu = OperMenu(self)

    sp = JPanel()
    jl = JLabel("(")
    sp.add(jl)
    self.mainPanel.add(sp)
    
    leftTxt = self.leftValue
    if (self.leftOn == 0):
      leftTxt = "--------"
    sp = JPanel()
    self.leftTextField = JTextField(leftTxt, actionPerformed=self.leftOperand)
    self.leftTextField.setBorder(LineBorder(lcolor, 2))
    sp.add(self.leftTextField)
    self.mainPanel.add(sp)

    sp = JPanel()
    #sp.add(self.operMenu.getComponent())
    sp.add(self.operMenu)
    self.mainPanel.add(sp)

    rghtTxt = self.rghtValue
    if (self.rghtOn == 0):
      rghtTxt = "--------"
    sp = JPanel()
    self.rightTextField = JTextField(rghtTxt, actionPerformed=self.rightOperand)
    self.rightTextField.setBorder(LineBorder(rcolor, 2))
    sp.add(self.rightTextField)
    self.mainPanel.add(sp)

    sp = JPanel()
    jl = JLabel(")")
    sp.add(jl)
    self.mainPanel.add(sp)
       
  def leftOperand(self, event):
    txt = self.leftTextField.getText()
    val = float(txt)
    nval = (self.clc.filereader.observationDomain.indexToValue(self.clc.filereader.observationDomain.valueToIndex([[val]])))[0][0]
    self.leftValue = '%7.1f' % nval    
    type = self.leftSelectRef.getData().getType()
    self.leftSelectRef.setData(Real(type, nval))
    
  def setLeft(self, txt):
    self.leftTextField.setText(txt)
    
    
  def rightOperand(self, event):
    txt = self.rightTextField.getText()
    val = float(txt)
    nval = (self.clc.filereader.observationDomain.indexToValue(self.clc.filereader.observationDomain.valueToIndex([[val]])))[0][0]
    self.rghtValue = '%7.1f' % nval
    type = self.rghtSelectRef.getData().getType()
    self.rghtSelectRef.setData(Real(type, nval))
  
  def setRight(self, txt):
    self.rightTextField.setText(txt)
    
    
  def getComponent(self):
    return self.mainPanel
    
  def evaluate(self):
    if (self.leftOn == 1 and self.rghtOn == 1):
      val = float(self.rightTextField.getText())
      rdata = self.clc.getOperandData(val)
      val = float(self.leftTextField.getText())
      ldata = self.clc.getOperandData(val)
      if self.operator == "+":
        result = rdata.add(ldata)
      if self.operator == "-":
        result = ldata.subtract(rdata)
      if self.operator == "/":
        result = ldata.divide(rdata)
        result = result.changeMathType(ldata.getType())
      if self.operator == "*":
        result = rdata.multiply(ldata)
    elif (self.leftOn == 1 and self.rghtOn == 0):
      val = float(self.leftTextField.getText())
      ldata = self.clc.getOperandData(val)      
      result = ldata
    elif (self.leftOn == 0 and self.rghtOn == 1):
      val = float(self.rightTextField.getText())
      rdata = self.clc.getOperandData(val)      
      result = rdata
    else:
      result = None
      
    return result
    
  def rightEnable(self, rghtOn):
    self.rghtOn = rghtOn
    if (self.rghtOn == 1):
      type = self.rghtSelectRef.getData().getType()
      self.rghtSelectRef.setData(Real(type, float(self.rghtValueDefault)))
      Delay() 
      self.rightTextField.setText(self.rghtValueDefault)
    if (self.rghtOn == 0):
      type = self.rghtSelectRef.getData().getType()
      self.rghtSelectRef.setData(Real(type, -3000))
      Delay() 
      self.rightTextField.setText("--------")
      
      
  def leftEnable(self, leftOn):
    self.leftOn = leftOn
    if (self.leftOn == 1):
      type = self.leftSelectRef.getData().getType()
      self.leftSelectRef.setData(Real(type, float(self.leftValueDefault)))
      Delay() 
      self.leftTextField.setText(self.leftValueDefault)
    if (self.leftOn == 0):
      type = self.leftSelectRef.getData().getType()
      self.leftSelectRef.setData(Real(type, -3000))
      Delay() 
      self.leftTextField.setText("--------")
      
  def toString(self):
    if self.rghtOn == 1:
      return "("+self.leftTextField.getText()+self.operator+self.rightTextField.getText()+")"
    if self.rghtOn == 0:
      return "("+self.leftTextField.getText()+")"
      
  def lockout(self, lock):  #- nop
    pass

       
class Operation:
  def __init__(self, left, rght):
    self.left     = left
    self.rght     = rght
    self.operator = " "
    self.mainPanel = JPanel()
    self.mainPanel.setLayout(FlowLayout())   
    self.operMenu = OperMenu(self)
    self.leftOn = 1
    self.rghtOn = 0
    
    sp = JPanel()
    jl = JLabel("(")
    sp.add(jl)
    
    sp = JPanel()
    sp.add(left.getComponent())
    self.mainPanel.add(sp)
    
    sp = JPanel()
    #sp.add(self.operMenu.getComponent())
    sp.add(self.operMenu)
    self.mainPanel.add(sp)
    
    sp = JPanel()
    sp.add(rght.getComponent())
    self.mainPanel.add(sp)
    
    sp = JPanel()
    jl = JLabel(")")
    sp.add(jl)
    
  def getComponent(self):
    return self.mainPanel
    
  def evaluate(self):
    if self.operator == "+":
      result = (self.rght.evaluate()).add(self.left.evaluate())
    if self.operator == "-":
      result = (self.left.evaluate()).subtract(self.rght.evaluate())
    if self.operator == "/":
      r1 = self.left.evaluate()
      r2 = self.rght.evaluate()
      result = r1.divide(r2)
      result = result.changeMathType(r1.getType())
    if self.operator == " ":
      result = self.left.evaluate()
        
    return result
    
  def rightEnable(self, rghtOn):
    self.rghtOn = rghtOn
    if rghtOn == 1:
      self.rght.leftEnable(rghtOn)
    if rghtOn == 0:
      self.rght.leftEnable(rghtOn)
      self.rght.rightEnable(rghtOn)
    
  def toString(self):
    if self.rghtOn == 1:
      return self.left.toString()+self.operator+self.rght.toString()
    if self.rghtOn == 0:
      return self.left.toString()
      
      
      
      
class OperationPairPullDown:
  def __init__(self, leftInit, leftSelectRef, rghtInit, rghtSelectRef, leftOn ,rghtOn, lcolor, rcolor, clc):
    self.rghtValue        = '%5f' % rghtInit
    self.leftValue        = '%5f' % leftInit
    self.leftValueDefault = '%5f' % leftInit
    self.rghtValueDefault = '%5f' % rghtInit
    self.operMenu         = None
    self.leftTextField    = None
    self.rightTextField   = None
    self.operator         = "-"
    self.leftSelectRef    = leftSelectRef
    self.rghtSelectRef    = rghtSelectRef
    self.clc              = clc
    
    self.leftOn   = leftOn
    self.rghtOn   = rghtOn
    if (self.leftOn == 1 and self.rghtOn == 1):
      self.operator = "-"
    elif (self.rghtOn == 0 and self.leftOn == 0):
      self.operator = " "
      self.leftValue = "----"
      self.rghtValue = "----"
      
    self.mainPanel = JPanel()
    self.mainPanel.setLayout(FlowLayout())
    self.operMenu = OperMenu(self)

    sp = JPanel()
    jl = JLabel("(")
    sp.add(jl)
    self.mainPanel.add(sp)
    
    leftTxt = self.leftValue
    if (self.leftOn == 0):
      leftTxt = "----"
    sp = JPanel()
    
    band_numbers = []
    band_numbers.append("----")
    for i in xrange(len(self.clc.filereader.band_numbers)):
      band_numbers.append(self.clc.filereader.band_numbers[i])
    self.leftTextField = JComboBox(band_numbers)
    
    class c1(java.awt.event.ActionListener):
      def __init__(self, filereader, comboBox, selectRef):
        self.filereader = filereader
        self.comboBox = comboBox
        self.selectRef = selectRef
        self.last_item = None
        self.lock_out  = 0
          
      def actionPerformed(self,event):
        item = self.comboBox.getSelectedItem()
        if item == "----":
          pass
        else:
          val = self.filereader.bandNameToValue(item)   
          nval = (self.filereader.observationDomain.indexToValue(self.filereader.observationDomain.valueToIndex([[val]])))[0][0]
          self.leftValue = '%5f' % nval    
          type = self.selectRef.getData().getType()
          if self.lock_out == 0:
            self.selectRef.setData(Real(type, nval))
          
    self.leftListener = c1(self.clc.filereader, self.leftTextField, self.leftSelectRef)
          
    self.leftTextField.addActionListener(self.leftListener)
      
    self.leftTextField.setBorder(LineBorder(lcolor, 2))
    sp.add(self.leftTextField)
    self.mainPanel.add(sp)

    sp = JPanel()
    #sp.add(self.operMenu.getComponent())
    sp.add(self.operMenu)
    self.mainPanel.add(sp)

    rghtTxt = self.rghtValue
    if (self.rghtOn == 0):
      rghtTxt = "----"
    sp = JPanel()
    self.rightTextField = JComboBox(band_numbers)
    
    class c2(java.awt.event.ActionListener):
      def __init__(self, filereader, comboBox, selectRef):
        self.filereader = filereader
        self.comboBox = comboBox
        self.selectRef = selectRef
        self.last_item = None
        self.lock_out  = 0
          
      def actionPerformed(self,event):
        item = self.comboBox.getSelectedItem() 
        if item == "----":
          pass
        else:
          val = self.filereader.bandNameToValue(item)    
          nval = (self.filereader.observationDomain.indexToValue(self.filereader.observationDomain.valueToIndex([[val]])))[0][0]
          self.rghtValue = '%5f' % nval
          type = self.selectRef.getData().getType()
          if self.lock_out == 0:
            self.selectRef.setData(Real(type, nval))
    
    self.rightListener = c2(self.clc.filereader, self.rightTextField, self.rghtSelectRef)      
    self.rightTextField.addActionListener(self.rightListener)
    
    self.rightTextField.setBorder(LineBorder(rcolor, 2))
    sp.add(self.rightTextField)
    self.mainPanel.add(sp)

    sp = JPanel()
    jl = JLabel(")")
    sp.add(jl)
    self.mainPanel.add(sp)
    
  def lockout(self, lock):
    self.leftListener.lock_out = lock
    self.rightListener.lock_out = lock

  
  def getComponent(self):
    return self.mainPanel
    
  def evaluate(self):
    if (self.leftOn == 1 and self.rghtOn == 1):
      val = self.clc.filereader.bandNameToValue(self.rightTextField.getSelectedItem())
      rdata = self.clc.getOperandData(val)
      val = self.clc.filereader.bandNameToValue(self.leftTextField.getSelectedItem())
      ldata = self.clc.getOperandData(val)
      if self.operator == "+":
        result = rdata.add(ldata)
      if self.operator == "-":
        result = ldata.subtract(rdata)
      if self.operator == "/":
        result = ldata.divide(rdata)
        result = result.changeMathType(ldata.getType())
      if self.operator == "*":
        result = rdata.multiply(ldata)
    elif (self.leftOn == 1 and self.rghtOn == 0):
      val = self.clc.filereader.bandNameToValue(self.leftTextField.getSelectedItem())
      ldata = self.clc.getOperandData(val)      
      result = ldata
    elif (self.leftOn == 0 and self.rghtOn == 1):
      val = float(self.rightTextField.getText())
      val = self.clc.filereader.bandNameToValue(self.rightTextField.getSelectedItem())
      rdata = self.clc.getOperandData(val)      
      result = rdata
    else:
      result = None
      
    return result
    
  def rightEnable(self, rghtOn):
    self.rghtOn = rghtOn
    if (self.rghtOn == 1):
      type = self.rghtSelectRef.getData().getType()
      self.rghtSelectRef.setData(Real(type, float(self.rghtValueDefault)))
    if (self.rghtOn == 0):
      type = self.rghtSelectRef.getData().getType()
      self.rghtSelectRef.setData(Real(type, -3000))
      
      
  def leftEnable(self, leftOn):
    self.leftOn = leftOn
    if (self.leftOn == 1):
      type = self.leftSelectRef.getData().getType()
      self.leftSelectRef.setData(Real(type, float(self.leftValueDefault)))
    if (self.leftOn == 0):
      type = self.leftSelectRef.getData().getType()
      self.leftSelectRef.setData(Real(type, -3000))
      
  def setLeft(self, txt):
    if txt == "--------":
      pass
      self.leftTextField.setSelectedIndex(0)
    else:
      val = float(txt)
      self.leftTextField.setSelectedItem(self.clc.filereader.bandValueToName(val))
    
  def setRight(self, txt):
    if txt == "--------":
      pass
      self.rightTextField.setSelectedIndex(0)
    else:
      val = float(txt)
      self.rightTextField.setSelectedItem(self.clc.filereader.bandValueToName(val))
      
  def toString(self):
    if self.rghtOn == 1:
      return "("+self.leftTextField.getSelectedItem()+self.operator+self.rightTextField.getSelectedItem()+")"
    if self.rghtOn == 0:
      return "("+self.leftTextField.getSelectedItem()+")"
