classdef MessageSendFunctionInfo < rtw.pil.QueuedIOFunctionInfo
    %MESSAGESENDFUNCTIONINFO: representation for Message Sender interface 
    
    %   Copyright 2017-2018 The MathWorks, Inc.
    methods (Access = {?rtw.pil.CSFunctionInfoFactory})
        % Only allow object construction by the factory class
        function this = MessageSendFunctionInfo(fcnName, rtmTypeIdentifier, argType, timing, variantInfo,...
                tid,...
                fcnId,...
                isDefined,...
                isAUTOSAR, ...
                portNumber, ...
                mf0ModelInstance)
            
           
            
            % call superclass constructor
            this@rtw.pil.QueuedIOFunctionInfo(fcnName, rtmTypeIdentifier, argType, timing, variantInfo,...
                tid,...
                fcnId,...
                isDefined,...
                isAUTOSAR, ...
                portNumber, ...
                'u', ...
                'INPUT', ...
                mf0ModelInstance)         
        end
    end
    
    methods
        % Write S-Function Send Api call
        function writeCallToFunction(this, writer, simStructArg, argsVarName, ~)
            
            portNumber = this.PortNumber;
            writer.wLine('returnArg = slmsg_ssSendDataInSIL(%s%d, %s);', simStructArg, portNumber, argsVarName);
        end
        
        % Define any arguments needed for the S-Function message send
        % call. Need the transferred message data and a return status to
        % send back to the target.
        function argPointerAccessString = defineArgsForSLCall(this, writer, argVarName) %#ok<INUSL>
                       
            argPointerAccessString  = ''; %Not Used
            
            writer.writeLine('void* %s;', argVarName);
            writer.writeLine('uint_T returnArg = 0;'); %Initialize return value. Set to OK by default
        end
        
        % Correctly process the message payload, so it can be passed to the
        % Simulink engine via the Message S-function API.
        function writeSfunctionDataAssignmentForSLCall(this, sfunObj, writer, argVarName)
            writer.wBlockStart('if (ssGetPWork(S) != NULL)');
            
            args = this.getAllCodeInfoArgs;
            for codeInfoArgIdx = 1:length(args)
                
                arg = args(codeInfoArgIdx);
                if ~strcmp(arg.IOType, 'INPUT')
                    continue;
                end
                codeArgPosition = this.getCodeArgPosition(arg);
                argDataInterface = this.getDataInterfacesForArgs(codeArgPosition);
                dataElements = this.getDataElementsForArgs(codeArgPosition);
                writer.wBlockStart(''); % scope around each argument
                % the first data element has all the info we need
                cData = dataElements(1);
                if cData.isStructElement
                    [~, ~, hostElementSize] = cData.getStructArrayTopLevelInfo;
                    if hostElementSize.needsDTA
                        % access the API that will give us Bus size information
                        writer.writeLine('slDataTypeAccess * dta = ssGetDataTypeAccess(S);');
                    end
                end
                
                argPtr = sprintf('%s', argVarName);
                pWorkIdx = sfunObj.getCallerFunctionArgumentPWorkIdx(this, argDataInterface);
                sfunObj.getPWorkValue('void', argPtr , pWorkIdx, false);
                
                writer.wBlockEnd; % scope around each argument
            end
            writer.wBlockEnd; %if (ssGetPWork(S) != NULL)
        end    
    end
end