;------------------------------------------------------------------------------;
;+
; NAME
;           EIS_LINES_GUI__DEFINE
;
; CATEGORY
;           EIS Technical Planning
;
; PURPOSE
;           This class defines a GUI object that adds spectral lines
;           from the EIS project list into eis_mk_raster
;
; INPUTS
;           parentClass - the object ID of eis_mk_raster (the superclass)
;
; WRITTEN
;           John A Rainnie RAL 30-Mar-2006
;
; HISTORY
;          v0.1 JAR 3-Jun-2006
;               Added "Sort" menu - whereby the user can sort the project
;               list in terms of either wavelength or alphabetically (ie: by
;               element name)
;          v0.2 29-10-2009 JAR
;               Added code to check if number of lines will exceed 25.
;               If so, complain and bail out
;
;-
;------------------------------------------------------------------------------;
FUNCTION eis_lines_gui::Init , parentClass

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

;-------------------create the main base---------------------------------------;
pt_version = eis_get_pt_version_number()
widTitle = 'EIS Line Selection Tool' + pt_version
TLB_EVENT                   = {eis_lines_gui_Event}
TLB_EVENT.eis_lines_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
Self->readLineList
Self->sortLineList

RETURN, 1

END
;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_lines_gui::createGUI

; Get eis_fonts
fonts = eis_fonts()

topBase                     = WIDGET_BASE(Self.tlbID ,                      $
                                    COLUMN      = 1  ,                      $
                                    /FRAME )

value = 'Wavelength  Type  Atomic Name'
ll_listLabel                = WIDGET_LABEL(topBase ,                        $
                                    /ALIGN_LEFT  ,                          $
                                    value       = value  ,                  $
                                    font        = fonts.mono)

LIST_EVENT                  = {eis_lines_gui_Event}
;Set it's values
LIST_EVENT.eis_lines_gui    = Self
LIST_EVENT.Type             = "LINELIST"
Self.listID                 = WIDGET_LIST(topBase ,                         $
                                    ySize       = 30 ,                      $
                                    xSize       = 40 ,                      $
                                    uValue      = LIST_EVENT,               $
                                    value       = '' ,                      $
                                    /MULTIPLE,                              $
                                    font        = fonts.mono)


value = ['Ascending wavelength'  , 'Ascending name'  ,                      $
         'Descending wavelength' , 'Descending name']
LL_SORT_EVENT               = {eis_lines_gui_Event}
LL_SORT_EVENT.eis_lines_gui = Self
LL_SORT_EVENT.Type          = "SORT"
Self.ll_sortID              = WIDGET_DROPLIST(topBase ,                     $
                                    title       = 'Sort:' ,                 $
                                    value       = value,                    $
                                    Event_Pro   = 'eis_lines_gui_EV',       $
                                    uValue      = LL_SORT_EVENT)


bottomBase                  = WIDGET_BASE(Self.tlbID ,                      $
                                    ROW         = 1  ,                      $
                                    /FRAME           ,                      $
                                    /GRID_LAYOUT)

ADD_EVENT                   = {eis_lines_gui_Event}
ADD_EVENT.eis_lines_gui     = Self
ADD_EVENT.Type              = "ADD"
ADDbutton                   = WIDGET_BUTTON(bottomBase,                     $
                                    value       = 'Add',                    $
                                    Event_Pro   = 'eis_lines_gui_EV',       $
                                    uValue      = ADD_EVENT)


QUIT_EVENT                  = {eis_lines_gui_Event}
QUIT_EVENT.eis_lines_gui    = Self
QUIT_EVENT.Type             = "QUIT"
quitbutton                  = WIDGET_BUTTON(bottomBase,                     $
                                    value       = ' Dismiss ',              $
                                    Event_Pro   = 'eis_lines_gui_EV',       $
                                    uValue      = QUIT_EVENT)


END

;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_lines_gui_Cleanup , wid

WIDGET_CONTROL , wid , get_uvalue = eis_lines_gui_Event
OBJ_DESTROY    , eis_lines_gui_Event.eis_lines_gui

END
;______________________________________________________________________________
; Cleanup
;______________________________________________________________________________
PRO eis_lines_gui::CleanUp

PTR_FREE , Self.lineList

END
;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_lines_gui::setProperty, autoScaleStr  = autoScaleStr

IF (N_ELEMENTS(autoScaleStr) GT 0) THEN BEGIN
    stop
ENDIF

End
;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_lines_gui::GetProperty, tlbID   = tlbID

tlbID = Self.tlbID

End
;______________________________________________________________________________
; Return widget id
;______________________________________________________________________________
Function eis_lines_gui::tlbID

    Return, Self.tlbID
End

;______________________________________________________________________________
; Widget_Control wrapper
;______________________________________________________________________________
PRO eis_lines_gui::Control, _Ref_Extra=Widget_Control_Keywords

Widget_Control, Self.tlbID, _Extra=Widget_Control_Keywords

End

;______________________________________________________________________________
; Widget_Info wrapper
;______________________________________________________________________________
Function eis_lines_gui::Info, _Ref_Extra=Widget_Info_Keywords

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

End

;______________________________________________________________________________
; Realize wrapper
;______________________________________________________________________________
PRO eis_lines_gui::Realize

Widget_Control, Self.tlbID, /Realize

End

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

XMANAGER , "eis_lines_gui" ,   Self.tlbID ,                                 $
    Event_Handler  = "eis_lines_gui_EV",                                    $
    cleanup        = "eis_lines_gui_Cleanup",                               $
    GROUP_LEADER   = Self.group_leader ,                                    $
    /NO_BLOCK

end

;______________________________________________________________________________
;
;______________________________________________________________________________
PRO eis_lines_gui_Event__Define

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

;Get event handler structure containing eis_lines_gui type object
Widget_CONTROL,Event.ID,get_uvalue = eis_lines_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_lines_gui's class member procedure "Handler"
eis_lines_gui_Event.eis_lines_gui->Handler,Event

END
;______________________________________________________________________________
;
; * THIS is the routine for putting in event handling NOT eis_lines_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_lines_gui::Handler, Event

WIDGET_CONTROL, Event.ID, Get_UValue = eis_lines_gui_Event
CASE eis_lines_gui_Event.Type OF
    "QUIT"    : Self->quit
    "ADD"     : Self->addLine
    "LINELIST": IF (event.clicks EQ 2) THEN Self->addLine
    "SORT"    : Self->sortLineList
    ELSE      : print,eis_lines_gui_Event.Type
ENDCASE
END
;______________________________________________________________________________
; QUIT
;______________________________________________________________________________
PRO eis_lines_gui::quit

;Self.parentClass->createUndoItem
Self->Control, /Destroy

END
;______________________________________________________________________________
; Sort the line List
;______________________________________________________________________________
PRO eis_lines_gui::sortLineList


; Get original
waveArray = LONARR(N_ELEMENTS(*Self.lineList))
typeArray = STRARR(N_ELEMENTS(*Self.lineList))
nameArray = STRARR(N_ELEMENTS(*Self.lineList))
ionzArray = STRARR(N_ELEMENTS(*Self.lineList))

FOR i = 0, N_ELEMENTS(*Self.lineList) -1 DO BEGIN

    line = (*Self.lineList)[i]
    ; OK, split up lineList
    doh          = STRSPLIT(line ,/EXTRACT)
    waveArray[i] = ROUND(doh[0]*100.)
    typeArray[i] = doh[1]
    nameArray[i] = doh[2]
    ionzArray[i] = doh[3]

ENDFOR

index = WIDGET_INFO(Self.ll_sortID ,/DROPLIST_SELECT)
; Get SORT indicies
waveIndicies = SORT(waveArray)
nameIndicies = SORT(nameArray)
CASE index OF
    0:      indicies = waveIndicies
    1:      indicies = nameIndicies
    2:      indicies = REVERSE(waveIndicies)
    3:      indicies = REVERSE(nameIndicies)
    ELSE:   stop
ENDCASE

sortedLineList = STRARR(N_ELEMENTS(*Self.lineList))
;
FOR i = 0, N_ELEMENTS(*Self.lineList) -1 DO BEGIN

    sortedLineList[i] =                                                     $
             STRCOMPRESS(waveArray[indicies[i]]/100.,/REMOVE_ALL) +         $
                                                         '      ' +         $
                           typeArray[indicies[i]]      + '     '  +         $
                           nameArray[indicies[i]]      + ' '      +         $
                           ionzArray[indicies[i]]

ENDFOR


PTR_FREE , Self.lineList
Self.lineList = PTR_NEW(sortedLineList)

; Sorting is done! Update Line List
WIDGET_CONTROL , Self.listID, set_value = sortedLineList

END
;______________________________________________________________________________
; Add a line
;______________________________________________________________________________
PRO eis_lines_gui::addLine

selection = WIDGET_INFO(Self.listID , /LIST_SELECT )
; If no items are selected, just return out
IF (selection[0] EQ -1) THEN RETURN

; Check we don't already have this wavelength - if so ignore it
Self.parentClass->getProperty , eis_ll_obj = eis_ll_obj
eis_ll_obj->getProperty , ll = ll

; 29-10-2009 JAR
; Added code to check if number of lines will exceed 25.
; If so, complain and bail out
new_total_lines = N_ELEMENTS(selection) + ll.nLines
IF (new_total_lines GT 25) THEN BEGIN
    mText1 = "The line list already has a maximum of 25 entries."
    mText2 = "Aborting!"
    mText3 = "Tip: Remove one or more existing lines"
    mText  = [mText1,'',mText2,'',mText3]
    beep
    dummy = DIALOG_MESSAGE(mText,/ERROR , DIALOG_PARENT = Self.tlbID)
    RETURN
ENDIF

; Just one thing, if we're starting with 0 lines, then no need to
; perform the following checks
IF (ll.nLines EQ 0) THEN BEGIN
    waveArray = 1L
ENDIF ELSE BEGIN
    ; OK, we have at least 1 line already - let's carry on with the checking
    waveArray = LONARR(ll.nLines)
    FOR i = 0, ll.nLines -1 DO BEGIN
        waveArray[i] = ll.lines[i].wavelength
    ENDFOR
ENDELSE

validLine = LONARR(N_ELEMENTS(selection)) + 1
lineArray = STRARR(N_ELEMENTS(selection))

FOR i = 0, N_ELEMENTS(selection) - 1 DO BEGIN

    line  = (*Self.lineList)[selection[i]]
    lineArray[i] = line
    ; OK, split up lineList
    doh = STRSPLIT(line ,/EXTRACT)
    newWavelength = ROUND( doh[0]*100. )

    index = WHERE(newWavelength EQ waveArray)
    IF (index EQ -1) THEN BEGIN
        ;Self.parentClass->addLine , line
    ENDIF ELSE BEGIN
        validLine[i] = 0
    ENDELSE

ENDFOR


; OK, report lines that didn't get added
IF (TOTAL(validLine) NE N_ELEMENTS(selection)) THEN BEGIN

    indicies = WHERE(validLine EQ 0 , count)
    ; Create a string array - 1 element per line already in Line List
    IF (count EQ 0) THEN stop
    mess = STRARR(count)
    FOR i = 0, count -1 DO BEGIN

        mess[i] = (*Self.lineList)[selection[indicies[i]]]

    ENDFOR
    IF (count EQ 1) THEN blah = 'This line is' ELSE blah = 'These lines are'
    messageText = [blah + " already selected - dummy!" , '' , mess]
    beep
    dummy = DIALOG_MESSAGE(messageText,/ERROR , DIALOG_PARENT = Self.tlbID)
ENDIF

; OK, which selected lines are valid - add them to mk_linelist
validIndex = WHERE(validLine EQ 1)
IF (validIndex[0] NE -1) THEN Self.parentClass->addLine , lineArray[validIndex]



END
;______________________________________________________________________________
; Event Handler wrapper
;______________________________________________________________________________
PRO eis_lines_gui::readLineList

; Create absolute filename
fileName = CONCAT_DIR(GETENV('ancillary') , "eis_official_lines.lis")
; Let's just check it's there
IF (FILE_TEST(fileName) NE 1) THEN stop

; OK, read "eis_official_lines.lis"
nLines = FILE_LINES(fileName)
dummy  = STRARR(nLines)
line   = ''
OPENR , lun , fileName , /GET_LUN
FOR i = 0, nLines - 1 DO BEGIN

    READF , lun , line
    doh  = STRSPLIT( line , /EXTRACT)
    wave = STRING(format='(F6.2)' , doh[2]/100.)
    type = STRTRIM(doh[3] , 2)
    name = STRTRIM(doh[0] , 2) + ' ' +STRTRIM(doh[1] , 2)

    dummy[i] = STRING(format='(A-6,A-7,A-1,A-4,A-9)',wave,'',type,'',name)

ENDFOR

FREE_LUN , lun
PTR_FREE , Self.lineList
Self.lineList = PTR_NEW(dummy)
WIDGET_CONTROL , Self.listID, set_value = dummy

END
;______________________________________________________________________________
; Define Data members
;______________________________________________________________________________
PRO	eis_lines_gui__Define

    struct          =	{ eis_lines_gui                                 ,     $
                                    tlbID           : 0L              ,     $
                                    group_leader    : 0L              ,     $
                                    parentClass     : OBJ_NEW()       ,     $
                                    lineList        : PTR_NEW()       ,     $
                                    listID          : 0L              ,     $
                                    ll_sortID       : 0L                    $
                      }


END
