from util import MyRubberBandBoxRendererJ3D
from visad import *  
import subs
from subs import * 
from visad.python.JPythonMethods import *
 
#---------------------------------------
false = 0
true  = 1
#---------------------------------------  


class Subset:
  def __init__(self, start_x, start_y, end_x, end_y, step=1):
    #- segment relative coordinates
    if start_x == None:
      start_x = 0
    if start_y == None:
      start_y = 0
    self.start_x      = start_x
    self.start_y      = start_y
    self.end_x        = end_x
    self.end_y        = end_y
    #self.segmentIndex = segmentIndex add this later
    self.step         = step

    
class SubsetImage(CellImpl):
  displayLineType = None
  displayElemType = None
  displayAltType  = None
  dtt             = None
  count           = 0
  
  def __init__(self, image, dsp, xmap, ymap, callback, subsetRef, color=None, ds_cs=None):
       
    #-------  display side coordinate system with rubberband box ------------- 
    rt   = image.getType().getDomain()
    cs   = rt.getCoordinateSystem()
    i_cs = IdentityCoordinateSystem(RealTupleType(makeType("Z")))
    cs   = CartesianProductCoordinateSystem([cs, i_cs])
    
    self.callback = callback
    self.subsetRef = subsetRef
    
    class TransformAdapter(CoordinateSystem):
      def __init__(self, cs, displayReference, smap_dspx, smap_dspy, ds_cs):
        self.cs               = cs
        self.ds_cs            = ds_cs
        self.displayReference = displayReference
        self.smap_dspx        = smap_dspx
        self.smap_dspy        = smap_dspy
        
        if ds_cs != None:
          ref     = cs.getReference()
          map_ref = ds_cs.getMapProjection().getReference()
        
        
        CoordinateSystem.__init__(self, displayReference, None)
        
        
      def toReference(self, values):
        new_values = self.cs.toReference(values)
        if self.ds_cs != None:
          new_values = self.ds_cs.toReference([new_values[1], new_values[0], new_values[2]])
        else:        
          sox = getScale(self.smap_dspx)
          soy = getScale(self.smap_dspy)
          for i in range(len(new_values[0])):
            new_values[1][i] = new_values[1][i]*sox[0][0] + sox[0][1]
            new_values[0][i] = new_values[0][i]*soy[0][0] + soy[0][1]
          tmp = new_values[1]
          new_values[1] = new_values[0]
          new_values[0] = tmp
        
        return new_values
        
      def fromReference(self, values):
        #-scale values to lon/lat first
        if self.ds_cs == None:        
          sox = getScale(self.smap_dspx)
          soy = getScale(self.smap_dspy)
          for i in range(len(values[0])):
            values[0][i] = (values[0][i] - sox[0][1])/sox[0][0]
            values[1][i] = (values[1][i] - soy[0][1])/soy[0][0]     
          tmp       = values[1]
          values[1] = values[0]
          values[0] = tmp
          new_values = self.cs.fromReference(values)
        else:
          new_values = self.ds_cs.fromReference(values)
          new_values = self.cs.fromReference([new_values[1], new_values[0], new_values[2]])
        
        return new_values
        
    new_cs = TransformAdapter(cs, Display.DisplaySpatialCartesianTuple, xmap, ymap, ds_cs)
        
    SubsetImage.displayLineType = DisplayRealType("displayLine_%d" % SubsetImage.count, true, 0.0, 10000.0, 0.0, None)
    SubsetImage.displayElemType = DisplayRealType("displayElem_%d" % SubsetImage.count, true, 0.0, 10000.0, 0.0, None)
    SubsetImage.displayAltType  = DisplayRealType("displayAlt_%d" % SubsetImage.count, true, -1.0, 1.0, 0.0, None)
    SubsetImage.dtt = DisplayTupleType([SubsetImage.displayLineType, SubsetImage.displayElemType, SubsetImage.displayAltType], new_cs)

    elemType = makeType("elem_%d" % SubsetImage.count)
    lineType = makeType("line_%d" % SubsetImage.count)
    self.boxRef = DataReferenceImpl("boxRef")
    self.noBox = Gridded2DSet(RealTupleType(lineType, elemType), None, 1)
    self.boxRef.setData(Gridded2DSet(RealTupleType(lineType, elemType), None, 1))
    dsp.addData("le", RealTuple(RealTupleType(lineType, elemType), [0, 0]), zlayer=-0.15)
    self.elemMap = ScalarMap(elemType, SubsetImage.displayElemType)
    self.lineMap = ScalarMap(lineType, SubsetImage.displayLineType)
    dset = image.getDomainSet()
    low  = dset.getLow()
    hi   = dset.getHi()
    self.elemMap.setRange(low[1], hi[1])
    self.lineMap.setRange(low[0], hi[0])
    dsp.addMap(self.elemMap)
    dsp.addMap(self.lineMap)
    self.rbbrj3d = MyRubberBandBoxRendererJ3D(lineType,elemType,0,0)
    self.rbbrj3d.setKeepLastBoxOn(true)
    constMap = None
    if color != None:
      constMap = makeColorMap(color)
    dsp.addReferences(self.rbbrj3d, self.boxRef, constMap)
    
    self.addReference(self.boxRef)
    
    self.subsetRef[0] = self.rbbrj3d
    SubsetImage.count += 1

    
  def doAction(self):
    samples = self.boxRef.getData().getSamples()
    if (samples != None):
      line = self.lineMap.scaleValues(samples[0])
      elem = self.elemMap.scaleValues(samples[1])
      
      self.callback(line,elem)
   