import sys
import java
sys.path.append('./multispectral/Lib')
sys.path.append('./multispectral/Lib/file')
from visad.python.JPythonMethods import *
import visad
import ucar
import graph
import subs
import jarray
from visad import RealType, RealTupleType, FunctionType, FlatField, Gridded1DSet, Gridded2DSet, GridCoordinateSystem, Data
from javax.swing import *
from java.awt import BorderLayout,GridLayout,FlowLayout,Color,Cursor, Toolkit, Dimension, Font
from java.awt.event import ActionEvent
from visad import Real, RealTuple, FieldImpl, Tuple, TupleType, TextType, Text, TextControl
from visad.bom import ImageRendererJ3D
from java.lang import Double, String, Float, Runtime
from visad import DisplayListener, DisplayEvent
#-- linear combination of channels
import channelLinearCombine
from channelLinearCombine import ChannelLinearCombo
import transect
from histostretch import dragHistLocation
from util import Helper, ScalarMapSyncher

false = 0
true  = 1

toolkit = Toolkit.getDefaultToolkit()

screen_size = toolkit.getScreenSize()
runtime = Runtime.getRuntime()
import hydra_properties

class acViewer:

   
  # changeImage is called when the user moves the spectra marker.
  # This method is used to change the image that is shown
  # you pass in a 'value' which is a Wave Number, and it
  # computes the wave number index, and calls 'getImage()' 

  def changeImage(self,observationChannel,dum_value):
    if observationChannel >= self.observationChannelsInstrumentMX[0] and observationChannel <= self.observationChannelsInstrumentMX[1]:  # in case their missing
      # get the range and make a new line...
      self.selChannel = observationChannel
      spectralIndex   = self.ad.observationDomain.valueToIndex([[observationChannel],])[0]
      self.channelIndex = spectralIndex
      if (self.last_spectralIndex != spectralIndex):
        self.last_spectralIndex = spectralIndex
    
        updown = self.maps2[1].getRange() # get the range of radiance values
        updown[0] = self.y0
        updown[1] = self.y1
        y_scalar = self.maps2[1].getScalar()
        x = self.ad.observationDomain.indexToValue([spectralIndex])
        pts = subs.makeLine( 
              #(self.observationChannelsInstrument,self.observationsInstrument) , ((observationChannel,observationChannel),(updown[0],updown[1])) )
              (self.observationChannelsInstrument,y_scalar) , ((x[0][0],x[0][0]),(updown[0],updown[1])) )
        self.lref.setData(pts)
      
        # compute the index (wnIndx) corresponding to the observationChannelsumber
        #print 'SpectralIndex',spectralIndex
        #print 'StartLine-EndLine',startLine[0],endLine[0]
       
        self.rgbMap.resetAutoScale()
        self.d.reAutoScale()
        self.frame.setCursor(3)
        syncher = ScalarMapSyncher(self.rgbMap)
        self.ad.getSameImageSegment(spectralIndex)
        self.frame.setCursor(0)
    
        syncher.waitForEvent()
        #set the channel string for the middle panel
        #-test self.instrumentString1.setText('Channel: %-6.2f  [cm^-1]' % (self.ad.observationChannels[spectralIndex]))
        self.instrumentString1.setText( '%-6.2f' % (self.ad.observationChannels[spectralIndex]))
        
        if self.ad.instrumentName == "MODIS":
          self.bandNumberText.setSelectedIndex(self.ad.fileIndexes[spectralIndex])
          if self.ad.fileIndexes[spectralIndex] <= 21 and self.colorMenu.current == "inv-grey":
            self.colorMenu.scaleSelect(ActionEvent(self,ActionEvent.ACTION_PERFORMED,"grey    "))
          elif self.ad.fileIndexes[spectralIndex] > 21 and self.colorMenu.current == "grey    ":
            self.colorMenu.scaleSelect(ActionEvent(self,ActionEvent.ACTION_PERFORMED,"inv-grey"))
            
        if self.ad.instrumentName == "MSG":
          self.bandNumberText.setSelectedIndex(self.ad.fileIndexes[spectralIndex])
          if self.ad.fileIndexes[spectralIndex] <= 2 and self.colorMenu.current == "inv-grey":
            self.colorMenu.scaleSelect(ActionEvent(self,ActionEvent.ACTION_PERFORMED,"grey    "))
          elif self.ad.fileIndexes[spectralIndex] > 2 and self.colorMenu.current == "grey    ":
            self.colorMenu.scaleSelect(ActionEvent(self,ActionEvent.ACTION_PERFORMED,"inv-grey"))
        
        minTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, self.ad.obsMin[0]), Real(self.obsLongitudeInstrument, self.ad.obsMin[1]), Text(self.text, '   %-6.2f' % self.ad.obsMin[2])])
        minMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument, self.ad.obsMin[0]), Real(self.obsLongitudeInstrument, self.ad.obsMin[1])], None)
        self.minRef.setData(minTuple)
        self.minMarkRef.setData(minMark)
        maxMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument, self.ad.obsMax[0]), Real(self.obsLongitudeInstrument, self.ad.obsMax[1])], None)
        maxTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, self.ad.obsMax[0]), Real(self.obsLongitudeInstrument, self.ad.obsMax[1]), Text(self.text, '   %-6.2f' % self.ad.obsMax[2])])
        self.maxRef.setData(maxTuple)
        self.maxMarkRef.setData(maxMark)
        
        tup = self.roamTextRef.getData()
        tup_type = tup.getType()
        c0 = tup.getComponent(0)
        c1 = tup.getComponent(1)
        val = self.ad.getImageValue(c0.getValue(),c1.getValue()).getValue()
        new_tup = Tuple(tup_type, [c0, c1, Text(self.text, '   %-6.2f' % val)])
        self.roamTextRef.setData(new_tup)
        
        ll = self.ad.cs.toReference([[self.currentLine],[self.currentElem]])
        lat = ll[0][0]
        lon = ll[1][0]
        val = self.ad.imageField.evaluate(RealTuple(self.ad.imageField.getType().getDomain().getCoordinateSystem().getReference(), [lat, lon]), Data.NEAREST_NEIGHBOR, Data.NO_ERRORS)             
        strg='Lat = %-6.2f  Lon = %-7.2f     Val = %-6.2f  ' % (lat, lon, val)
        strg = strg+self.ad.imageRangeUnit.toString()
        self.latLonStringInstrument.setText(strg)
        
# changeSpectra is called when the user moves the spot around
# on the image, indicating to read a new spectra.
# This method is used to get a Spectra and also move the
# little marker in the image.

  def changeSpectra(self,lon,lat):
    #if x > 0 and x < ad.numObsElements and y > 0 and y < ad.numObsLines: 
    self.shapes.moveShape(self.shapeMarkerIndex,(lon,lat))
    if self.ad.cs != None:
      xy = self.ad.cs.fromReference([[lat,],[lon,]])
      numLine = xy[0][0]
      numElem = xy[1][0]
        
      imageDomain = self.ad.imageField.getDomainSet()
      lens = imageDomain.getLengths()
      dim = len(lens)
      idx = imageDomain.valueToIndex([[numLine], [numElem]])[0]
      grid = []

      k = idx;
      for j in xrange(dim-1):
        grid.append( k % lens[j]);
        k = k / lens[j];
      grid.append(k)

      numLine = int(grid[0])
      numElem = int(grid[1])
 
      if numLine >= 0 and numLine < self.dimInstrument[0] and numElem >= 0 and numElem < self.dimInstrument[1]:
        self.currentLine = numLine
        self.currentElem = numElem
        self.frame.setCursor(3)
        self.ad.getObservations(numLine,numElem)
        self.frame.setCursor(0)
        
        val = self.ad.imageField.evaluate(RealTuple(self.ad.imageField.getType().getDomain().getCoordinateSystem().getReference(), [lat, lon]), Data.NEAREST_NEIGHBOR, Data.NO_ERRORS)             
        strg='Lat = %-6.2f  Lon = %-7.2f     Val = %-6.2f  ' % (lat, lon, val)
        strg = strg+self.ad.imageRangeUnit.toString()
        tt = self.ad.getTimeObs(numLine,numElem)
        strgTime = ""
        if tt != None:
          strgTime='Time = %-6.2f [offset (s)]' % (tt)
        strgFOV = ""
        ff = self.ad.getFOVangleObs(numLine,numElem)
        if ff != None:
          strgFOV='FOV angle = %-6.2f [degrees]' % (ff)
      else:
        strg='Lat = %-6.2f  Lon = %-7.2f not in swath' % (lat, lon)
        strgTime='Time not available'
        strgFOV='FOV angle not defined'
 
      self.latLonStringInstrument.setText(strg)
      self.timeStringInstrument.setText(strgTime)
      self.FOVangleStringInstrument.setText(strgFOV)
      self.roamTextRef.setData(Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, Float.NaN), Real(self.obsLongitudeInstrument, Float.NaN), Text(self.text, '   %-6.2f' % Float.NaN)]))

     
  def sliderchanged(self,event):
    if self.slider.getValueIsAdjusting(): return
    seg=int(self.slider.getValue())

    if (seg != self.selSegment):
      self.selSegment = seg
      self.frame.setCursor(3)
      self.obs=self.ad.getImageSegment(self.channel,self.selSegment)
      self.frame.setCursor(0)
      self.rgbMap.resetAutoScale()
      self.d.reAutoScale()
      self.refToImage.setData(self.obs)
  
  
      dimInstrumentDom=self.obs.getDomainSet()
      self.dimInstrument=dimInstrumentDom.getLengths()
      #-self.dimInstrument=dimInstrumentDom.getHi()
  
      ll0=self.ad.cs.toReference([[0],[0]])
      ll1=self.ad.cs.toReference([[0],[self.dimInstrument[1]-1]])
      ll2=self.ad.cs.toReference([[self.dimInstrument[0]-1],[self.dimInstrument[1]-1]])
      ll3=self.ad.cs.toReference([[self.dimInstrument[0]-1],[0]])
    
      self.changeSpectra(ll0[1][0],ll0[0][0])
      
      strg='Lat = %-6.2f  Lon = %-7.2f' % (ll0[0][0], ll0[1][0])
      self.latLonStringInstrument.setText(strg)
    
      tt = self.ad.getTimeObs(0,0)
      strgTime = ""
      if tt != None:
        strgTime='Time = %-6.2f [offset (s)]' % (tt)
      self.timeStringInstrument.setText(strgTime)
      
      ff = self.ad.getFOVangleObs(0,0)
      strgFOV = ""
      if ff != None:
        strgFOV='FOV angle = %-6.2f [degrees]' % (ff)
      self.FOVangleStringInstrument.setText(strgFOV)

      minTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, self.ad.obsMin[0]), Real(self.obsLongitudeInstrument, self.ad.obsMin[1]), Text(self.text, '   %-6.2f' % self.ad.obsMin[2])])
      minMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument,
self.ad.obsMin[0]), Real(self.obsLongitudeInstrument, self.ad.obsMin[1])], None)
      self.minRef.setData(minTuple)
      self.minMarkRef.setData(minMark)
      maxMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument,
self.ad.obsMax[0]), Real(self.obsLongitudeInstrument, self.ad.obsMax[1])], None)
      maxTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, self.ad.obsMax[0]), Real(self.obsLongitudeInstrument, self.ad.obsMax[1]), Text(self.text, '   %-6.2f' % self.ad.obsMax[2])])
      self.maxRef.setData(maxTuple)
      self.maxMarkRef.setData(maxMark)

      
  def changeSubset(self, subset):
    self.frame.setCursor(3)
    self.obs = self.ad.getImageSegment(self.channelIndex,self.selSegment,subset)
    self.rgbMap.resetAutoScale()
    self.d.reAutoScale()
    self.refToImage.setData(self.obs)
    
    obsLonMinMax = Helper.minmax(self.ad.lons, -180, 180)
    obsLatMinMax = Helper.minmax(self.ad.lats, -90, 90)
    
    londiff = obsLonMinMax[1] - obsLonMinMax[0]
    latdiff = obsLatMinMax[1] - obsLatMinMax[0]
    if londiff >= latdiff:
      lon_low = obsLonMinMax[0]
      lon_hi  = obsLonMinMax[1]
      lat_low = obsLatMinMax[0]
      lat_hi  = lat_low + londiff
    else:
      lat_low = obsLatMinMax[0]
      lat_hi  = obsLatMinMax[1]
      lon_low = obsLonMinMax[0]
      lon_hi  = lon_low + latdiff
    self.proj_cntrl.setMatrix(self.init_matrix)
    self.maps[0].setRange(lon_low, lon_hi)
    self.maps[1].setRange(lat_low, lat_hi)

    dimInstrumentDom=self.obs.getDomainSet()
    self.dimInstrument=dimInstrumentDom.getLengths()
    #-self.dimInstrument=dimInstrumentDom.getHi()

    ll0=self.ad.cs.toReference([[0],[0]])

    self.changeSpectra(ll0[1][0],ll0[0][0])

    strg='Lat = %-6.2f  Lon = %-7.2f' % (ll0[0][0], ll0[1][0])
    self.latLonStringInstrument.setText(strg)

    tt = self.ad.getTimeObs(0,0)
    strgTime = ""
    if tt != None:
      strgTime='Time = %-6.2f [offset (s)]' % (tt)
    self.timeStringInstrument.setText(strgTime)

    ff = self.ad.getFOVangleObs(0,0)
    strgFOV = ""
    if ff != None:
      strgFOV='FOV angle = %-6.2f [degrees]' % (ff)
    self.FOVangleStringInstrument.setText(strgFOV)
    self.frame.setCursor(0)
  
    minTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, self.ad.obsMin[0]), Real(self.obsLongitudeInstrument, self.ad.obsMin[1]), Text(self.text, '   %-6.2f' % self.ad.obsMin[2])])
    minMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument, self.ad.obsMin[0]), Real(self.obsLongitudeInstrument, self.ad.obsMin[1])], None)
    self.minRef.setData(minTuple)
    self.minMarkRef.setData(minMark)
    maxMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument, self.ad.obsMax[0]), Real(self.obsLongitudeInstrument, self.ad.obsMax[1])], None)
    maxTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, self.ad.obsMax[0]), Real(self.obsLongitudeInstrument, self.ad.obsMax[1]), Text(self.text, '   %-6.2f' % self.ad.obsMax[2])])
    self.maxRef.setData(maxTuple)
    self.maxMarkRef.setData(maxMark)

  from java.lang import Double
  from visad import DisplayListener, DisplayEvent

  class linkHistLocation(DisplayListener):
    def __init__(self, display, scalar):
      self.x, self.y, self.z, self.display=subs.getDisplayMaps(display)
      self.dr = self.display.getDisplayRenderer()
      self.display.addDisplayListener(self)
      self.scalar=scalar
      self.called=0

    def displayChanged(self, event):
      if event.getId() == DisplayEvent.MOUSE_RELEASED:
        self.xx = self.dr.getDirectAxisValue(self.x)
        self.yy = self.dr.getDirectAxisValue(self.y)
        if not Double(self.xx).isNaN():
          if self.called==0:
            self.display.disableAction()
            range=self.scalar.getRange()
            self.val=[self.xx]
            self.display.enableAction()
            self.called=1
          else:
            self.display.disableAction()
            range=self.scalar.getRange()
            self.val.append(self.xx)         
            self.called=0
            self.scalar.setRange(min(self.val),max(self.val))
            self.display.enableAction()

            
  def doSetColorRangeD0(self,event):
    #histDisp=graph.histogram(self.obs, 20, clip=0)
    #dragHistLocation(histDisp,self.rgbMap)
    dragHistLocation(self.rgbMap, self.obs)
    
  def doGetLinCombD0(self,event):
    clc = ChannelLinearCombo(self.ad,self.spectrum)
    
  def doChangeParameter(self,event):
    if self.currentParam == "radiance":
      new_param       = "brightnessTemp"  
      menuText        = "BT->radiance"
    elif self.currentParam == "brightnessTemp":
      new_param         = "radiance"
      menuText          = "radiance->BT"
    
    self.obs, self.spectrum = self.ad.changeParameter(new_param,self.channelIndex, self.currentLine, self.currentElem)
    
    #-  rebuild image display
    
    self.observationsInstrument = self.ad.spectrumRangeType
    self.d.removeReference(self.refToImage)
    self.d.removeMap(self.rgbMap)
    map = subs.makeMaps(self.ad.imageRangeType, "rgb")
    self.rgbMap = map[0]
    self.d.addMap(self.rgbMap)
    self.refToImage=subs.addData('a',self.obs,self.d, renderer=ImageRendererJ3D(), zlayer = -0.1)
    self.colorMenu.changeColorScalarMap(self.rgbMap)

    
    #- rebuild spectrum display
    #self.d2.removeReference(self.spectrumRef)
    self.d2.removeReference(self.lref)
    self.d2.removeReference(self.rrbzRef)
    
    minTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, self.ad.obsMin[0]), Real(self.obsLongitudeInstrument, self.ad.obsMin[1]), Text(self.text, '   %-6.2f' % self.ad.obsMin[2])])
    minMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument, self.ad.obsMin[0]), Real(self.obsLongitudeInstrument, self.ad.obsMin[1])], None)
    self.minRef.setData(minTuple)
    self.minMarkRef.setData(minMark)
    maxMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument, self.ad.obsMax[0]), Real(self.obsLongitudeInstrument, self.ad.obsMax[1])], None)
    maxTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, self.ad.obsMax[0]), Real(self.obsLongitudeInstrument, self.ad.obsMax[1]), Text(self.text, '   %-6.2f' % self.ad.obsMax[2])])
    self.maxRef.setData(maxTuple)
    self.maxMarkRef.setData(maxMark)
    
    if self.ad.instrumentName == "MODIS" or self.ad.instrumentName == "MSG":
      domain_range = self.ad.getObservationChannelRange()
      self.maps2[0].setRange(domain_range[0], domain_range[1])
      self.d2.removeAllReferences()
      self.d2.removeMap(self.maps2[1])
      self.d2.removeMap(self.maps2[2])
      map = subs.makeMaps(self.ad.spectrumRangeType.getComponent(0), "y")
      self.maps2[1] = map[0]
      map = subs.makeMaps(self.ad.spectrumRangeType.getComponent(1), "y")
      self.maps2[2] = map[0]
      as = self.maps2[2].getAxisScale()
      as.setVisible(1)
      as.setSide(1)
      as.setColor(Color.orange)
      as = self.maps2[1].getAxisScale()
      as.setSide(0)
      as.setColor(hydra_properties.foreground_color)
      valid_range = self.ad.getObsValidRange()
      self.y0 = valid_range[0][0]
      self.y1 = valid_range[0][1]
      self.maps2[1].setRange(valid_range[0][0], valid_range[0][1])
      self.maps2[2].setRange(valid_range[1][0], valid_range[1][1])
      self.d2.addMap(self.maps2[1])
      self.d2.addMap(self.maps2[2])
      self.d2.disableAction()
      self.spectrumRef[0] = subs.addData('0',self.spectrum.getComponent(0),self.d2, subs.makeColorMap(hydra_properties.foreground_color))
      self.spectrumRef[1] = subs.addData('1',self.spectrum.getComponent(1),self.d2, subs.makeColorMap("orange"))
      self.lref = subs.drawLine(self.d2,[(self.selChannel,self.selChannel),(valid_range[1][0],valid_range[1][1])],color="green")
      self.d2.enableAction()
    else:
      valid_range = self.ad.getObsValidRange()
      domain_range = self.ad.getObservationChannelRange()
      self.maps2[0].setRange(domain_range[0], domain_range[1])
      self.d2.removeAllReferences()
      self.d2.removeMap(self.maps2[1])  
      map = subs.makeMaps(self.ad.spectrumRangeType, "y")
      self.maps2[1] = map[0]
      map[0].setRange(valid_range[0], valid_range[1])
      self.d2.addMap(map[0])
      as = self.maps2[1].getAxisScale()
      as.setSide(0)
      as.setColor(hydra_properties.foreground_color)
      valid_range = self.ad.getObsValidRange()
      self.y0 = valid_range[0]
      self.y1 = valid_range[1]
      self.d2.disableAction()
      self.spectrumRef = subs.addData('b',self.spectrum,self.d2,subs.makeLineStyleMap('solid',1)+subs.makeColorMap(hydra_properties.foreground_color))
      self.lref = subs.drawLine(self.d2,[(self.selChannel,self.selChannel),(valid_range[0],valid_range[1])],color="green")
      self.d2.enableAction()
      
    self.rrbzRef = self.d2.enableRubberBandBoxZoomer ( 1 )
    self.item3.setText(menuText)
    
    
    if new_param == "radiance":
      self.currentParam = new_param
    if new_param == "brightnessTemp":
      self.currentParam = new_param
   
    minTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, self.ad.obsMin[0]), Real(self.obsLongitudeInstrument, self.ad.obsMin[1]), Text(self.text, '   %-6.2f' % self.ad.obsMin[2])])
    minMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument, self.ad.obsMin[0]), Real(self.obsLongitudeInstrument, self.ad.obsMin[1])], None)
    self.minRef.setData(minTuple)
    self.minMarkRef.setData(minMark)
    maxMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument, self.ad.obsMax[0]), Real(self.obsLongitudeInstrument, self.ad.obsMax[1])], None)
    maxTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, self.ad.obsMax[0]), Real(self.obsLongitudeInstrument, self.ad.obsMax[1]), Text(self.text, '   %-6.2f' % self.ad.obsMax[2])])
    self.maxRef.setData(maxTuple)
    self.maxMarkRef.setData(maxMark)
    
    ll = self.ad.cs.toReference([[self.currentLine],[self.currentElem]])
    lat = ll[0][0]
    lon = ll[1][0]
    val = self.ad.getImageValue(lat, lon).getValue()
    roamText = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, lat), Real(self.obsLongitudeInstrument, lon), Text(self.text, '   %-6.2f' % val)])
    self.roamTextRef.setData(roamText)   
    """
    ll = self.ad.cs.toReference([[self.currentLine],[self.currentElem]])
    lat = ll[0][0]
    lon = ll[1][0]
    val = self.ad.imageField.evaluate(RealTuple(self.ad.imageField.getType().getDomain().getCoordinateSystem().getReference(), [lat, lon]), Data.NEAREST_NEIGHBOR, Data.NO_ERRORS)             
    strg='Lat = %-6.2f  Lon = %-7.2f     Val = %-6.2f  ' % (lat, lon, val)
    strg = strg+self.ad.imageRangeUnit.toString()
    self.latLonStringInstrument.setText(strg)
    """
   
  def doTransect(self, event):
    self.viewToolBar.select(ActionEvent(self,ActionEvent.ACTION_PERFORMED,"pick"),leftFunc="DIRECT")
    self.viewToolBar.buttonGroup.setSelected(self.viewToolBar.click.getModel(), true)
    transect.makeTransectDisplay(self.ad, self.obs, self.d, self.roamTextRef, self)
    
  def finishTransect(self):
    self.viewToolBar.select(ActionEvent(self,ActionEvent.ACTION_PERFORMED,"pick"))
    self.viewToolBar.buttonGroup.setSelected(self.viewToolBar.click.getModel(), true)
    
  def captureDisplay(self, event):
    Helper.saveDisplay(self.d, JFrame().getContentPane())
 
 
  def bandBoxChange(self, event):
    self.changeImage(self.ad.bandNameToValue(self.bandNumberText.getText()), None)

    
  def channelBoxChange(self, event):
    self.changeImage(float(self.instrumentString1.getText()), None)
    
  
  def imageStatToggle(self, event):
    if self.minmaxToggleButton.isSelected() == true:
      self.d.toggle(self.minRef, true)
      self.d.toggle(self.minMarkRef, true)
      self.d.toggle(self.maxRef, true)
      self.d.toggle(self.maxMarkRef, true)
    else:
      self.d.toggle(self.minRef, false)
      self.d.toggle(self.minMarkRef, false)
      self.d.toggle(self.maxRef, false)
      self.d.toggle(self.maxMarkRef, false)
      
  def windowClose(self, event):
    self.frame.dispose()
    runtime.gc()
  
  #------------------------------------------------------------------
  def __init__(self, ad, subset=None):
    self.ad = ad
    self.last_spectralIndex = -1
    self.currentParam = ad.paramName

    
    obsElementInstrument, obsLineInstrument, obsChannelIndexInstrument, self.observationChannelsInstrument, self.observationsInstrument = ad.getRealTypes()
    self.obsLatitudeInstrument, self.obsLongitudeInstrument  = ad.getGeoRealTypes()
    obsLatMinMaxInstrument, obsLonMinMaxInstrument           = ad.getGeoDomain()
    self.text = TextType.Generic

    self.observationChannelsInstrumentMX = ad.getObservationChannelRange()

    self.maps = subs.makeMaps(self.obsLongitudeInstrument,'x', self.obsLatitudeInstrument, 'y', self.observationsInstrument, 'rgb','marker','shape', RealType.getRealType("BT"), 'rgb', self.text, 'text')
    d = subs.makeDisplay(self.maps)
    self.d = d
    dsp_rdr = self.d.getDisplayRenderer()
    dsp_rdr.setBackgroundColor(hydra_properties.background_color)
    dsp_rdr.setForegroundColor(hydra_properties.foreground_color)
    self.proj_cntrl  = self.d.getProjectionControl()
    self.init_matrix = self.proj_cntrl.getMatrix()

    # set the box size and turn off clipping
    subs.setBoxSize(d,.7,clip=0)

    #delta=0.2
    #self.maps[0].setRange(obsLonMinMaxInstrument[0]-delta,obsLonMinMaxInstrument[1]+delta)
    #self.maps[1].setRange(obsLatMinMaxInstrument[0]-delta,obsLatMinMaxInstrument[1]+delta)
    
    londiff = obsLonMinMaxInstrument[1] - obsLonMinMaxInstrument[0]
    latdiff = obsLatMinMaxInstrument[1] - obsLatMinMaxInstrument[0]
    if londiff >= latdiff:
      lon_low = obsLonMinMaxInstrument[0]
      lon_hi  = obsLonMinMaxInstrument[1]
      lat_low = obsLatMinMaxInstrument[0]
      lat_hi  = lat_low + londiff
    else:
      lat_low = obsLatMinMaxInstrument[0]
      lat_hi  = obsLatMinMaxInstrument[1]
      lon_low = obsLonMinMaxInstrument[0]
      lon_hi  = lon_low + latdiff
      
      
    self.maps[0].setRange(lon_low, lon_hi)
    self.maps[1].setRange(lat_low, lat_hi)
    self.rgbMap = self.maps[2]

    subs.enableRubberBandBoxZoomer(d, 1)


    numSegments=ad.getNumSegments()
    self.selSegment=0
    if ad.instrumentName == "MODIS":
      self.channel      = 32
      self.channelIndex = 32
    else:
      self.channel=int(ad.numObsChannels/3)
      self.channelIndex = self.channel
    #Get the flat field
    self.obs=ad.getImageSegment(self.channel,self.selSegment,subset)

    
    #...and its dimensions
    dimInstrumentDom=self.obs.getDomainSet()
    self.dimInstrument=dimInstrumentDom.getLengths()
    #-self.dimInstrument=dimInstrumentDom.getHi()

    
    #-- display the observations
    self.refToImage=subs.addData('a',self.obs,d, renderer=ImageRendererJ3D(), zlayer = -0.1)
    mode = d.getGraphicsModeControl()
    mode.setCurvedSize(2)
    map=load('./data/outlsupw')
    subs.addData('m',map,d,constantMaps=subs.makeColorMap(hydra_properties.foreground_color))


    # enable the Listener for mouse up events
    subs.HandlePickEvent( d, self.changeSpectra)

    # finally, we want to have a small 'cross' to show the position
    self.shapes = subs.Shapes(d,self.maps[3])
    self.shapeMarkerIndex = self.shapes.addShape("cross",scale=.03,color="cyan", autoScale=0)

    
    from javax.swing import JSlider
    
    butPanelD0 = JPanel()
    buttColorRangeD0 = JButton("Set Color Range",actionPerformed=self.doSetColorRangeD0)
    butNaturalD0 = JPanel()
    butNaturalD0.setLayout(FlowLayout())
    butNaturalD0.add("West", buttColorRangeD0)
    butNaturalD0.setBackground(Color.black)

    buttCombineLinChanD1 = JButton("Get linear combinations",actionPerformed=self.doGetLinCombD0)
    butNaturalD0.add("East",buttCombineLinChanD1)


    sliderPanel = JPanel()
    sliderPanel.setLayout(BorderLayout())
    sliderPanel.add("Center",d.getComponent())
    if numSegments > 1: # only if more than one segment
      self.slider = JSlider(JSlider.VERTICAL,0,numSegments-1,self.selSegment,stateChanged=self.sliderchanged)
      sliderPanel.add("West",self.slider)
    #sliderPanel.add("South",butNaturalD0)

    textPanelD0 = JPanel()
    textPanelD0.setLayout(GridLayout(0,1,5,5))
    self.instrumentString=JLabel('Instrument: '+ad.instrumentName)
    self.instrumentString.setForeground(hydra_properties.foreground_color)
    self.latLonStringInstrument=JLabel('Lat: ?, Lon: ?')
    self.latLonStringInstrument.setForeground(hydra_properties.foreground_color)
    self.timeStringInstrument=JLabel('time: ?')
    self.timeStringInstrument.setForeground(hydra_properties.foreground_color)
    self.FOVangleStringInstrument=JLabel('FOV angle: ?')
    self.FOVangleStringInstrument.setForeground(hydra_properties.foreground_color)
    textPanelD0.add(self.instrumentString)
    #textPanelD0.add(self.latLonStringInstrument)
    #textPanelD0.add(self.timeStringInstrument)
    #textPanelD0.add(self.FOVangleStringInstrument)
    textPanelD0.setBackground(hydra_properties.background_color)

    InstrumentPanel = JPanel()
    InstrumentPanel.setLayout(BorderLayout())
    InstrumentPanel.add("Center",sliderPanel)
    InstrumentPanel.add("South",textPanelD0)
    
    
    #-- min/max label 
    minTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, ad.obsMin[0]), Real(self.obsLongitudeInstrument, ad.obsMin[1]), Text(self.text, '   %-6.2f' % ad.obsMin[2])])
    minMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument, ad.obsMin[0]), Real(self.obsLongitudeInstrument, ad.obsMin[1])], None)
    self.minRef=subs.addData('a',minTuple,d,subs.makeColorMap(Color(0.8, 0.8, 0.0)),zlayer = 0.1)
    self.minMarkRef=subs.addData('a',minMark,d,subs.makeColorMap(Color(0.8, 0.8, 0.0)),zlayer = 0.1)
    maxMark = RealTuple(RealTupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument]), [Real(self.obsLatitudeInstrument, ad.obsMax[0]), Real(self.obsLongitudeInstrument, ad.obsMax[1])], None)
    maxTuple = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, ad.obsMax[0]), Real(self.obsLongitudeInstrument, ad.obsMax[1]), Text(self.text, '   %-6.2f' % ad.obsMax[2])])
    self.maxRef=subs.addData('a',maxTuple,d,subs.makeColorMap(Color(0.2, 0.8, 0.2)),zlayer = 0.1)
    self.maxMarkRef=subs.addData('a',maxMark,d,subs.makeColorMap(Color(0.2, 0.8, 0.2)),zlayer = 0.1)
    
    subs.setPointSize(d, 4)    
    txtCntrl = self.maps[5].getControl()
    txtCntrl.setJustification(TextControl.Justification.LEFT)
    txtCntrl.setAutoSize(1)
    txtCntrl.setFont(Font("sansserif", Font.PLAIN, 14))
    
    roamText = Tuple(TupleType([self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text]), [Real(self.obsLatitudeInstrument, Float.NaN), Real(self.obsLongitudeInstrument, Float.NaN), Text(self.text, '   %-6.2f' % Float.NaN)])
    self.roamTextRef = subs.addData('a', roamText, d, subs.makeColorMap(Color(1.0,0.0,1.0)),zlayer = 0.1)
    
    
    #--------- now define the second panel:  single observation (full spectrum) at a pixel
    #-------------------------------------------------------------------------------------
    self.currentLine = 0
    self.currentElem = 0
    self.spectrum    = ad.getObservations(self.currentLine, self.currentElem)
    specDomain       = self.ad.observationDomain
    
    valid_range = ad.getObsValidRange()
    
    self.spectrumRef = None
    d2      = None
    self.d2 = None
    
    if ad.instrumentName == "MODIS" or ad.instrumentName == "MSG":
      self.maps2 = subs.makeMaps(self.observationChannelsInstrument,'x',ad.spectrumRangeType.getComponent(0),'y',ad.spectrumRangeType.getComponent(1),'y')
      as = self.maps2[2].getAxisScale()
      as.setVisible(1)
      as.setSide(1)
      self.maps2[2].setRange(valid_range[1][0], valid_range[1][1])
      self.maps2[1].setRange(valid_range[0][0], valid_range[0][1])
      d2 = subs.makeDisplay(self.maps2)
      self.d2 = d2
      dsp_rdr = self.d2.getDisplayRenderer()
      dsp_rdr.setBackgroundColor(hydra_properties.background_color)
      dsp_rdr.setForegroundColor(hydra_properties.foreground_color)
      self.spectrumRef = []
      self.spectrumRef.append(subs.addData('0',self.spectrum.getComponent(0), d2, subs.makeColorMap(hydra_properties.foreground_color)))
      self.spectrumRef.append(subs.addData('1',self.spectrum.getComponent(1), d2, subs.makeColorMap("orange")))
      as.setColor(Color.orange)
    else:
      self.maps2 = subs.makeMaps(self.observationChannelsInstrument,'x',self.observationsInstrument,'y')
      self.maps2[1].setRange(valid_range[0], valid_range[1])
      d2 = subs.makeDisplay(self.maps2)
      self.d2 = d2
      dsp_rdr = self.d2.getDisplayRenderer()
      dsp_rdr.setBackgroundColor(hydra_properties.background_color)
      dsp_rdr.setForegroundColor(hydra_properties.foreground_color)
      self.spectrumRef = subs.addData('b',self.spectrum,d2, subs.makeColorMap(hydra_properties.foreground_color))
    

    
    self.rrbzRef = self.d2.enableRubberBandBoxZoomer ( 1 )
    
   
    subs.setPointSize(d2, 4)
    showAxesScales(d2,1)
    subs.setAspectRatio(d2,2.2)
    subs.setBoxSize(d2,.6,clip=0)

    
    #-- update text labels
    self.ll = ad.cs.toReference([[0],[0]])
    strg='Lat = %-6.2f  Lon = %-7.2f' % (self.ll[0][0], self.ll[1][0])
    self.latLonStringInstrument.setText(strg)
    
    tt = ad.getTimeObs(0,0)
    strgTime = ""
    if tt != None:
      strgTime='Time = %-6.2f [offset (s)]' % (tt)
    self.timeStringInstrument.setText(strgTime)
    
    ff = ad.getFOVangleObs(0,0)
    strgFOV = ""
    if ff != None:
      strgFOV='FOV angle = %-6.2f [degrees]' % (ff)
    self.FOVangleStringInstrument.setText(strgFOV)
    

    # in this panel, we'll be drawing the vertical green line...for now,
    # just make a short one since we don't know the range yet...
    self.selChannel=(specDomain.indexToValue([self.channel]))[0][0]
    if ad.instrumentName == "MODIS" or ad.instrumentName == "MSG":
      self.y0 = valid_range[0][0]
      self.y1 = valid_range[0][1]
    else:
      self.y0 = valid_range[0]
      self.y1 = valid_range[1]
    self.lref = subs.drawLine(d2,[(self.selChannel,self.selChannel),(self.y0,self.y1)],color="green")

    subs.HandlePickEvent(d2, self.changeImage)

    
    
    textPanelD2 = JPanel()
    textPanelD2.setLayout(FlowLayout())
    xVariable=ad.getObservationChannels()
    
    if ad.instrumentName == "MODIS" or ad.instrumentName == "MSG":
      textPanelD2.add(JLabel("Band: "))
      self.bandNumberText = JTextField(ad.bandValueToName(xVariable[self.channel]), actionPerformed=self.bandBoxChange)
      self.bandNumberText = JComboBox(ad.band_numbers)
      self.bandNumberText.setSelectedItem(ad.band_numbers[ad.fileIndexes[self.channel]])
      
      class c1(java.awt.event.ActionListener):
        def __init__(self, mom, comboBox):
          self.mom = mom
          self.comboBox = comboBox
          
        def actionPerformed(self,event):
          self.mom.changeImage(self.mom.ad.bandNameToValue(self.comboBox.getSelectedItem()), None)
          
      self.bandNumberText.addActionListener(c1(self, self.bandNumberText))
      
      textPanelD2.add(self.bandNumberText)
      
    #strg='Channel:  '
    strg=self.ad.observationDomain.getType().getDomain().toString()
    textPanelD2.add(JLabel(strg))
    strg = '%7.1f' % (xVariable[self.channel])
    self.instrumentString1 = JTextField(strg, actionPerformed=self.channelBoxChange)
    textPanelD2.add(self.instrumentString1)
    unit = self.ad.observationDomain.getType().getDomain().getComponent(0).getDefaultUnit()
    if unit != None:     
      textPanelD2.add(JLabel(unit.toString()))
    
    

    SingleObsPanel = JPanel()
    SingleObsPanel.setLayout(BorderLayout())
    SingleObsPanel.add("Center",d2.getComponent())
    #SingleObsPanel.add("South",textPanelD2)
    InstrumentPanel.add("North", textPanelD2)
    #------------------------------------------------------------------------------------
    
    #--- main window selection
    menuBar  = JMenuBar()
    toolMenu = JMenu("Tools")
    settingsMenu = JMenu("Settings")
    menuBar.add(toolMenu)
    menuBar.add(settingsMenu)
    
    item1 = JMenuItem("Set Color Range", actionPerformed=self.doSetColorRangeD0)
    item1.setEnabled(1)
    settingsMenu.add(item1)
    item2 = JMenuItem("Linear Combinations", actionPerformed=self.doGetLinCombD0)
    item2.setEnabled(1)
    toolMenu.add(item2)
    self.item3 = JMenuItem("radiance->BT", actionPerformed=self.doChangeParameter)
    self.item3.setEnabled(1)
    settingsMenu.add(self.item3)
    item4 = JMenuItem("transect", actionPerformed=self.doTransect)
    item4.setEnabled(1)
    toolMenu.add(item4)
    item5 = JMenuItem("Capture Display", actionPerformed=self.captureDisplay)
    item5.setEnabled(1)
    toolMenu.add(item5)
    
    statMenu = JMenu("Statistics")
    self.minmaxToggleButton = JRadioButtonMenuItem("min/max", actionPerformed=self.imageStatToggle)
    self.minmaxToggleButton.setSelected(1)
    statMenu.add(self.minmaxToggleButton)
    toolMenu.add(statMenu)
    
    projMenu = JMenu("Projection")
    psItem = JMenuItem("Polar-Stereo")
    lcItem = JMenuItem("Lambert Equal Area")
    llItem = JMenuItem("latlon")
    llItem.setEnabled(1)
    lcItem.setEnabled(1)
    psItem.setEnabled(1)
    projMenu.add(psItem)
    projMenu.add(lcItem)
    projMenu.add(llItem)
    settingsMenu.add(projMenu)
    
    from ColorScaleSelect import ColorScaleSelect
    self.colorMenu = ColorScaleSelect("set color scale", self.rgbMap)
    settingsMenu.add(self.colorMenu)
    

    frame = JFrame("Multi-Channel viewer",windowClosing=self.windowClose)
    frame.setJMenuBar(menuBar)
    pane = frame.getContentPane()
    pane.setLayout(BorderLayout())
    
    from DisplayViewSelect import DisplayViewSelectToolBar

    splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT)
    SingleObsPanel.setPreferredSize(Dimension(500,220))
    splitpane.add(SingleObsPanel)
    splitpane.add(InstrumentPanel)    
    splitpane.setContinuousLayout(1)
    splitpane.setOneTouchExpandable(1)
    splitpane.setDividerSize(12)
    
    pane.add("Center", splitpane)
    self.viewToolBar = DisplayViewSelectToolBar([self.d, self.d2], [0, 1])    
    pane.add("South", self.viewToolBar)

    class roamProbe(DisplayListener):
      def __init__(self, display, ad, toolbar, textRef, y, x, txt):
        self.display = display
        self.display.addDisplayListener(self)
        self.dr = display.getDisplayRenderer()
        self.ad = ad
        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.ad.getImageValue(lat,lon).getValue()
          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(d, ad, self.viewToolBar, self.roamTextRef, self.obsLatitudeInstrument, self.obsLongitudeInstrument, self.text)

    frame.pack()
    frame.show()
    frame.setSize(500,700)
    frame.setVisible(1)
    self.frame = frame

  def buildImageDisp(self):
    pass    

#----------------------------------------------------------------------------------

class linkHistLocation(DisplayListener):
  def __init__(self, display, scalar):
    self.x, self.y, self.z, self.display=subs.getDisplayMaps(display)
    self.dr = self.display.getDisplayRenderer()
    self.display.addDisplayListener(self)
    self.scalar=scalar
    self.called=0

  def displayChanged(self, event):
    if event.getId() == DisplayEvent.MOUSE_RELEASED:
      self.xx = self.dr.getDirectAxisValue(self.x)
      self.yy = self.dr.getDirectAxisValue(self.y)
      if not Double(self.xx).isNaN():
        if self.called==0:
          self.display.disableAction()
          self.val=[self.xx]
          self.display.enableAction()
          self.called=1
        else:
          self.display.disableAction()
          self.val.append(self.xx)         
          self.called=0
          self.scalar.setRange(min(self.val),max(self.val))
          self.display.enableAction()
