Compile function NDW_GAN_RETAIN_MANAGER_SEARCH_EDIT_DEV_EVENTS(CtrlEntId, Event, @PARAMS)
/***********************************************************************************************************************

    Name        :   NDW_GAN_RETAIN_MANAGER_SEARCH_EDIT_DEV_EVENTS

    Description :   Commuter module for the NDW_GAN_RETAIN_MANAGER_SEARCH_EDIT_DEV form.

    Notes       :   Application errors should be logged using the Error Services module. There are a few methodological
                    assumptions built into way errors are managed which are important to understand in order to properly
                    work with Error Services:

                    - The term 'top' refers to the originating procedure of a call stack and the term 'bottom' refers to
                      the last routine (or the current routine) within a call stack. Within the OpenInsight Debugger
                      this will appear backwards since the originating procedure always appears at the bottom of the
                      list and the current routine appears at the top of the list. We are using this orientation because
                      it is common to refer to the process of calling other procedures as 'drilling down'.

                    - The reason for defining the orientation of the call stack is because Error_Services allows for
                      multiple error conditions to be appended to an original error. In most cases this will happen when
                      a procedure at the bottom of the stack generates an error condition and then returns to its
                      calling procedure. This higher level procedure can optionally add more information relevant to
                      itself. This continues as the call stack 'bubbles' its way back to the top to where the
                      originating procedure is waiting.

                    - Native OpenInsight commands that handle errors (e.g., Set_Status, Set_FSError, Set_EventStatus)
                      preserve their error state until explicitly cleared. This can hinder the normal execution of code
                      since subsequent procedures (usually SSPs) will fail if a pre-existing error condition exists.
                      Our philosophy is that error conditions should automatically be cleared before a new procedure
                      is executed to avoid this problem. However, the nature of Basic+ does not make this easy to
                      automate for any given stored procedure. Therefore, if a stored procedure wants to conform to our
                      philosophy then it should include a call into the 'Clear' service request at the top of the
                      program. Alternatively this can be done through a common insert (see SERVICE_SETUP for example.)

                    - Service modules will use the SERVICE_SETUP insert and therefore automatically clear out any
                      error conditions that were set before.

    Parameters  :
        Service         [in] -- Name of the service being requested
        Param1-10   [in/out] -- Additional request parameter holders
        Response       [out] -- Response to be sent back to the Controller (MCP) or requesting procedure

    Metadata    :

    History     :   (Date, Initials, Notes)
        03/11/20    djs     Original programmer. 

***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
#window NDW_GAN_RETAIN_MANAGER_SEARCH_EDIT_DEV

$Insert LOGICAL
$Insert APPCOLORS
$Insert RETAINED_WAFERS_EQUATES

// Control Name equates
Equ SearchTable$    To @Window : '.OLE_EDT_SEARCH'
Equ FilterTree$     To @Window : '.OLE_TREE_ACTIVE_FILTERS'
Equ BreadcrumbBar$  To @Window : '.OLE_BREADCRUMBBAR'

// OLE Edit Table Columns
Equ RUN_ID$         To  1
Equ RECIPE$         To  2
Equ POCKET$         To  3
Equ SCRIBE$         To  4
Equ GRADE$          To  5
Equ PART$           To  6
Equ WO_NO$          To  7
Equ RETAIN_BOX$     To  8
Equ RETAIN_SLOT$    To  9
Equ RETAIN_LOC$     To 10
Equ STATUS$         To 11
Equ COMMENT$        To 12
Equ OPERATOR$       To 13
Equ RETAIN_DATE$    To 14
Equ DESTROY_SIG$    To 15
Equ DESTROY_DATE$   To 16 
Equ WAFER_ID$       To 17


// Reduce modes (for Select statement)
Equ NEW_EXIST$ To 0 
Equ NEXT_CUR$  To 1
Equ ADD_EXIST$ To 2

Declare Function   Form_Services, Get_Property, Utility, Database_Services, Error_Services, Send_Message
Declare Function   Memory_Services, Create_Dialog, Dialog_Box, SRP_Array, SRP_FastArray, SRP_Sort_Array
Declare Function   Retain_Manager_Services, SRP_Trim, SRP_BreadcrumbBar
Declare Subroutine SRP_Show_Window, Set_Property, Send_Message, Post_Event, Reduce, FSMsg, Btree.Extract
Declare Subroutine SRP_Stopwatch, SRP_Edittable_Manager, Error_Services, Memory_Services, Utility, SRP_FastArray
Declare Subroutine SRP_BreadcrumbBar

SubclassInfo    = Form_Services('FindSubclassControl')
Subclass        = SubclassInfo<1>

If Assigned(Param8) else Param8 = ''

If Event EQ 'OLE' then
    Transfer Event to OIEvent
    Transfer Param1 to Event
    Transfer Param2 to Param1
    Transfer Param3 to Param2
    Transfer Param4 to Param3
    Transfer Param5 to Param4
    Transfer Param6 to Param5
    Transfer Param7 to Param6
    Transfer Param8 to Param7
end

GoToEvent Event for CtrlEntId else
    // Event not implemented
end

Return EventFlow or 1

//-----------------------------------------------------------------------------
// EVENT HANDLERS
//-----------------------------------------------------------------------------

Event WINDOW.CREATE(CreateParam)
    GoSub SetupOLEControls
    SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, '', 1)
End Event


Event WINDOW.CLOSE(CancelFlag)
    GoSub ClearMemory
    Memory_Services('RemoveKey', 'AllowedFilters')
    SRP_BreadcrumbBar(BreadcrumbBar$, 'Close')
end event


Event PUB_SUBMIT.CLICK()
    GoSub ClearMemory
    GoSub UpdateSearchData
    // Send event to SearchTable$ to cause the Wafer Details to update for position 1;1
    Send_Message(SearchTable$, 'OLE.FireEvent', 'PosChanged', '1; 1')
end event


Event OLE_EDT_SEARCH.OnHeaderClick(Cell, Point, Button, Shift, Ctrl)
    Set_Property(SearchTable$, 'OLE.Redraw', False$)
    DataList = Get_Property(SearchTable$, 'OLE.ARRAY')
    
    If DataList then
        FilterOptions   = ''
        CellxPos        = Cell[1, ';']
        CellyPos        = Cell[Col2() + 1, ';']
        // Remove 1 cell position due to the hidden header column
        CellSize        = Send_Message(SearchTable$, "OLE.GetCellRect", (CellxPos - 1) : ';' CellyPos)
        Memory_Services('SetValue', 'Cell_Size', CellSize)
        Begin Case
            Case Button EQ 'Left'
                
                Header          = Get_Property(SearchTable$, 'HeaderText[' : Cell : ']')
                ColumnPos       = CellxPos - 1
                TreeFilterList  = Get_Property(FilterTree$, 'OLE.ItemList')
                AllowedFilters  = Memory_Services('GetValue', 'AllowedFilters')
                
                Locate Header in AllowedFilters Using @VM setting pos then
                    PrimarySegment = SRP_Breadcrumbbar(BreadcrumbBar$, 'GetSegmentPath', '', False$)<1>
                    If Header NE PrimarySegment then
                        ColumnData = Get_Property(SearchTable$, 'OLE.ColumnData[' : ColumnPos : ']')
                        Swap @VM with @FM in ColumnData
                        
                        FilterArray = ''
                        FilterList  = ''
                        
                        For Each Data in ColumnData Using @FM
                            Locate Data in FilterArray Using @FM Setting FilterPos else
                                FilterArray := Data : @FM
                            end
                        Next Data
                        
                        FilterArray[-1, 1]  = ''
                        FilterArray         = SRP_Sort_Array(FilterArray, 'AL2', 1)
                        
                        // Build filter list in SRP Tree Control format
                        For Each Filter in FilterArray using @FM
                            FilterList := 1 : @VM : SRP_Trim(Filter, 'FA', '0')  : @VM : Filter : @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM : 'Left' : @VM : @FM
                        Next FilterArray
                        
                        // Place all filter options into memory for reference
                        Memory_Services('SetValue', Header : '*MasterFilterList', FilterList)                    
                    end else
                        FilterList = Memory_Services('GetValue', Header : '*MasterFilterList')
                    end
                      
                    // Get existing filter for column and pass through to memory services to be transferred
                    // to NDW_TREE_FILTER.
                    ExistingFilter       = Memory_Services('GetValue', Header : '*FilterList')
                    Memory_Services('SetValue', 'SelectedFilterItems', ExistingFilter)
                    
                    // Call the Tree_Filter Window and place it under the column header. Combine current list and current
                    // filter lists together so the NDW_TREE_FILTER displays the full list and current filtered items
                    SelectedFilterItems  = Dialog_Box('NDW_TREE_FILTER', @Window, FilterList)
                    Memory_Services('SetValue', Header : '*FilterList', SelectedFilterItems)
                    
                    // Save current DataList to Memory Services
                    Memory_Services('SetValue', Header : '*CurrentDataList', DataList)
                    
                    CurrentActiveSegment = SRP_BreadcrumbBar(BreadcrumbBar$, 'GetActiveSegment')
                    
                    Begin Case
                        Case SelectedFilterItems NE '' AND CurrentActiveSegment EQ ''
                            SRP_BreadcrumbBar(BreadcrumbBar$, 'AddSegment', Header : @VM : Header : @VM : Header : '*CurrentDataList', '', True$)
                        
                        Case SelectedFilterItems NE '' AND CurrentActiveSegment NE ''
                            SRP_BreadcrumbBar(BreadcrumbBar$, 'AddSegment', Header : @VM : Header : @VM : Header : '*CurrentDataList', CurrentActiveSegment, True$)
                            
                        Case SelectedFilterItems EQ '' AND CurrentActiveSegment NE ''
                            // Add Remove Statement Logic Here
                    End Case
                        
                    FullSegmentPath = SRP_BreadcrumbBar(BreadcrumbBar$, 'GetSegmentPath', '', True$)
                    Memory_Services('SetValue', 'FullSegmentPath', FullSegmentPath)
                        
                    // Check to see if there is a master list for each header and filter against that list.
*                    MasterListforHeader = Memory_Services('GetValue', Header : '*MasterList')
*                    If MasterListforHeader NE '' then
*                        SearchCtrlList  = MasterListforHeader
*                    end else
                        SearchCtrlList  = Get_Property(SearchTable$, 'OLE.ARRAY')
                        SearchCtrlList  = SRP_Array('Rotate', SearchCtrlList, @FM, @VM)
*                        Memory_Services('SetValue', Header : '*MasterList', SearchCtrlList)
*                    end
                    
                    If SelectedFilterItems then
                        SearchTableArray    = SRP_FastArray('Create', SearchCtrlList)
                        SearchCtrlList      = Retain_Manager_Services('UpdateRetainList', SearchTableArray, SelectedFilterItems)    
                        Set_Property(SearchTable$, 'OLE.ARRAY', SearchCtrlList)
                    end

*                   GoSub UpdateActiveFiltersTree
                    
                end else
                    Error_Services('Set' , 'Filter Empty, please select another filter')
                    Error_Services('DisplayError', 'C')
                end
            Case Button EQ 'Right'
                // Present sort options
        End Case
        SRP_FastArray("Release", SearchTableArray)
    end
    Set_Property(SearchTable$, 'OLE.Redraw', True$)
end event


Event OLE_BREADCRUMBBAR.OnSegmentClick(CurrentCell)
    SegmentMisc                 = SRP_BreadcrumbBar(BreadcrumbBar$, 'GetSegmentMisc', CurrentCell)
    FullSegmentPath             = Memory_Services('GetValue', 'FullSegmentPath')
    NumberofPreviousSegments    = Count(FullSegmentPath, @FM)
    
    Locate CurrentCell in FullSegmentPath using @FM setting SegmentPos then
        // Move position by one to not include the currently clicked segment in the clearing process
        SegmentPos = SegmentPos + 1
        For Counter = SegmentPos to NumberofPreviousSegments
            // Clear existing filter for cleared segment
            HeaderName = FullSegmentPath<Counter>
            Memory_Services('SetValue', HeaderName : '*FilterList', '')
            Memory_Services('SetValue', HeaderName : '*MasterFilterList', '')
            Memory_Services('SetValue', SelectedFilterItems, '')
        Next Counter
    end

    UpdatedSegmentPath = SRP_BreadcrumbBar(BreadcrumbBar$, 'GetSegmentPath', '', True$)
    Memory_Services('SetValue', 'FullSegmentPath', UpdatedSegmentPath)
    
    DataList    = Memory_Services('GetValue', SegmentMisc)
    Set_Property(SearchTable$, 'OLE.ARRAY', DataList)
end event


Event OLE_TREE_ACTIVE_FILTERS.OnItemClose(ItemKey)
    // Get Filter List from SRP Tree Control, remove entry from memory services list
    TreeFilterList = Get_Property(FilterTree$, 'OLE.ItemList')
    For each FilterEntry in TreeFilterList using @FM setting FilterPos
        If FilterEntry<1,1> EQ 1 then
            Header = FilterEntry<1,2>
        end else
            Filter = FilterEntry<1,2>
            If Filter EQ ItemKey then
                FilterList = Memory_Services('GetValue', Header : '*FilterList')
                Locate ItemKey in FilterList using @FM setting FilterPos then
                    FilterList = Delete(FilterList, FilterPos, 0, 0)
                    Memory_Services('SetValue', Header : '*FilterList', FilterList)
                end
            end
        end
    Next FilterEntry
    
    // Update SRP Tree Control with removed entry
    GoSub UpdateActiveFiltersTree
end event


Event OLE_EDT_SEARCH.PosChanged(Cell, PrevCell, Button, RepeatCount)
    PrevColPos  = PrevCell[1, ';']
    PrevRowPos  = PrevCell[Col2() + 1, ';']   
    ColPos      = Cell[1, ';']
    RowPos      = Cell[Col2() + 1, ';']
    
    If PrevRowPos NE RowPos then
        GoSub UpdateWaferDetails
    end
end event


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


SetupOLEControls:
    Set_Property(@Window : '.STA_DESTROYED_SIGN', 'VISIBLE', False$)
    Set_Property(@Window : '.EDL_DESTROYED_SIGN', 'VISIBLE', False$)
    Set_Property(@Window : '.STA_DESTROYED_DATE', 'VISIBLE', False$)
    Set_Property(@Window : '.EDL_DESTROYED_DATE', 'VISIBLE', False$)
    
    // Recreating EditTable format using SRP_EditTable_Manager for better control
    ArrayDimension      = 17 : @FM : 50
    TitleList           = 'Run ID' : @VM : 'Recipe' : @VM : 'Pocket' : @VM : 'Scribe' : @VM : 'Grade' : @VM : 'Part' : @VM
    ColumnWidths        = '80'     : @FM : '130'    : @FM : '55'     : @FM : '70'     : @FM : '50'    : @FM : '100'  : @FM
    ColumnAlignments    = 'L'      : @FM : 'L'      : @FM : 'C'      : @FM : 'C'      : @FM : 'C'     : @FM : 'L'    : @FM
    
    TitleList          := 'WO' : @VM : 'Retain Box' : @VM : 'Slot' : @VM : 'Location' : @VM : 'Status' : @VM : 'Comment' : @VM
    ColumnWidths       := '45' : @FM : '75'         : @FM : '40'   : @FM : '70'       : @FM : '60'     : @FM : 'A'       : @FM
    ColumnAlignments   := 'C'  : @FM : 'C'          : @FM : 'C'    : @FM : 'L'        : @FM : 'L'      : @FM : 'L'       : @FM
    
    TitleList          := 'Retained Sign' : @VM : 'Retain Date'  : @VM : 'Destroy Sign'  : @VM : 'Destroy Date' : @VM : 'Wafer ID'
    ColumnWidths       := '90'            : @FM : '80'           : @FM : '85'            : @FM : '85'           : @FM : ''
    ColumnAlignments   := 'C'             : @FM : 'C'            : @FM : 'C'             : @FM : 'C'            : @FM : 'C'

    VirtualPos          = ''
    RowsAsColumns       = ''
    CellsAsFields       = ''
    ClearFill           = ''
    OIEditTable         = ''
    SRP_EditTable_Manager('Setup1', SearchTable$, ArrayDimension, TitleList, ColumnWidths, ColumnAlignments, VirtualPos, RowsAsColumns, CellsAsFields, ClearFill, OIEditTable)
    Set_Property(SearchTable$, 'OLE.SelectionStyle', 'Black' : @VM : OI_HOT_BLUE$ : ' L=70' : @FM : 'Black' : @VM : OI_HOT_BLUE$)     ; // Automatically highlight the current row with one color and highlight the current row with another color.
    Set_Property(SearchTable$, 'OLE.HeaderFont[All; All]', 'Segoe UI' : @SVM : 8)
    Set_Property(SearchTable$, 'OLE.CellFont[All; All]', 'Segoe UI' : @SVM : 8)
    Set_Property(SearchTable$, 'OLE.HeaderColumn[1]', '' : @FM : False$ : @FM : False$ : @FM)
    Set_Property(SearchTable$, 'OLE.CellProtection[ALL; All]', 'SEL')
 	Set_Property(SearchTable$, 'OLE.NewRowCount', 0)
    Set_Property(SearchTable$, 'OLE.HeaderRow[ALL]', '' : @FM : '' : @FM : False$ : @FM)
    Set_Property(SearchTable$, 'OLE.DataColumn[ALL]', '' : @FM : '' : @FM : False$ : @FM)
    Set_Property(SearchTable$, 'OLE.DataRow[ALL]', '' : @FM : '' : @FM : False$ : @FM)
    Set_Property(SearchTable$, 'OLE.HeaderColors[All; All]', 'Auto' : @FM : 'None' : @FM : 'None' : @FM : OI_HOT_BLUE$ : @FM : False$)
    Set_Property(SearchTable$, 'OLE.ResetSelPos', False$)
    Set_Property(SearchTable$, 'OLE.HeaderArrow[All; 1]', 'Down')
	Set_Property(SearchTable$, 'OLE.AllowDeletions', False$)
    Set_Property(SearchTable$, 'OLE.AllowInserts', False$)
    // Begin with hidden destroyed sig and date
    Set_Property(SearchTable$, 'OLE.DataColumn[' : DESTROY_SIG$ : ']', '' : @FM : False$)
    Set_Property(SearchTable$, 'OLE.DataColumn[' : DESTROY_DATE$ : ']', '' : @FM : False$)
    Set_Property(SearchTable$, 'OLE.DataColumn[' : WAFER_ID$ : ']', '' : @FM : False$)
    Set_Property(SearchTable$, 'OLE.SelectionStyle', '' : @FM : '' : @FM : '' : @FM : '' : @FM : '' : @FM : '' : @FM : '' : @FM : True$ : @FM)
    
    // Qualify OLE events that we want to intercept
    Qualifier       = ''
    Qualifier<1>    = 1
    Qualifier<4>    = 0 ; * process synchronously (i.e. immediately)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.AfterUpdate',         Qualifier)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.OnClick',             Qualifier)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.OnButtonClick',       Qualifier)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.OnContextMenuClick',  Qualifier)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.PosChanged',          Qualifier)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.OnComboClicked',      Qualifier)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.OnHeaderClick',       Qualifier)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.OnCheckChanged',      Qualifier)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.AfterUpdate',         Qualifier)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.OnContextMenuClick',  Qualifier)
    Send_Message(SearchTable$,  'QUALIFY_EVENT', 'OLE.OnDblClick',          Qualifier)
    
    Send_Message(FilterTree$,   'QUALIFY_EVENT', 'OLE.OnItemClose',          Qualifier)
    
    // Configure columns that have filtering requirements
    AllowedFilters  = 'Run ID' : @VM : 'Recipe' : @VM : 'Pocket' : @VM : 'Scribe' : @VM : 'Grade' : @VM : 'Part' : @VM
    AllowedFilters := 'WO' : @VM : 'Retain Box' : @VM : 'Retained Sign' : @VM : 'Retain Date' : @VM : 'Location'
    Memory_Services('SetValue', 'AllowedFilters', AllowedFilters)
    
    SRP_BreadcrumbBar(BreadcrumbBar$, 'Init', SystemFont$)
return


ClearMemory:
    // NOTE: Clean up naming to clarify this is each header column
    AllowedFilters = Memory_Services('GetValue', 'AllowedFilters')
    For Each Header in AllowedFilters using @VM
        Memory_Services('RemoveKey', Header : '*MasterFilterList')
        Memory_Services('RemoveKey', Header : '*FilterList')
        Memory_Services('RemoveKey', Header : '*MasterList')
    Next Header
    
    Memory_Services('RemoveKey', 'MasterRetainList')
    Memory_Services('RemoveKey', 'SelectedFilterItems')
    Memory_Services('RemoveKey', 'MasterRetainList')
return


UpdateSearchData:
    Set_Property(SearchTable$, 'OLE.Redraw', False$)
    WaferSize     = Get_Property(@Window : '.RAG_WAFER_TYPE', 'VALUE')
    ShowDestoryed = Get_Property(@Window : '.CHB_SHOW_DESTROYED', 'CHECK')
    
    Begin Case
        Case WaferSize EQ '150 mm 6 in' AND ShowDestoryed EQ False$
            CtrlList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_6IN')
            CtrlListHandle  = SRP_FastArray('Create', CtrlList)
            Locationfilters = 'Warehouse' : @FM : 'Cleanroom'
            SearchCtrlList  = Retain_Manager_Services('UpdateRetainList', CtrlListHandle, LocationFilters)
            
        Case WaferSize EQ '200 mm 8 in' AND ShowDestoryed EQ False$
            CtrlList        = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_8IN')
            CtrlListHandle  = SRP_FastArray('Create', CtrlList)
            Locationfilters = 'Warehouse' : @FM : 'Cleanroom'
            SearchCtrlList  = Retain_Manager_Services('UpdateRetainList', CtrlListHandle, LocationFilters)
            
        Case WaferSize EQ '150 mm 6 in' AND ShowDestoryed EQ True$
            CtrlList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_6IN')
            SearchCtrlList = SRP_Array('Rotate', CtrlList, @FM, @VM)
            
        Case WaferSize EQ '200 mm 8 in' AND ShowDestoryed EQ True$
            CtrlList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_8IN')
            SearchCtrlList = SRP_Array('Rotate', CtrlList, @FM, @VM)
    End Case
    
    SearchCtrlList<14> = OConv(SearchCtrlList<14>, 'D2/')
    SearchCtrlList<16> = OConv(SearchCtrlList<16>, 'D2/')
    
    Set_Property(SearchTable$, 'OLE.ARRAY', SearchCtrlList)
    
    // Save the whole retain list to memory services for later reference by primary filter
    Memory_Services('SetValue', 'MasterRetainList', SearchCtrlList)
    
    // Set Destroy Signature and Destory Date columns based off of Show Destroyed checkbox    
    Set_Property(SearchTable$, 'OLE.DataColumn[' : DESTROY_SIG$ : ']', '' : @FM : ShowDestoryed)
    Set_Property(SearchTable$, 'OLE.DataColumn[' : DESTROY_DATE$ : ']', '' : @FM : ShowDestoryed)
    Set_Property(@Window : '.STA_DESTROYED_SIGN', 'VISIBLE', ShowDestoryed)
    Set_Property(@Window : '.EDL_DESTROYED_SIGN', 'VISIBLE', ShowDestoryed)
    Set_Property(@Window : '.STA_DESTROYED_DATE', 'VISIBLE', ShowDestoryed)
    Set_Property(@Window : '.EDL_DESTROYED_DATE', 'VISIBLE', ShowDestoryed)
    
    SRP_FastArray("Release", CtrlListHandle)
    Set_Property(SearchTable$, 'OLE.Redraw', True$)
return


UpdateActiveFiltersTree:
    TreeFilterList  = ''
    HeaderTitles    = Get_Property(SearchTable$, 'OLE.TitleList')
    
    For Each Header In HeaderTitles using @VM
        SelectedFilterItems = Memory_Services('GetValue', Header : '*FilterList')
        If SelectedFilterItems NE '' then
            TreeFilterList := 1 : @VM : Header : @VM : Header : @FM
            For Each Filter in SelectedFilterItems using @FM
                TreeFilterList := 2 : @VM : Filter : @VM : Filter : @FM
            Next Filter
        end
    Next Header
    
    TreeFilterList[-1,1] = ''
    
    Set_Property(FilterTree$, 'OLE.ItemList', TreeFilterList)
    Set_Property(FilterTree$, 'OLE.CloseButtonConditions', 'Not(HasChildren)')
    Set_Property(FilterTree$, 'OLE.ItemExpanded[All]', True$)
*    SelectedFilterItems = Memory_Services('SetValue', Header : '*FilterList', '')
return


UpdateWaferDetails:
    Set_Property(SearchTable$, 'OLE.Redraw', False$)
    // Assign column positions to values to avoid magic numbers
    RunIDPos            = 1
    RecipePos           = 2
    PocketPos           = 3
    ScribePos           = 4
    GradePos            = 5
    PartPos             = 6
    WOPos               = 7
    RetainBoxPos        = 8
    SlotPos             = 9
    LocationPos         = 10
    StatusPos           = 11
    CommentPos          = 12
    RetainedSignPos     = 13
    RetainedDatePos     = 14
    DestroyedSigPos     = 15
    DestroyedDatePos    = 16
    WaferIDPos          = 17

    CellPos         = Param1
    ColPos          = CellPos[1, ';']
    RowPos          = CellPos[Col2() + 1, ';']    

    // Load RunID data to wafer details area
    RunID           = Get_Property(SearchTable$, 'OLE.CellText[' : RunIDPos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_RUN_ID', 'TEXT', RunID)

    // Load Recipe data to wafer details area
    Recipe          = Get_Property(SearchTable$, 'OLE.CellText[' : RecipePos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_RECIPE', 'TEXT', Recipe)
    
    // Load Pocket data to wafer details area    
    Pocket          = Get_Property(SearchTable$, 'OLE.CellText[' : PocketPos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_POCKET', 'TEXT', Pocket)    

    // Load Scribe data to wafer details area    
    Scribe          = Get_Property(SearchTable$, 'OLE.CellText[' : ScribePos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_SCRIBE', 'TEXT', Scribe)    
    
    // Load Grade data to wafer details area    
    Grade           = Get_Property(SearchTable$, 'OLE.CellText[' : GradePos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_GRADE', 'TEXT', Grade)        

    // Load Part data to wafer details area    
    Part            = Get_Property(SearchTable$, 'OLE.CellText[' : PartPos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_PART', 'TEXT', Part)
    
    // Load WO data to wafer details area    
    WO              = Get_Property(SearchTable$, 'OLE.CellText[' : WOPos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_WO', 'TEXT', WO)       

    // Load RetainBox data to wafer details area    
    RetainBox       = Get_Property(SearchTable$, 'OLE.CellText[' : RetainBoxPos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_RETAIN_BOX', 'TEXT', RetainBox)
    
    // Load Slot data to wafer details area    
    Slot            = Get_Property(SearchTable$, 'OLE.CellText[' : SlotPos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_SLOT', 'TEXT', Slot)    
    
    // Load Retained Sign data to wafer details area    
    RetainedSign    = Get_Property(SearchTable$, 'OLE.CellText[' : RetainedSignPos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_RETAINED_SIGN', 'TEXT', RetainedSign)
    
    // Load Retain Date data to wafer details area    
    RetainedDate      = Get_Property(SearchTable$, 'OLE.CellText[' : RetainedDatePos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_RETAINED_DATE', 'TEXT', RetainedDate)

    // Load Destroy Sign data to wafer details area    
    DestroyedSign      = Get_Property(SearchTable$, 'OLE.CellText[' : DestroyedSigPos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_DESTROYED_SIGN', 'TEXT', DestroyedSign)
    
    // Load Destroy Date data to wafer details area    
    DestroyedDate     = Get_Property(SearchTable$, 'OLE.CellText[' : DestroyedDatePos :';' : RowPos : ']')
    Set_Property(@Window :'.EDL_DESTROYED_DATE', 'TEXT', DestroyedDate)

    // Load Location data to wafer details area    
    Location        = Get_Property(SearchTable$, 'OLE.CellText[' : LocationPos :';' : RowPos : ']')
    Set_Property(@Window :'.COB_LOCATION', 'TEXT', Location)

    // Load Status data to wafer details area    
    Status          = Get_Property(SearchTable$, 'OLE.CellText[' : StatusPos :';' : RowPos : ']')
    Set_Property(@Window :'.COB_STATUS', 'TEXT', Status)    

    // Load Comment data to wafer details area    
    Comment         = Get_Property(SearchTable$, 'OLE.CellText[' : CommentPos :';' : RowPos : ']')
    Set_Property(@Window :'.EDB_COMMENTS', 'TEXT', Comment)
    Set_Property(SearchTable$, 'OLE.Redraw', True$)
return

