#pragma once
#include "GroupPropertyInternal.h"
#include "NDTS2100Sdk.h"


namespace NDTS
{
	namespace SCO
	{
		class IntPropertyInternal;
		class EnumPropertyInternal;
		class EventPropertyInternal;
		class SIShadowPropertyInternal;
	}

using namespace SCO;
namespace NDTS2100
{
	static const int defaultRangeForNewStep = 1000;
	static const int defaultRepRateForNewStep = 200000; // 1Khz

	class TCGInternal;
	class NDTS2100_API ChangeHook : public GroupHooks
	{
	public:
		ChangeHook(void);
		virtual ~ChangeHook(void);

		// Called during an IntPropertyInternal setValue before the value is sent to the SDK 
		// return false if it is not currently OK to set the property, e.g. if scanning
		virtual bool isOkToSet(PropertyInternal *pProperty);
		// Called once the property has been set in the SDK.  E.g. if the rep rate has been changed,
		// update the max of the range.
		// Returns true if there have been no errors or property changes
		virtual void postSetUpdate(IntPropertyInternal *pProp);
		virtual void postEventUpdate(EventPropertyInternal *pProp);
		// Called after the app has called commitGroup() but before any properties changed in the commit have been applied
		// used to set certain values so that the commit won't fail, e.g. set the A Scan range to a small value.
		virtual void preCommit();

		void setTcg(TCGInternal *pTcg);


	private:

		// Functions called during the post set hook
		void updateRangeDelayRepMax(int card, int step);
		void configureTriggering(int card);
		void setNotCurrentlyValid(Property *pProp, bool isNotCurrentlyValid);
		void updateNumberOfSteps(int card);
		void setIsFullAScanCapture(unsigned long card);
		void configureGate(unsigned long card, unsigned long step, unsigned long gate);
		void updateSampleParameters(unsigned long card);

		// The properties that we need to know about which are set in SDKPropertiesCollection
		friend class SDKPropertiesCollection;

		TCGInternal *pTcg;

		IntPropertyInternal *pNumberOfCardsProp;
		IntPropertyInternal *pIsScanningProp;
		IntPropertyInternal *pAreCardsSynchronisedProp;

		// MultiCard - made snapshot one property for all cards.  This will be better when multiple cards are running in sync 
		// as all the cards will have B Scans corresponding to the same time period.  This will be particularly useful
		// if an encoder is only connected to the master card.
		// However, it may be more efficient to let the cards and snaphots run asynchronously.
		// I think it would be best to either have takeSnapshot global or per card in all circumstances, rather than having 
		// it global when cards are synchronised and per card when the cards are running asynchronously.
		// The SDK was originally written with a snapshot per card, so doing a search for pTakeSnapshotProp and uncommenting the old lines
		// will soon have it back to a property per card.
		//EventPropertyInternal  *pTakeSnapshotProp[maxCards];
		EventPropertyInternal  *pTakeSnapshotProp;

		IntPropertyInternal *pNumberOfStepsProp[maxCards] ;
		IntPropertyInternal *pScanTriggerModeProp[maxCards];
		IntPropertyInternal *pBScanRepRateSamplesProp[maxCards];
		SIShadowPropertyInternal  *pBScanRepRateSIProp[maxCards];
		IntPropertyInternal  *pEncoderToTriggerOffProp[maxCards];
		IntPropertyInternal  *p9230SerialAddressReg[maxCards];
		IntPropertyInternal  *p9230SerialDataReg[maxCards];
		EnumPropertyInternal *pIsFullAScanCapture[maxCards];
		
		IntPropertyInternal  *pSamplesDividerProp[maxCards][maxSteps];
        
		IntPropertyInternal *pAScanRangeProp[maxCards][maxSteps];
		IntPropertyInternal *pAScanRepRateProp[maxCards][maxSteps];
		IntPropertyInternal  *pAScanDelayProp[maxCards][maxSteps];
		
		EnumPropertyInternal *pInterfaceTriggeredTCG[maxCards][maxSteps];
		EnumPropertyInternal *pSimpleGainOrTCG[maxCards][maxSteps];
		IntPropertyInternal *pSimpleGain[maxCards][maxSteps];

    	EnumPropertyInternal *pGateEnableProp[maxCards][maxSteps][maxGates];
    	EnumPropertyInternal *pGateDistanceMetricProp[maxCards][maxSteps][maxGates];
    	EnumPropertyInternal *pGateStoreOnlyWhenTriggeredProp[maxCards][maxSteps][maxGates];
    	EnumPropertyInternal *pGateTriggerGateProp[maxCards][maxSteps][maxGates];
	};
}}