classdef coverageBuildable < coder.ExternalDependency
    %This class is for internal use only. It may be removed in the future.

    %COVERAGEBUILDABLE Class implementing the UAV Dubins methods that are
    %   compatible with code generation

    % Copyright 2022-2023 The MathWorks, Inc.

    %#codegen

    properties
        %coverageBuildableObj
        coverageBuildableObj;
    end

    methods (Static)

        function name = getDescriptiveName(~)
            %getDescriptiveName Return descriptive name for external dependency
            name = 'coverageBuildable';
        end

        function tf = isSupportedContext(~)
            %isSupportedContext Determine if build context supports external dependency

            % We support both host and portable code generation
            tf = true;
        end

        function updateBuildInfo(buildInfo, buildConfig)
            %updateBuildInfo Update build information (for host codegen only)

            %We write code in builtins folder but while building the
            %component we publish all headers in
            %libsrc/<module>codegen/export to extern folder. Thus we can
            %include paths from that location in codegen.
            buildInfo.addIncludePaths(fullfile(matlabroot, 'extern', 'include', 'uav','coverage','coveragecodegen'));

            % Add defines to OPTS group, so rapid accelerator recognizes these
            % defines. See g1762922 and g1974701 for more information.
            buildInfo.addDefines('_USE_MATH_DEFINES', 'OPTS');
            %https://stackoverflow.com/questions/51858657/adding-c-headers-is-breaking-visual-studio-project-compilation
            %%buildInfo.addDefines('_XKEYCHECK_H','OPTS');

            if ~buildConfig.isCodeGenTarget('mex')
                buildInfo.addDefines('IS_NOT_MATLAB_HOST', 'OPTS'); % use non-TBB code if this is not a MEX on host platform
            end

            % Assign build info
            % Use full sources

            % Include sources for coverage codegen implementation.
            coverageCodegenDir = fullfile(matlabroot,'toolbox', ...
                'uav','uavbuiltins','libsrc','coveragecodegen', 'coverage');
            buildInfo.addSourceFiles('coveragePathUtils.cpp', coverageCodegenDir);
            buildInfo.addSourceFiles('exhaustivePlanner.cpp', coverageCodegenDir);
            buildInfo.addSourceFiles('exhaustivePlanner.cpp', coverageCodegenDir);
            buildInfo.addSourceFiles('minTraversalPlanner.cpp', coverageCodegenDir);
            buildInfo.addSourceFiles('CoveragePathOptimization_API.cpp', coverageCodegenDir);
        end

    end

    methods

        function obj = coverageBuildable()
            %uavDubinsBuildable Constructor

            coder.inline('never');
        end

        function [Sequence,SweepSequence,TransitionCost] = planExhaustivePath(~,VisitOrderSpecified,SpecifiedSequence,MinAdjacencyCount,NumPolygons,AdjacencyInfo,startPoses,endPoses,Takeoff,Landing)
            %planExhaustivePath call C-API
            SpecifiedSequence_SizeT = coder.internal.sizeT(SpecifiedSequence);
            % Initialize the output variables
            Sequence_SizeT=coder.internal.sizeT(zeros(1,NumPolygons));
            SweepSequence_SizeT=coder.internal.sizeT(zeros(1,NumPolygons));
            TransitionCost=0;
            %Initialize input variables
            AdjacencyInfo_SizeT=coder.internal.sizeT(AdjacencyInfo);
            %Parameters for size_t
            NumAdjacency_SizeT=coder.internal.sizeT(numel(AdjacencyInfo));
            NumPoses_SizeT=coder.internal.sizeT(length(startPoses));
            NumPolygons_SizeT=coder.internal.sizeT(NumPolygons);
            %Include headers.
            coder.cinclude('CoveragePathOptimization_API.hpp');
            % Call the C API
            coder.ceval('planExhaustivePathAPI',...
                coder.ref(Sequence_SizeT),coder.ref(SweepSequence_SizeT),coder.ref(TransitionCost),...
                VisitOrderSpecified,SpecifiedSequence_SizeT,MinAdjacencyCount,AdjacencyInfo_SizeT,startPoses, ...
                endPoses,Takeoff,Landing,NumPolygons_SizeT,NumPoses_SizeT,NumAdjacency_SizeT);
            %Convert to MATLAB friendly format prior to returning from
            %function.
            Sequence=int32(Sequence_SizeT);
            SweepSequence=int32(SweepSequence_SizeT);
        end

        function [Sequence,SweepSequence,TransitionCost] = planMinTraversalPath(~,VisitOrderSpecified,SpecifiedSequence,StartingPolygonIndex,NumPolygons,AdjacencyInfo,startPoses,endPoses,Takeoff,Landing)
            %planMinTraversalPath call C-API.
            coder.inline('always');
            SpecifiedSequence_SizeT = coder.internal.sizeT(SpecifiedSequence);
            % Initialize the output variables
            Sequence_SizeT=coder.internal.sizeT(zeros(1,NumPolygons));
            SweepSequence_SizeT=coder.internal.sizeT(zeros(1,NumPolygons));
            TransitionCost=0;
            %Initialize input variables
            startIndex_SizeT=coder.internal.sizeT(StartingPolygonIndex);
            AdjacencyInfo_SizeT=coder.internal.sizeT(AdjacencyInfo);
            %Parameters for size_t
            NumAdjacency_SizeT=coder.internal.sizeT(numel(AdjacencyInfo));
            NumPoses_SizeT=coder.internal.sizeT(length(startPoses));
            NumPolygons_SizeT=coder.internal.sizeT(NumPolygons);
            %Include headers.
            coder.cinclude('CoveragePathOptimization_API.hpp');
            % Call the C API
            coder.ceval('planMinTraversalPathAPI',...
                coder.ref(Sequence_SizeT),coder.ref(SweepSequence_SizeT),coder.ref(TransitionCost),...
                VisitOrderSpecified,SpecifiedSequence_SizeT,startIndex_SizeT, ...
                AdjacencyInfo_SizeT,startPoses, ...
                endPoses,Takeoff,Landing,NumPolygons_SizeT,NumPoses_SizeT,NumAdjacency_SizeT);
            %Convert to MATLAB friendly format prior to returning from
            %function.
            Sequence=int32(Sequence_SizeT);
            SweepSequence=int32(SweepSequence_SizeT);
        end
    end
end
