Function NDW_TREE_FILTER_EVENTS(CtrlEntId, Event, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)

/***********************************************************************************************************************

    This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
    permission from SRP Computer Solutions, Inc.

    Name        :   NDW_TREE_FILTER_EVENTS

    Description :   Event commuter module for the NDW_Tree_Filter window.

    Notes       :   This is typically called by setting up a QuickEvent to execute a procedure and	
				    the procedure will be this function. The Parameters field would then contain	
				    the necessary parameters to for proper event routing in this routine. The syntax
				    for these parameters are:														
																								
				    'event name','@SELF',['@PARAM1','@PARAMx']										
																								
				    'event name' is the actual event that is being called (e.g. 'CREATE'). It should
				    be surrounded by single quotes. '@SELF' will tell NDW_DatePicker_Events what    
				    the fully qualified name of the current control is. '@PARAMx' is to pass any	
				    additional parameters that the current event may have. '@SELF' and '@PARAMx'	
				    also need to be surrounded by single quotes.									

    Parameters  :
        Event          [in] -- The event that is being executed in the window.							
        CtrlEntId	   [in] -- The control that is calling the event.									
        Param1-13	   [in] -- Additional parameters that the event is passing through.				

    History     :   (Date, Initials, Notes)
        04/10/20    cn     Original programmer.
        

***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
#window NDW_TREE_FILTER

$Insert APP_INSERTS
$Insert EVENT_SETUP

Equ TreeFilter$     To @Window : '.OLE_TREE_FILTER'

Declare function   SendMessage, Send_Message, SRP_Get_Window_Rect, Delete, SRP_Rotate_Array, Insert

Equ DTM_READCELLRECT$       to 1079
Equ DTM_GETCELLLEFTBOTTOM$  to 1160
Equ DTA_CURRENT$            to 1

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

If Assigned(Param8) else Param8 = ''

// Update the arguments so that the OpenInsight OLE event will treate the ActiveX event as a native event handler.
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

If Assigned(EventFlow) else EventFlow = EVENT_CONTINUE$

Return EventFlow or 1


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


Event WINDOW.CREATE(CreateParam)
    CreateParam     = Param1
    // If CreateParam has a value then this is the control that needs to get the return result. It also means this
    // window was launched as a modeless dialog box rather than modal. This will determine how this window should be
    // closed.
*    Set_Property(@Window, '@PARENTCONTROL', CreateParam)

	GoSub Setup_OLE_Controls

    GoSub Determine_Position

 	SRP_Show_Window(@Window, '', '', '', True$, '', True$, True$, Size, False$)
end event


Event OLE_TREE_FILTER.OnItemCheck(ItemKey, Checked)
    Convert ',' to @FM in ItemKey
    SelectedItems = Memory_Services('GetValue', 'SelectedFilterItems')
    For each Item in ItemKey
        KeyValue = Get_Property(TreeFilter$, 'OLE.Item[' : Item : ']')<1>
        If Checked then
            Locate KeyValue in SelectedItems using @FM Setting DataPos else
                SelectedItems = Insert(SelectedItems, -1, 0, 0, KeyValue)    
            end
        end else
            Locate KeyValue in SelectedItems using @FM Setting DataPos then
                SelectedItems = Delete(SelectedItems, DataPos, 0, 0)
            end
        end
    Next Item
    
    Memory_Services('SetValue', 'SelectedFilterItems', SelectedItems)    
end event


Event PUB_CANCEL.CLICK()
    End_Dialog(@Window, 'Cancel')
end event


Event PUB_OK.CLICK()
    GoSub Return_Filter_Items
end event


********************************************
* Internal procedures follow				
********************************************

Setup_OLE_Controls:
    SizeWindow  = Get_Property(@Window, 'SIZE')
    
    Set_Property(TreeFilter$, 'OLE.Theme', 'Windows7Blue')
    Set_Property(TreeFilter$, 'OLE.Font', SystemFont$)

	// Use asynchronous event handling (because in Dialog Box)
	Send_Message(TreeFilter$, "QUALIFY_EVENT", "ALL_OLES", 1)

    GoSub Setup_Filter_Items
    
    AllowFilter = Memory_Services('GetValue', 'AllowFilter')
    Set_Property(@Window : '.PUB_OK', 'ENABLED', AllowFilter)
return


Determine_Position:
    // Determine the Parent window
    MdiActive = Get_Property(Parent, "MDIACTIVE")
    If Len(MdiActive) then
        Parent = MdiActive
    end

    // Determine the control to do the lookup for
    CtrlId = Get_Property(Parent, "FOCUS")
    
    // Get some property values
    Ctrls  = Parent     :@RM: @Window :@RM: CtrlId :@RM: CtrlId   :@RM: CtrlId   :@RM: CtrlId      :@RM: "SYSTEM"
    Props  = "MDIFRAME" :@RM: "SIZE"  :@RM: "TYPE" :@RM: "HANDLE" :@RM: "SELPOS" :@RM: "ORIG_TEXT" :@RM: "SIZE"
    Vals = Get_Property(Ctrls, Props)

    Frame  = Field(Vals, @RM, 1)
    Size   = Field(Vals, @RM, 2)
    Type   = Field(Vals, @RM, 3)
    CtlHdl = Field(Vals, @RM, 4)
    SelPos = Field(Vals, @RM, 5)
    ProgID = Field(Vals, @RM, 6)    ; // To check for OLE EditTables
    Screen = Field(Vals, @RM, 7)
    
    // If no frame, use window size to determine if calendar should show below or above control
    If Frame then
        WinSize = SRP_Get_Window_Rect(Frame)
    end else
        WinSize = SRP_Get_Window_Rect(Parent)
    end        

    Table = (Type EQ "EDITTABLE") OR (ProgID _EQC "SRP.EditTable.1")
    If Table else
        SelPos = ""
    end
  
    If ProgID _EQC "SRP.EditTable.1" then
        // OLE EditTables need to use the CellText property
        ColNo = SelPos<1>
        RowNo = SelPos<2>
        Convert @FM to ";" in SelPos
        DfltDate = Iconv(Get_Property(CtrlId, "OLE.CellText[":SelPos:"]"), "D")
    end else
        DfltDate = Get_Property(CtrlId, "INVALUE", SelPos)
    end
 	If DfltDate then
        Set_Property(@Window:".OLE_DATEPICKER", "OLE.Selection", DfltDate)
        Send_Message(@Window:".OLE_DATEPICKER", "OLE.EnsureVisible", DfltDate)
    end

    Rect = Str(\00\, 16)
    
    CtlSize = SRP_Get_Window_Rect(CtrlId)
    xPos    = CtlSize<1>
    yPos    = CtlSize<2>
    
    If Table then
        // add x, y and y+h of cell
        If ProgID _EQC "SRP.EditTable.1" then
            CellSize = Memory_Services('GetValue', 'Cell_Size')
            *xPos   += CellSize<1>
            xPos    += CellSize<1> + 1  ; // This makes alignment better
            yPos    += CellSize<2>
            cyPos    = yPos + CellSize<4>
        end else
            LeftBottom = SendMessage(CtlHdl, DTM_GETCELLLEFTBOTTOM$, DTA_CURRENT$,  0)
            xPos += mod(LeftBottom, 65536)
            cyPos = yPos + int(LeftBottom / 65536)

            // Get y position with different SendMessage call
            SendMessage(CtlHdl, DTM_READCELLRECT$, DTA_CURRENT$, GetPointer(Rect))
            yPos += seq(Rect [5,1]) + (seq(Rect [6,1]) * 256)
        end
    end else
        // get y+h of control
        cyPos = CtlSize<2> + CtlSize<4>
    end
    
    // get y+h of frame or parent window
    MaxCy = WinSize<2> + WinSize<4>
    
    // Set x and y of calendar window
    Size<1> = xPos
    If Size<1> + Size<3> GT Screen<1> AND (Screen<1> GT Size<1>) then
        // Shift calendar to left to fit on screen
        Size<1> = Screen<1> - Size<3>
    end    
    If cyPos+Size<4> GT MaxCy then
        // Position above control so calendar shows fully
        Size<2> = yPos - Size<4>
    end else    
        Size<2> = cyPos
    end
return


Setup_Filter_Items:
    ItemList                = CreateParam
    SelectedFilterItems     = Memory_Services('GetValue', 'SelectedFilterItems')
    ItemListTemp            = SRP_Rotate_Array(ItemList, @FM)<3>
    
    Set_Property(TreeFilter$, 'OLE.ItemList', ItemList)
    
    For Each Filter in SelectedFilterItems using @FM
        Locate Filter in ItemListTemp using @VM Setting FilterPos then
            Set_Property(TreeFilter$, 'OLE.ItemChecked[' : Filter : ']', True$)
        end
    Next Filter
return


Return_Filter_Items:
    NewSelectedItems        = ''
    ParentControl           = Get_Property(@Window, '@PARENTCONTROL')
    SelectedFilterItems     = Memory_Services('GetValue', 'SelectedFilterItems')
    
    If Len(ParentControl) then
        Send_Event(ParentControl, 'UPDATE', SelectedFilterItems)
        Post_Event(@Window, 'CLOSE')
    end else
	    End_Dialog(@Window, SelectedFilterItems)
	end
	
	// Since we are ending the window now, there is no need to allow the event chain to continue.
	// If we do, then we will get the "labeled common variable has been freed and is no longer valid" error.	
    EventFlow = EVENT_CONTINUE_NO_SYSTEM$
return
