classdef urdfExporter < handle
%

%   Copyright 2023 The MathWorks, Inc.

    properties(Dependent)
        OutputFileName
        RobotName
        VisualMeshFileLocation
        CollisionMeshFileLocation
        ExportMesh
        AbsoluteTolerance
    end

    properties (Access = private)
        %RobotDataWriterImpl Implementation of the robot data writer
        RobotDataWriterImpl
    end

    methods
        function filename = get.OutputFileName(obj)
            filename = obj.RobotDataWriterImpl.OutputFileName;
        end

        function robotname = get.RobotName(obj)
            robotname = obj.RobotDataWriterImpl.RobotName;
        end

        function visualMeshlocation = get.VisualMeshFileLocation(obj)
            visualMeshlocation = obj.RobotDataWriterImpl.VisualMeshFileLocation;
        end

        function collisionMeshlocation = get.CollisionMeshFileLocation(obj)
            collisionMeshlocation = obj.RobotDataWriterImpl.CollisionMeshFileLocation;
        end

        function isExport = get.ExportMesh(obj)
            isExport = obj.RobotDataWriterImpl.ExportMesh;
        end

        function absTol = get.AbsoluteTolerance(obj)
            absTol = obj.RobotDataWriterImpl.AbsoluteTolerance;
        end

        function set.OutputFileName(obj, filename)
            validateattributes(convertStringsToChars(filename), ["char", "string"], ["scalartext","nonempty"], ...
                               "urdfExporter","OutputFileName");
            [~, ~, fileExt] = fileparts(filename);
            if ~strcmp(fileExt, obj.RobotDataWriterImpl.SupportedOutputURDFFileExt)
                error(message('robotics:robotmanip:urdfexporter:UnsupportedFileExtension'));
            end
            obj.RobotDataWriterImpl.OutputFileName = filename;
        end

        function set.RobotName(obj, robotname)
            validateattributes(convertStringsToChars(robotname), ["char", "string"], ["scalartext","nonempty"], ...
                               "urdfExporter","RobotName");
            obj.RobotDataWriterImpl.RobotName = robotname;
        end

        function set.VisualMeshFileLocation(obj, visualMeshLocation)
            validateattributes(convertStringsToChars(visualMeshLocation),["char", "string"], "scalartext", ...
                               "urdfExporter","VisualMeshFileLocation");
            obj.RobotDataWriterImpl.VisualMeshFileLocation = visualMeshLocation;
        end

        function set.CollisionMeshFileLocation(obj, collisionMeshLocation)
            validateattributes(convertStringsToChars(collisionMeshLocation),["char", "string"], "scalartext", ...
                               "urdfExporter","CollisionMeshFileLocation");
            obj.RobotDataWriterImpl.CollisionMeshFileLocation = collisionMeshLocation;
        end

        function set.ExportMesh(obj, exportmesh)
            validateattributes(exportmesh, ["logical", "numeric"], ["scalar", "binary"], ...
                               "urdfExporter","ExportMesh");
            obj.RobotDataWriterImpl.ExportMesh = exportmesh;
        end

        function set.AbsoluteTolerance(obj, abstol)
            validateattributes(abstol, "numeric", ["nonempty", "finite", "nonnan", "real", "positive", "scalar"], ...
                               "urdfExporter","AbsoluteTolerance");
            obj.RobotDataWriterImpl.AbsoluteTolerance = abstol;
        end
    end

    methods
        function obj = urdfExporter(robot)
            validateattributes(robot,"rigidBodyTree",{"scalar", "nonempty"},"urdfExporter", "robot");
            robotics.manip.internal.errorIfUnsupportedForFloatingJoint(robot,'urdfExporter');

            % Create default file name based on input variable name
            outputFileName = robotics.manip.internal.exportRobot.utils.getOutputFileName(inputname(1));

            obj.RobotDataWriterImpl = robotics.manip.internal.exportRobot.RobotDataWriter(robot, outputFileName);
        end

        function writefile(obj, varargin)
            p = inputParser;
            addParameter(p, "OutputFileName", [], @(x) validateattributes(convertStringsToChars(x),["char", "string"], ["scalartext","nonempty"], "writefile", "OutputFileName"));
            addParameter(p, "RobotName", [], @(x) validateattributes(convertStringsToChars(x),["char", "string"], ["scalartext","nonempty"], "writefile", "RobotName"));
            addParameter(p, "ExportMesh", [], @(x) validateattributes(x, ["logical", "numeric"], ["scalar", "binary"], "writefile", "ExportMesh"));
            addParameter(p, "AbsoluteTolerance", [], @(x) validateattributes(x, "numeric", ["nonempty", "finite", "nonnan", "real", "positive", "scalar"], "writefile", "AbsoluteTolerance"));
            parse(p, varargin{:});

            obj.RobotDataWriterImpl.writeAsFile(varargin{:});
        end

        function xmlNode = writenode(obj, varargin)
            p = inputParser;
            addParameter(p, "RobotName", [], @(x) validateattributes(convertStringsToChars(x),["char", "string"], ["scalartext","nonempty"], "writenode", "RobotName"));
            addParameter(p, "AbsoluteTolerance", [], @(x) validateattributes(x, "numeric", ["nonempty", "finite", "nonnan", "real", "positive", "scalar"], "writenode", "AbsoluteTolerance"));
            parse(p, varargin{:});

            xmlNode = obj.RobotDataWriterImpl.writeAsDOMNode(varargin{:});
        end
    end
end
