; $Id: Display_Window__DEFINE.pro,v 1.6 2001/01/15 22:26:36 scottm Exp $
;
;+
; CLASS_NAME:
;   sodasurf_display_window
;
; PURPOSE:
;   The purpose of this routine is to implement a Display Window
;   for the Solar Data Surfer (SoDaSurf) package within Solarsoft.
;
; CATEGORY:
;   Display Window Module
;
;
; SUPERCLASSES:
;       List classes this class inherits from.
;
; SUBCLASSES:
;       List classes that inherit from this class, if any.
;
; CREATION:
;       Note how an object of this class is created.
;       Generally, this is just a reference to the class'
;       Init method.
;
; METHODS:
;       List the methods intrinsic to this class. There is no
;       need to list the inherited methods.
;
; MODIFICATION HISTORY:
;   Adapted from Fanning routines
;   Written by:  Mark Cheung, April 2007.
;      Any additional mods get described here.  Remember to
;      change the stuff above if you add a new keyword or
;      something!
;   July 2007 - Account for maximum screen size when creating Display Window
;

PRO DW_update, event

   widget_control, event.top, get_uvalue = DW ;Reference to Display_Window object
   DW->Refresh

END

PRO sodasurf_display_window_TLB_Events, event

; The event handler for top-level base events.

Widget_Control, event.top, Get_UValue=DW
DW->GetProperty, drawID=drawID, $
    DW_tabs = DW_tabs, $
    xsize=xsize, $
    ysize=ysize, $
    red=red, green=green, blue=blue, $
    plugins_ptr=plugins_ptr

   ; What kind of event is this:

thisEvent = Tag_Names(event, /Structure_Name)

CASE thisEvent OF

   'WIDGET_TAB': BEGIN
   ENDCASE

   'WIDGET_BASE': BEGIN

         ; Resize the draw widget.

;      IF StrUpCase(!Version.OS_Family) NE 'UNIX' THEN BEGIN
;
;         Widget_Control, drawid, XSize=event.x, YSize=event.y
;         xsize = event.x
;         ysize = event.y
;
;      ENDIF ELSE BEGIN

            ; This code added to work-around UNIX resize bug when
            ; TLB has a menu bar in IDL 5.2.

         Widget_Control, event.top, TLB_GET_Size=newsize
         xsize = event.x
         ysize = event.y
     widget_control, DW_tabs, XSize=xsize, YSize=ysize-70
     widget_control, DW_tabs, get_uvalue = DW_tabs_state

     FOR i=0,(N_ELEMENTS(*(plugins_ptr))-1) DO BEGIN
       this_plugin = (*(plugins_ptr))[i]
       IF this_plugin NE Obj_New() THEN $
          this_plugin->ResizeTab, tab_size=[xsize,ysize-100]
     ENDFOR

   ;ENDELSE

         ; Need to refresh the Display Window

      DW->Refresh, resize=1

   ENDCASE

   'WIDGET_KBRD_FOCUS': BEGIN

         ; Keyboard focus events if color protection is turned on.

      IF event.enter EQ 0 THEN BEGIN
         ;Widget_Control, event.top, Set_UValue=info, /No_Copy
         RETURN
      ENDIF

         ; Load colors and execute.

      TVLCT, red, green, blue
      print, "Calling from sodasurf_display_window_TBL_Events"
;      wset, wid
;      erase
      DW_update, {top:event.top, id:event.id}
      ;DW->Redraw

      ENDCASE

ENDCASE

DW->SetProperty, xsize=xsize, ysize=ysize

END
;----------------------------------------------------------------------------------------


PRO sodasurf_display_window_PostScript, event

; This event handler executes PostScript output.

   ; Error handling.

Catch, theError
IF theError NE 0 THEN BEGIN
   Catch, /Cancel
   IF !Error_State.Name EQ 'IDL_M_UPRO_UNDEF' THEN BEGIN
      ok = Dialog_Message(['Cannot find PSConfig. Please download now',$
         'or add PSConfig directory to path.'])
      ;Widget_Control, event.top, Set_UValue=DW
      RETURN
   ENDIF ELSE BEGIN
      ok = Error_Message(Traceback=1, /Error)
      ;Widget_Control, event.top, Set_UValue=DW
      RETURN
   ENDELSE
ENDIF

default_ps_path = '~'
openr, u, '~/.muramgui/my_config', error=config_file_error, /get_lun
IF config_file_error EQ 0 THEN BEGIN
   lines = strarr(5)
   fields = strarr(5)
   values = strarr(5)
   i = 0
   WHILE NOT(EOF(u)) AND (i LE 5) DO BEGIN
	line = '' & READF, u, line
	split_line = strsplit(line, '=', /extract)
	IF (N_ELEMENTS(split_line) EQ 2) THEN BEGIN
	   fields[i] = split_line[0]
	   values[i] = split_line[1]
	   i=i+1
	ENDIF
   ENDWHILE

   default_ps_path = values[where(fields EQ 'default_ps_path')]

ENDIF

   ; Get the info structure.

Widget_Control, event.top, Get_UValue=DW
DW->GetProperty, psconfiguration=psconfiguration

   ; Allow user to configure the PostScript device.

;keywords = PSConfig(psconfiguration, Cancel=cancelled, Group_Leader=event.top)
psconfiguration->SetProperty, Directory=default_ps_path
psconfiguration->GUI,Cancel=cancelled, Group_Leader=event.top
keywords = psconfiguration->GetKeywords()
IF cancelled THEN BEGIN
   DW->SetProperty, psconfiguration=psconfiguration
   RETURN
ENDIF

   ; Display the graphics by executing the command.

DW->SetProperty, psconfiguration=psconfiguration

thisDevice = !D.Name
Set_Plot, 'PS'
Device, _Extra=keywords
DW->Redraw
Device, /Close_File

Set_Plot, thisDevice

DW->SetProperty, psconfiguration=psconfiguration


END 

;----------------------------------------------------------------------------------------

PRO sodasurf_display_window_Print, event

; This event handler executes the command in the Printer device.

   ; Set up the printer.

ok = Dialog_PrinterSetup()
IF NOT ok THEN RETURN

   ; Get info structure and printer orientation.

Widget_Control, event.top, Get_UValue=DW
DW->GetProperty, red=red, green=green, blue=blue

Widget_Control, event.id, Get_UValue=orientation

   ; Load the program's color vectors.

TVLCT, r, g, b

   ; Save the current graphics device.

thisDevice = !D.Name

   ; Set up the printer. You may have to adjust the fudge factors
   ; to account for the printable area offset.

CASE orientation OF
   'PORTRAIT': BEGIN
      keywords = PSWindow(/Printer, Fudge=0.25)
      Set_Plot, 'PRINTER', /Copy
      Device, Portrait=1
      ENDCASE
   'LANDSCAPE': BEGIN
      keywords = PSWindow(/Printer, /Landscape, Fudge=0.25)
      Set_Plot, 'PRINTER', /Copy
      Device, Landscape=1
      ENDCASE
ENDCASE

   ; Display the grapics by executing the command.

Device, _Extra=keywords
DW->Update
Device, /Close_Document
Set_Plot, thisDevice


END 

;----------------------------------------------------------------------------------------

PRO sodasurf_display_window_SaveAs, event

; Saves the current display window as output files.

   ; Get the info structure and the appropriate file extension.

Widget_Control, event.top, Get_UValue=DW
Widget_Control, event.id, Get_UValue=file_extension

   ; Base name for file output.

basename = 'display_window'

DW->GetProperty, tvorder=tvorder

;Get the index number of the draw canvas in the current tab.
current_plugin = DW->Current_plugin()
current_plugin->GetProperty, drawID = drawID
widget_control, drawID, get_value = wid
wset, wid

   ; Take a snapshot of the display window and write file.

CASE file_extension OF
   'BMP'  : image = TVREAD(Filename = basename, /BMP, Order=tvorder)
   'GIF'  : image = TVREAD(Filename = basename, /GIF, Order=tvorder)
   'PICT' : image = TVREAD(Filename = basename, /PICT, Order=tvorder)
   'JPG'  : image = TVREAD(Filename = basename, /JPEG, Order=tvorder)
   'TIF'  : image = TVREAD(Filename = basename, /TIFF, Order=tvorder)
   'PNG'  : image = TVREAD(Filename = basename, /PNG, Order=tvorder)
ENDCASE

;   ; Restore the info structure.
;
;Widget_Control, event.top, Set_UValue=info, /No_Copy

END 

;----------------------------------------------------------------------------------------

PRO sodasurf_display_window_Command__Define

; The definition of the command structure.

   struct = { display_Window_Command, $
              command: "", $        ; The command to execute.
              p1: Ptr_New(), $      ; The first parameter.
              p2: Ptr_New(), $      ; The second parameter.
              p3: Ptr_New(), $      ; The third parameter.
              nparams: 0, $         ; The number of parameters.
              keywords: Ptr_New() $ ; The command keywords.
            }
END 

;-----------------------------------------------------------------------------

PRO sodasurf_display_window_Quit, event

; This event handler destroys the program.
; Get object reference to the Display Window object
widget_control, event.top, get_uvalue = DW

;Destroy it. The CleanUp method for this object class will
;automatically free up memory if the heap variable pointed to by
;the cube_ptr of DW is no pointed to by other Display Window objects.
Obj_Destroy, DW

END

;-----------------------------------------------------------------------------

PRO sodasurf_display_Window_Cleanup, DW_ID

; The cleanup routine for the program.

Widget_Control, DW_ID, Get_UValue=DW, /No_Copy
DW->GetProperty, data_obj = data_obj

   ; Free up the pointers and objects used in the program.

Obj_Destroy, data_obj
;Ptr_Free, cmdStruct.p1
;Ptr_Free, cmdStruct.p2
;Ptr_Free, cmdStruct.p3
;Ptr_Free, cmdStruct.keywords
;Obj_Destroy, psconfiguration
;widget_control, info.drawid, get_value = draw_object
;obj_destroy, draw_object
END 

;----------------------------------------------------------------------------------------

PRO sodasurf_display_window_Colors, event

; This event handler handles color events.
; It is called when the user clicks on the Colors button on the file menu
; to change the color scheme.

Widget_Control, event.top, Get_UValue=DW
DW->GetProperty, $
	red=red, $
	blue=blue, $
	green=green, $
	wcolors=wcolors, $
	data_obj = data_obj, $
	colorbar = colorbar

;data_obj->GetProperty, minValue=minValue, maxValue=maxValue

   ; What kind of event is this?

thisEvent = Tag_Names(event, /Structure_Name)

CASE thisEvent OF

   'WIDGET_BUTTON': BEGIN

         ; Call XColors to change colors.

      TVLCT, red, green, blue
      XColors, Group_Leader=event.top, NColors=wcolors[0], Bottom=wcolors[1], $
         Title='Colors', NotifyID=[event.id, event.top]

      END

   'XCOLORS_LOAD': BEGIN

         ; New color tables are loaded. Save them.
         ; Redisplay graphics on 24-bit displays.

      Device, Get_Visual_Depth=theDepth
      DW->SetProperty, $
	red = event.r, $
     	green = event.g, $
     	blue = event.b

      IF theDepth GT 8 THEN DW->Refresh
      END
ENDCASE 


END 
;----------------------------------------------------------------------------------------


PRO sodasurf_display_window_Command__Define

; The definition of the command structure.

   struct = { sodasurf_display_window_Command, $
              command: "", $        ; The command to execute.
              p1: Ptr_New(), $      ; The first parameter.
              p2: Ptr_New(), $      ; The second parameter.
              p3: Ptr_New(), $      ; The third parameter.
              nparams: 0, $         ; The number of parameters.
              keywords: Ptr_New() $ ; The command keywords.
            }
END 
;----------------------------------------------------------------------------------------


PRO sodasurf_display_window::Register_Plugin, plugin=plugin

IF (N_ELEMENTS(plugin) NE 0) THEN BEGIN
    plugin->GetProperty, tab_ID = tab_ID
    IF (self.plugins_ptr EQ Ptr_New()) THEN BEGIN
       self.plugins_ptr = Ptr_New([plugin])
       self.tabs_IDs_ptr = Ptr_New([tab_ID])
    ENDIF ELSE BEGIN
       self.plugins_ptr = Ptr_New([*(self.plugins_ptr), plugin])
       self.tabs_IDs_ptr = Ptr_New([*(self.tabs_IDs_ptr), tab_ID])
    ENDELSE
ENDIF
print, *(self.tabs_IDs_ptr), "=Tabs_IDs"
print, *(self.plugins_ptr),  "=Plugins"
END

PRO sodasurf_display_window::Unregister_Plugin, plugin=plugin

old_plugins = *(self.plugins_ptr)
old_tabs_IDs = *(self.tabs_IDs_ptr)
a = where(plugin NE old_plugins)
b = where(plugin EQ old_plugins)
IF (b NE -1) and N_ELEMENTS(b) EQ 1 THEN BEGIN
   new_plugins = old_plugins[a]
   new_tabs_IDs = old_tabs_IDs[a]
   old_plugins[b[0]]->Destroy
ENDIF

print, new_plugins, "=new_plugins"
self.plugins_ptr = Ptr_New(new_plugins)
self.tabs_IDs_ptr = Ptr_New(new_tabs_IDs)

END

PRO sodasurf_display_window::Redraw
current_plugin = self->Current_plugin()
IF current_plugin NE Obj_New() THEN BEGIN
   CASE !D.NAME OF
    'WIN': current_plugin->Update
    'X'  : current_plugin->Update
    'PS': current_plugin->DrawPostscript
   ENDCASE
ENDIF
END

; METHODNAME:
;       sodasurf_display_window::Refresh
;
; PURPOSE:
;   Method to refresh the Display Window. The difference between
;   sodasurf_display_window::Refresh and sodasurf_display_window::Redraw is that
;   sodasurf_display_window::Refresh will create and draw a new colorbar and then
;   call sodasurf_display_window::Redraw.

PRO sodasurf_display_window::Refresh, resize=resize

   IF N_ELEMENTS(resize) EQ 0 THEN resize=0
   current_plugin = self->Current_plugin()
   IF current_plugin NE Obj_New() THEN current_plugin->Refresh,resize=resize

END

; FUNCTIONNAME:
;       sodasurf_display_window::Current_tab_ID
;
; PURPOSE:
;   Function to return the widget ID of the tab in the Display Window that
;   is currently selected.

FUNCTION sodasurf_display_window::Current_tab_ID

IF (self.plugins_ptr) NE Ptr_New() THEN BEGIN
   FOR i=0, (N_ELEMENTS(*(self.plugins_ptr))-1) DO BEGIN
    this_plugin = *(self.plugins_ptr)[i]
    this_plugin->GetProperty, this_tab_ID=this_tab_ID
    tab_index = widget_info(self.DW_tabs, /tab_current)
    IF (self.tabs_IDs[tab_index] EQ tab_ID) THEN RETURN, tab_ID
   ENDFOR
ENDIF
RETURN, 0
END

; FUNCTIONNAME:
;       sodasurf_display_window::Current_Plugin
;
; PURPOSE:
;   Function to return the object reference to the plugin
;   that is associated with the tab currently selected.

FUNCTION sodasurf_display_window::Current_Plugin

IF (self.plugins_ptr) NE Ptr_New() THEN BEGIN
   FOR i=0,(N_ELEMENTS(*(self.plugins_ptr))-1) DO BEGIN
       this_plugin = (*(self.plugins_ptr))[i]
    IF this_plugin NE Obj_New() THEN BEGIN
       this_plugin->GetProperty, tab_ID=tab_ID
       tab_index = widget_info(self.DW_tabs, /tab_current)
       IF (*(self.tabs_IDs_ptr))[tab_index] EQ tab_ID THEN $
       RETURN, this_plugin
    ENDIF
   ENDFOR
ENDIF ELSE BEGIN
   RETURN, Obj_New()
ENDELSE

END
;
; METHODNAME:
;       sodasurf_display_window::CleanUp
;
; PURPOSE:
;   Method to clean up after a Display Window object is no longer needed

PRO sodasurf_display_window::Cleanup
;if (self.profiles_window ne 0) then widget_control, self.profiles_window, /destroy
FOR I=0,N_ELEMENTS(self.data_obj)-1 DO BEGIN
   IF self.data_obj[I] NE Obj_new() THEN BEGIN
	(self.data_obj[I])->GetProperty, cube_ptr=cube_ptr
   	Ptr_Free, cube_ptr
   ENDIF
   obj_destroy, (self.data_obj)[I]
   ;heap_Free, (self.data_obj)[I]
ENDFOR
heap_Free, self
;stop
widget_control, self.DW_ID, /destroy
END


; METHODNAME:
;       sodasurf_display_window::SetProperty
;
; PURPOSE:
;   Method to set/modify the property of a Display Window object
;
; CALLING SEQUENCE:
;   Obj->[sodasurf_display_window::]SetProperty, property=value
;
; INPUTS:
;   property: the property of the object to be returned
;
; OPTIONAL INPUTS:
;   Parm2:    Describe optional inputs here. If you don't have any, just
;     delete this section.
;
; KEYWORD PARAMETERS:
;   KEY1: Document keyword parameters like this. Note that the keyword
;     is shown in ALL CAPS!
;
;   KEY2: Yet another keyword. Try to use the active, present tense
;     when describing your keywords.  For example, if this keyword
;     is just a set or unset flag, say something like:
;     "Set this keyword to use foobar subfloatation. The default
;      is foobar superfloatation."
;
; OPTIONAL OUTPUTS:
;   Describe optional outputs here.  If the routine doesn't have any,
;   just delete this section.
;
; COMMON BLOCKS:
;   BLOCK1:   Describe any common blocks here. If there are no COMMON
;     blocks, just delete this entry. Object methods probably
;               won't be using COMMON blocks.
;
; SIDE EFFECTS:
;   Describe "side effects" here.  There aren't any?  Well, just delete
;   this entry.
;
; RESTRICTIONS:
;   Describe any "restrictions" here.  Delete this section if there are
;   no important restrictions.
;
; PROCEDURE:
;   You can describe the foobar superfloatation method being used here.
;   You might not need this section for your routine.
;
; EXAMPLE:
;   The following example creates a sodasurf_display_window object named DW and retrives the
;   widget ID of the Display Window using the GetProperty function of this object.
;
;   DW = Obj_New("sodasurf_display_window", group_leader=group_leader)
;   DW->GetProperty, DW_ID = DW_ID
;
; MODIFICATION HISTORY:
;   Written by:  Mark Cheung, April 2003
;   April, 2003   Any additional mods get described here.  Remember to
;      change the stuff above if you add a new keyword or
;      something!

PRO sodasurf_display_window::SetProperty, $
xsize = xsize, $
ysize = ysize, $
red = red, $
green = green, $
blue = blue, $
wtitle = wtitle, $
wbackground = wbackground, $
weraseit = weraseit, $
data_obj = data_obj, $
variable = variable, $
variable_name = variable_name, $
minValue = minValue, $
maxValue = maxValue, $
movie_player = movie_player, $
colorbar = colorbar, $
orientation = orientation, $
draw_contours = draw_contours, $
profiles_window = profiles_window, $
psconfiguration = psconfiguration, $
bounding_box = bounding_box, $
bookmarks = bookmarks, $
chaincode_ptr = chaincode_ptr

;Error handling
Catch, Error
IF Error NE 0 THEN BEGIN
   Catch, Cancel=1
   ok = Dialog_Message('Error in SetProperty method. Returning ...')
   Print, ''
   Print, 'sodasurf_display_window::SetProperty Method: ' + !Error_State.Msg
   RETURN
ENDIF

;Set property if requested

If n_elements(xsize) ne 0 then self.xsize = xsize
If n_elements(ysize) ne 0 then self.ysize = ysize
If n_elements(red) ne 0 then self.red = red
If n_elements(green) ne 0 then self.green = green
If n_elements(blue) ne 0 then self.blue = blue
If n_elements(colorbar) ne 0 then self.colorbar = colorbar
If n_elements(wtitle) ne 0 then self.wtitle = wtitle
If n_elements(orientation) ne 0 then self.orientation = orientation
If n_elements(data_obj) ne 0 then self.data_obj = data_obj
If n_elements(draw_contours) ne 0 then self.draw_contours = draw_contours
If n_elements(movie_player) ne 0 then self.movie_player = movie_player
If n_elements(variable) ne 0 then self.variable = variable
If n_elements(variable_name) ne 0 then self.variable_name = variable_name
If n_elements(wbackground) ne 0 then self.wbackground = wbackground
If n_elements(weraseit) ne 0 then self.weraseit = weraseit
If n_elements(profiles_window) ne 0 then self.profiles_window = profiles_window
If n_elements(psconfiguration) ne 0 then self.psconfiguration = psconfiguration
if n_elements(bounding_box) eq 4 then self.bounding_box = bounding_box
if n_elements(bookmarks) eq 3 then self.bookmarks=bookmarks
if n_elements(chaincode_ptr) ne 0 then self.chaincode_ptr = chaincode_ptr
END

; METHODNAME:
;       sodasurf_display_window::GetProperty
;
; PURPOSE:
;       Describe what the method does. Note whether the method is
;       a lifecycle method for the class.
;
; CALLING SEQUENCE:
;   Obj->[sodasurf_display_window::]GetProperty, property=variable
;
; INPUTS:
;   property: the property of the object to be returned
;
; OPTIONAL INPUTS:
;   Parm2:    Describe optional inputs here. If you don't have any, just
;     delete this section.
;
; KEYWORD PARAMETERS:
;   KEY1: Document keyword parameters like this. Note that the keyword
;     is shown in ALL CAPS!
;
;   KEY2: Yet another keyword. Try to use the active, present tense
;     when describing your keywords.  For example, if this keyword
;     is just a set or unset flag, say something like:
;     "Set this keyword to use foobar subfloatation. The default
;      is foobar superfloatation."
;
; OUTPUTS:
;   This function returns the value of some property of the sodasurf_display_window object
;
; OPTIONAL OUTPUTS:
;   Describe optional outputs here.  If the routine doesn't have any,
;   just delete this section.
;
; COMMON BLOCKS:
;   BLOCK1:   Describe any common blocks here. If there are no COMMON
;     blocks, just delete this entry. Object methods probably
;               won't be using COMMON blocks.
;
; SIDE EFFECTS:
;   Describe "side effects" here.  There aren't any?  Well, just delete
;   this entry.
;
; RESTRICTIONS:
;   Describe any "restrictions" here.  Delete this section if there are
;   no important restrictions.
;
; PROCEDURE:
;   You can describe the foobar superfloatation method being used here.
;   You might not need this section for your routine.
;
; EXAMPLE:
;   The following example creates a sodasurf_display_window object named DW and retrives the
;   widget ID of the Display Window using the GetProperty function of this object.
;
;   DW = Obj_New("sodasurf_display_window", group_leader=group_leader)
;   DW->GetProperty, DW_ID = DW_ID
;
; MODIFICATION HISTORY:
;   Written by:  Mark Cheung, April 2003
;   April, 2003   Any additional mods get described here.  Remember to
;      change the stuff above if you add a new keyword or
;      something!
;-


PRO sodasurf_display_window::GetProperty, $
; The GetProperty method of the sodasurf_display_window object class.
; All properties are obtained via the following keywords:

DW = DW, $
DW_ID=DW_ID, $
main_ID=main_ID, $
xsize = xsize, $
ysize = ysize, $
tvorder = tvorder, $
red = red, $
green = green, $
blue = blue, $
wcolors = wcolors, $
wtitle = wtitle, $
wbackground = wbackground, $
weraseit = weraseit, $
drawID = drawID, $
data_obj = data_obj, $
colorbar = colorbar, $
movie_player = movie_player, $
orientation = orientation, $
mbarID = mbarID, $
draw_contours = draw_contours, $
DW_tabs = DW_tabs, $
view_menu = view_menu, $
profiles_menu = profiles_menu, $
psconfiguration = psconfiguration, $
plugins=plugins, $
plugins_ptr = plugins_ptr, $
tabs_IDs_ptr = tabs_IDs_ptr, $
bounding_box = bounding_box, $
bookmarks=bookmarks, $
chaincode_ptr=chaincode_ptr

;Error handling
Catch, Error
IF Error NE 0 THEN BEGIN
   Catch, Cancel=1
   ok = Dialog_Message('Error in GetProperty method. Returning ...')
   Print, ''
   Print, 'sodasurf_display_window::GetProperty Method: ' + !Error_State.Msg
   RETURN
ENDIF

;Return value of self object

DW = self
DW_ID = self.DW_ID
main_ID = self.main_ID
xsize = self.xsize
ysize = self.ysize
tvorder = self.tvorder
red = self.red
green = self.green
blue = self.blue
wcolors = self.wcolors
wtitle = self.wtitle
wbackground = self.wbackground
weraseit = self.weraseit
drawID = self.drawID
data_obj = self.data_obj
colorbar = self.colorbar
movie_player = self.movie_player
mbarID = self.mbarID
orientation = self.orientation
view_menu = self.view_menu
;profiles_menu = self.profiles_menu
;profiles_window = long(self.profiles_window)
;overlays_menu = self.overlays_menu
draw_contours = self.draw_contours
DW_tabs = self.DW_tabs
psconfiguration = self.psconfiguration
plugins=self.plugins
plugins_ptr = self.plugins_ptr
tabs_IDs_ptr = self.tabs_IDs_ptr
bounding_box = self.bounding_box
bookmarks = self.bookmarks
chaincode_ptr = self.chaincode_ptr
END

; METHODNAME:
;       sodasurf_display_window::Init
;
; PURPOSE:
;       Creates and Initializes a Display Window class object
;
; CALLING SEQUENCE:
;   DW = Obj_New("sodasurf_display_window", ...)
;
; INPUTS:
;   property: the property of the object to be returned
;
; SIDE EFFECTS:
;   Describe "side effects" here.  There aren't any?  Well, just delete
;   this entry.
;
; RESTRICTIONS:
;   Describe any "restrictions" here.  Delete this section if there are
;   no important restrictions.
;
; PROCEDURE:
;   You can describe the foobar superfloatation method being used here.
;   You might not need this section for your routine.
;
; EXAMPLE:
;   The following example creates a sodasurf_display_window object named DW:
;   DW = Obj_New("sodasurf_display_window", group_leader=group_leader)
;
; MODIFICATION HISTORY:
;   Written by:  Mark Cheung, April 2003
;   April, 2003   Any additional mods get described here.  Remember to
;      change the stuff above if you add a new keyword or
;      something!
;-

FUNCTION sodasurf_display_window::Init, $

;=========The INIT method of the sodasurf_display_window object class.==============

   p1, p2, p3, $                    ; The three allowed positional parameters.
   _Extra = extra, $                ; Any extra keywords. Usually the "command" keywords.
   Group_Leader = group_leader, $   ; The group leader of the display_Window program.
   TVOrder=tvorder, $               ; The order in which window contents should be transferred from the display. By default, !Order.
   WEraseIt = Weraseit, $           ; Set this keyword to erase the display before executing the command.
   WXSize = wxsize, $               ; The X size of the display_Window graphics window in pixels. By default: 400.
   WYSize = wysize, $               ; The Y size of the display_Window graphics window in pixels. By default: 400.
   WColors = wcolors, $             ; This keyword controls the ability to set colors.
   WTitle = wtitle, $               ; The window title.
   WXPos = wxpos, $                 ; The X offset of the window on the display. The window is centered if not set.
   WYPos = wypos, $                 ; The Y offset of the window on the display. The window is centered if not set.
   WBackground = wbackground, $     ; The background color. Set to !P.Background by default.
   WPostScript=needPS, $            ; Set if you want PostScript capability. Set to 1 automatically for 24-bit displays.
   WPrint = needPrint, $            ; Set if you want Printer capability. Set to 1 automatically for 24-bit displays.
   orientation = orientation, $     ; Get viewing orientation
   draw_contours = draw_contours, $ ; If =1, then overlay image with contours
   data_obj = data_obj       ; Data obj with info and data about data cube/sub-cube
   ; Error handling.

On_Error, 2
Catch, theError
IF theError NE 0 THEN BEGIN
   Catch, /Cancel
   ok = Error_Message(Traceback=1, /Error)
   RETURN, 0
ENDIF

   ; Check for availability of GIF files.

thisVersion = Float(!Version.Release)
IF thisVersion LT 5.4 THEN haveGif = 1 ELSE haveGIF = 0

   ; Check keywords and define values if required.

screen_size=get_screen_size()
IF N_ELEMENTS(wxsize) EQ 0 THEN wxsize=floor(screen_size[0])
IF N_ELEMENTS(wysize) EQ 0 THEN wysize=floor(screen_size[1])

FOR I=0,3 DO BEGIN
   IF data_obj[I] NE Obj_New() THEN BEGIN
      (data_obj[I])->GetProperty, cube_ptr=cube_ptr
      wxsize = max([min([wxsize,250+N_ELEMENTS((*cube_ptr)[*,0,0])]),400])
      wysize = max([min([wysize,200+N_ELEMENTS((*cube_ptr)[0,*,0])]),400])
   ENDIF
ENDFOR

IF N_Elements(tvorder) EQ 0 THEN tvorder = !Order
IF N_Elements(wxpos) EQ 0 THEN wxpos = -1
IF N_Elements(wypos) EQ 0 THEN wypos = -1
IF N_Elements(wtitle) EQ 0 THEN wtitle = "Solar Data Surfer V1.0"
IF N_Elements(wbackground) EQ 0 THEN wbackground=!P.Background
IF N_Elements(orientation) EQ 0 THEN orientation=2
IF N_Elements(profiles_window) EQ 0 THEN profiles_window=0L
IF N_Elements(draw_contours) EQ 0 THEN draw_contours=-1
IF N_ELEMENTS(Group_leader) EQ 0 THEN Group_leader = 0
self.plugins_ptr = Ptr_New()
self.tabs_IDs_ptr = Ptr_New()
IF !D.NAME NE 'X' OR !D.NAME NE 'WIN' THEN BEGIN
   case strlowcase(!VERSION.OS_FAMILY) OF
	'unix': set_plot, 'X'
	'windows': set_plot, 'WIN'
   endcase
ENDIF
Device, Get_Visual_Depth=theDepth
IF theDepth GT 8 AND N_Elements(needPS) EQ 0 THEN needPS = 1
IF theDepth GT 8 AND N_Elements(needPrint) EQ 0 THEN needPrint = 1
needPS = Keyword_Set(needPS)
needPrint = Keyword_Set(needPrint)
wcolors = !D.Table_Size
needPrint = 1
needPS = 1

; Check for color handling.

IF Keyword_Set(wcolors) THEN BEGIN
   needColors = 1
   IF N_Elements(wcolors) EQ 1 THEN BEGIN
      IF wcolors[0] EQ 1 THEN wcolors = [!D.Table_Size, 0] ELSE $
    wcolors = [wcolors, 0]
   ENDIF
   wcolors[0] = (wcolors[1] + wcolors[0]) < (!D.Table_Size - wcolors[1])
   IF wcolors[0] EQ 0 THEN $
      Message, 'Problem with COLORS keyword. Check calling sequence.', /NoName
ENDIF ELSE BEGIN
   needColors = 0
   wcolors = 1
ENDELSE
weraseit = Keyword_Set(weraseit)

;=================Initialize the widgets.======================
;Create a new display window and an associated structure to store
;information about the window
tbl_size_events=1 ; Window not resizable.
DW_ID = Widget_Base(tLB_Size_Events=tbl_size_events, column=1, MBar=mbarID,$
   group_leader=group_leader, xsize=wxsize, ysize=wysize)
self.DW_ID = DW_ID
self.xsize = wxsize
self.ysize = wysize
self.mbarID = mbarID

;Create tab widget to hold several tabs (of type base)
DW_tabs = widget_tab(DW_ID, xsize=wxsize, ysize=wysize-100, $
    event_pro='tab_switch_events');,tab_mode=1)
self.DW_tabs = DW_tabs

;====================Load the cube========================

(data_obj[0])->GetProperty, $
    cube_ptr=cube_ptr, $
    variable_name=variable_name, $
    variable_object=variable_object, $
    minValue = minValue, $
    maxValue = maxValue, $
    nmod = nmod, $
    dir = dir, data_type=data_type

self.data_obj=data_obj

variable_object->GetProperty, unit=unit

;============Create movie player compound widget===============
movie_player = sodasurf_movie_player(DW_ID, wxsize, wysize)
self.movie_player = movie_player

;======================Create File Menu========================
file_menu = Widget_Button(mbarID, Value='File')

;-----------------------Export Sub-Menu------------------------

export = Widget_Button(file_menu, Value='Export', Event_Pro='export_cube_events', /Menu)
dummy = widget_button(export, value="Binary cube", event_pro='export_cube_events')

;------------------------Save As sub-menu----------------------

saveID = Widget_Button(file_menu, Value='Save As', $
    Event_Pro='sodasurf_display_window_SaveAs', /Menu)
dummy = Widget_Button(saveID, Value='BMP File', UValue='BMP')
IF havegif THEN dummy = Widget_Button(saveID, Value='GIF File', UValue='GIF')
dummy = Widget_Button(saveID, Value='PICT File', UValue='PICT')
dummy = Widget_Button(saveID, Value='PNG File', UValue='PNG')
dummy = Widget_Button(saveID, Value='JPEG File', UValue='JPG')
dummy = Widget_Button(saveID, Value='TIFF File', UValue='TIF')
;IF needPS THEN dummy = Widget_Button(saveID, Value='PostScript File', $
;   Event_Pro='sodasurf_display_window_PostScript')

; Colors button, if needed.
IF needcolors THEN dummy = Widget_Button(file_menu, Value='Colors...', $
   /Separator, Event_Pro='sodasurf_display_window_Colors')

; Quit button.
quitID = Widget_Button(file_menu, Value='Close', $
    Event_Pro='sodasurf_display_window_Quit', /Separator)

;=======================Create View Menu======================
view_menu = widget_button(mbarID, Value='View')
in_current_window = Widget_Button(view_menu, Value='In current window', $
    Event_Pro='view_events', /Menu)
in_new_window = Widget_Button(view_menu, Value='In new window', $
    Event_Pro='view_events', /Menu)
dummy_variable = obj_new("variable_type")
dummy_variable->VariablesMenuItems, menu_item_ids=in_current_window_items, $
    menu_parent = in_current_window, event_pro="view_events"
dummy_variable->VariablesMenuItems, menu_item_ids=in_new_window_items, $
    menu_parent = in_new_window, event_pro="view_events"

widget_control, in_current_window, set_uvalue = {in_current_window:in_current_window,$
    menu_item_ids:in_current_window_items}
widget_control, in_new_window, set_uvalue = {in_new_window:in_new_window,$
    menu_item_ids:in_new_window_items}
view_menu_state = {view_menu:view_menu, in_current_window:in_current_window,$
    in_new_window:in_new_window}
widget_control, view_menu, set_uvalue=view_menu_state


;==========Position the program on the display.===========
IF wxpos LT 0 OR wypos LT 0 THEN CenterTLB, DW_ID ELSE $
   Widget_Control, DW_ID, XOffset=wxpos, YOFFset=wypos

;==============Store the program's colors.================
TVLCT, red, green, blue, /Get

;==Configure Movie Player according to properties of cube===

widget_control, movie_player, get_uvalue = movie_player_state
if (n_elements((*cube_ptr)[0,0,*]) ge 1) then begin
   widget_control, movie_player_state.frame_slider, $
    set_slider_max = n_elements((*cube_ptr)[0,0,*])-1
endif else begin
   ; 3D cube is actually a 2D slice, so set the max to a HUGE number.
   widget_control, movie_player_state.frame_slider, $
    set_slider_max = 10000
   widget_control, movie_player_state.frame_slider, sensitive=0
   widget_control, movie_player_state.forward_button, sensitive=0
   widget_control, movie_player_state.rewind_button, sensitive=0
   widget_control, movie_player_state.view_buttons, get_uvalue = view_buttons_state
   widget_control, view_buttons_state.xy_view, sensitive=0
   widget_control, view_buttons_state.yz_view, sensitive=0
endelse

;===================Set Title for Display Window===================
Widget_Control, DW_ID, TLB_Set_Title=wtitle

;========================Record in log=============================
;IF Group_leader GT 0 THEN BEGIN
;   widget_control, group_leader, get_uvalue = main_state
;   widget_control, main_state.CP, get_uvalue = CP_state
;   log_entry, group_leader, dir+nmod+", "+variable_name +" loaded"
;ENDIF


;=============If Custom cube, desensitize view sub-menus===========
If (nmod EQ '') OR data_type eq 2 Then begin
   widget_control, in_current_window, sensitive=0
   widget_control, in_new_window, sensitive=0
endif

;=========================Create Colorbar==========================
TVLCT, red, green, blue, /Get
self.colorbar = Obj_New("COLORBAR", Title=variable_name,$
	 Range=[minValue,maxValue],/vertical,position=[(1-(60./wxsize)),0.1,1-(50./(wxsize)),0.9])

;================Fill out this particular instance=================
;================of the sodasurf_display_window object class================

self.DW = self
self.DW_ID = DW_ID
self.main_ID = group_leader
self.xsize = wxsize
self.ysize = wysize
self.tvorder = tvorder
self.red = red
self.green = green
self.blue = blue
self.wcolors = wcolors
self.wtitle = wtitle
self.wbackground = wbackground
self.weraseit = weraseit
self.data_obj = data_obj
self.movie_player = movie_player
self.orientation = orientation
self.view_menu = view_menu
self.overlays_menu = 0
self.draw_contours = draw_contours
self.DW_tabs = DW_tabs

;If PostScript output is required, initialize the PSConfig object.
IF needPS THEN self.psconfiguration = Obj_New("FSC_PSConfig")

widget_control, DW_ID, set_uvalue = self

;=======================Start er up!==============================
Widget_Control, DW_ID, /Realize
XManager, 'display_window__define', DW_ID, /No_Block, $
    Event_Handler='sodasurf_display_window_TLB_Events', $
    Group_Leader=group_leader, Cleanup='sodasurf_display_window_Cleanup'


;==================Load add-on modules/plugins====================
load_addon_plugins, Display_Window=self
self->Refresh, resize=1

RETURN, 1
END
;--------------------------------------------------------------------------------------------------------


PRO Sodasurf_Display_Window__DEFINE

struct = { Sodasurf_Display_Window, $            ; The Display_Window object class definition
     DW: Obj_New(), $        ; Self-reference pointer for the Display_Window object
     DW_ID:0L, $           ; Widget ID of Display Window
     main_ID:0L, $             ; Widget ID of main window
     xsize:0, $                          ; X size of display window.
     ysize:0, $                          ; Y size of display window.
     tvorder:0, $                        ; The order of window transfer. 0 means Direct Graphics
     red: intarr(256), $                   ; The red color vector for 8 bit display
     green: intarr(256), $                   ; The green color vector for 8 bit display
     blue: intarr(256), $                   ; The blue color vector.
     psconfiguration:Obj_New(), $        ; The window's PostScript configuration.
     drawID: 0L, $                       ; The draw widget identifier.
     wcolors:intarr(2), $                ; The window's color information.
     wtitle:"", $                        ; The window's title.
     wbackground: 0, $                   ; The window's background color.
     weraseit: 0, $                      ; The window's erase flag.
     data_obj: [Obj_New(),Obj_New(),Obj_New(),Obj_New()], $          ; The data_set object with info about data cube.
     colorbar: Obj_New(), $                 ; Object graphics colorbar
     movie_player: 0L, $                ; The movie player's widget ID
     orientation: 0, $              ; The orientation
     mbarID: 0L, $             ; Widget ID of the menu bar
     view_menu: 0L, $        ; Widget ID of View Menu
     profiles_menu: 0L, $        ; Widget ID of profiles_menu
     profiles_window: 0L, $            ; widget ID of profiles_window
     overlays_menu: 0L, $        ; Widget ID of overlays_menu
     draw_contours: 0,$            ; Index of variable to be plotted by contours, -1 = disable
     bounding_box:[0.,0.,0.,0.], $ ; Bounding box used for Knowledge Base Tab.
     bookmarks:[0l,0l,0l], $ ;bookmarks for framenumbers
     chaincode_ptr:Ptr_New(), $  ;Chaincode 
     DW_tabs:0L, $             ; Widget ID of the tab widget in this DW.
     tabs_IDs_ptr:Ptr_New(), $      ; Pointer to array holding widget IDs of plugin tabs
     plugins_ptr:Ptr_New(), $       ; Pointer to array holding objects of class (or sub-class) plugin
     plugins:objarr(3) $          ; An array to hold the object pointers to plugin objects.
    }
END
;--------------------------------------------------------------------------------------------------------
