# Allan Spale
# Project 1
# CS 526


import Tkinter
import sys
import os
import time
import struct
#import tkFont

import vtk
from vtk.tk.vtkTkRenderWindowInteractor import vtkTkRenderWindowInteractor

#f = tkFont.Font( size=10 )


# global widget and event functions
global dictStandardGridSettings
global disableMenus
global dictContourLines
global dictLandscape
global initContours

dictStandardGridSettings = { 'padx':5, 'pady':5, 'sticky':Tkinter.SW }
disableMenus = 1
initContours = 0

dictContourLines = {}

dictLandscape = {}
dictLandscape[ 'warp' ]= 1.0
dictLandscape[ 'reduction' ]= 2.0
        
def registerMouseEvents( object, callback ):
    object.bind( '<B1-Motion>', callback )
    object.bind( '<B2-Motion>', callback )
    object.bind( '<Button-1>', callback )
    object.bind( '<Button-2>', callback )
    object.bind( '<ButtonRelease-1>', callback )
    object.bind( '<ButtonRelease-2>', callback )

    
    
# from tkinter docs
class VTKRender:    
    def __init__(self, frame):
        self.CONTOURS = 10
        self.ELEVATION = 20
        self.TEXTURE = 30
        self.COLORMAP = 40
        self.NOTHING = 0
        self.CONTOURS_ONLY = 5

        self.OK = 0
        self.NO_FILE_TEXTURE = -10
        self.NO_FILE_ELEVATION = -20

        self.RED = 10
        self.YELLOW = 20
        self.GREEN = 30
        self.BLUE = 40

        self.view = self.NOTHING
        
        # pipeline
        self.readerTexture = vtk.vtkImageReader2()
        self.readerTexture.SetDataScalarTypeToUnsignedChar()
        self.readerTexture.SetFileDimensionality( 2 )
        #self.readerTexture.SetDataExtent ( 0,1023, 0,511, 0,0 )
        self.readerTexture.SetDataSpacing( 1, 1, 1 )
        #self.readerTexture.SetNumberOfScalarComponents( 3 )
        #self.readerTexture.SetFileName("C:\\Allan-Folder\cs526\project1\\canyon_rgb.raw")

        self.readerElev = vtk.vtkImageReader2()
        #self.readerElev.SetFileName("C:\\Allan-Folder\cs526\project1\\canyon_elev.raw")
        self.readerElev.SetDataScalarTypeToUnsignedChar()
        self.readerElev.SetFileDimensionality( 2 )
        #self.readerElev.SetDataExtent ( 0,1023, 0,511, 0,0 )
        self.readerElev.SetDataSpacing( 1, 1, 1 )
        #self.readerElev.SetNumberOfScalarComponents( 1 )

        self.shrinkFactor = 2
        
        self.shrinkTex = vtk.vtkImageShrink3D()
        self.shrinkTex.SetShrinkFactors(self.shrinkFactor, self.shrinkFactor, 1)
        self.shrinkTex.SetInput(self.readerTexture.GetOutput())
        self.shrinkTex.AveragingOn()

        self.shrinkElev = vtk.vtkImageShrink3D()
        self.shrinkElev.SetShrinkFactors(self.shrinkFactor, self.shrinkFactor, 1)
        self.shrinkElev.SetInput(self.readerElev.GetOutput())
        self.shrinkElev.AveragingOn()        

        self.geometry = vtk.vtkImageDataGeometryFilter()
        self.geometry.SetInput(self.shrinkElev.GetOutput())
        
        self.warp = vtk.vtkWarpScalar()
        self.warp.SetInput(self.geometry.GetOutput())

        self.merge = vtk.vtkMergeFilter()
        self.merge.SetGeometry(self.warp.GetOutput())

        self.mapperStandard = vtk.vtkDataSetMapper()
        self.mapperStandard.SetInput(self.merge.GetOutput())
        self.mapperStandard.SetScalarRange(0, 255)
        self.mapperStandard.ImmediateModeRenderingOff()

        # colormap
        self.colormapLookup = vtk.vtkLookupTable()
        self.colormapLookup.SetHueRange(0,1)
        self.colormapLookup.SetSaturationRange(1,0)
        self.colormapLookup.SetValueRange(0,1)
        self.colormapLookup.SetAlphaRange(0.9,0.5)

        self.hi = 255
        self.lo = 0

        self.elevation = vtk.vtkElevationFilter()
        self.elevation.SetInput(self.warp.GetOutput())
        self.elevation.SetLowPoint(0, 0, self.lo)
        self.elevation.SetHighPoint(0, 0, self.hi)
        self.elevation.SetScalarRange(self.lo, self.hi)
        self.elevation.ReleaseDataFlagOn()

        self.colormapMapper = vtk.vtkPolyDataMapper()
        self.colormapMapper.SetInput(self.elevation.GetOutput())
        self.colormapMapper.SetScalarRange(self.lo,self.hi)
        self.colormapMapper.SetLookupTable(self.colormapLookup)
        self.colormapMapper.ImmediateModeRenderingOn()

        self.actorColormap = vtk.vtkActor()
        self.actorColormap.SetMapper(self.colormapMapper)

        # contour
        self.contourRed = vtk.vtkContourFilter()
        self.contourRed.SetInput( self.warp.GetOutput() )
        self.contourRed.ComputeScalarsOff()
        self.contourRed.SetNumberOfContours( 1 )
        self.contourRedMapper = vtk.vtkPolyDataMapper()
        self.contourRedMapper.SetInput( self.contourRed.GetOutput() )
        self.contourRedActor = vtk.vtkActor()
        self.contourRedActor.SetMapper( self.contourRedMapper )
        self.contourRedActor.GetProperty().SetColor( 0.7,0,0)

        self.contourGreen = vtk.vtkContourFilter()
        self.contourGreen.SetInput( self.warp.GetOutput() )
        self.contourGreen.ComputeScalarsOff()
        self.contourGreen.SetNumberOfContours( 1 )
        self.contourGreenMapper = vtk.vtkPolyDataMapper()
        self.contourGreenMapper.SetInput( self.contourGreen.GetOutput() )
        self.contourGreenActor = vtk.vtkActor()
        self.contourGreenActor.SetMapper( self.contourGreenMapper )
        self.contourGreenActor.GetProperty().SetColor( 0,0.7,0)

        self.contourYellow = vtk.vtkContourFilter()
        self.contourYellow.SetInput( self.warp.GetOutput() )
        self.contourYellow.ComputeScalarsOff()
        self.contourYellow.SetNumberOfContours( 1 )
        self.contourYellowMapper = vtk.vtkPolyDataMapper()
        self.contourYellowMapper.SetInput( self.contourYellow.GetOutput() )
        self.contourYellowActor = vtk.vtkActor()
        self.contourYellowActor.SetMapper( self.contourYellowMapper )
        self.contourYellowActor.GetProperty().SetColor( 0.7,0.7,0)

        self.contourBlue = vtk.vtkContourFilter()
        self.contourBlue.SetInput( self.warp.GetOutput() )
        self.contourBlue.ComputeScalarsOff()
        self.contourBlue.SetNumberOfContours( 1 )
        self.contourBlueMapper = vtk.vtkPolyDataMapper()
        self.contourBlueMapper.SetInput( self.contourBlue.GetOutput() )
        self.contourBlueActor = vtk.vtkActor()
        self.contourBlueActor.SetMapper( self.contourBlueMapper )
        self.contourBlueActor.GetProperty().SetColor( 0,0,0.7)
        
        
        # setup rendering
        self.ren = vtk.vtkRenderer()
        self.ren.SetBackground(0.5,0.5,0.5)
        self.ren.GetActiveCamera().SetPosition( -100,10000,1000 )
        self.ren.GetActiveCamera().SetFocalPoint( 0,0,0 )
        self.ren.ResetCameraClippingRange()
        
        self.renWin = vtk.vtkRenderWindow()
        self.renWin.AddRenderer(self.ren)
        self.rw = vtkTkRenderWindowInteractor(
            frame, width=400, height=400, rw=self.renWin )
        self.rw.pack(fill=Tkinter.BOTH, expand=1)
        self.rw.Initialize()
        self.renWin.Render()
        self.rw.Start()


        #*** can add and remove actors!  self.ren.RemoveActor( blahActor )
    def prepareFiles( self, dictFormData ):
        self.maxElevationValue = 0
        self.minElevationValue = 255

        # First, check elevation file        
        stElevFilePath = os.path.normpath( dictFormData[ 'elevationFile' ] )
        print stElevFilePath
        if ( os.path.exists( stElevFilePath ) == 1 ):
            fileCurrent = open( stElevFilePath, "rb" )
            iFileSize = os.path.getsize( stElevFilePath )
            print iFileSize

            for i in range( 0, iFileSize ):
                hexByte = fileCurrent.read( 1 )
                item = struct.unpack( 'B', hexByte )
                decimalValue = item[ 0 ]

                if ( decimalValue > self.maxElevationValue ):
                    self.maxElevationValue = decimalValue
                elif ( decimalValue < self.minElevationValue ):
                    self.minElevationValue = decimalValue


            # Now, check the texture file
            stTexFilePath = os.path.normpath( dictFormData[ 'textureFile' ] )
            print stTexFilePath
            if ( os.path.exists( stTexFilePath ) == 1 ):
                errorNumber = self.OK

                self.readerTexture.SetFileName( stTexFilePath )
                self.readerTexture.SetDataExtent (
                    0,dictFormData[ 'texImageWidth' ]-1,
                    0,dictFormData[ 'texImageHeight' ]-1, 0,0 )
                self.readerTexture.SetNumberOfScalarComponents(
                    dictFormData[ 'texColorType' ] )
                self.readerTexture.Update()

                self.readerElev.SetFileName( stElevFilePath )
                self.readerElev.SetDataExtent (
                    0,dictFormData[ 'elevImageWidth' ]-1,
                    0,dictFormData[ 'elevImageHeight' ]-1, 0,0 )
                self.readerElev.SetNumberOfScalarComponents(
                    dictFormData[ 'elevColorType' ] )
                self.readerElev.Update()
                
            else:
                errorNumber = self.NO_FILE_TEXTURE
            
        else:
            errorNumber = self.NO_FILE_ELEVATION

        return errorNumber
        
        
    def removeOldActors( self ):
        if self.view==self.COLORMAP:
            self.ren.RemoveActor( self.actorColormap )
        elif ( self.view==self.CONTOURS ) or ( self.view==self.CONTOURS_ONLY ):
            self.ren.RemoveActor( self.contourRedActor )
            self.ren.RemoveActor( self.contourYellowActor )
            self.ren.RemoveActor( self.contourGreenActor )
            self.ren.RemoveActor( self.contourBlueActor )        
        elif self.view==self.ELEVATION:
            self.ren.RemoveActor( self.elevationGrayscaleActor )
        elif self.view==self.TEXTURE:
            self.ren.RemoveActor( self.textureActor )
        else:
            pass
        

    def setWarpFactor( self, warpValue ):
        self.warp.SetScaleFactor( warpValue )

        if ( self.view==self.COLORMAP ) or ( self.view==self.CONTOURS ):
            if warpValue < 0:
                temp = self.hi
                self.hi = 0
                self.lo = int( 256 * warpValue )
            elif warpValue == 0:
                self.lo = 0
                self.hi = 255
            else:
                self.hi = int( 256 * warpValue )

            print "hi=", self.hi
            print "lo=",self.lo

            self.elevation.SetLowPoint(0, 0, self.lo)
            self.elevation.SetHighPoint(0, 0, self.hi)
            self.elevation.SetScalarRange(self.lo, self.hi)
            self.colormapMapper.SetScalarRange(self.lo,self.hi)
        

    def setDataReductionFactor( self, reductionValue ):
        self.shrinkFactor = reductionValue
        self.shrinkElev.SetShrinkFactors(self.shrinkFactor, self.shrinkFactor, 1)
        self.shrinkTex.SetShrinkFactors(self.shrinkFactor, self.shrinkFactor, 1)
        
    def setViewColormap( self ):
        self.removeOldActors()
        self.view = self.COLORMAP
        self.ren.AddActor( self.actorColormap )
        pass

    def setViewContours( self ):
        self.view = self.CONTOURS
        self.ren.AddActor( self.contourRedActor )
        self.ren.AddActor( self.contourYellowActor )
        self.ren.AddActor( self.contourGreenActor )
        self.ren.AddActor( self.contourBlueActor )        

    def setViewContoursOnly( self ):
        self.removeOldActors()
        self.view = self.CONTOURS_ONLY
        self.ren.AddActor( self.contourRedActor )
        self.ren.AddActor( self.contourYellowActor )
        self.ren.AddActor( self.contourGreenActor )
        self.ren.AddActor( self.contourBlueActor )        

    def setViewElevation( self ):
        self.removeOldActors()
        self.view = self.ELEVATION
        self.merge.SetScalars(self.shrinkElev.GetOutput())
        self.elevationGrayscaleActor = vtk.vtkActor()
        self.elevationGrayscaleActor.SetMapper( self.mapperStandard )
        self.ren.AddActor( self.elevationGrayscaleActor )

    def setViewTexture( self ):
        self.removeOldActors()
        self.view = self.TEXTURE
        self.merge.SetScalars(self.shrinkTex.GetOutput())
        self.textureActor = vtk.vtkActor()
        self.textureActor.SetMapper( self.mapperStandard )
        self.ren.AddActor( self.textureActor )


    def setContourLineHeight( self, colorID, value ):
        if (  colorID == self.RED ):
            self.contourRed.SetValue( 0, value )

        elif ( colorID == self.YELLOW ):
            self.contourYellow.SetValue( 0, value )
            
        elif ( colorID == self.GREEN ):
            self.contourGreen.SetValue( 0, value )
            
        elif ( colorID == self.BLUE ):
            self.contourBlue.SetValue( 0, value )        


    def setContourLineThickness( self, colorID, value ):
        if ( colorID == self.RED ):
            self.contourRedActor.GetProperty().SetLineWidth( value )

        elif ( colorID == self.YELLOW ):
            self.contourYellowActor.GetProperty().SetLineWidth( value )            
            
        elif ( colorID == self.GREEN ):
            self.contourGreenActor.GetProperty().SetLineWidth( value )            
            
        elif ( colorID == self.BLUE ):
            self.contourBlueActor.GetProperty().SetLineWidth( value )        


    def getMaxElevation( self ):
        return self.maxElevationValue

    def getMinElevation( self ):
        return self.minElevationValue
    

    def destroy( self ):
        del self.ren
        del self.renWin
        del self.rw


class DialogLandscapeOptions:
    def __init__(self, rootWindow, vtkWindow ):
        global dictLandscape
        
        self.vtkWindow = vtkWindow
        self.dialog = Tkinter.Toplevel( rootWindow )
        self.dialog.title( 'Landscape' )
        self.dialog.resizable( 0,0 )


        labelWarp = Tkinter.Label( self.dialog,
            text='Warp Factor:' )
        labelWarp.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                   row=0, rowspan=1, column=0, columnspan=1 )
        self.labelWarpValue = Tkinter.Label( self.dialog, text=dictLandscape[ 'warp' ],
                                               anchor=Tkinter.W)
        self.labelWarpValue.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=0, rowspan=1, column=1, columnspan=1 )
        self.sliderWarp = Tkinter.Scale( self.dialog, { 'from':-50, 'to':50,
                                        'orient':Tkinter.HORIZONTAL,
                                        'showvalue':0 } )
        self.sliderWarp.set( dictLandscape[ 'warp' ] )
        self.sliderWarp.grid( sticky=Tkinter.SW,
                                   row=0, rowspan=1, column=2, columnspan=2 )
        registerMouseEvents( self.sliderWarp, self.updateWarpValue )


        labelReduction = Tkinter.Label( self.dialog,
            text='Data Reduction Factor:' )
        labelReduction.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                   row=1, rowspan=1, column=0, columnspan=1 )
        self.labelReductionValue = Tkinter.Label( self.dialog, text=dictLandscape[ 'reduction' ],
                                               anchor=Tkinter.W)
        self.labelReductionValue.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=1, rowspan=1, column=1, columnspan=1 )
        self.sliderReduction = Tkinter.Scale( self.dialog, { 'from':2, 'to':10,
                                        'orient':Tkinter.HORIZONTAL,
                                        'showvalue':0 } )
        self.sliderReduction.set(dictLandscape[ 'reduction' ] )
        self.sliderReduction.grid( sticky=Tkinter.SW,
                                   row=1, rowspan=1, column=2, columnspan=2 )
        registerMouseEvents( self.sliderReduction, self.updateReductionValue )


    def updateWarpValue( self, *unusedArgument ):
        dictLandscape[ 'warp' ] = self.sliderWarp.get() / 10.0
        self.labelWarpValue.config( text=dictLandscape[ 'warp' ] )
        self.vtkWindow.setWarpFactor( dictLandscape[ 'warp' ] )

    def updateReductionValue( self, *unusedArgument ):
        dictLandscape[ 'reduction' ] = self.sliderReduction.get()
        self.labelReductionValue.config( text=dictLandscape[ 'reduction' ] )
        self.vtkWindow.setDataReductionFactor( dictLandscape[ 'reduction' ] )
        
    """
    def doOK( self ):
        pass

    def doCancel( self ):
        dialog.destroy()
        pass        
    """

class DialogContourLines:
    def __init__(self, rootWindow, vtkWindow ):
        global dictContourLines
        global initContours
        
        self.dialog = Tkinter.Toplevel( rootWindow )
        self.dialog.title( 'Contour Lines' )
        self.dialog.resizable( 0,0 )
        self.vtkWindow = vtkWindow

        max = self.vtkWindow.getMaxElevation()
        min = self.vtkWindow.getMinElevation()

        if ( initContours == 0 ):
            dictContourLines[ 'redThickness' ] = 0;
            dictContourLines[ 'redHeight' ] = min;
            dictContourLines[ 'yellowThickness' ] = 0;
            dictContourLines[ 'yellowHeight' ] = min;
            dictContourLines[ 'greenThickness' ] = 0;
            dictContourLines[ 'greenHeight' ] = min;
            dictContourLines[ 'blueThickness' ] = 0;
            dictContourLines[ 'blueHeight' ] = min;
            initContours = 1;        

        labelColor = Tkinter.Label( self.dialog,
            text='Color   ' )
        labelColor.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                   row=0, rowspan=1, column=0, columnspan=2 )
        self.intColor = Tkinter.IntVar()
        self.intColor.set( self.vtkWindow.RED )
        radioRed = Tkinter.Radiobutton( self.dialog, text='Red', command=self.getRed,
                                  variable=self.intColor, value=self.vtkWindow.RED )
        radioRed.grid( sticky=Tkinter.SW,
                       row=0, rowspan=1, column=2, columnspan=2 )
        radioYellow = Tkinter.Radiobutton( self.dialog, text='Yellow', command=self.getYellow,
                                           value=self.vtkWindow.YELLOW, variable=self.intColor )
        radioYellow.grid( sticky=Tkinter.SW,
                          row=0, rowspan=1, column=4, columnspan=2 )
        radioGreen = Tkinter.Radiobutton( self.dialog, text='Green', command=self.getGreen,
                                                 variable=self.intColor,
                                                 value=self.vtkWindow.GREEN )
        radioGreen.grid( sticky=Tkinter.SW,
                                      row=0, rowspan=1, column=6, columnspan=2 )
        radioBlue = Tkinter.Radiobutton( self.dialog, text='Blue', command=self.getBlue,
                                                 variable=self.intColor,
                                                 value=self.vtkWindow.BLUE )
        radioBlue.grid( sticky=Tkinter.SW,
                                      row=0, rowspan=1, column=8, columnspan=2 )

        labelHeight = Tkinter.Label( self.dialog,
            text='Height:   ' )
        labelHeight.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                   row=1, rowspan=1, column=0, columnspan=2 )
        self.labelHeightValue = Tkinter.Label( self.dialog, text='  0',
                                               anchor=Tkinter.W)
        self.labelHeightValue.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=1, rowspan=1, column=2, columnspan=1 )
        self.sliderHeight = Tkinter.Scale( self.dialog, { 'from':min, 'to':max,
                                        'orient':Tkinter.HORIZONTAL,
                                        'showvalue':0 } )
        self.sliderHeight.grid( sticky=Tkinter.SW,
                                   row=1, rowspan=1, column=3, columnspan=6 )
        registerMouseEvents( self.sliderHeight, self.updateHeightValue )

        labelThickness = Tkinter.Label( self.dialog,
            text='Line Thickness:   ' )
        labelThickness.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                   row=2, rowspan=1, column=0, columnspan=2 )
        self.labelThicknessValue = Tkinter.Label( self.dialog, text='  1',
                                                  anchor=Tkinter.W)
        self.labelThicknessValue.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=2, rowspan=1, column=2, columnspan=1 )
        self.sliderThickness = Tkinter.Scale( self.dialog, { 'from':0, 'to':50,
                                        'orient':Tkinter.HORIZONTAL,
                                        'showvalue':0 } )
        self.sliderThickness.grid( sticky=Tkinter.SW,
                                   row=2, rowspan=1, column=3, columnspan=6 )
        registerMouseEvents( self.sliderThickness, self.updateThicknessValue )


        filler1 = Tkinter.Label( self.dialog, text=' ', anchor=Tkinter.W)
        filler1.grid( padx=5, pady=5, sticky=Tkinter.SW,
                     row=3, rowspan=1, column=0, columnspan=10 )


        filler2 = Tkinter.Label( self.dialog, text='       ', anchor=Tkinter.W)
        filler2.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=4, rowspan=1, column=0, columnspan=2 )
        labelRed = Tkinter.Label( self.dialog, text='Red', anchor=Tkinter.W)
        labelRed.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=4, rowspan=1, column=2, columnspan=2 )
        labelYellow = Tkinter.Label( self.dialog, text='Yellow', anchor=Tkinter.W)
        labelYellow.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=4, rowspan=1, column=4, columnspan=2 )
        labelGreen = Tkinter.Label( self.dialog, text='Green', anchor=Tkinter.W)
        labelGreen.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=4, rowspan=1, column=6, columnspan=2 )
        labelBlue = Tkinter.Label( self.dialog, text='Blue', anchor=Tkinter.W)
        labelBlue.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=4, rowspan=1, column=8, columnspan=2 )

        labelHeightLabel = Tkinter.Label( self.dialog, text='Height', anchor=Tkinter.W)
        labelHeightLabel.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=5, rowspan=1, column=0, columnspan=2 )
        self.labelRedHeight = Tkinter.Label( self.dialog,
                                             text=dictContourLines[ 'redHeight' ], anchor=Tkinter.W)
        self.labelRedHeight.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=5, rowspan=1, column=2, columnspan=2 )
        self.labelYellowHeight = Tkinter.Label( self.dialog,
                                                text=dictContourLines[ 'yellowHeight' ], anchor=Tkinter.W)
        self.labelYellowHeight.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=5, rowspan=1, column=4, columnspan=2 )
        self.labelGreenHeight = Tkinter.Label( self.dialog,
                                               text=dictContourLines[ 'greenHeight' ], anchor=Tkinter.W)
        self.labelGreenHeight.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=5, rowspan=1, column=6, columnspan=2 )
        self.labelBlueHeight = Tkinter.Label( self.dialog,
                                              text=dictContourLines[ 'blueHeight' ], anchor=Tkinter.W)
        self.labelBlueHeight.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=5, rowspan=1, column=8, columnspan=2 )


        labelThicknessLabel = Tkinter.Label( self.dialog, text='Thickness', anchor=Tkinter.W)
        labelThicknessLabel.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=6, rowspan=1, column=0, columnspan=2 )
        self.labelRedThickness = Tkinter.Label( self.dialog,
                                                text=dictContourLines[ 'redThickness' ], anchor=Tkinter.W)
        self.labelRedThickness.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=6, rowspan=1, column=2, columnspan=2 )
        self.labelYellowThickness = Tkinter.Label( self.dialog,
                                                   text=dictContourLines[ 'yellowThickness' ], anchor=Tkinter.W)
        self.labelYellowThickness.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=6, rowspan=1, column=4, columnspan=2 )
        self.labelGreenThickness = Tkinter.Label( self.dialog,
                                                  text=dictContourLines[ 'greenThickness' ], anchor=Tkinter.W)
        self.labelGreenThickness.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=6, rowspan=1, column=6, columnspan=2 )
        self.labelBlueThickness = Tkinter.Label( self.dialog,
                                                 text=dictContourLines[ 'blueThickness' ], anchor=Tkinter.W)
        self.labelBlueThickness.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                    row=6, rowspan=1, column=8, columnspan=2 )

        self.statusLabel = Tkinter.Label( self.dialog, relief=Tkinter.SUNKEN,
                                          text=' ', justify=Tkinter.LEFT,
                                          anchor=Tkinter.W, width=60 )
        self.statusLabel.grid( sticky=Tkinter.SW,
                               row=9, rowspan=1, column=0, columnspan=11)

    def getRed( self, *unusedArgument ):
        self.sliderHeight.set( dictContourLines[ 'redHeight' ] )
        self.labelHeightValue.config( text=dictContourLines[ 'redHeight' ] )
        self.sliderThickness.set( dictContourLines[ 'redThickness' ] )
        self.labelThicknessValue.config( text=dictContourLines[ 'redThickness' ] )

    def getGreen( self, *unusedArgument ):
        self.sliderHeight.set( dictContourLines[ 'greenHeight' ] )
        self.labelHeightValue.config( text=dictContourLines[ 'greenHeight' ] )
        self.sliderThickness.set( dictContourLines[ 'greenThickness' ] )
        self.labelThicknessValue.config( text=dictContourLines[ 'greenThickness' ] )
        
    def getBlue( self, *unusedArgument ):
        self.sliderHeight.set( dictContourLines[ 'blueHeight' ] )
        self.labelHeightValue.config( text=dictContourLines[ 'blueHeight' ] )
        self.sliderThickness.set( dictContourLines[ 'blueThickness' ] )
        self.labelThicknessValue.config( text=dictContourLines[ 'blueThickness' ] )
        
    def getYellow( self, *unusedArgument ):
        self.sliderHeight.set( dictContourLines[ 'yellowHeight' ] )
        self.labelHeightValue.config( text=dictContourLines[ 'yellowHeight' ] )
        self.sliderThickness.set( dictContourLines[ 'yellowThickness' ] )
        self.labelThicknessValue.config( text=dictContourLines[ 'yellowThickness' ] )

    def updateHeightValue( self, *unusedArgument ):
        value = self.sliderHeight.get()
        self.labelHeightValue.config( text="%3d"%value )
        color = self.intColor.get()
        
        if ( color == self.vtkWindow.RED ):
            dictContourLines[ 'redHeight' ] = value
            self.labelRedHeight.config( text="%3d"%value )
 
        elif ( color == self.vtkWindow.YELLOW ):
            dictContourLines[ 'yellowHeight' ] = value
            self.labelYellowHeight.config( text="%3d"%value )
            
        elif ( color == self.vtkWindow.GREEN ):
            dictContourLines[ 'greenHeight' ] = value
            self.labelGreenHeight.config( text="%3d"%value )
             
        elif ( color == self.vtkWindow.BLUE ):
            dictContourLines[ 'blueHeight' ] = value
            self.labelBlueHeight.config( text="%3d"%value )
 
        self.vtkWindow.setContourLineHeight( color, value )            


    def updateThicknessValue( self, *unusedArgument ):
        value = self.sliderThickness.get() / 10.0
        self.labelThicknessValue.config( text=value )
        color = self.intColor.get()

        if ( color == self.vtkWindow.RED ):
            dictContourLines[ 'redThickness' ] = value
            self.labelRedThickness.config( text=value )

        elif ( color == self.vtkWindow.YELLOW ):
            dictContourLines[ 'yellowThickness' ] = value
            self.labelYellowThickness.config( text=value )
                    
        elif ( color == self.vtkWindow.GREEN ):
            dictContourLines[ 'greenThickness' ] = value
            self.labelGreenThickness.config( text=value )      
            
        elif ( color == self.vtkWindow.BLUE ):
            dictContourLines[ 'blueThickness' ] = value
            self.labelBlueThickness.config( text=value )

        self.vtkWindow.setContourLineThickness( color, value )             


class DialogFileOpen:
    def __init__(self, rootWindow, vtkWindow ):
        self.RGB = 3
        self.GRAYSCALE = 1
        
        self.dialog = Tkinter.Toplevel( rootWindow )
        self.dialog.title( 'Open' )
        self.dialog.resizable( 0,0 )
        self.vtkWindow = vtkWindow

        labelElevation = Tkinter.Label( self.dialog,
            text='Elevation File' )
        labelElevation.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                  row=0, rowspan=1, column=0, columnspan=4 )
        self.entryElevation = Tkinter.Entry( self.dialog, justify=Tkinter.LEFT, width=50 )
        self.entryElevation.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                  row=0, rowspan=1, column=4, columnspan=10 )

        labelElevationWidth = Tkinter.Label( self.dialog,
            text='Image Width' )
        labelElevationWidth.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                  row=1, rowspan=1, column=0, columnspan=4 )
        self.entryElevationWidth = Tkinter.Entry( self.dialog,
                                                  justify=Tkinter.LEFT )
        self.entryElevationWidth.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                  row=1, rowspan=1, column=4, columnspan=3 )

        labelElevationHeight = Tkinter.Label( self.dialog,
            text='Image Height' )
        labelElevationHeight.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                  row=2, rowspan=1, column=0, columnspan=4 )
        self.entryElevationHeight = Tkinter.Entry( self.dialog, justify=Tkinter.LEFT )
        self.entryElevationHeight.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                  row=2, rowspan=1, column=4, columnspan=1 )

        labelElevationColorType = Tkinter.Label( self.dialog,
            text='Image Color Type' )
        labelElevationColorType.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                   row=3, rowspan=1, column=0, columnspan=4 )
        self.intElevationColorType = Tkinter.IntVar()
        radioElevationRGB = Tkinter.Radiobutton( self.dialog, text='RGB',
                              variable=self.intElevationColorType, value=self.RGB )
        radioElevationRGB.grid( sticky=Tkinter.SW,
                                row=3, rowspan=1, column=4, columnspan=1 )
        radioElevationGrayscale = Tkinter.Radiobutton( self.dialog, text='Grayscale',
                                    variable=self.intElevationColorType,
                                    value=self.GRAYSCALE )
        radioElevationGrayscale.grid( sticky=Tkinter.SW,
                                      row=3, rowspan=1, column=5, columnspan=1 )


        filler1 = Tkinter.Label( self.dialog,
            text='                                                  ' )
        filler1.grid( padx=5, pady=5, sticky=Tkinter.SW,
                      row=4, rowspan=1, column=0, columnspan=10 )
        

        labelTexture = Tkinter.Label( self.dialog,
            text='Texture File' )
        labelTexture.grid( padx=5, pady=5, sticky=Tkinter.SW,
                           row=5, rowspan=1, column=0, columnspan=4 )
        self.entryTexture = Tkinter.Entry( self.dialog, justify=Tkinter.LEFT, width=50 )
        self.entryTexture.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                row=5, rowspan=1, column=4, columnspan=10 )

        labelTextureWidth = Tkinter.Label( self.dialog,
            text='Image Width' )
        labelTextureWidth.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                row=6, rowspan=1, column=0, columnspan=4 )
        self.entryTextureWidth = Tkinter.Entry( self.dialog, justify=Tkinter.LEFT )
        self.entryTextureWidth.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                  row=6, rowspan=1, column=4, columnspan=3 )

        labelTextureHeight = Tkinter.Label( self.dialog,
            text='Image Height' )
        labelTextureHeight.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                  row=7, rowspan=1, column=0, columnspan=4 )
        self.entryTextureHeight = Tkinter.Entry( self.dialog, justify=Tkinter.LEFT )
        self.entryTextureHeight.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                  row=7, rowspan=1, column=4, columnspan=3 )

        labelTextureColorType = Tkinter.Label( self.dialog,
            text='Image Color Type' )
        labelTextureColorType.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                   row=8, rowspan=1, column=0, columnspan=4 )
        self.intTextureColorType = Tkinter.IntVar()
        radioTextureRGB = Tkinter.Radiobutton( self.dialog, text='RGB',
                                  variable=self.intTextureColorType, value=self.RGB )
        radioTextureRGB.grid( sticky=Tkinter.SW,
                                row=8, rowspan=1, column=4, columnspan=1 )
        radioTextureGrayscale = Tkinter.Radiobutton( self.dialog, text='Grayscale',
                                                 variable=self.intTextureColorType,
                                                 value=self.GRAYSCALE )
        radioTextureGrayscale.grid( sticky=Tkinter.SW,
                                      row=8, rowspan=1, column=5, columnspan=1 )


        filler2 = Tkinter.Label( self.dialog,
            text='          ' )
        filler2.grid( padx=5, pady=5, sticky=Tkinter.SW,
                                  row=9, rowspan=1, column=0, columnspan=1 )


        self.buttonOK = Tkinter.Button( self.dialog,
            text='    OK    ', command=self.doOK )
        self.buttonOK.grid( padx=5, pady=5, sticky=Tkinter.SW,
                            row=10, rowspan=1, column=4, columnspan=3 )

        self.buttonCancel = Tkinter.Button( self.dialog,
            text='   Cancel  ', command=self.doCancel )
        self.buttonCancel.grid( padx=5, pady=5, sticky=Tkinter.SW,
                            row=10, rowspan=1, column=5, columnspan=3 )

        self.statusLabel = Tkinter.Label( self.dialog, relief=Tkinter.SUNKEN,
                                          text='OK', justify=Tkinter.LEFT,
                                          anchor=Tkinter.W, width=70 )
        self.statusLabel.grid( sticky=Tkinter.SW,
                               row=11, rowspan=1, column=0, columnspan=11)

        

    def doOK( self ):
        global disableMenus
        
        dictFileData = {}
        dictFileData[ 'elevationFile' ] = self.entryElevation.get()
        dictFileData[ 'elevImageWidth' ] = int( self.entryElevationWidth.get() )
        dictFileData[ 'elevImageHeight' ] = int( self.entryElevationHeight.get() )
        dictFileData[ 'elevColorType' ] = self.intElevationColorType.get()
        dictFileData[ 'textureFile' ] = self.entryTexture.get()
        dictFileData[ 'texImageWidth' ] = int( self.entryTextureWidth.get() )
        dictFileData[ 'texImageHeight' ] = int( self.entryTextureHeight.get() )
        dictFileData[ 'texColorType' ] = self.intTextureColorType.get()            

        print dictFileData
        statusValue = self.vtkWindow.prepareFiles( dictFileData )

        print "Returned with status ", statusValue
        if ( statusValue == self.vtkWindow.OK ):
            print "ok"
            self.statusLabel.config( text='Both files were successfully opened. '
                + 'Click on the window to update.' )
            disableMenus = 0
            print disableMenus
            
        elif ( statusValue == self.vtkWindow.NO_FILE_TEXTURE ):
            print "no texture"
            self.statusLabel.config( text='>>>>> The texture file named'
                + dictFileData[ 'textureFile' ] + ' could not be opened.' )
            disableMenus = 1
            print disableMenus
            
        elif ( statusValue == self.vtkWindow.NO_FILE_ELEVATION ):
            print "no elevation"            
            self.statusLabel.config( text='>>>>> The elevation file named'
                + dictFileData[ 'elevationFile' ] + ' could not be opened.' )
            disableMenus = 1
            print disableMenus            
            
        self.dialog.destroy()

    def doCancel( self ):
        print "Clear status"
        self.status = 0
        self.dialog.destroy()

    def update( self, *unusedArgument ):
        self.label.config( text=self.slider.get() )

    def getStatus( self ):
        return self.statusValue


class GUI:
    def __init__( self, rootWindow ):
        self.TRUE = 1
        self.FALSE = 0
        
        # Create window frame
        self.rootWindow = rootWindow
        rootWindow.title( 'Project 1' )
        frame = Tkinter.Frame( self.rootWindow )
        self.disableMenus = self.TRUE

        # Add menu bar
        menuBar = Tkinter.Menu( frame )
        self.rootWindow.config( menu=menuBar )
        self.buildMenu( menuBar )

        # Add VTK rendering viewport
        self.vtkViewport = VTKRender( frame )
        frame.pack( fill=Tkinter.BOTH, expand=1, side=Tkinter.TOP )

        # Add pseudo-status bar (from "An Introduction to Tkinter" )
        self.statusLabel = Tkinter.Label( frame, relief=Tkinter.SUNKEN,
                                          text='by Allan Spale',
                                          justify=Tkinter.LEFT,
                                          anchor=Tkinter.W )
        self.statusLabel.pack( fill=Tkinter.BOTH, side=Tkinter.BOTTOM )

        self.frame=frame
        
    
    def show_dialog( self ):
        d = MyDialog(self.master)
        self.master.wait_window(d.top)

        
    def buildMenu( self, menuMainMenu ):          
        menuFile = Tkinter.Menu( menuMainMenu, tearoff=0 )
        menuFile.add_command( label='Open', command=self.doMenuFileOpen )
        menuFile.add_separator()       
        menuFile.add_command( label='Exit', command=self.doMenuFileExit )
        menuMainMenu.add_cascade( label='File', menu=menuFile )

        menuViz = Tkinter.Menu( menuMainMenu, tearoff=0 )
        menuViz.add_command( label='Colormap', command=self.doMenuVizColormap )
        menuViz.add_command(
            label='Contour Lines', command=self.doMenuVizContour )
        #menuViz.add_command(
        #    label='Contour Lines Only', command=self.doMenuVizContourOnly )        
        menuViz.add_command(
            label='Grayscale', command=self.doMenuVizElevation )
        menuViz.add_command( label='Texture', command=self.doMenuVizTexture )
        menuMainMenu.add_cascade( label='Visualization', menu=menuViz )

        menuOptions = Tkinter.Menu( menuMainMenu, tearoff=0 )
        menuOptions.add_command(
            label='Landscape', command=self.doMenuOptionsLandscape )
        menuMainMenu.add_cascade( label='Options', menu=menuOptions )


    ####################### MENU PROCESSING #################################
    def updateMenuStatus( self ):
        status = dialog.getStatusValue()

        if ( status == self.vtkViewport.OK ):
            self.disableMenus = self.FALSE        


    def doMenuFileOpen(self):
        dialog = DialogFileOpen( self.frame, self.vtkViewport )

        
    def doMenuFileClose(self):
        pass


    def doMenuFileExit(self):
        self.vtkViewport.destroy()
        self.rootWindow.destroy()
        sys.exit( 0 )


    def doMenuVizColormap(self):
        print disableMenus
        if ( disableMenus == self.TRUE ):
            self.statusLabel.config( text='>>>>> Please open a file.' )
        else:
            self.vtkViewport.setViewColormap()
            #dialogColormap = DialogColormap( self.frame )
            self.statusLabel.config( text='Viewing colormap.  '
                + 'Click in the window to update.' )


    def doMenuVizContour(self):
        print disableMenus
        if ( disableMenus == self.TRUE ):
            self.statusLabel.config( text='>>>>> Please open a file.' )
        else:
            self.statusLabel.config( text='Viewing contour lines. '
                + 'Click in the window to update.' )
            self.vtkViewport.setViewContours()
            dialogContour = DialogContourLines( self.frame,
                                                self.vtkViewport )
    def doMenuVizContourOnly(self):
        print disableMenus
        if ( disableMenus == self.TRUE ):
            self.statusLabel.config( text='>>>>> Please open a file.' )
        else:
            self.statusLabel.config( text='Viewing only contour lines. '
                + 'Click in the window to update.' )
            self.vtkViewport.setViewContoursOnly()
            dialogContour = DialogContourLines( self.frame,
                                                self.vtkViewport )


    def doMenuVizElevation(self):
        print disableMenus
        if ( disableMenus == self.TRUE ):
            self.statusLabel.config( text='>>>>> Please open a file.' )
        else:
            self.statusLabel.config( text='Viewing elevation grayscale. '
                + 'Click in the window to update.' )        
            self.vtkViewport.setViewElevation()


    def doMenuVizTexture(self):
        print disableMenus
        if ( disableMenus == self.TRUE ):
            self.statusLabel.config( text='>>>>> Please open a file.' )
        else:
            self.statusLabel.config( text='Viewing elevation texture. '
                + 'Click in the window to update.' )
            self.vtkViewport.setViewTexture()


    def doMenuOptionsLandscape(self):
        if ( disableMenus == self.TRUE ):
            self.statusLabel.config( text='>>>>> Please open a file.' )
        else:
            dialogOptions = DialogLandscapeOptions( self.frame, self.vtkViewport )
    
    ############################ END OF MENU PROCESSING ####################
    
#-------------------- END OF CLASS: GUI ------------------------------------


#### main function ####
root = Tkinter.Tk()
gui = GUI(root)
root.mainloop()
