#pragma once

#include "NDTSEnums.h"
#include "SIPropertyInternal.h"

// Shadow an IntPropertyInternal with an SI unit 
namespace NDTS
{
	namespace SCO
	{
	class IntPropertyInternal;
	class SIStoragePropertyInternal;
	class SCO_API SIShadowPropertyInternal:	public SIPropertyInternal
	{
	public:
		// Conversion values are always specified in the direction From int to SI unit
		enum Relationship
		{
			ProportionalRelationship,  // See below
			InverseRelationship   
		};

		SIShadowPropertyInternal(char *pShortName, char *pLongName, int flags, SI::BaseUnit baseUnit, SI::Prefix prefix, 
			IntPropertyInternal *pShadowedProperty,     // The Int property that is being shadowed by this setting
			SIPropertyInternal *pScaleProperty,			// The Property that is used to apply a scale, 
														// e.g. if shadowing number of A Scans per B Scan to get the scan width in mm, we multiply by the element pitch which is an SIStoragePropertyInternal.
														// This is set to null if there is a fixed scale, e.g. for the gain.
			Relationship relationshipType,				// Whether the shadowed Int property is inverted, e.g. clicks per sample is converted to clicks PER metre and so is metres ^-1
			double intToSamplesMultiplier = 1.0);		// An extra fixed value scale to apply if required, e.g. to convert from a gain of int value 0..255 to a dB value of 0..80.0, specify a value of 80 / 255
		
		virtual ~SIShadowPropertyInternal(void);
		virtual double getSIValue();
		virtual void setSIValue(double value);
		virtual double getSIMin();
		virtual double getSIMax();

		
		// Only for use by the parent group and postCommit hook
		bool getHaveUncommittedChange();
		double getUncommittedSIValue();

		// Functions for internal use - not by app.
		void setScaleProperty(SIStoragePropertyInternal *pScaleProperty, enum ShadowScaleType scaleType);

	private:
		IntPropertyInternal *pShadowedProperty;
		SIPropertyInternal *pScaleProperty;
		enum Relationship relationshipType;
		double scaleForGet(int value); // Scale the integer value to a value suitable to return from get
		int  scaleForSet(double value);
		double getScale();             // Calculate the scale value to convert From Int to Double

		double uncommittedValue;
		bool haveUncommittedChange;
		double intToSamplesMultiplier;
		bool isValueSignificantlyDifferentFromShadow(double value);

	};
}}
