/*++

Copyright (C) 2024 3MF Consortium (Original Author)

All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This file has been generated by the Automatic Component Toolkit (ACT) version 1.8.1-develop.

Abstract: This is an autogenerated Java file in order to allow an easy
 use of the 3MF Library

Interface version: 2.5.0

*/

package lib3mf;

import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;


import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

public class BeamLattice extends Base {

	public BeamLattice(Lib3MFWrapper wrapper, Pointer handle) {
		super(wrapper, handle);
	}

	/**
	 * Returns the minimal length of beams for the beamlattice.
	 *
	 * @return minimal length of beams for the beamlattice
	 * @throws Lib3MFException
	 */
	public double getMinLength() throws Lib3MFException {
		Pointer bufferMinLength = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getminlength.invokeInt(new java.lang.Object[]{mHandle, bufferMinLength}));
		return bufferMinLength.getDouble(0);
	}

	/**
	 * Sets the minimal length of beams for the beamlattice.
	 *
	 * @param minLength minimal length of beams for the beamlattice
	 * @throws Lib3MFException
	 */
	public void setMinLength(double minLength) throws Lib3MFException {
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_setminlength.invokeInt(new java.lang.Object[]{mHandle, minLength}));
	}

	/**
	 * Returns the clipping mode and the clipping-mesh for the beamlattice of this mesh.
	 *
	 * @return GetClipping Result Tuple
	 * @throws Lib3MFException
	 */
	public GetClippingResult getClipping() throws Lib3MFException {
		Pointer bufferClipMode = new Memory(4);
		Pointer bufferUniqueResourceID = new Memory(4);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getclipping.invokeInt(new java.lang.Object[]{mHandle, bufferClipMode, bufferUniqueResourceID}));
		GetClippingResult returnTuple = new GetClippingResult();
		returnTuple.ClipMode = Lib3MFWrapper.EnumConversion.convertConstToBeamLatticeClipMode(bufferClipMode.getInt(0));
		returnTuple.UniqueResourceID = bufferUniqueResourceID.getInt(0);
		return returnTuple;
	}

	public static class GetClippingResult {
		/**
		 * contains the clip mode of this mesh
		 */
		public Lib3MFWrapper.BeamLatticeClipMode ClipMode;

		/**
		 * filled with the UniqueResourceID of the clipping mesh-object or an undefined value if pClipMode is MODELBEAMLATTICECLIPMODE_NONE
		 */
		public int UniqueResourceID;

	}
	/**
	 * Sets the clipping mode and the clipping-mesh for the beamlattice of this mesh.
	 *
	 * @param clipMode contains the clip mode of this mesh
	 * @param uniqueResourceID the UniqueResourceID of the clipping mesh-object. This mesh-object has to be defined before setting the Clipping.
	 * @throws Lib3MFException
	 */
	public void setClipping(Lib3MFWrapper.BeamLatticeClipMode clipMode, int uniqueResourceID) throws Lib3MFException {
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_setclipping.invokeInt(new java.lang.Object[]{mHandle, Lib3MFWrapper.EnumConversion.convertBeamLatticeClipModeToConst(clipMode), uniqueResourceID}));
	}

	/**
	 * Returns the representation-mesh for the beamlattice of this mesh.
	 *
	 * @return GetRepresentation Result Tuple
	 * @throws Lib3MFException
	 */
	public GetRepresentationResult getRepresentation() throws Lib3MFException {
		Pointer bufferHasRepresentation = new Memory(1);
		Pointer bufferUniqueResourceID = new Memory(4);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getrepresentation.invokeInt(new java.lang.Object[]{mHandle, bufferHasRepresentation, bufferUniqueResourceID}));
		GetRepresentationResult returnTuple = new GetRepresentationResult();
		returnTuple.HasRepresentation = bufferHasRepresentation.getByte(0) != 0;
		returnTuple.UniqueResourceID = bufferUniqueResourceID.getInt(0);
		return returnTuple;
	}

	public static class GetRepresentationResult {
		/**
		 * flag whether the beamlattice has a representation mesh.
		 */
		public boolean HasRepresentation;

		/**
		 * filled with the UniqueResourceID of the clipping mesh-object.
		 */
		public int UniqueResourceID;

	}
	/**
	 * Sets the representation-mesh for the beamlattice of this mesh.
	 *
	 * @param uniqueResourceID the UniqueResourceID of the representation mesh-object. This mesh-object has to be defined before setting the representation.
	 * @throws Lib3MFException
	 */
	public void setRepresentation(int uniqueResourceID) throws Lib3MFException {
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_setrepresentation.invokeInt(new java.lang.Object[]{mHandle, uniqueResourceID}));
	}

	/**
	 * Returns the ball mode and the default ball radius for the beamlattice of this mesh.
	 *
	 * @return GetBallOptions Result Tuple
	 * @throws Lib3MFException
	 */
	public GetBallOptionsResult getBallOptions() throws Lib3MFException {
		Pointer bufferBallMode = new Memory(4);
		Pointer bufferBallRadius = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getballoptions.invokeInt(new java.lang.Object[]{mHandle, bufferBallMode, bufferBallRadius}));
		GetBallOptionsResult returnTuple = new GetBallOptionsResult();
		returnTuple.BallMode = Lib3MFWrapper.EnumConversion.convertConstToBeamLatticeBallMode(bufferBallMode.getInt(0));
		returnTuple.BallRadius = bufferBallRadius.getDouble(0);
		return returnTuple;
	}

	public static class GetBallOptionsResult {
		/**
		 * contains the ball mode of this mesh
		 */
		public Lib3MFWrapper.BeamLatticeBallMode BallMode;

		/**
		 * default ball radius of balls for the beamlattice
		 */
		public double BallRadius;

	}
	/**
	 * Sets the ball mode and thedefault ball radius for the beamlattice.
	 *
	 * @param ballMode contains the ball mode of this mesh
	 * @param ballRadius default ball radius of balls for the beamlattice
	 * @throws Lib3MFException
	 */
	public void setBallOptions(Lib3MFWrapper.BeamLatticeBallMode ballMode, double ballRadius) throws Lib3MFException {
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_setballoptions.invokeInt(new java.lang.Object[]{mHandle, Lib3MFWrapper.EnumConversion.convertBeamLatticeBallModeToConst(ballMode), ballRadius}));
	}

	/**
	 * Returns the beam count of a mesh object.
	 *
	 * @return filled with the beam count.
	 * @throws Lib3MFException
	 */
	public int getBeamCount() throws Lib3MFException {
		Pointer bufferCount = new Memory(4);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getbeamcount.invokeInt(new java.lang.Object[]{mHandle, bufferCount}));
		return bufferCount.getInt(0);
	}

	/**
	 * Returns indices, radii and capmodes of a single beam of a mesh object.
	 *
	 * @param index Index of the beam (0 to beamcount - 1).
	 * @return filled with the beam indices, radii and capmodes.
	 * @throws Lib3MFException
	 */
	public Beam getBeam(int index) throws Lib3MFException {
		Pointer bufferBeamInfo = new Memory(Beam.SIZE);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getbeam.invokeInt(new java.lang.Object[]{mHandle, index, bufferBeamInfo}));
		Beam beamInfo = new Beam();
		beamInfo.readFromPointer(bufferBeamInfo, 0);
		return beamInfo;
	}

	/**
	 * Adds a single beam to a mesh object.
	 *
	 * @param beamInfo contains the node indices, radii and capmodes.
	 * @return filled with the new Index of the beam.
	 * @throws Lib3MFException
	 */
	public int addBeam(Beam beamInfo) throws Lib3MFException {
		Pointer bufferBeamInfo = new Memory(Beam.SIZE);
		beamInfo.writeToPointer(bufferBeamInfo, 0);
		Pointer bufferIndex = new Memory(4);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_addbeam.invokeInt(new java.lang.Object[]{mHandle, bufferBeamInfo, bufferIndex}));
		return bufferIndex.getInt(0);
	}

	/**
	 * Sets the indices, radii and capmodes of a single beam of a mesh object.
	 *
	 * @param index Index of the beam (0 to beamcount - 1).
	 * @param beamInfo filled with the beam indices, radii and capmodes.
	 * @throws Lib3MFException
	 */
	public void setBeam(int index, Beam beamInfo) throws Lib3MFException {
		Pointer bufferBeamInfo = new Memory(Beam.SIZE);
		beamInfo.writeToPointer(bufferBeamInfo, 0);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_setbeam.invokeInt(new java.lang.Object[]{mHandle, index, bufferBeamInfo}));
	}

	/**
	 * Sets all beam indices, radii and capmodes of a mesh object.
	 *
	 * @param beamInfo contains information of a number of  beams
	 * @throws Lib3MFException
	 */
	public void setBeams(Beam[] beamInfo) throws Lib3MFException {
		Pointer bufferBeamInfo = new Memory(Math.max(1, Beam.SIZE * beamInfo.length));
		for (int i = 0; i < beamInfo.length; i++) {
		  beamInfo[i].writeToPointer(bufferBeamInfo, i * Beam.SIZE);
		}
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_setbeams.invokeInt(new java.lang.Object[]{mHandle, (long) beamInfo.length, bufferBeamInfo}));
	}

	/**
	 * obtains all beam indices, radii and capmodes of a mesh object.
	 *
	 * @return contains information of all beams
	 * @throws Lib3MFException
	 */
	public Beam[] getBeams() throws Lib3MFException {
		Pointer countNeededBeamInfo = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getbeams.invokeInt(new java.lang.Object[]{mHandle, 0L, countNeededBeamInfo, null}));
		long countBeamInfo = countNeededBeamInfo.getLong(0);
		Pointer bufferBeamInfo = new Memory(Math.max(1, countBeamInfo * Beam.SIZE));
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getbeams.invokeInt(new java.lang.Object[]{mHandle, countBeamInfo, countNeededBeamInfo, bufferBeamInfo}));
		Beam beamInfo[] = new Beam[(int)countBeamInfo];
		for (int i = 0; i < (int)countBeamInfo; i++) {
		  beamInfo[i] = new Beam();
		  beamInfo[i].readFromPointer(bufferBeamInfo, i * Beam.SIZE);
		}
		return beamInfo;
	}

	/**
	 * Returns the ball count of a mesh object.
	 *
	 * @return filled with the ball count.
	 * @throws Lib3MFException
	 */
	public int getBallCount() throws Lib3MFException {
		Pointer bufferCount = new Memory(4);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getballcount.invokeInt(new java.lang.Object[]{mHandle, bufferCount}));
		return bufferCount.getInt(0);
	}

	/**
	 * Returns index and radius of a single ball of a mesh object.
	 *
	 * @param index Index of the ball (0 to ballcount - 1).
	 * @return filled with the ball node index and radius.
	 * @throws Lib3MFException
	 */
	public Ball getBall(int index) throws Lib3MFException {
		Pointer bufferBallInfo = new Memory(Ball.SIZE);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getball.invokeInt(new java.lang.Object[]{mHandle, index, bufferBallInfo}));
		Ball ballInfo = new Ball();
		ballInfo.readFromPointer(bufferBallInfo, 0);
		return ballInfo;
	}

	/**
	 * Adds a single ball to a mesh object.
	 *
	 * @param ballInfo contains the node index and radius.
	 * @return filled with the new Index of the ball.
	 * @throws Lib3MFException
	 */
	public int addBall(Ball ballInfo) throws Lib3MFException {
		Pointer bufferBallInfo = new Memory(Ball.SIZE);
		ballInfo.writeToPointer(bufferBallInfo, 0);
		Pointer bufferIndex = new Memory(4);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_addball.invokeInt(new java.lang.Object[]{mHandle, bufferBallInfo, bufferIndex}));
		return bufferIndex.getInt(0);
	}

	/**
	 * Sets the index and radius of a single ball of a mesh object.
	 *
	 * @param index Index of the ball (0 to ballcount - 1).
	 * @param ballInfo filled with the ball node index and radius.
	 * @throws Lib3MFException
	 */
	public void setBall(int index, Ball ballInfo) throws Lib3MFException {
		Pointer bufferBallInfo = new Memory(Ball.SIZE);
		ballInfo.writeToPointer(bufferBallInfo, 0);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_setball.invokeInt(new java.lang.Object[]{mHandle, index, bufferBallInfo}));
	}

	/**
	 * Sets all ball indices and radii of a mesh object.
	 *
	 * @param ballInfo contains information of a number of  balls
	 * @throws Lib3MFException
	 */
	public void setBalls(Ball[] ballInfo) throws Lib3MFException {
		Pointer bufferBallInfo = new Memory(Math.max(1, Ball.SIZE * ballInfo.length));
		for (int i = 0; i < ballInfo.length; i++) {
		  ballInfo[i].writeToPointer(bufferBallInfo, i * Ball.SIZE);
		}
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_setballs.invokeInt(new java.lang.Object[]{mHandle, (long) ballInfo.length, bufferBallInfo}));
	}

	/**
	 * obtains all ball indices and radii of a mesh object.
	 *
	 * @return contains information of all balls
	 * @throws Lib3MFException
	 */
	public Ball[] getBalls() throws Lib3MFException {
		Pointer countNeededBallInfo = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getballs.invokeInt(new java.lang.Object[]{mHandle, 0L, countNeededBallInfo, null}));
		long countBallInfo = countNeededBallInfo.getLong(0);
		Pointer bufferBallInfo = new Memory(Math.max(1, countBallInfo * Ball.SIZE));
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getballs.invokeInt(new java.lang.Object[]{mHandle, countBallInfo, countNeededBallInfo, bufferBallInfo}));
		Ball ballInfo[] = new Ball[(int)countBallInfo];
		for (int i = 0; i < (int)countBallInfo; i++) {
		  ballInfo[i] = new Ball();
		  ballInfo[i].readFromPointer(bufferBallInfo, i * Ball.SIZE);
		}
		return ballInfo;
	}

	/**
	 * Returns the number of beamsets of a mesh object.
	 *
	 * @return filled with the beamset count.
	 * @throws Lib3MFException
	 */
	public int getBeamSetCount() throws Lib3MFException {
		Pointer bufferCount = new Memory(4);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getbeamsetcount.invokeInt(new java.lang.Object[]{mHandle, bufferCount}));
		return bufferCount.getInt(0);
	}

	/**
	 * Adds an empty beamset to a mesh object
	 *
	 * @return the new beamset
	 * @throws Lib3MFException
	 */
	public BeamSet addBeamSet() throws Lib3MFException {
		Pointer bufferBeamSet = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_addbeamset.invokeInt(new java.lang.Object[]{mHandle, bufferBeamSet}));
		Pointer valueBeamSet = bufferBeamSet.getPointer(0);
		BeamSet beamSet = null;
		if (valueBeamSet == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "BeamSet was a null pointer");
		}
		beamSet = mWrapper.PolymorphicFactory(valueBeamSet, BeamSet.class);
		return beamSet;
	}

	/**
	 * Returns a beamset of a mesh object
	 *
	 * @param index index of the requested beamset (0 ... beamsetcount-1).
	 * @return the requested beamset
	 * @throws Lib3MFException
	 */
	public BeamSet getBeamSet(int index) throws Lib3MFException {
		Pointer bufferBeamSet = new Memory(8);
		mWrapper.checkError(this, mWrapper.lib3mf_beamlattice_getbeamset.invokeInt(new java.lang.Object[]{mHandle, index, bufferBeamSet}));
		Pointer valueBeamSet = bufferBeamSet.getPointer(0);
		BeamSet beamSet = null;
		if (valueBeamSet == Pointer.NULL) {
		  throw new Lib3MFException(Lib3MFException.LIB3MF_ERROR_INVALIDPARAM, "BeamSet was a null pointer");
		}
		beamSet = mWrapper.PolymorphicFactory(valueBeamSet, BeamSet.class);
		return beamSet;
	}


}

