Function Tool_Parms_Services(@Service, @Params)
/***********************************************************************************************************************

    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        :   Tool_Parms_Services

    Description :   Handler program for all module related services.

    Notes       :   The generic parameters should contain all the necessary information to process the services. Often
                    this will be information like the data Record and Key ID.

    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

    History     :   (Date, Initials, Notes)
        09/11/18    djs     Original programmer.

***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler

$Insert LOGICAL
$Insert RLIST_EQUATES
$Insert RDS_LAYER_EQUATES
$Insert TOOL_PARMS_EQUATES
$Insert RDS_EQUATES
$Insert WO_DAILY_SCHED_EQU

Declare subroutine RList, Set_Status, Error_Services, Database_Services, Tool_Parms_Services, Btree.Extract
Declare function Database_Services, Error_Services, Tool_Parms_Services

GoToService

Return Response or ""

//-----------------------------------------------------------------------------
// SERVICES
//-----------------------------------------------------------------------------

Service GetCurrentToolParmKey(PSN, Reactor)

    If PSN NE '' and Reactor NE '' then
        ToolParmKey = ''
        // Query for the most recent TOOL_PARMS record
        Query       = 'SELECT TOOL_PARMS WITH PSN EQ ':PSN:' AND WITH REACTOR EQ ':Reactor:' BY-DSND DATETIME'        
        GoSub ClearCursors
        Set_Status(0)
        RList(Query, TARGET_ACTIVELIST$, '', '' '')
        ErrorCode   = ''
        If Get_Status(ErrorCode) then
            ErrorMsg = 'Error calling RList(): error code ':ErrorCode
            Error_Services('Add', ErrorMsg)
            return
        end
        Done = False$
        Loop
            Until Done
            Readnext ToolParmKey Else Done = True$       
            // We have the most recent ToolParmKey -> Done
            Done = True$
        Repeat
        GoSub ClearCursors
        
        If ToolParmKey EQ '' then
            // Widen query to exclude reactor
            Query  = 'SELECT TOOL_PARMS WITH PSN EQ ':PSN:' BY-DSND DATETIME'           
            GoSub ClearCursors
            Set_Status(0)
            RList(Query, TARGET_ACTIVELIST$, '', '' '')
            If Get_Status(ErrorCode) then
                ErrorMsg = 'Error calling RList(): error code ':ErrorCode
                Error_Services('Add', ErrorMsg)
                return
            end
            Done = False$
            Loop
                Readnext ToolParmKey Else Done = True$
            Until Done
                // We have the most recent ToolParmKey -> Done
                Done = True$
            Repeat
            GoSub ClearCursors
        end
        
        If ToolParmKey EQ '' then
            // Matching TOOL_PARMS record does not yet exist -> Build one
            ToolParmKey = Tool_Parms_Services('CreateToolParmsRec', PSN, Reactor)
        end
        
        Response = ToolParmKey
    end else
        Response = ''
    end
    
End Service


//----------------------------------------------------------------------------------------------------------------------
// CreateToolParmsRec
//
// Input:
//  PSN       - [Required]
//  ReactorNo - [Required]
//  RDSNo     - [Optional]
//
// Output:
//  NewToolParmKey
//
// Creates a new TOOL_PARMS record. If RDSNo is not supplied, then the most recent RDS which matches the supplied
// PSN and ReactorNo will be referenced for RDS_LAYER parameters. If RDSNo is supplied, then a new TOOL_PARMS
// record will be created using the associated RDS_LAYERS for that RDSNo. The key ID of the new TOOL_PARMS record
// is returned in the response.
//----------------------------------------------------------------------------------------------------------------------
Service CreateToolParmsRec(PSN, ReactorNo, RDSNo)

    CurrentTime    = OConv(Time(), 'MT')
    CurrentDate    = OConv(Date(), 'D')
    CurrentDTM     = CurrentDate:' ':CurrentTime
    CurrentDTM     = IConv(CurrentDTM, 'DT')
    NewToolParmKey = PSN:'*':ReactorNo:'*':CurrentDTM
    NewToolParmRec = ''
    RDSRec         = ''
    
    If RDSNo EQ '' then   
        Query  = 'SELECT RDS WITH PROD_SPEC_ID EQ ':PSN:' AND WITH REACTOR EQ ':ReactorNo:' BY-DSND DATE_IN'
        GoSub ClearCursors
        Set_Status(0)
        RList(Query, TARGET_ACTIVELIST$, '', '', '')
        If Get_Status(ErrorCode) then
            ErrorMsg = 'Error calling RList(): error code ':ErrorCode
            Error_Services('Add', ErrorMsg)
            return
        end
        NumResultRows = @RecCount
        If NumResultRows LT 1 then
            // No RDS records found that match this criteria. Widen the query to search the most recent
            // RDS that matches the Recipe ID and PSN, but to any reactor.
            Query  = 'SELECT RDS WITH PROD_SPEC_ID EQ ':PSN:' BY-DSND DATE_IN'
            GoSub ClearCursors
            Set_Status(0)
            RList(Query, TARGET_ACTIVELIST$, '', '', '')
            If Get_Status(ErrorCode) then
                ErrorMsg = 'Error calling RList(): error code ':ErrorCode
                Error_Services('Add', ErrorMsg)
                return
            end
        end            
        Readnext RDSKey then
            RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKey)
        end
        GoSub ClearCursors
    end else
        // RDSNo supplied -> use RDSNo 
        RDSRec = Database_Services('ReadDataRow', 'RDS', RDSNo)
    end
    
    If RDSRec NE '' then
        RDSLayerKeys = RDSRec<RDS_RDS_LAYER_KEYS$>
        For each RDSLayerKey in RDSLayerKeys using @VM setting vPos               
            RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey)
            
            LayerID                                             = RDSLayerKey[-1, 'B*']
            NewToolParmRec<TOOL_PARMS.LS_ID$, vPos>             = LayerID
            NewToolParmRec<TOOL_PARMS.DOPANT$, vPos>            = RDSLayerRec<RDS_LAYER_DOPANT$>
            NewToolParmRec<TOOL_PARMS.EPI_DILUENT$, vPos>       = RDSLayerRec<RDS_LAYER_EPI_DILUENT$>
            NewToolParmRec<TOOL_PARMS.EPI_TIME$, vPos>          = RDSLayerRec<RDS_LAYER_EPI_TIME$>
            NewToolParmRec<TOOL_PARMS.DILUENT_ADJ_PARAM$, vPos> = RDSLayerRec<RDS_LAYER_DILUENT_ADJ_PARAM$>
            NewToolParmRec<TOOL_PARMS.DOPANT_FLOW$, vPos>       = RDSLayerRec<RDS_LAYER_DOPANT_FLOW$>
            NewToolParmRec<TOOL_PARMS.HCL_FLOW$, vPos>          = RDSLayerRec<RDS_LAYER_HCL_FLOW$>
            NewToolParmRec<TOOL_PARMS.BAKE_TIME$, vPos>         = RDSLayerRec<RDS_LAYER_BAKE_TIME$>
            NewToolParmRec<TOOL_PARMS.EPI_H2_FLOW$, vPos>       = RDSLayerRec<RDS_LAYER_EPI_H2_FLOW$>
            NewToolParmRec<TOOL_PARMS.TCS_FLOW$, vPos>          = RDSLayerRec<RDS_LAYER_TCS_FLOW$>
            NewToolParmRec<TOOL_PARMS.DCS_FLOW$, vPos>          = RDSLayerRec<RDS_LAYER_DCS_FLOW$>
            NewToolParmRec<TOOL_PARMS.AUX1$, vPos>              = RDSLayerRec<RDS_LAYER_AUX1$>
            NewToolParmRec<TOOL_PARMS.AUX2$, vPos>              = RDSLayerRec<RDS_LAYER_AUX2$>
            NewToolParmRec<TOOL_PARMS.F_OFFSET$, vPos>          = RDSLayerRec<RDS_LAYER_F_OFFSET$>
            NewToolParmRec<TOOL_PARMS.S_OFFSET$, vPos>          = RDSLayerRec<RDS_LAYER_S_OFFSET$>
            NewToolParmRec<TOOL_PARMS.R_OFFSET$, vPos>          = RDSLayerRec<RDS_LAYER_R_OFFSET$>
            NewToolParmRec<TOOL_PARMS.ETCH1$, vPos>             = RDSLayerRec<RDS_LAYER_ETCH1$>
            NewToolParmRec<TOOL_PARMS.ETCH2$, vPos>             = RDSLayerRec<RDS_LAYER_ETCH2$>
            NewTOolParmRec<TOOL_PARMS.ETCH3$, vPos>             = RDSLayerRec<RDS_LAYER_ETCH3$>
            NewToolParmRec<TOOL_PARMS.OVERGROW_REQ$, vPos>      = RDSLayerRec<RDS_LAYER_OVERGROW_REQ$>
            NewToolParmRec<TOOL_PARMS.ENTRY_USERNAME$, vPos>    = @USER4
            NewToolParmRec<TOOL_PARMS.SUSC_ETCH$, vPos>         = RDSLayerRec<RDS_LAYER_SUSC_ETCH$>
            NewToolParmRec<TOOL_PARMS.UNLOAD_TEMP$, vPos>       = RDSLayerRec<RDS_LAYER_UL_TEMP$>                  
            
        Next RDSLayerKey
    end                
      
    Database_Services('WriteDataRow', 'TOOL_PARMS', NewToolParmKey, NewToolParmRec)
    If Error_Services('NoError') else
        Error_Services('Add', 'Error writing TOOL_PARMS record: ':NewToolParmKey)
    end
    
    Response = NewToolParmKey
    
end service


Service ApplyCurrentRunParms(PSN, Reactor)

    // Updates all RDS records in the current run without an unload signature.
    DailySchedKey = 'WO_DAILY_SCHED':Reactor
	DailySchedRec = Database_Services('ReadDataRow', 'CONFIG', DailySchedKey)
	WorkOrderCust = DailySchedRec<WOCust$>
	WorkOrderNo   = FIELD(WorkOrderCust, ' ', 1)
    If WorkOrderNo NE '' then
        CurrToolParmKey = Tool_Parms_Services('GetCurrentToolParmKey', PSN, Reactor)
        Record = Database_Services('ReadDataRow', 'TOOL_PARMS', CurrToolParmKey)
        Open 'DICT.RDS' to @DICT then
            FailFlag      = ''
            RDSKeys       = ''
            SearchString  = 'WO':@VM:WorkOrderNo:@FM
            Btree.Extract(SearchString, 'RDS', @DICT, RDSKeys, '', FailFlag)
            If FailFlag NE '-1' then
                Done = False$
                For each RDSKey in RDSKeys using @VM
                    // Ensure the current TOOL_PARMS record being saved matches the current run on the reactor.
                    // If they do not match, then do not update the RDS_LAYER records in the current run.
                    RdsPSN     = Xlate('RDS', RDSKey, 'PROD_SPEC_ID', 'X')
                    RDSReactor = Xlate('RDS', RDSKey, 'REACTOR', 'X')
                    ReactorChange = False$
                    If RDSReactor NE '' then
                        If (RDSReactor NE Reactor) then ReactorChange = True$
                    end
                    If (RdsPSN NE PSN) or (ReactorChange) then Done = True$
                Until Done
                    // Need to check if unload stage has been signed
                    UnloadSig = Xlate('RDS', RDSKey, 'OPERATOR_OUT', 'X')
                    If UnloadSig EQ '' then                
                        // Get RDSLayer keys -> copy tool parameters to each layer
                        RDSLayerIDs = Xlate('RDS', RDSKey, 'RDS_LAYER_KEYS', 'X')
                        If RDSLayerIDs NE '' then
                            ToolParmLayers = Record<TOOL_PARMS.LS_ID$>
                            For each RDSLayerKey in RDSLayerIDs
                                // Copy tool paramters
                                LayerID = Field(RDSLayerKey, '*', 2)
                                RDSLayerRec     = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey)
                                RDSLayerTPKey   = RDSLayerRec<RDS_LAYER_TOOL_PARMS_KEY$>
                                If RDSLayerTPKey NE CurrToolParmKey then
                                    // Only update RDS_LAYER record if TOOL_PARMS record has been updated.                       
                                    Locate LayerID in ToolParmLayers using @VM setting LayerPos then
                                        RDSLayerRec<RDS_LAYER_DOPANT$>            = Record<TOOL_PARMS.DOPANT$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_EPI_DILUENT$>       = Record<TOOL_PARMS.EPI_DILUENT$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_EPI_TIME$>          = Record<TOOL_PARMS.EPI_TIME$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_DILUENT_ADJ_PARAM$> = Record<TOOL_PARMS.DILUENT_ADJ_PARAM$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_DOPANT_FLOW$>       = Record<TOOL_PARMS.DOPANT_FLOW$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_HCL_FLOW$>          = Record<TOOL_PARMS.HCL_FLOW$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_BAKE_TIME$>         = Record<TOOL_PARMS.BAKE_TIME$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_EPI_H2_FLOW$>       = Record<TOOL_PARMS.EPI_H2_FLOW$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_TCS_FLOW$>          = Record<TOOL_PARMS.TCS_FLOW$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_DCS_FLOW$>          = Record<TOOL_PARMS.DCS_FLOW$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_AUX1$>              = Record<TOOL_PARMS.AUX1$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_AUX2$>              = Record<TOOL_PARMS.AUX2$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_F_OFFSET$>          = Record<TOOL_PARMS.F_OFFSET$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_S_OFFSET$>          = Record<TOOL_PARMS.S_OFFSET$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_R_OFFSET$>          = Record<TOOL_PARMS.R_OFFSET$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_ETCH1$>             = Record<TOOL_PARMS.ETCH1$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_ETCH2$>             = Record<TOOL_PARMS.ETCH2$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_ETCH3$>             = Record<TOOL_PARMS.ETCH3$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_OVERGROW_REQ$>      = Record<TOOL_PARMS.OVERGROW_REQ$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_SUSC_ETCH$>         = Record<TOOL_PARMS.SUSC_ETCH$, LayerPos>
                                        RDSLayerRec<RDS_LAYER_UL_TEMP$>           = Record<TOOL_PARMS.UNLOAD_TEMP$, LayerPos>                                 
                                        RDSLayerRec<RDS_LAYER_MODIFY_USER$, -1>   = Record<TOOL_PARMS.ENTRY_USERNAME$>
                                        RDSLayerRec<RDS_LAYER_MODIFY_DTM$, -1>    = Field(CurrToolParmKey, '*', 3)
                                        RDSLayerRec<RDS_LAYER_TOOL_PARMS_KEY$>    = CurrToolParmKey
                                        Database_Services('WriteDataRow', 'RDS_LAYER', RDSLayerKey, RDSLayerRec, True$, True$, True$)
                                    end
                                end
                            Next RDSLayerKey
                        end
                    end
                Next RDSKey
            end
        end
    end
end service


Service ApplyCurrentParms(RDSNo, PSN, Reactor)
    
    If (RDSNo NE '') and (PSN NE '') and (Reactor NE '') then
        CurrToolParmKey = Tool_Parms_Services('GetCurrentToolParmKey', PSN, Reactor)
        If CurrToolParmKey NE '' then
            // Get current tool parameter record
            TPRec = Database_Services('ReadDataRow', 'TOOL_PARMS', CurrToolParmKey)
            // Get RDSLayer keys -> copy tool parameters to each layer
            RDSLayerIDs = Xlate('RDS', RDSNo, 'RDS_LAYER_KEYS', 'X')
            If RDSLayerIDs NE '' then
                ToolParmLayers = TPRec<TOOL_PARMS.LS_ID$>
                For each RDSLayerKey in RDSLayerIDs
                    // Copy tool paramters
                    LayerID = Field(RDSLayerKey, '*', 2)
                    RDSLayerRec     = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey)                       
                    Locate LayerID in ToolParmLayers using @VM setting LayerPos then
                        RDSLayerRec<RDS_LAYER_DOPANT$>            = TPRec<TOOL_PARMS.DOPANT$, LayerPos>
                        RDSLayerRec<RDS_LAYER_EPI_DILUENT$>       = TPRec<TOOL_PARMS.EPI_DILUENT$, LayerPos>
                        RDSLayerRec<RDS_LAYER_EPI_TIME$>          = TPRec<TOOL_PARMS.EPI_TIME$, LayerPos>
                        RDSLayerRec<RDS_LAYER_DILUENT_ADJ_PARAM$> = TPRec<TOOL_PARMS.DILUENT_ADJ_PARAM$, LayerPos>
                        RDSLayerRec<RDS_LAYER_DOPANT_FLOW$>       = TPRec<TOOL_PARMS.DOPANT_FLOW$, LayerPos>
                        RDSLayerRec<RDS_LAYER_HCL_FLOW$>          = TPRec<TOOL_PARMS.HCL_FLOW$, LayerPos>
                        RDSLayerRec<RDS_LAYER_BAKE_TIME$>         = TPRec<TOOL_PARMS.BAKE_TIME$, LayerPos>
                        RDSLayerRec<RDS_LAYER_EPI_H2_FLOW$>       = TPRec<TOOL_PARMS.EPI_H2_FLOW$, LayerPos>
                        RDSLayerRec<RDS_LAYER_TCS_FLOW$>          = TPRec<TOOL_PARMS.TCS_FLOW$, LayerPos>
                        RDSLayerRec<RDS_LAYER_DCS_FLOW$>          = TPRec<TOOL_PARMS.DCS_FLOW$, LayerPos>
                        RDSLayerRec<RDS_LAYER_AUX1$>              = TPRec<TOOL_PARMS.AUX1$, LayerPos>
                        RDSLayerRec<RDS_LAYER_AUX2$>              = TPRec<TOOL_PARMS.AUX2$, LayerPos>
                        RDSLayerRec<RDS_LAYER_F_OFFSET$>          = TPRec<TOOL_PARMS.F_OFFSET$, LayerPos>
                        RDSLayerRec<RDS_LAYER_S_OFFSET$>          = TPRec<TOOL_PARMS.S_OFFSET$, LayerPos>
                        RDSLayerRec<RDS_LAYER_R_OFFSET$>          = TPRec<TOOL_PARMS.R_OFFSET$, LayerPos>
                        RDSLayerRec<RDS_LAYER_ETCH1$>             = TPRec<TOOL_PARMS.ETCH1$, LayerPos>
                        RDSLayerRec<RDS_LAYER_ETCH2$>             = TPRec<TOOL_PARMS.ETCH2$, LayerPos>
                        RDSLayerRec<RDS_LAYER_ETCH3$>             = TPRec<TOOL_PARMS.ETCH3$, LayerPos>
                        RDSLayerRec<RDS_LAYER_OVERGROW_REQ$>      = TPRec<TOOL_PARMS.OVERGROW_REQ$, LayerPos>
                        RDSLayerRec<RDS_LAYER_SUSC_ETCH$>         = TPRec<TOOL_PARMS.SUSC_ETCH$, LayerPos>
                        RDSLayerRec<RDS_LAYER_UL_TEMP$>           = TPRec<TOOL_PARMS.UNLOAD_TEMP$, LayerPos>                                 
                        RDSLayerRec<RDS_LAYER_MODIFY_USER$, -1>   = TPRec<TOOL_PARMS.ENTRY_USERNAME$>
                        RDSLayerRec<RDS_LAYER_MODIFY_DTM$, -1>    = Field(CurrToolParmKey, '*', 3)
                        RDSLayerRec<RDS_LAYER_TOOL_PARMS_KEY$>    = CurrToolParmKey
                        Database_Services('WriteDataRow', 'RDS_LAYER', RDSLayerKey, RDSLayerRec, True$, True$, True$)
                    end
                Next RDSLayerKey
            end
        end
    end

end service


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


ClearCursors:
    For counter = 0 to 8
        ClearSelect counter
    Next counter
return
