from platform import system as ostype
from os.path import basename
from os.path import exists
from os import chdir
from os import remove
from os import chmod
from os import popen
from pickle import loads
from pickle import dumps
from time import localtime
import Pmw
import Tkinter
import tkFont
import tkMessageBox
from path import path

    
class MsgBox:
    """ A class to create an error message box for ease of use."""
    def __init__( self, parent, error ):
        self.error = error
        self.parent = parent
        tkMessageBox.showwarning( "Error!", self.error )
        return
        
class ReportViewer:
    """ A class to create the report viewer window. Has the options to quit and print."""
    def __init__( self, parent, report ):
        self.checkerreport = report
        self.window = Tkinter.Toplevel( parent )
        self.font = tkFont.Font( family = "Arial", size = "10" )
        self.window.option_add( "*Font", "Arial 10" )
        self.window.title( "Report Viewer" )
        self.fixedFont = Pmw.logicalfont( 'Fixed' )
        self.output = Pmw.ScrolledText( self.window,
                                        hull_width = 300,
                                        hull_height = 250,
                                        text_font = self.font,
                                        text_padx = 2,
                                        text_pady = 2,
                                        text_state = 'disabled' )
        self.output.pack( padx = 1, pady = 3 )
        self.button_group = Pmw.Group( self.window, tag_text = "Options" )
        self.button_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )
        Tkinter.Label( self.button_group.interior(),
                      text = "Print button prints to your default printer" ).pack( anchor = 'w' )
        self.buttons = Pmw.ButtonBox( self.button_group.interior() )
        self.buttons.pack( padx = 5, pady = 5, anchor = 'e' )
        self.buttons.add( 'Print', command = lambda
                                              arg1 = self.checkerreport:
                                              self.Print( arg1 ) )
        self.buttons.add( 'Quit', command = self.Quit )
        
        self.output.clear()
        # Open the report, read and insert the contents
        input = file( self.checkerreport, 'r' )
        while 1:
            line = input.readline()
            if not line:
                break
            self.output.appendtext( str( line ) )
        
    def Print( self, checkerreport ):
        """ Print the report. Print method depends on OS."""
        if ostype() == "SunOS":
            command = "lp " + self.checkerreport
            system( command )
        elif ostype() == "Windows":
            from win32com.client import Dispatch
            word = Dispatch( 'Word.Application' )
            doc = word.Documents.Add( self.checkerreport )
            doc.PrintOut()
            doc.Close()
        else:
            MsgBox( self.window, "An error occured in the Print function" )
            
    def Quit( self ):
        self.window.destroy()
   
class CheckerWindow:
    """
    Window that executes the checker and redirects STDOUT to a text field for viewing.
    Provides buttons to accept the checker run and view the report
    """
    def __init__( self, parent, checkerApp, checker, command, report ):
        self.checkerreport = report
        self.checkerApp = checkerApp
        self.checker = checker
        self.myparent = parent
        self.command = command
        self.window = Tkinter.Toplevel( parent )
        self.window.option_add( "*Font", "Arial 10" )
        self.font = tkFont.Font( family = "Arial", size = "10" )
        self.window.title( "Output for checker : " + self.checker )
        self.output = Pmw.ScrolledText( self.window,
                                        hull_width = 300,
                                        hull_height = 250,
                                        text_font = self.font,
                                        text_padx = 2,
                                        text_pady = 2 )
        self.output.pack( padx = 1, pady = 3 )
        self.button_group = Pmw.Group( self.window, tag_text = "Options" )
        self.button_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )
        Tkinter.Label( self.button_group.interior(),
                       text = "Click 'Accept' if the report ran correctly." ).pack( anchor = 'w' )
        Tkinter.Label( self.button_group.interior(),
                       text = "Click 'Cancel' if there were errors." ).pack( anchor = 'w' )
        self.buttons = Pmw.ButtonBox( self.button_group.interior() )
        self.buttons.pack( padx = 5, pady = 5, anchor = 'e' )
        self.buttons.add( 'Run Checker', command = self.Run )
        if report:
            self.buttons.add( 'View Report', command = self.ViewReport )
        self.buttons.add( 'Accept', command = self.Accept )
        self.buttons.add( 'Cancel', command = self.Cancel )


    def Run( self ):
        input = popen( self.command, 'r' )
        self.Clear()
        while 1:
            line = input.readline()
            if not line:
                break
            self.Insert( str( line ) )

    def Accept( self  ):
        self.checkerApp.CheckerAccept( self.checker, self.checkerreport )
        self.window.destroy()
                
    def Cancel( self ):
        #self.checkerApp.CheckerCancel( checker, checkerreport )
        self.window.destroy()
    
    def Clear( self ):
        self.output.clear()

    def Insert( self, data ):
        self.output.appendtext( data )
        
    def  ViewReport( self ):
        if not exists( self.checkerreport ):
            MsgBox( self.window, "The report does not exist!" )
        else:
            ReportViewer( self.window, self.checkerreport )

class CheckerApp:
    """
    Main Window that displays the buttons to run the various checker programs.
    """
    STATUSFILE = 'chk_status'
    OPTIONS = {}
    BINPATH = path( 'c:\\usr\\geoset\\bin\\' )
    SSBIN = path( 'c:\\usr\\geoset\\bin\\start_socet.bat -single ' )
    PROJPATH = path( 'c:\\usr\\geoset\\data\\' )
        
    def __init__( self, parent, project, database, dbpath ):
        # Window Initialization routines
        self.PROJECT = project
        self.DATABASE = database
        self.DBPATH = dbpath
        self.newroot = Tkinter.Toplevel()
        self.newroot.resizable( width = False, height = False )
        self.newroot.option_add( "*Font", "Arial 10" )
        self.newroot.title( "SAIC Checker Front End" )
        self.newroot.focus_set()

        # Change the current working directory to the database directory
        # so that the checkers function correctly.
        chdir( path( dbpath ).joinpath( path( database ) ) )

        # Check for the existance of 'chk_status' if it doesn't, exist, create it with defaults
        # if it does exist, load it.
        if not exists( self.STATUSFILE ):
            self.OPTIONS = { 'SAC_adj_bldg_hts' : [ "", "" ],
                             'ftr_count' : [ "", ".cnt" ],
                             'find_dup_feat' : [ "", ".df" ],
                             'nweed_gp' : [ "", ".wg " ],
                             'SAC_populate' : [ "", ".auto_rep" ],
                             'SAC_validity_check' : [ "", ".nvc" ],
                             'OIS_parser' : [ "", ".txt" ],
                             'SAC_VO_finder' : [ "", ".vof" ] }
            self.SaveStatus()
        else:
            try:
                self.LoadStatus()
            except:
                MsgBox( self.newroot, "There is an error loading the 'fe_status' file. Delete the file and try again" )
                
        # Create a status bar
        self.statusbar = Tkinter.Label( self.newroot, bd = 1, relief = Tkinter.SUNKEN,
                                        anchor = Tkinter.W )
        self.statusbar.pack( side = Tkinter.BOTTOM, fill = 'x' )

        # Setup the bottom two buttons ('quit' and 'final report')
        self.bottom_frame = Tkinter.Frame( self.newroot )
        self.bottom_frame.pack( side = Tkinter.BOTTOM )
        self.left_bottom_frame = Tkinter.Frame( self.bottom_frame )
        self.left_bottom_frame.pack( padx = 10, pady = 5, side = Tkinter.LEFT )
        self.right_bottom_frame = Tkinter.Frame( self.bottom_frame )
        self.right_bottom_frame.pack( padx = 10, pady = 5, side = Tkinter.RIGHT )
        Tkinter.Button( self.left_bottom_frame, text = "Quit", command = self.newroot.destroy ).pack( pady = 5 )
        Tkinter.Button( self.right_bottom_frame, text = "Final Report", command = self.PrintFinalReport ).pack( pady = 5 )
        
        #############################################
        #            Information Group              #
        #############################################
        self.info_group = Pmw.Group( self.newroot, tag_text = "Information" )
        self.info_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )
        Tkinter.Label( self.info_group.interior(), text = "Project : " + project, width = 45, anchor = Tkinter.CENTER ).pack()
        Tkinter.Label( self.info_group.interior(), text = "Database : " + database, width = 45, anchor = Tkinter.CENTER ).pack()

        #############################################
        #         Weed Ground Point Group           #
        #############################################
        # Variable to hold the last-ran date
        self.weed_gp_run = Tkinter.StringVar()

        # Setup the initial PMW group for labels and buttons
        self.weed_gp_group = Pmw.Group( self.newroot, tag_text = "Weed Ground Points" )
        self.weed_gp_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )

        # Setup the frames to split the PMW group into left and right sides (for button placement)
        self.left_weed_gp_frame = Tkinter.Frame( self.weed_gp_group.interior() )
        self.left_weed_gp_frame.pack( side = Tkinter.LEFT )
        self.right_weed_gp_frame = Tkinter.Frame( self.weed_gp_group.interior() )
        self.right_weed_gp_frame.pack( side = Tkinter.RIGHT )

        # Check to see if the program has been ran and accepted before in the fe_status file
        if self.OPTIONS['nweed_gp'][ 0 ] == "":
            self.weed_gp_run.set( "Last ran on : Never" )
        else:
            self.weed_gp_run.set( "Last ran on : " + self.OPTIONS[ 'nweed_gp' ][ 0 ] )

        # Label that actually displays the self.weed_gp_run StringVar
        Tkinter.Label( self.left_weed_gp_frame, textvariable = self.weed_gp_run ).pack( side = Tkinter.LEFT )

        # Create a button group and add  buttons to it
        self.weed_gp_btns = Pmw.ButtonBox( self.right_weed_gp_frame )
        self.weed_gp_btns.pack( fill = 'both', expand = 'yes', padx = 5, pady = 5, side = Tkinter.LEFT )
        self.weed_gp_btns.add( 'View Report', command = lambda arg1 = "nweed_gp": self.ViewReport( arg1 ) )
        self.weed_gp_btns.add( 'Run Checker', command = lambda arg1 = 'nweed_gp': self.RunChecker( arg1 ) )

        # Do not show the Find Duplicate Features Group if the database is a VOL database
        if not self.DATABASE.count( "VOL" ):
            #############################################
            #      Find Duplicate Features Group        #
            #############################################
            # Variable to hold the last-ran date
            self.fnd_dup_run = Tkinter.StringVar()

            # Setup initial PMW group for labels and buttons
            self.fnd_dup_group = Pmw.Group( self.newroot, tag_text = "Find Duplicate Features" )
            self.fnd_dup_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )
            self.fnd_dup_run = Tkinter.StringVar()

            # Setup the frames to split the PMW group into left and right sides (for button placement)
            self.left_fnd_dup_frame = Tkinter.Frame( self.fnd_dup_group.interior() )
            self.left_fnd_dup_frame.pack( side = Tkinter.LEFT )
            self.right_fnd_dup_frame = Tkinter.Frame( self.fnd_dup_group.interior() )
            self.right_fnd_dup_frame.pack( side = Tkinter.RIGHT )

            # Check to see if the program has been ran and accepted before in the fe_status file
            if self.OPTIONS[ 'find_dup_feat' ][ 0 ] == "":
                self.fnd_dup_run.set( "Last ran on : Never" )
            else:
                self.fnd_dup_run.set( "Last ran on : " + self.OPTIONS[ 'find_dup_feat' ][ 0 ] )

            # Label that actually displays the self.find_dup_run StringVar
            Tkinter.Label( self.left_fnd_dup_frame, textvariable = self.fnd_dup_run ).pack( side = Tkinter.LEFT )

            # Create a button group and add buttons to it
            self.fnd_dup_btns = Pmw.ButtonBox( self.right_fnd_dup_frame )
            self.fnd_dup_btns.pack( fill = 'both', expand = 'yes', padx = 5, pady = 5, side = Tkinter.LEFT )
            self.fnd_dup_btns.add( 'View Report', command = lambda arg1 = 'find_dup_feat': self.ViewReport( arg1 ) )
            self.fnd_dup_btns.add( 'Run Checker', command = lambda arg1 = 'find_dup_feat': self.RunChecker( arg1 ) )

        # Only show the Adjust Building Heights Group if the database is a PLAN database
        if self.DATABASE.count( "PLAN" ):
            #############################################
            #     Adjust Building Heights Group         #
            #############################################
            # Variable to hold the last-ran date
            self.adj_hts_run = Tkinter.StringVar()

            # Setup initial PMW group for labels and buttons
            self.adj_hts_group = Pmw.Group( self.newroot, tag_text = "Adjust Building Heights" )
            self.adj_hts_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )

            # Setup the frames to split the PMW group into left and right sides (for button placement)
            self.left_adj_hts_frame = Tkinter.Frame( self.adj_hts_group.interior(), width = 35 )
            self.left_adj_hts_frame.pack( side = Tkinter.LEFT )
            self.right_adj_hts_frame = Tkinter.Frame( self.adj_hts_group.interior() )
            self.right_adj_hts_frame.pack( side = Tkinter.RIGHT )
            
            # Check to see if the program has been ran and accepted before in the fe_status file
            if self.OPTIONS[ 'SAC_adj_bldg_hts' ][ 0 ] == "":
                self.adj_hts_run.set( "Last ran on : Never" )
            else:
                self.adj_hts_run.set( "Last ran on : " + self.OPTIONS[ 'SAC_adj_bldg_hts' ][ 0 ] )

            # Label that actually displays self.adj_hts_run StringVar
            Tkinter.Label( self.left_adj_hts_frame, textvariable = self.adj_hts_run ).pack( side = Tkinter.LEFT )

            # Create a button group and add buttons to it (this checker only has 1 button)
            self.adj_hts_btns = Pmw.ButtonBox( self.right_adj_hts_frame )
            self.adj_hts_btns.pack( fill = 'both', expand = 'yes', padx = 5, pady = 5, side = Tkinter.RIGHT )
            self.adj_hts_btns.add( 'Run Checker', command = lambda arg1 = 'SAC_adj_bldg_hts': self.RunChecker( arg1 ) )

        # All databases get Airfields Populator Group
        #############################################
        #            Airfields Populator Group      #
        #############################################
        # Variable to hold the last-ran date
        self.af_pop_run = Tkinter.StringVar()

        # Setup the initial PMW group for labels and buttons
        self.af_pop_group = Pmw.Group( self.newroot, tag_text = " Airfields Populator" )
        self.af_pop_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )

        # Setup the frames to split the PMW group into left and right sides (for button placement)
        self.left_af_pop_frame = Tkinter.Frame( self.af_pop_group.interior() )
        self.left_af_pop_frame.pack( side = Tkinter.LEFT )
        self.right_af_pop_frame = Tkinter.Frame( self.af_pop_group.interior() )
        self.right_af_pop_frame.pack( side = Tkinter.RIGHT )

        # Check to see if the program has been ran and accepted before in the fe_status file
        if self.OPTIONS[ 'SAC_populate' ][ 0 ] == "":
            self.af_pop_run.set( "Last ran on : Never" )
        else:
            self.af_pop_run.set( "Last ran on : " + self.OPTIONS[ 'SAC_populate' ][ 0 ] )

        # Label that actually displays the self.af_pop_run StringVar
        Tkinter.Label( self.left_af_pop_frame, textvariable = self.af_pop_run ).pack( side = Tkinter.LEFT )

        # Create a button group and add buttons to it
        self.af_pop_btns = Pmw.ButtonBox( self.right_af_pop_frame )
        self.af_pop_btns.pack( fill = 'both', expand = 'yes', padx = 5, pady = 5, side = Tkinter.LEFT )
        self.af_pop_btns.add( 'View Report', command = lambda arg1 = 'SAC_populate': self.ViewReport( arg1 ) )
        self.af_pop_btns.add( 'Run Checker', command = lambda arg1 = 'SAC_populate': self.RunChecker( arg1 ) )

        # Do not show the Airfields Validator Group if the database is a VOL database
        if not self.DATABASE.count( "VOL" ):
            #############################################
            #            Airfields Validator Group      #
            #############################################
            # Variable to hold the last-ran date
            self.af_val_run = Tkinter.StringVar()

            # Setup the initial PMW group for labels and buttons
            self.af_val_group = Pmw.Group( self.newroot, tag_text = "Airfields Validator" )
            self.af_val_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )

            # Setup the frames to split the PMW group into left and right sides (for button placement)
            self.left_af_val_frame = Tkinter.Frame( self.af_val_group.interior() )
            self.left_af_val_frame.pack( side = Tkinter.LEFT )
            self.right_af_val_frame = Tkinter.Frame( self.af_val_group.interior() )
            self.right_af_val_frame.pack( side = Tkinter.RIGHT )
            
            # Check to see if the program has been ran and accepted before in the fe_status file
            if self.OPTIONS[ 'SAC_validity_check' ][ 0 ] == "":
                self.af_val_run.set( "Last ran on : Never" )
            else:
                self.af_val_run.set( "Last ran on " + self.OPTIONS[ 'SAC_validity_check' ][ 0 ] )

            # Label that actually displays the self.af_val_run StringVar
            Tkinter.Label( self.left_af_val_frame, textvariable = self.af_val_run ).pack( side = Tkinter.LEFT )

            # Create a button group and add buttons to it
            self.af_val_btns = Pmw.ButtonBox( self.right_af_val_frame )
            self.af_val_btns.pack( fill = 'both', expand = 'yes', padx = 5, pady = 5, side = Tkinter.RIGHT )
            self.af_val_btns.add( 'View Report', command = lambda arg1 = 'SAC_validity_check': self.ViewReport( arg1 ) )
            self.af_val_btns.add( 'Run Checker', command = lambda arg1 = 'SAC_validity_check': self.RunChecker( arg1 ) )
        # Do not show the Feature Counter Group if the database is a VOL database
        if not self.DATABASE.count( "VOL"):
            #############################################
            #         Feature Counter Group             #
            #############################################
            # Variable to hold the last-ran date
            self.ftr_count_run = Tkinter.StringVar()

            # Setup initial PMW group for labels and buttons
            self.ftr_count_group = Pmw.Group( self.newroot, tag_text = "Feature Counter" )
            self.ftr_count_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )

            # Setup the frames to split the PMW group into left and right sides (for button placement)
            self.left_ftr_count_frame = Tkinter.Frame( self.ftr_count_group.interior() )
            self.left_ftr_count_frame.pack( side = Tkinter.LEFT )
            self.right_ftr_count_frame = Tkinter.Frame( self.ftr_count_group.interior() )
            self.right_ftr_count_frame.pack( side = Tkinter.RIGHT )

            # Check to see if the program has been ran and accepted before in the fe_status file        
            if self.OPTIONS[ 'ftr_count' ][ 0 ] == "":
                self.ftr_count_run.set( "Last ran on : Never" )
            else:
                self.ftr_count_run.set( "Last ran on : " + self.OPTIONS[ 'ftr_count' ][ 0 ] )

            # Label that actually displays self.ftr_count_run StringVar
            Tkinter.Label( self.left_ftr_count_frame, textvariable = self.ftr_count_run ).pack( side = Tkinter.LEFT )

            # Create a button group and add buttons to it 
            self.ftr_count_btns = Pmw.ButtonBox( self.right_ftr_count_frame )
            self.ftr_count_btns.pack( fill = 'both', expand = 'yes', padx = 5, pady = 5, side = Tkinter.RIGHT )
            self.ftr_count_btns.add( 'View Report', command = lambda arg1 = 'ftr_count': self.ViewReport( arg1 ) )
            self.ftr_count_btns.add( 'Run Checker', command = lambda arg1 = 'ftr_count': self.RunChecker( arg1 ) )

        if self.DATABASE.count( "OIS" ):
            #############################################
            #               OIS Parser Group            #
            #############################################
            # Variable to hold the last-ran date
            self.ois_parser_run = Tkinter.StringVar()

            # Setup the initial PMW group for labels and buttons
            self.ois_parser_group = Pmw.Group( self.newroot, tag_text = "OIS Parser" )
            self.ois_parser_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )
            
            # Setup the frames to split the PMW group into left and right sides (for button placement)
            self.left_ois_parser_frame = Tkinter.Frame( self.ois_parser_group.interior() )
            self.left_ois_parser_frame.pack( side = Tkinter.LEFT )
            self.right_ois_parser_frame = Tkinter.Frame( self.ois_parser_group.interior() )
            self.right_ois_parser_frame.pack( side = Tkinter.RIGHT )

            # Check to see if the program has been ran and accepted before in the fe_status file
            if self.OPTIONS[ 'OIS_parser' ][ 0 ] == "":
                self.ois_parser_run.set( "Last ran on : Never" )
            else:
                self.ois_parser_run.set( "Last ran on : " + self.OPTIONS[ 'OIS_parser' ][ 0 ] )

            # Label that actually displays the self.ois_parser_run StringVar
            Tkinter.Label( self.left_ois_parser_frame, textvariable = self.ois_parser_run ).pack( side = Tkinter.LEFT )

            # Create a buytton group and add buttons to it
            self.ois_parser_btns = Pmw.ButtonBox( self.right_ois_parser_frame )
            self.ois_parser_btns.pack( fill = 'both', expand = 'yes', padx = 5, pady = 5, side = Tkinter.RIGHT )
            self.ois_parser_btns.add( 'View Report', command = lambda arg1 = 'OIS_parser': self.ViewReport( arg1 ) )        
            self.ois_parser_btns.add( 'Run Checker', command = lambda arg1 = 'OIS_parser': self.RunChecker( arg1 ) )

        # Only display the VO Finder Group if the database is a OIS database
        if self.DATABASE.count( "OIS" ):
            #############################################
            #              VO Finder Group              #
            #############################################        
            # Variable to hold the last-ran date
            self.vo_finder_run = Tkinter.StringVar()

            # Setup the initial PMW group for labels and buttons
            self.vo_finder_group = Pmw.Group( self.newroot, tag_text = "VO Finder" )
            self.vo_finder_group.pack( pady = 2, padx = 2, expand = 'yes', fill = 'both' )

            # Setup the frames to split the PMW group into left and right sides (for button placement)
            self.left_vo_finder_frame = Tkinter.Frame( self.vo_finder_group.interior() )
            self.left_vo_finder_frame.pack( side = Tkinter.LEFT )
            self.right_vo_finder_frame = Tkinter.Frame( self.vo_finder_group.interior() )
            self.right_vo_finder_frame.pack( side = Tkinter.RIGHT )

            # Check to see if the program has been ran and accepted before in the fe_status file
            if self.OPTIONS[ 'SAC_VO_finder' ][ 0 ] == "":
                self.vo_finder_run.set( "Last ran on : Never" )
            else:
                self.vo_finder_run.set( "Last ran on : " + self.OPTIONS[ 'SAC_VO_finder' ][ 0 ] )

            # Label that actually displays the self.vo_finder_run StringVar
            Tkinter.Label( self.left_vo_finder_frame, textvariable = self.vo_finder_run ).pack( side = Tkinter.LEFT )

            # Create a button group and add buttons to it
            self.vo_finder_btns = Pmw.ButtonBox( self.right_vo_finder_frame )
            self.vo_finder_btns.pack( fill = 'both', expand = 'yes', padx = 5, pady = 5, side = Tkinter.RIGHT )
            self.vo_finder_btns.add( 'View Report', command = lambda arg1 = 'SAC_VO_finder': self.ViewReport( arg1 ) )
            self.vo_finder_btns.add( 'Run Checker', command = lambda arg1 = 'SAC_VO_finder': self.RunChecker( arg1 ) )

    def RunChecker( self, checker ):
        """
        Instantiates the CheckerWindow class and runs the selected checker
        """
        self.statusbar.config( text = "Running Checker : " + checker )
        command = self.SSBIN + " " + checker + " " + self.PROJPATH + \
                  self.PROJECT + ".prj" + " " + path.joinpath( self.DBPATH, self.DATABASE )
        if self.OPTIONS[ checker ][ 1 ]:
            report = self.DBPATH.joinpath( self.DATABASE ) + self.OPTIONS[ checker ][ 1 ]
        else:
            report = ""

        # If the report exists already, remove it
        # we have to make sure report is good (sac_adj_bldg_hts does not have a report)
        if not report:
            if exists( report ):
                try:
                    remove( report )
                except:
                    MsgBox( self.newroot, "Error deleting existing report!" )
                
        # Do some sanity checks to check for Socet Set and Binaries for the Checkers
        # before we actually do the run.
        if not exists( self.SSBIN.split()[ 0 ] ):
            MsgBox( self.newroot, "There was an error locating the Socet Set programs" )
        elif not exists( self.BINPATH + checker + ".exe" ):
            MsgBox( self.newroot, "There was an error locating the checker : " + checker )
        else:
            CheckerWindow( self.newroot, self, checker, command, report )
            
    def CheckerAccept( self, checker, report ):
        """
        Accepts the checker run, adjusts the date in the OPTIONS file, and saves the file
        """
        if not exists( report ) and not checker == "SAC_adj_bldg_hts":
            MsgBox( "The report file was not found for this checker.\nThis indicates a software error. Please try rerunning the report" )
        else:
            date = str( + localtime()[ 1 ] ) + "/" + str( localtime()[ 2 ] )
            
            if checker == "ftr_count":
                self.ftr_count_run.set( "Last ran on : " + date )
            elif checker == "find_dup_feat":
                self.fnd_dup_run.set( "Last ran on : " + date )
            elif checker == "nweed_gp":
                self.weed_gp_run.set( "Last ran on : " + date )
            elif checker == "SAC_populate":
                self.af_pop_run.set( "Last ran on : " + date )
            elif checker == "SAC_validity_check":
                self.af_val_run.set( "Last ran on : " + date )
            elif checker == "SAC_adj_bldg_hts":
                self.adj_hts_run.set( "Last ran on: " + date )
            elif checker == "OIS_parser":
                self.ois_parser_run.set( "Last ran on: " + date )
            elif checker == "SAC_VO_finder":
                self.vo_finder_run.set( "Last ran on: " + date )
            else:
                pass

            # If the checker is accepted, update the dates in the status file and save the file
            # also open the permissions of the report file
            self.OPTIONS[ checker ][ 0 ] = date
            self.SaveStatus()
            self.newroot.focus_set()
            if exists( report ):
                chmod( report, 0777 )
            self.statusbar.config( text = "" )
    
    def CheckerCancel( self, checker ):
        pass
        
    def ViewReport( self, checker ):
        """
        Instatiates the ReportViewer class with the report for the passed checker
        """
        report = self.DBPATH.joinpath( self.DATABASE ) + self.OPTIONS[ checker ][ 1 ]

        # If the report doesn't exist, we can't view it
        if not exists( report ):
            MsgBox( self.newroot, "The report does not exist!" )
        else:
            ReportViewer( self.newroot, report )
                
    def SaveStatus( self ):
        """
        Saves a pickled self.OPTIONS dictionary to self.STATUSFILE
        """
        file = open( self.STATUSFILE, 'wb' )
        file.write( dumps( self.OPTIONS, 1 ) )
        file.close()

    def LoadStatus( self ):
        """
        Loads a picked self.OPTIONS dictionary from self.STATUSFILE
        """
        file = open( self.STATUSFILE, 'rb' )
        buffer = ""
        while 1:
            data = file.read()
            if data == "":
                break
            buffer += data
        self.OPTIONS = loads( buffer )
        file.close()

    def PrintFinalReport( self ):
        """
        Prints a final project report, documenting what checkers have been ran and
        the dates that they were run.
        """
        self.statusbar.config( text = "This has no function yet!" )
        
class MainApp:
    def __init__( self, parent ):
        self.myparent = parent
        
        if ostype() == "Windows":
            self.projpath = path('c:\usr\geoset\data')
        elif ostype() == "SunOS":
            self.projpath = path('/usr/geoset/data' )
        else:
            print "Non-supported platform"
            return
        
        # Create a status bar
        self.statusbar = Tkinter.Label( parent, bd = 1, relief = Tkinter.SUNKEN,
                                        anchor = Tkinter.W )
        self.statusbar.grid( row = 99, column = 0, columnspan = 2,
                             sticky = Tkinter.NE + Tkinter.SW )

        # Setup the dropdown list and select button
        self.projmenu = Pmw.ComboBox( parent,
                                      label_text = "Select a Project : ",
                                      labelpos = 'w',
                                      scrolledlist_items = self.InitProjList(),
                                      selectioncommand = self.PrjSelection)
        self.projmenu.grid( row = 0, column = 0, pady = 5, sticky = Tkinter.W )

        # Setup the List Box with available databases
        self.dblist = Pmw.ScrolledListBox( parent, labelpos = 'w',
                                           label_text = 'Databases',
                                           listbox_height = 10,
                                           listbox_width = 30,
                                           scrollmargin = 1,
                                           hull_width = 200,
                                           hull_height = 200,
                                           vscrollmode = 'static' )
        self.dblist.grid( row = 2, column = 0, sticky = Tkinter.W, pady = 5 )

        # Button Box for Select and Quit buttons

        self.buttons = Pmw.ButtonBox( parent )
        self.buttons.grid( row = 3, column = 0, pady = 10 )
        self.buttons.add( 'Select Database', command = self.DBSelectButton )
        self.buttons.add( 'Quit', command = parent.destroy )
        self.buttons.setdefault( 'Select Database' )
        
    def PrjSelection( self, event  ):
        # Callback for selecting a project from the dropdown list
        if self.projmenu.get() == "":
            self.statusbar.config( text = "You must select a project first!")
        else:
            self.statusbar.config( text = "" )
            databases = self.InitDBList( self.projmenu.get() )
            self.dblist.clear()
            if databases:
                for database in databases:
                    self.dblist.insert( Tkinter.END, basename( database ) )
            else:
                self.dblist.insert( Tkinter.END, "NO DATABASES AVAILABLE" )

    def DBSelectButton( self ):
        # Callback for selecting a database then clicking the button.
        if self.projmenu.get() == "":
            self.statusbar.config( text = "You must select a project, then a database!" )
            return
        if not self.dblist.getvalue():
            self.statusbar.config( text = "You must select a database first!" )
            return
        if self.dblist.getvalue()[0] == "NO DATABASES AVAILABLE":
            self.statusbar.config( text = "This is not a valid database" )
            return
        else:
            self.statusbar.config( text = "" )
            CheckerApp( self.myparent, self.projmenu.get(),
                                        self.dblist.getvalue()[ 0 ], self.dbpath )
            
    def InitProjList( self ):
        # Initialization of the project dropdown list
        projlist = []
        for file in self.projpath.files( '*.prj' ):
            projlist.append( basename( file ).split( "." )[ 0 ] )
        projlist.sort()
        return projlist

    def InitDBList( self, project ):
        # Initialization of the database listing
        databases = []
        projfile = self.projpath.joinpath( project + ".prj" )
        fpoint = open( projfile, 'r' )
        while 1:
            data = fpoint.readline()
            if data == "":
                break
            if data.count( 'DATA_PATH' ) is 0:
                continue
            else:
                datapath = data.split()[ 1 ]
                break
        self.dbpath = path( datapath )
        if not exists( self.dbpath ):
            return
        for dir in self.dbpath.dirs():
            temppath = self.dbpath.joinpath( dir ).joinpath( 'fdb.history' )
            if exists( temppath ):
                databases.append( dir )
        fpoint.close()
        return databases
    
def main():
    try:
        root = Tkinter.Tk()
    except:
        print
        print "An error occured when attempting to initialize the GUI."
        print "Is your DISPLAY variable set correctly?"
        print
        print "Exiting"
        return
    root.resizable( width = False, height = False )
    root.option_add( "*Font", "Tahoma 10" )
    root.focus_set()
    Pmw.initialise( root )
    root.title( "SAIC Checker Front End" )
    app = MainApp( root )
    root.mainloop()

if __name__ == "__main__":
    main()
