Private Sub GE_interrogate_Timer()
'************************************************************************************

'This procedure receives control from the GE_interrogate timer control every
'1/100 seconds or the best the processor can do

'The input parameters are:

'       None

'Notes on this procedure:

'       o When reading this procedure the first question is likely to be: why?
'       o The answer is:
'           o We have to quite regularly update the latitude and longitude of the
'             current GE view by <LookAt> in GE_Update_Chart and the SetCamera
'             API calls in GE_Update_Chart and GE_Update_Vessel
'           o Neither of these mechanisms appear to have the ability to only update
'             latitude and longitude - you must also supply range, bearing and tilt
'           o If you just use an arbitrary/default range, bearing and tilt the
'             effect is that any changes the user makes to these using the GE
'             Navigator control will be overridden at the next <LookAt> or SetCamera,
'             which is not a very pleasant user experience
'           o We therefor need to know immediately whenever the user changes any of
'             the current GE view properties using the GE Navigator control and then
'             use these new GE view properties in any subsequent <LookAt> or
'             SetCamera
'       o This is a sledgehammer approach and a bit embarrassing, however there
'         is no obvious neat alternative - some form of event notification from GE
'         when the user changes a navigation parameter or the ability to just update
'         latitude and longitude in <LookAt> and SetCamera would be very useful
'       o A clunky alternate approach would be to require the user to input desired
'         changes to current GE view range, bearing and tilt externally to GE, via
'         controls under our direct programmatic control, and then just feed these
'         to <LookAt> and SetCamera - actually tried this and it is decidedly tacky
'       o Having said all this, performance is suprisingly unaffected
'       o The procedure is also used to solve another problem:
'           o At one point during development of the GE_... procedures they were
'             called directly by various procedures within greater C_wiz, including
'             some timers
'           o It was found that under extreme duress (e.g. when replaying with a Map
'             Throttle of 100) occasionally an Automation Error -2147418107
'             (80010005) would occur
'           o Microsoft KB article KB176399 explains the causes and suggests some
'             workarounds:
'               o Just allow a single call to GE at any time
'               o "Create the server as a DLL, not an EXE", the "server" being
'                 googleearth.exe - is this possible?
'               o Error wrap all GE calls and ignore the error - is this stable?
'           o The best(?) solution is to just allow a single call to GE at a time,
'             which is effectively what we have done by:
'               o Requiring all procedures in greater C_wiz that want to update the
'                 GE chart overlay to just set the GE_status_chart_update flag to 1
'               o Requiring all procedures in greater C_wiz that want to update the
'                 GE vessels to just set the GE_status_vessel_update flag to 1
'               o Controlling all production calls to GE by one procedure (this one)
'                 so ensuring that all GE calls must be sequential
'           o This is all rather messy  - is it feasible for googleearth.exe to be
'             supplied as a DLL with the standard GE install?

'************************************************************************************
    
    'Set up error handler
    On Error GoTo BAD_GE
    
    'Get GE's current view info
    Set GE_interface_view = GE_interface.GetCamera(True)
    
    'Extract new GE range, bearing and tilt
    new_range! = GE_interface_view.range
    new_bearing% = GE_interface_view.Azimuth
    new_tilt% = GE_interface_view.Tilt
    
    'Turn default error handling back on
    On Error GoTo 0
    
    'If GE range, bearing or tilt has changed...
    If new_range! <> GE_range Or new_bearing% <> GE_bearing Or new_tilt% <> GE_tilt Then
        
        'Save new GE range, bearing and tilt
        GE_range = new_range!
        GE_bearing = new_bearing%
        GE_tilt = new_tilt%
        
        'Flag GE range, bearing or tilt is changing
        GE_status_changing = True

        'Record time this was observed
        GE_time_change = GetTickCount

    'Otherwise, if GE range, bearing or tilt has been changing...
    ElseIf GE_status_changing Then
    
        'If a GE latency period has transpired since the last GE range, bearing
        'or tilt change ...
        If Abs(GetTickCount - GE_time_change) > GE_latency Then

            'Flag GE range, bearing and tilt are not changing
            GE_status_changing = False

        End If
        
    End If

    'If GE range, bearing or tilt is not changing...
    If Not GE_status_changing Then
        
        'If GE chart update required...
        If GE_status_chart_update = 1 Then
        
            'Update GE chart
            Call GE_Update_Chart
        
        End If
        
        'If GE vessel update required...
        If GE_status_vessel_update = 1 Then
            
            'If GE vessels were last updated more than 1/2 second ago (the idea here
            'is to only update the vessel data kml file actually pointed to by the
            'vessel link kml file a maximum of twice a second - as the
            '<refreshInterval> setting in the vessel kml link file is set to cause GE
            'to read the vessel data kml file once a second (the minimum possible)
            'there is little point doing it more frequently)...
            If Abs(GetTickCount - GE_vessel_update_time) > 500 Then
            
                'Update GE vessels
                Call GE_Update_Vessel
            
            End If
    
        End If
    
    End If
    
    'Quit
    Exit Sub
    
'************************************************************************************

'This GOSUB handles an error...

'************************************************************************************

BAD_GE:
        
    'Turn default error handling back on
    On Error GoTo 0
    
    'If handle of main GE window no longer points to a window...
    If IsWindow(GE_main_window_handle) = 0 Then
        
        'Tidy up
        Call GE_Tidy
        
    End If
        
End Sub