/*
 * Copyright (C) 2012-2026 MotionSystems
 * 
 * This file is part of ForceSeatMI SDK.
 *
 * www.motionsystems.eu
 *
 */

using System;
using System.Runtime.InteropServices;

namespace MotionSystems
{
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public struct FSMI_SFX_Effect
	{
		/// <summary>
		/// Effect type. It is one of FSMI_SFX_EffectType.
		/// </summary>
		public byte type;

		/// <summary>
		/// Area where the effect should be generated. It is combination of FSMI_SFX_AreaFlags.
		/// </summary>
		public ushort area;

		/// <summary>
		/// Frequency (Hz) of the effect, from 0 to 255. Not all effects support all frequencies.
		/// - SinusL2: 0 to 100
		/// - SinusL3: 0 to 100
		/// </summary>
		public byte frequency;

		/// <summary>
		/// Amplitude of the effect, from -1 to 1. Not all effects support full amplitudes.
		/// - SinusL2: -0.12 to 0.12
		/// - SinusL3: -0.12 to 0.12
		/// </summary>
		public float amplitude;

		/// <summary>
		/// For future use
		/// </summary>
		public byte reserved1;

		/// <summary>
		/// For future use
		/// </summary>
		public byte reserved2;

		/// <summary>
		/// For future use
		/// </summary>
		public byte reserved3;

		/// <summary>
		/// For future use
		/// </summary>
		public byte reserved4;

		/// <summary>
		/// For future use
		/// </summary>
		public byte reserved5;

		/// <summary>
		/// For future use
		/// </summary>
		public byte reserved6;

		/// <summary>
		/// For future use
		/// </summary>
		public byte reserved7;

		/// <summary>
		/// For future use
		/// </summary>
		public byte reserved8;
	}

	/// <summary>
	/// This structure defines special effects that are generated by the hardware and are independent to
	/// the primary telemetry or positioning data stream. Not all devices support this feature.
	/// </summary>
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public struct FSMI_SFX
	{
		/// <summary>
		/// Put here sizeof(FSMI_SFX).
		/// NOTE: This field is mandatory.
		/// </summary>
		public byte structSize;

		/// <summary>
		/// Number of the effects specified in the below filed. From 0 to FSMI_SFX_MaxEffectsCount.
		/// </summary>
		public byte effectsCount;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)FSMI_Defines.SFX_MaxEffectsCount)]
		public FSMI_SFX_Effect[] effects;

		/// <summary>
		/// Helper method to create a structure with preallocated space for nested structures
		/// </summary>
		public static FSMI_SFX Prepare()
		{
			var sfx        = new FSMI_SFX();
			sfx.structSize = (byte)Marshal.SizeOf(sfx);
			sfx.effects    = new FSMI_SFX_Effect[(int)FSMI_Defines.SFX_MaxEffectsCount];
			return sfx;
		}
	}

	public enum FSMI_SFX_EffectType
	{
		/// <summary>
		/// Effect is appended to the required position before trajectory generator uses the position.
		/// It means that this effect affects state of the adaptive algorithms which are used to adjust motion platform
		/// operation parameters to the signal dynamics. This effect might be also less pronounced if trajectory generator
		/// is configured to use long acceleration ramps.
		/// It is supported only by "PS" and "QS" motion platforms.
		/// </summary>
		SinusLevel2 = 0,

		/// <summary>
		/// Effect is appended to the output (position) of the trajectory generator. It is NOT affected by the
		/// trajectory generator configuration and it does NOT affect the adaptive algorithms. Result of this effect
		/// might be different depending on the actuator hardware configuration (length/pitch).
		/// It is supported only by "QS" motion platforms.
		/// </summary>
		SinusLevel3 = 1
	};

	public struct FSMI_SFX_AreaFlags
	{
		/// <summary>
		/// Effect is generated on the actuator(s) assigned to the front-left area of the cockpit.
		/// </summary>
		public const int FrontLeft = 1 << 0;

		/// <summary>
		/// Effect is generated on the actuator(s) assigned to the front-right area of the cockpit.
		/// </summary>
		public const int FrontRight = 1 << 1;

		/// <summary>
		/// Effect is generated on the actuator(s) assigned to the rear-left area of the cockpit.
		/// </summary>
		public const int RearLeft = 1 << 2;

		/// <summary>
		/// Effect is generated on the actuator(s) assigned to the rear-right area of the cockpit.
		/// </summary>
		public const int RearRight = 1 << 3;

		/// <summary>
		/// Effect is generated on auxiliary actuator, e.g. seat belt tensioner.
		/// </summary>
		public const int Aux1 = 1 << 4;

		/// <summary>
		/// Effect is generated on auxiliary actuator, e.g. seat belt tensioner.
		/// </summary>
		public const int Aux2 = 1 << 5;
	};
}
