;+
; PROJECT
;
;           Solar-B EIS
;
; NAME
;           EIS_DR_GUI__DEFINE
;
;
; PURPOSE
;
;           GUI Class to calculate and display the data rate of the
;           timeline plan. The start and stop times can be entered.
;
; INPUTS
;
;           parentClass - the eis_mk_plan object
;
;
; CATEGORY
;
;           EIS Timeline Planning
;
; WRITTEN
;           John A Rainnie RAL 24-Jan-2007
;
; HISTORY:
;
;          v0.0 JAR 24-Mar-2007
;               Corrected study data rate calculation by including
;               compression factor of rasters
;          v0.1 JAR 30-Apr-2007
;               Added an extra 5% onto the calculated data rate. This
;               was at Hiro's request.
;          v0.2 JAR 30-Aug-2007
;               Check for recursive studies. For DR file creation, if found
;               then set ra_stop timeline as start_time of the next study.
;          v0.3 JAR 10-Sep-2007
;               For RECURSIVE studies - list study as a single line.
;          v0.4 JAR 16-Nov-2007
;               Introduced DR plotting tool
;          v0.5 JAR 30-Nov-2007
;               DR Plotting completed. Introduced tab widgets so the user
;               can switch between ascii text and graphical plot.
;          v0.6 JAR 17-Dec-2007
;              Plot (POLYFILL) selected study on DR plot
;          v0.7 JAR 10-Apr-2008
;               Added facility to toggle plotting of timeline studies
;          v0.8 JAR 23-May-2008
;               Now use tlc->create_dr_output method to return DR text
;          v0.9 JAR 27-May-2008
;               Removed all dr_tlc (subset of tlc) stuff
;          v1.0 JAR 6-Jun-2008 (ISAS)
;               Fixed bug where there were no entries on the timeline
;          v1.1 JAR 14-Jun-2009
;               Print out total data volume accumulated.
;
;-
;______________________________________________________________________________
FUNCTION eis_dr_gui::Init , parentClass

Self.parentClass  = parentClass
Self.group_leader = parentClass->tlbID()


;-------------------create the main base---------------------------------------;
pt_version = eis_get_pt_version_number()
widTitle = "EIS Data Rate Tool" + pt_version
TLB_EVENT                   = {eis_dr_gui_Event}
TLB_EVENT.eis_dr_gui       = Self
TLB_EVENT.Type              = "TLB"
Self.tlbID                  = WIDGET_BASE(                                  $
                                    TITLE       = widTitle,                 $
                                    COLUMN      = 1,                        $
                                    /FLOATING      ,                        $
                                    ;/MODAL         ,                        $
                                    GROUP_LEADER = Self.group_leader ,      $
                                    UValue      = TLB_EVENT)

;-------------------create the GUI------------------------------;
Self->createGUI

RETURN, 1

END
;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_dr_gui::createGUI

; ______________________________________________________________________
;
; Time base
;
; ______________________________________________________________________
timeBase                   = WIDGET_BASE(Self.tlbID ,                      $
                                   COLUMN      = 1  ,                      $
                                   FRAME       = 1 )

start_stop_timeBase        = WIDGET_BASE(timeBase ,                      $
                                    ROW         = 1 )
;---------------------------------------------------------------------------
;
; Time START
;
;---------------------------------------------------------------------------
startBase                   = WIDGET_BASE(start_stop_timeBase ,                        $
                                    ROW         = 1)

aLabel                      = WIDGET_LABEL(startBase ,                      $
                                    value       = 'Start Time: '    ,       $
                                    /ALIGN_LEFT)


; Get tStart and tStop
Self.parentClass->getProperty , tl_graphics = tl_graphics
; Ok, get display start time (TAI) in UTC
tStart_tai   = tl_graphics.axes.x_axis_day_tai

startTime    = anytim2utc(tl_graphics.axes.x_axis_day_tai)
; Convert hours (cursor position, event.x) into UTC
tLength      = sec2utc(tl_graphics.axes.x_axis_length * 60. * 60.)

tStop        = startTime
tStop.mjd    = startTime.mjd  + tLength.mjd
tStop.time   = startTime.time + tLength.time
tStop_tai    = utc2tai(tStop)
;
; Create "Start Time" text widget
;
Self.tstart_gui = OBJ_NEW("eis_datetime_gui", Self ,                        $
                               startBase , tStart_tai , type = 'start')

;---------------------------------------------------------------------------
;
; Time END
;
;---------------------------------------------------------------------------
stopBase                    = WIDGET_BASE(start_stop_timeBase ,                        $
                                    ROW         = 1)

aLabel                      = WIDGET_LABEL(stopBase  ,                      $
                                    value       = 'Stop Time: '    ,        $
                                    /ALIGN_LEFT )

;
; Create "Stop Time" text widget
;
Self.tstop_gui = OBJ_NEW("eis_datetime_gui", Self ,                      $
                               stopBase , tStop_tai , type = 'stop')

; ______________________________________________________________________
;
; Reset Time Base
;
; ______________________________________________________________________
reset_timeBase             = WIDGET_BASE(timeBase ,                      $
                                   ROW         = 1 )

disp_start_t_string = anytim2utc(startTime,/stime,/TRUNCATE)
disp_stop_t_string  = anytim2utc(tStop_tai,/stime,/TRUNCATE)
value = STRJOIN(['Reset to: ',disp_start_t_string,' -> ',        $
                              disp_stop_t_string],/SINGLE)

RESET_EVENT                = {eis_dr_gui_Event}
RESET_EVENT.eis_dr_gui     = Self
RESET_EVENT.Type           = "T_RESET"
Self.resetButtonID         = WIDGET_BUTTON(reset_timeBase ,                $
                                   value       = value  ,                  $
                                   Event_Pro   = 'eis_dr_gui_EV',          $
                                   uValue      = RESET_EVENT)


; ______________________________________________________________________
;
; Widget Tab
;
; ______________________________________________________________________
dr_tab                     = WIDGET_TAB(Self.tlbID)

; ______________________________________________________________________
;
; Plot base
;
; ______________________________________________________________________
plotBase                   = WIDGET_BASE(dr_tab ,                      $
                                    Title      = '   Graphics   '  ,       $
                                    COLUMN     = 1)


optionsBase                = WIDGET_BASE(plotBase   ,                      $
                                    ROW        = 1)

aLabel                     = WIDGET_LABEL(optionsBase    ,                 $
                                   value       = 'Plot DR:')

plotDRBase                 = WIDGET_BASE(optionsBase   ,                   $
                                    ROW        = 1      ,                  $
                                    /EXCLUSIVE)

DR_ALL_EVENT               = {eis_dr_gui_Event}
DR_ALL_EVENT.eis_dr_gui    = Self
DR_ALL_EVENT.Type          = "DR_ALL"
DR_ALL_EVENT.extra         = 0
Self.totalButtonID         = WIDGET_BUTTON(plotDRBase ,                     $
                                    value       = 'Total',                $
                                    Event_Pro   = 'eis_dr_gui_EV',          $
                                    uValue      = DR_ALL_EVENT   ,         $
                                    /NO_RELEASE)
WIDGET_CONTROL , Self.totalButtonID , set_button = 1


DR_IN_EVENT                = {eis_dr_gui_Event}
DR_IN_EVENT.eis_dr_gui     = Self
DR_IN_EVENT.Type           = "DR_IN"
DR_ALL_EVENT.extra         = 1
Self.inButtonID            = WIDGET_BUTTON(plotDRBase ,                    $
                                    value       = 'Upload',                $
                                    Event_Pro   = 'eis_dr_gui_EV',         $
                                    uValue      = DR_IN_EVENT   ,         $
                                    /NO_RELEASE)

DR_OUT_EVENT               = {eis_dr_gui_Event}
DR_OUT_EVENT.eis_dr_gui    = Self
DR_OUT_EVENT.Type          = "DR_OUT"
DR_ALL_EVENT.extra         = 2
Self.outButtonID           = WIDGET_BUTTON(plotDRBase ,                    $
                                    value       = 'Download',              $
                                    Event_Pro   = 'eis_dr_gui_EV',         $
                                    uValue      = DR_OUT_EVENT   ,         $
                                    /NO_RELEASE)


plotDRBase                 = WIDGET_BASE(optionsBase   ,                   $
                                    ROW        = 1      ,                  $
                                    /NONEXCLUSIVE)

PLOT_ST_EVENT              = {eis_dr_gui_Event}
PLOT_ST_EVENT.eis_dr_gui   = Self
PLOT_ST_EVENT.Type         = "PLOT_ST"
Self.plotStudiesButtonID   = WIDGET_BUTTON(plotDRBase ,                     $
                                    value       = 'Plot Studies',           $
                                    Event_Pro   = 'eis_dr_gui_EV',          $
                                    uValue      = PLOT_ST_EVENT)
WIDGET_CONTROL , Self.plotStudiesButtonID , set_button = 1



Self.xySize = [700,400]

PLOT_EVENT                 = {eis_dr_gui_Event}
PLOT_EVENT.eis_dr_gui      = Self
PLOT_EVENT.Type            = "PLOT"
Self.drawID                = WIDGET_DRAW(plotBase    ,                     $
                                   xSize      = Self.xySize[0] ,           $
                                   ySize      = Self.xySize[1] ,           $
                                   /MOTION_EVENTS   ,                      $
                                   /TRACKING_EVENTS ,                      $
                                   /BUTTON_EVENTS   ,                      $
                                   Event_Pro   = 'eis_dr_gui_EV',          $
                                   uValue      = PLOT_EVENT ,              $
                                   frame       = 4)
WINDOW , /FREE , /PIXMAP , xSize = Self.xySize[0] , ySize = Self.xySize[1]
Self.pixID = !D.window


plotInfoBaseID             = WIDGET_BASE(plotBase    ,                     $
                                    ROW        = 1)


aLabel                     = WIDGET_LABEL(plotInfoBaseID ,                 $
                                   value       = 'Time (UT):')
Self.timeTextID            = WIDGET_TEXT(plotInfoBaseID ,                  $
                                    xSize       = 22)

aLabel                     = WIDGET_LABEL(plotInfoBaseID ,                 $
                                   value       = '  Volume (MBits):')
Self.volTextID             = WIDGET_TEXT(plotInfoBaseID ,                  $
                                    xSize       = 10)

;
; Offset widgets
;
value = '  Initial Volume (Mbit):'
aLabel                     = WIDGET_LABEL(plotInfoBaseID    ,              $
                                   value       = value)

OFFSET_EVENT               = {eis_dr_gui_Event}
OFFSET_EVENT.eis_dr_gui    = Self
OFFSET_EVENT.Type          = "OFFSET"
Self.offsetID              = WIDGET_TEXT(plotInfoBaseID                ,   $
                                    value       = '0'                ,    $
                                    Event_Pro   = 'eis_dr_gui_EV',         $
                                    /EDITABLE                          ,    $
                                    xSize       = 10                  ,     $
                                    uValue      = OFFSET_EVENT)


; ______________________________________________________________________
;
; Output Base
;
; ______________________________________________________________________
title = '   DR output file - text   '
outputBase                  = WIDGET_BASE(dr_tab ,                      $
                                    Title       = title          ,      $
                                    COLUMN      = 1)

Self.outputTextID           = WIDGET_TEXT(outputBase ,                      $
                                    ySize       = 33 ,                      $
                                    xSize       = 80 ,                      $
                                    /SCROLL)

; ______________________________________________________________________
;
; Bottom base
;
; ______________________________________________________________________
bottomBase                  = WIDGET_BASE(Self.tlbID ,                      $
                                    ROW         = 1  ,                      $
                                    /FRAME           ,                      $
                                    /GRID_LAYOUT)

REFRESH_EVENT              = {eis_dr_gui_Event}
REFRESH_EVENT.eis_dr_gui   = Self
REFRESH_EVENT.Type         = "REFRESH"
REFRESHbutton              = WIDGET_BUTTON(bottomBase,                     $
                                    value       = ' Refresh ',                $
                                    Event_Pro   = 'eis_dr_gui_EV',          $
                                    uValue      = REFRESH_EVENT)

EXPORT_EVENT                = {eis_dr_gui_Event}
EXPORT_EVENT.eis_dr_gui     = Self
EXPORT_EVENT.Type           = "EXPORT"
EXPORTbutton                = WIDGET_BUTTON(bottomBase,                     $
                                    value       = ' Export Text... ',       $
                                    Event_Pro   = 'eis_dr_gui_EV',          $
                                    uValue      = EXPORT_EVENT)

QUIT_EVENT                  = {eis_dr_gui_Event}
QUIT_EVENT.eis_dr_gui      = Self
QUIT_EVENT.Type             = "QUIT"
quitbutton                  = WIDGET_BUTTON(bottomBase,                     $
                                    value       = ' Quit ',              $
                                    Event_Pro   = 'eis_dr_gui_EV',          $
                                    uValue      = QUIT_EVENT)

END

;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_dr_gui_Cleanup , wid

WIDGET_CONTROL , wid , get_uvalue = eis_dr_gui_Event
OBJ_DESTROY    , eis_dr_gui_Event.eis_dr_gui

END
;______________________________________________________________________________
; Cleanup
;______________________________________________________________________________
PRO eis_dr_gui::CleanUp

OBJ_DESTROY , Self.tstart_gui
OBJ_DESTROY , Self.tstop_gui
PTR_FREE    , Self.dr_in_struct
PTR_FREE    , Self.data_plot
WDELETE     , Self.pixID
print,'Shutting down Data Rate Tool'

END
;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_dr_gui::setProperty, start_time = start_time      ,                 $
                             stop_time  = stop_time

IF (N_ELEMENTS(start_time) GT 0) THEN BEGIN

    Self.tstart_gui->setProperty , datetime = start_time

ENDIF
IF (N_ELEMENTS(stop_time)  GT 0) THEN BEGIN

    Self.tstop_gui->setProperty , datetime = stop_time

ENDIF

END
;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_dr_gui::GetProperty, tlbID      = tlbID          ,                  $
                             tstart_gui = tstart_gui     ,                  $
                             tstop_gui  = tstop_gui

tlbID      = Self.tlbID
tstart_gui = Self.tstart_gui
tstop_gui  = Self.tstop_gui


END
;______________________________________________________________________________
; Return widget id
;______________________________________________________________________________
FUNCTION eis_dr_gui::tlbID

    RETURN, Self.tlbID
END
;______________________________________________________________________________
; Widget_Control wrapper
;______________________________________________________________________________
PRO eis_dr_gui::Control, _Ref_Extra=Widget_Control_Keywords

Widget_Control, Self.tlbID, _Extra=Widget_Control_Keywords

End
;______________________________________________________________________________
; Widget_Info wrapper
;______________________________________________________________________________
FUNCTION eis_dr_gui::Info, _Ref_Extra=Widget_Info_Keywords

Return, Widget_Info(Self.tlbID, _Extra=Widget_Info_Keywords)

End

;______________________________________________________________________________
; Realize wrapper
;______________________________________________________________________________
PRO eis_dr_gui::Realize

Widget_Control, Self.tlbID, /Realize

End

;______________________________________________________________________________
; XManager wrapper
;______________________________________________________________________________
PRO eis_dr_gui::XManager;,group=group

XMANAGER , "eis_dr_gui" ,   Self.tlbID ,                                 $
    Event_Handler  = "eis_dr_gui_EV",                                    $
    cleanup        = "eis_dr_gui_Cleanup",                               $
    GROUP_LEADER   = Self.group_leader ,                                    $
    /NO_BLOCK

end

;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_dr_gui_Event__Define

    struct = {  eis_dr_gui_Event,                                              $
                Type            : "",        $ ;Unique identifier for event
                eis_dr_gui   : OBJ_NEW(), $ ;Reference to object passed
                extra           : 0          $ ;to - often object associated
             }
END
;______________________________________________________________________________
; Event Handler wrapper
;______________________________________________________________________________
PRO eis_dr_gui_EV , Event

;Get event handler structure containing eis_dr_gui type object
Widget_CONTROL,Event.ID,get_uvalue = eis_dr_gui_Event
;If a WIDGET_TAB event , just quit
IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_TAB') THEN BEGIN
    ;print,'tab event'
    RETURN
ENDIF

;Call eis_dr_gui's class member procedure "Handler"
eis_dr_gui_Event.eis_dr_gui->Handler,Event

END
;______________________________________________________________________________
;
; * THIS is the routine for putting in event handling NOT eis_dr_gui_Ev above.
;
; Event Handler - handle events.  Derived classes must
; contain their own implementation in order to handle events or else pass in an
; procedure name/function name using the Event_Pro/Event_Func keywords to
; CWidget::Init()
;______________________________________________________________________________
PRO eis_dr_gui::Handler, Event

WIDGET_CONTROL, Event.ID, Get_UValue = eis_dr_gui_Event
CASE eis_dr_gui_Event.Type OF
    "QUIT"      : Self->Control, /Destroy
    "PLOT_ST"   : Self->refresh
    "REFRESH"   : Self->refresh
    "EXPORT"    : Self->export
    "PLOT"      : Self->plot_event , event
    "DR_ALL"    : Self->change_plot_state_to_all
    "DR_IN"     : Self->change_plot_state_to_in
    "DR_OUT"    : Self->change_plot_state_to_out
    "T_RESET"   : Self->t_reset
    "OFFSET"    : Self->vol_offset
    ELSE        : print,eis_dr_gui_Event.Type
ENDCASE
END
;______________________________________________________________________________
; Update value of inital offset volume
;______________________________________________________________________________
PRO eis_dr_gui::vol_offset

WIDGET_CONTROL , Self.offsetID , get_value = new_value
new_value = new_value[0]
old_value = Self.offset

; Check input is a number
IF (is_number(new_value) NE 1) THEN BEGIN

   ; Set text widget back to original value - and bail out!
   old_value_string = STRCOMPRESS(FIX(old_value),/REMOVE_ALL)
   WIDGET_CONTROL , Self.offsetID , set_value = old_value_string
   RETURN

ENDIF ELSE BEGIN

   ; Number is valid
   Self.offset = FLOAT(new_value)

ENDELSE

Self->refresh

END
;______________________________________________________________________________
; Update value of Reset Button - this method is called from eis_mk_plan
;______________________________________________________________________________
PRO eis_dr_gui::update_reset_button

; Get tStart and tStop
Self.parentClass->getProperty , tl_graphics = tl_graphics
; Ok, get display start time (TAI) in UTC
tStart_tai = tl_graphics.axes.x_axis_day_tai
duration   = tl_graphics.axes.x_axis_length * 60. * 60.
tStop_tai  = tStart_tai + duration

; Make up strings
disp_start_t_string = anytim2utc(tStart_tai,/stime,/TRUNCATE)
disp_stop_t_string  = anytim2utc(tStop_tai ,/stime,/TRUNCATE)
value = STRJOIN(['Reset to: ',disp_start_t_string,' -> ',        $
                              disp_stop_t_string],/SINGLE)

WIDGET_CONTROL , Self.resetButtonID , set_value = value

END
;______________________________________________________________________________
; Plot ALL data
;______________________________________________________________________________
PRO eis_dr_gui::t_reset

; Get tStart and tStop
Self.parentClass->getProperty , tl_graphics = tl_graphics
; Ok, get display start time (TAI) in UTC
tStart_tai   = tl_graphics.axes.x_axis_day_tai

Self.tstart_gui->setProperty , datetime = tStart_tai

; Convert hours (cursor position, event.x) into UTC
tLength      = tl_graphics.axes.x_axis_length * 60. * 60.
Self.tstop_gui->setProperty , datetime = tStart_tai + tLength

Self->refresh

END
;______________________________________________________________________________
; Plot ALL data
;______________________________________________________________________________
PRO eis_dr_gui::change_plot_state_to_all

Self.plot_state = 0
Self->plot_dr

END
;______________________________________________________________________________
; Plot DATA IN data
;______________________________________________________________________________
PRO eis_dr_gui::change_plot_state_to_in

Self.plot_state = 1
Self->plot_dr

END
;______________________________________________________________________________
; Plot DATA OUT data
;______________________________________________________________________________
PRO eis_dr_gui::change_plot_state_to_out

Self.plot_state = 2
Self->plot_dr

END
;______________________________________________________________________________
; PLOT event
;______________________________________________________________________________
PRO eis_dr_gui::plot_event , event

WIDGET_CONTROL , Self.drawID , get_value = drawID
WSET , drawID

; Catch TRACKING_EVENTS - redraw plot then bail!
IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ                $
                    'WIDGET_TRACKING') THEN BEGIN

    IF (event.enter EQ 1) THEN Self->tracker
    RETURN

ENDIF

;
; Display cursor information
;
;convert from DEVICE coords to DATA coords
coords=Convert_Coord(event.x,event.y,/Device,/To_Data)
;constrain coords to within the ROI draw area
xPos= !X.crange[0] > coords[0] < !X.crange[1]
yPos= !Y.crange[0] > coords[1] < !Y.crange[1]

vol_text = STRCOMPRESS(yPos,/REMOVE_ALL)
WIDGET_CONTROL , Self.volTextID , set_value = vol_text

real_start_t = (*Self.dr_in_struct).real_start_t
time_text    = anytim2utc(real_start_t + xPos , /STIME , /TRUNCATE)
WIDGET_CONTROL , Self.timeTextID , set_value = time_text


; Button Events
possibleEventTypes = ['DOWN','UP','MOTION','SCROLL']
thisEvent   = possibleEventTypes[event.type]


; IF (thisevent eq 'DOWN') AND (event.press EQ 1) THEN BEGIN
;
;     Self->copyToPixmap ,xPos,yPos
;     ;print,xPos,yPos
;
; ENDIF
; IF (thisevent eq 'MOTION') THEN BEGIN
;
;     Self->copyToPixmap ,xPos,yPos
;     ;print,xPos,yPos
;
; ENDIF

END
;______________________________________________________________________________
; Copy to Pixmap
;______________________________________________________________________________
PRO eis_dr_gui::copyToPixmap , xPos , yPos

; Retrieve default colour table properties
Self.parentClass->getProperty , o_def_ct = o_def_ct
o_def_ct->getProperty , plotsCT = plotsCT , imageCT = imageCT

TVLCT , plotsCT[*,0] , plotsCT[*,1] , plotsCT[*,2]     ;PLOT ct
Device,Copy=[0,0,Self.xySize[0],Self.xySize[1],0,0,Self.pixID]

; This if for drawing rubber-band boxes
; xPlot = [Self.xys[0],Self.xys[0],Self.xyd[0],Self.xyd[0],Self.xys[0]]
; yPlot = [Self.xys[1],Self.xyd[1],Self.xyd[1],Self.xys[1],Self.xys[1]]
;OPLOT , xPlot , yPlot , color = 1 , thick = 1

XYOUTS , xPos , yPos , 'That tickles' , /DATA , color = 0

TVLCT , imageCT[*,0] , imageCT[*,1] , imageCT[*,2] ;IMAGE ct

END
;______________________________________________________________________________
; Catch TRACKING_EVENTS
;______________________________________________________________________________
PRO eis_dr_gui::tracker

; Create a temporary Pixmap window
WINDOW , /FREE , /PIXMAP , xsize = Self.xySize[0]         ,                $
                           ysize = Self.xySize[1]
tempPixmap = !D.WINDOW
;  Create plot - with no data
Self->plotAxes
; Destroy Pixmap
WDELETE,tempPixmap
; Job Done

END
;______________________________________________________________________________
; Catch TRACKING_EVENTS
;______________________________________________________________________________
PRO eis_dr_gui::plotAxes

; Check plot_state - apply yRange accordingly
CASE Self.plot_state OF
   0    : BEGIN
               data_plot = (*Self.dr_in_struct).data_total
               max_data_max = MAX((*Self.dr_in_struct).data_max)
               CASE (max_data_max GT 0) OF
                   0    : yRange = [MIN(data_plot),MAX(data_plot)]
                   ELSE : yRange = [MIN(data_plot),max_data_max]
               ENDCASE
          END
   1    : BEGIN
               data_plot = (*Self.dr_in_struct).data_in
               yRange    = [MIN(data_plot),MAX(data_plot)]
          END
   2    : BEGIN
               data_plot = (*Self.dr_in_struct).data_out
               yRange    = [MIN(data_plot),MAX(data_plot)]
          END
   ELSE : BEGIN
               data_plot = (*Self.dr_in_struct).data_total
               max_data_max = MAX((*Self.dr_in_struct).data_max)
               CASE (max_data_max GT 0) OF
                   0    : yRange = [MIN(data_plot),MAX(data_plot)]
                   ELSE : yRange = [MIN(data_plot),max_data_max]
               ENDCASE
          END
ENDCASE

; Refresh data
PTR_FREE , Self.data_plot
Self.data_plot = PTR_NEW(data_plot)
Self.yRange    = yRange

;stop
; Must set xRange to duration
;xRange = [0,86400.]
xRange = [0,FLOAT(N_ELEMENTS(data_plot)-2.)]
;help,86400.,N_ELEMENTS(data_plot)-2

UTPLOT , FINDGEN(N_ELEMENTS(data_plot))                      ,             $
         data_plot                                           ,             $
         anytim2utc((*Self.dr_in_struct).real_start_t)       ,             $
         xrange         = xRange                             ,             $
         yr             = yRange                             ,             $
         ;title          = 'EIS Data Rate (Mbits/s)'          ,             $
         yTitle         = 'MBits'                            ,             $
         ;xTitle         = "Blah"                           ,             $
         thick          = 1                                  ,             $
         background     = 255                                ,             $
         yMargin        = [4,6]                              ,             $
         color          = 0                                  ,             $
         xCharsize      = 1.2                                ,             $
         yCharsize      = 1.2                                ,             $
         xstyle         = 1                                  ,             $
         /NODATA

XYOUTS , 0.3 , 0.93 , 'EIS Data Rate (Mbits/s)' , /NORM ,color=0,charsize = 2.

END
;______________________________________________________________________________
; Plot DR
;______________________________________________________________________________
PRO eis_dr_gui::plot_dr

WIDGET_CONTROL , Self.drawID , get_value = drawID
WSET , drawID
drawArea = [drawID , Self.pixID]

; Retrieve default colour table properties
Self.parentClass->getProperty , o_def_ct = o_def_ct
o_def_ct->getProperty , plotsCT = plotsCT , imageCT = imageCT
TVLCT , plotsCT[*,0] , plotsCT[*,1] , plotsCT[*,2] ;PLOT ct

FOR i = 0,1 DO BEGIN

   WSET , drawArea[i]
   ; Plot the axes - with NO data.
   Self->plotAxes

   ; Now on with the other good stuff
   yMax = [!Y.CRange[1]]
   yMin = [!Y.CRange[0]]

   plot_studies = WIDGET_INFO(Self.plotStudiesButtonID,/BUTTON_SET)
   IF (plot_studies EQ 1) THEN Self->plot_studies , yMin , yMax


    ; Colour-coded key at bottom left of plot
    XYOUTS , 0.07 , 0.01 , 'EIS Max Allocation' , /NORM , color = 1
    ;XYOUTS , 0.03 , 0.01 , 'SVA'     , /NORM , color = 9
    ;XYOUTS , 0.07 , 0.01 , 'USC'     , /NORM , color = 3

   dely = !Y.Crange[1] -!Y.Crange[0]
   ;
   ; OverPlot Contact Periods - use Polfill to color them in. Nice!
   ;
   IF (N_TAGS((*Self.dr_in_struct).real_contacts[0]) GT 0) THEN BEGIN
   FOR j = 0, N_ELEMENTS((*Self.dr_in_struct).real_contacts) -1 DO BEGIN

           c_start = (*Self.dr_in_struct).real_contacts[j].start_time -    $
                                        (*Self.dr_in_struct).real_start_t
           c_stop  = (*Self.dr_in_struct).real_contacts[j].stop_time -     $
                                        (*Self.dr_in_struct).real_start_t
           xPoints = [c_start , c_start , c_stop , c_stop , c_start]
           yPoints = [yMin    , yMax    , yMax   , yMin   , yMin]
           res_name = (*Self.dr_in_struct).real_contacts[j].res_name
           ; Stick with same colours as on timeline plot
           CASE res_name OF
               'SVA'  : color = 9
               'USC'  : color = 3
               'SNT'  : color = 2
               'KTU'  : color = 10
               ELSE   : color = 4
           ENDCASE
           ; Colour them in
           POLYFILL,xPoints,yPoints,color=color,noclip=1
           XYOUTS , c_stop , yMax + (0.01*dely) , res_name ,/DATA,color=0,orientation = 90
       ENDFOR

       ;
       ; DATA_MAX plot
       ;
       IF (Self.plot_state EQ 0) THEN Self->plot_data_max

   ENDIF ELSE BEGIN

       XYOUTS , .4 , .15 , 'No Download Contacts found!' , /NORM ,        $
           color = 1 , charsize = 1.5

   ENDELSE

   ; Time to actually draw the dr plot
   OPLOT , FINDGEN(N_ELEMENTS(*Self.data_plot)) , (*Self.data_plot) ,      $
           color = 0 , thick = 2


ENDFOR

TVLCT , imageCT[*,0] , imageCT[*,1] , imageCT[*,2] ;IMAGE ct

END
;______________________________________________________________________________
; RUN DR
;______________________________________________________________________________
PRO eis_dr_gui::plot_studies , yMin , yMax

; Firstly, check there ARE studies and that one is selected
Self.parentClass->getProperty , eis_timeline_container = tlc
count = tlc->count()
IF (count LT 1) THEN RETURN
tlc->getProperty, working_position = wp
FOR i = 0 , count - 1 DO BEGIN

    ; Get object reference
    temp = tlc->get( position   = i)
    temp->getproperty , visible = visible
    IF (visible EQ 1) THEN BEGIN
        ; Get copy of eis_timeline_entry structure
        tl = temp->get()
        ; Need t1, t2, and acronym
        t1 = tl.time_component.start_time
        t2 = tl.time_component.end_time
        tc = tl.time_component
        sc = tl.science_component

        ; Wot colour?
        CASE tc.time_tagged OF
            0     : color = 4      ; CYAN for NON-time-tagged
            1     : color = 11      ; RED  for time-tagged
            ELSE  : color = 4           ; oh oh!
        ENDCASE
        ; Selected study is Yellow
        IF (i EQ wp) THEN color = 5

        st_start = t1 - (*Self.dr_in_struct).real_start_t
        st_stop  = t2 - (*Self.dr_in_struct).real_start_t
        xPoints  = [st_start , st_start , st_stop , st_stop , st_start]
        yPoints  = [yMin    , yMax    , yMax   , yMin   , yMin]
        POLYFILL,xPoints,yPoints,color=color,noclip=0

    ENDIF

ENDFOR

END
;______________________________________________________________________________
; RUN DR
;______________________________________________________________________________
PRO eis_dr_gui::plot_data_max

data_max     = (*Self.dr_in_struct).data_max
real_start_t = (*Self.dr_in_struct).real_start_t

; Plot data_max
OPLOT , FINDGEN(N_ELEMENTS(data_max)) , data_max , color = 1 , thick = 2 ,lines=3

;
; Plot groovy symbols at start of each file
;
n_data_max = N_ELEMENTS(data_max) - 1
vol_array = (*Self.dr_in_struct).data_out_struct.vol_array
FOR j = 0, N_ELEMENTS(vol_array) - 1 DO BEGIN

   plot_index = vol_array[j].first_time - real_start_t

   IF (plot_index GT 0) AND (plot_index LT n_data_max) THEN BEGIN

;        OPLOT , [plot_index           ,plot_index]            ,     $
;                [data_max[plot_index] , data_max[plot_index]] ,     $
;                color=1 , psym = 4 , symsize = 3

       OPLOT , [plot_index           ,plot_index]            ,     $
               [data_max[plot_index] , data_max[plot_index]] ,     $
               color=1 , psym = 4 , symsize = 2

       OPLOT , [plot_index           ,plot_index]            ,     $
               [data_max[plot_index] , data_max[plot_index]] ,     $
               color=1 , psym = 4 , symsize = 1

       delx = !X.Crange[1] -!X.Crange[0]
       dely = !Y.Crange[1] -!Y.Crange[0]
       XYOUTS , plot_index           - (0.05 * delx)         ,             $
                data_max[plot_index] - (0.05 * dely)         ,             $
                anytim2utc(vol_array[j].date,/stime,/date)   ,             $
                color = 1 , /DATA , charsize = 1.5

    ENDIF

ENDFOR

END
;______________________________________________________________________________
; RUN DR
;______________________________________________________________________________
PRO eis_dr_gui::refresh

WIDGET_CONTROL , /HOURGLASS

WIDGET_CONTROL , Self.drawID , get_value = drawID
WSET , drawID
ERASE , 255

WSET , Self.pixID
ERASE , 255


; Get the input wavelengths
;
; TStart
;
Self.tstart_gui->getProperty , datetime = datetime_start
startTime = anytim2utc(datetime_start,/stime,/truncate)
;
; TStop
;
Self.tstop_gui->getProperty , datetime = datetime_stop
stopTime = anytim2utc(datetime_stop,/stime,/truncate)

; Check stopTime >= startTime
IF (datetime_start GE datetime_stop) THEN BEGIN
    mText = 'This is not a valid time range. Aborting.'
    Self->timeNotValid , mText ; Reset time string back to original
    RETURN
ENDIF

; ; Make sure times selected in the text boxes are within study start and
; ; stop times - the first may start before the display time, while
; ; the last may finish after the display time.
; first_start_time = MIN((*Self.dr_in_struct).dr[*].start_t)
; last_stop_time   = MAX((*Self.dr_in_struct).dr[*].stop_t)
;
; stop
; IF (datetime_start LT first_start_time) OR                $
;    (datetime_stop  GT last_stop_time  ) THEN BEGIN
;         mText = 'Time must be with mk_plan display period. Aborting.'
;         Self->timeNotValid , mText ; Reset time string back to original
;         RETURN
; ENDIF


;
; Write dR output file
;
Self.parentClass->getProperty , eis_timeline_container = tlc         ,     $
                                num_days               = num_days
olines = tlc->create_dr_output(start_time = datetime_start           ,     $
                               stop_time  = datetime_stop)

;stop
WIDGET_CONTROL , Self.outputTextID , set_value = olines


;
; Get Data OUT
;
; Get duration in hours
duration = (datetime_stop - datetime_start)/3600.
data_out = eis_read_dr_events(datetime_start , duration , num_days = num_days)

;
; Get Data IN
;
; Get text widget contents - strip off header and bottom lines
WIDGET_CONTROL , Self.outputTextID , get_value=orig_lines
IF (N_ELEMENTS(orig_lines) LE 5) THEN BEGIN
   lines = ''
ENDIF ELSE BEGIN
   lines = orig_lines[4:N_ELEMENTS(orig_lines)-2]
ENDELSE
;
; TStart
;
Self.tstart_gui->getProperty , datetime = datetime_start
startTime = anytim2utc(datetime_start,/stime,/truncate)
;
; TStop
;
Self.tstop_gui->getProperty , datetime = datetime_stop
stopTime = anytim2utc(datetime_stop,/stime,/truncate)

dr_in_struct = eis_get_data_in( lines                       ,              $
                                datetime_start              ,              $
                                datetime_stop               ,              $
                                data_out                    ,              $
                                Self.offset                                $
                               )

PTR_FREE , Self.dr_in_struct
Self.dr_in_struct = PTR_NEW(dr_in_struct)



Self->plot_dr

print,""
print," Total Upload Volume is;"
print,max((*Self.dr_in_struct).data_in)
print,""

END
;______________________________________________________________________________
; Export ASCII file
;______________________________________________________________________________
PRO eis_dr_gui::export

; Get info from widget
WIDGET_CONTROL , Self.outputTextID , get_value = dr_output
; If info is a null string, then bail out
IF (STRLEN(dr_output[0]) EQ 0) THEN BEGIN

    mText = 'There is nowt to print. Aborting.'
    BEEP
    d = DIALOG_MESSAGE(mText , /ERROR , DIALOG_PARENT = Self.tlbID)
    RETURN

ENDIF

; OK, create a fileName and check whether it already exists. If so, then
; ask if it can be overwritten. If not, then the user can enter his/her
; own filename.
fileName = Self->get_dr_output_filename()
valid    = Self->check_dr_output_filename(fileName)
; This will be zero if the dialog was cancelled
IF (valid EQ 0) THEN RETURN

; Create a file
OPENW  , lun , fileName , /GET_LUN
; For some strange reason, the first 2 lines are printed on 1 line.
; Ho-hum - let's do it manually then!
FOR i = 0 , N_ELEMENTS(dr_output) - 1 DO PRINTF   , lun , dr_output[i]
; Finally, close the file and free up the LUN
FREE_LUN , lun

END
;______________________________________________________________________________
; Check fileName
;______________________________________________________________________________
FUNCTION eis_dr_gui::check_dr_output_filename , fileName

; Get fileName
title    = 'This file already exists....'
fileName = DIALOG_PICKFILE(path = path                     ,                $
                           file = fileName                 ,                $
                           default_extension = 'txt'       ,                $
                           dialog_parent     = Self.tlbID  ,                $
                           /OVERWRITE_PROMPT               ,                $
                           /WRITE                          ,                $
                           title = title)

IF (fileName[0] EQ '') THEN RETURN, 0

RETURN , 1

END
;______________________________________________________________________________
; Create a filename
;______________________________________________________________________________
FUNCTION eis_dr_gui::get_dr_output_filename

; Get TStart
;
Self.tstart_gui->getProperty , datetime = datetime_start
startTime = anytim2cal(datetime_start , form = 8 , /DATE)

; Create fileName
pathName = EXPAND_PATH(GETENV('HOME'))
baseName = STRJOIN(['dr_EIS_',startTime,'0001.txt'],/SINGLE)

RETURN , CONCAT_DIR(pathName , baseName)

END
;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_dr_gui::updateTime

Self->refresh

END
;______________________________________________________________________________
; Time is NOT valid
;______________________________________________________________________________
PRO eis_dr_gui::timeNotValid , mText

BEEP
d     = DIALOG_MESSAGE(mText , /ERROR , DIALOG_PARENT = Self.tlbID)

END
;______________________________________________________________________________
; Define Data members
;______________________________________________________________________________
PRO eis_dr_gui__Define

    struct   = { eis_dr_gui                                          ,     $
                   tlbID                : 0L                         ,     $
                   group_leader         : 0L                         ,     $
                   parentClass          : OBJ_NEW()                  ,     $
                   tstart_gui           : OBJ_NEW()                  ,     $
                   tstop_gui            : OBJ_NEW()                  ,     $
                   outputTextID         : 0L                         ,     $
                   drawID               : 0L                         ,     $
                   pixID                : 0L                         ,     $
                   timeTextID           : 0L                         ,     $
                   volTextID            : 0L                         ,     $
                   dr_in_struct         : PTR_NEW()                  ,     $
                   data_plot            : PTR_NEW()                  ,     $
                   yRange               : LONARR(2)                  ,     $
                   xySize               : LONARR(2)                  ,     $
                   motion_ev_on         : 0B                         ,     $
                   totalButtonID        : 0L                         ,     $
                   inButtonID           : 0L                         ,     $
                   outButtonID          : 0L                         ,     $
                   plot_state           : 0B                         ,     $
                   resetButtonID        : 0L                         ,     $
                   offsetID             : 0L                         ,     $
                   plotStudiesButtonID  : 0L                         ,     $
                   offset               : 0.                               $
               }


END
