Function NDW_HTTP_DatePicker_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_HTTP_DatePicker_Events

    Description :   This function acts as a commuter module for all events related to this window.

    Notes       :   Commuter Modules are automatically called from the Promoted_Events function which is called by the
                    application-specific promoted event handler. This makes it possible to add QuickEvents that need to
                    execute Basic+ logic without having use the Form Designer to make the association, although this is
                    limited to the events which are currently promoted.

                    If the form needs to call the commuter module directly then the QuickEvent parameters should be
                    formatted like this:                                        

                        '@SELF','@EVENT',['@PARAM1','@PARAMx']

    Parameters  :
        CtrlEntId   [in] -- The fully qualified name of the control calling the promoted event
        Event       [in] -- The event being executed. See the Notes section regarding "PRE" events
        Param1-15   [in] -- Additional event parameter holders
        EventFlow  [out] -- Set to 1 or 0 so the calling event knows whether or not to chain forward. See comments in
                            EVENT_SETUP insert

    History (Date, Initials, Notes)
        07/18/19    dmb     Original programmer although ported the NDW_DATEPICKER from FrameWorks as a base.

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

#pragma precomp SRP_PreCompiler
#window NDW_HTTP_DATEPICKER

$insert LOGICAL
$insert MSG_EQUATES

Equ EVENT_CONTINUE$             to 1
Equ EVENT_CONTINUE_NO_SYSTEM$   to 3
Equ EVENT_STOP$                 to 0
Equ CRLF$                       to \0D0A\

Declare subroutine  Set_Property, Send_Event, Post_Event, Send_Message, SendMessage, End_Dialog
Declare function    Get_Property, SRP_Get_Window_Rect, Send_Message, SendMessage

// Get the design time name of the window in case this is a multi-instance window.
Window = @Window[1, 'F*']

// Always get the CtrlClassID since we are not passing it through the event parameters.
CtrlClassId = Get_Property(CtrlEntId, 'TYPE')

// Get the name of the control on the window based on the CtrlClassId.
Begin Case
    Case CtrlClassId EQ 'WINDOW'
        Control = Window
    Case CtrlClassId EQ 'RADIOBUTTON'
        Control = Field(CtrlEntId, '.', 2, 2)
    Case CtrlClassId EQ 'MENU'
        Control = CtrlEntId[-1, 'B.']
    Case 1
        Control = Field(CtrlEntId, '.', 2, 1)
End Case

If Event EQ 'OLE' then GoSub TransferParams
GoToEvent Event for CtrlEntID
If Event EQ 'OLE' then GoSub RestoreParams

Return EventFlow OR EVENT_CONTINUE$


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Events
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Event WINDOW.CREATE(CreateParam)

	GoSub SetupOLEControls
    GoSub DeterminePosition
    Set_Property(@Window, 'SIZE', Size)

end event


Event WINDOW.INACTIVATED()

    Post_Event(@Window, 'CLOSE')

end event


Event PUB_OK.CLICK()

    GoSub ReturnDate

return


Event OLE_DATEPICKER.OnDblClick(Month, Week, DayOfWeek, Date, Point, Button, Shift, Ctrl)

    If Date NE '' then
        GoSub ReturnDate
    end

return


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal Gosubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SetupOLEControls:

    // All OLE controls can use this qualify configuration.
    Qualify     = ''
    Qualify<1>  = 1
    Qualify<3>  = ''
    Qualify<4>  = 0

    //------------------------------------------------------------------------------------------------------------------
    //
    //  SRP DatePicker Control
    //
    //------------------------------------------------------------------------------------------------------------------
    Ctrl        = @Window : '.OLE_DATEPICKER'
    SizeWindow  = Get_Property(@Window, 'SIZE')
    SizePicker  = -1 : @FM : -1 : @FM : SizeWindow<3> : @FM : SizeWindow<4>
    Set_Property(Ctrl, 'SIZE', SizePicker)
    Set_Property(Ctrl, 'OLE.Theme', 'Windows7Blue')
    Set_Property(Ctrl, 'OLE.Font', 'Segoe UI' : @SVM : 9 : @SVM : 400)

	// Use asynchronous event handling (because in Dialog Box)
	Send_Message(@Window : '.OLE_DATEPICKER', 'QUALIFY_EVENT', 'OLE.OnDblClick', Qualify)

return


TransferParams:

    // ActiveX controls pass their own event names through Param1. Modify the parameter values so they conform to
    // OpenInsight event parameter values. This will allow commuter modules to be structured the same for OpenInsight
    // event and ActiveX (OLE) events.
    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
    Transfer Param9  to Param8
    Transfer Param10 to Param9
    Transfer Param11 to Param10
    Transfer Param12 to Param11
    Transfer Param13 to Param12
    Transfer Param14 to Param13
    Transfer Param15 to Param14

return


RestoreParams:

    // Restore the event parameters so the rest of the event chain will see the parameter values as they were originally
    // created by OpenInsight. This will also prevent the parameter values from being transferred multiple times in case
    // there are multiple OLE promoted event handlers (e.g. APPNAME*..OIWIN* and APPNAME*OLE..OIWIN*).
    Transfer Param14 to Param15
    Transfer Param13 to Param14
    Transfer Param12 to Param13
    Transfer Param11 to Param12
    Transfer Param10 to Param11
    Transfer Param9  to Param10
    Transfer Param8  to Param9 
    Transfer Param7  to Param8 
    Transfer Param6  to Param7
    Transfer Param5  to Param6
    Transfer Param4  to Param5
    Transfer Param3  to Param4
    Transfer Param2  to Param3
    Transfer Param1  to Param2
    Transfer Event   to Param1
    Event             = 'OLE'

return


DeterminePosition:

    Parent  = Get_Property(@Window, 'PARENT')

    // 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
	// Set initial selection to date passed in and make it visible
	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 = Send_Message(CtrlId, 'OLE.GetCellRect', ColNo:@FM:RowNo)
            *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


ReturnDate:

    SelDate = Get_Property(@Window : '.OLE_DATEPICKER', 'OLE.Selection')
    End_Dialog(@Window, SelDate)

    // 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
