#pragma once
#include "Property.h"
#include "IntProperty.h"
#include "EnumProperty.h"
#include "SIProperty.h"
#include "EventProperty.h"

using namespace System;
using namespace System::Runtime::InteropServices;

namespace NDTS
{
namespace Managed
{
namespace SCO
{
	public ref class GroupProperty : Property
	{
	public:
		GroupProperty();
		~GroupProperty();

		int getNumberOfProperties();
		Property ^getPropertyByNumber(int index);
		Property ^getPropertyByName(String ^s);

		// -------------------------------Gang added on 28 Aug, 2008 -------------------------
		int getFlatNumberOfIntProperties();
		IntProperty ^getFlatIntPropertyByNumber(int index);
        
		int getFlatNumberOfEnumProperties();
		EnumProperty ^getFlatEnumPropertyByNumber(int index);
        
		int getFlatNumberOfSIProperties();
		SIProperty ^getFlatSIPropertyByNumber(int index);

		int getFlatNumberOfEventProperties();
		EventProperty ^getFlatEventPropertyByNumber(int index);	
		// -------------------------------Gang added on 28 Aug, 2008 -------------------------
        
		// beginGroupChange() and commitGroupChange() are used when setting several properties at once
		// e.g. when reading from a file.  No range checking or writing to the SDK is done until 
		// commitGroupChange() is called.  This prevents errors caused by for example an existing
		// A Scan range of 10 samples and rep rate of 100 samples and a new A Scan range of 1000 samples and rep
		// rate of 2000 samples.  Without begin / end group, setting the A Scan range to 1000 would fail because
		// the range is greater than the rep rate
		void beginGroupChange();
		void commitGroupChange();

		bool getIsArray();

		// The property change list contains a list of properties whose values, min, max or flags have changed.
		// Each group maintains its own property change list.  
		// There is at most one entry in the change list for each property.  This entry may have several flags masked together,
		// e.g. if the value and the max of the property has changed.
		// The list is reset by calling clearChangeItemLog().
		// The list then grows as properties are set with setValue() calls.
		// If a setValue() call sets the value to the value requested, a change for the value is not added to the list.
		// A change is added to the list if the value is clamped or the set fails completely, in which case a change is added
		// to indicate that the value is still the previous value.  A change is also added to the list if the min or max of 
		// a property is updated.  For example setting range to 100 may produce a change in the min of the rep rate.
		//virtual PropertyChangeItem *getChangeItemByIndex(int index)=0;
		//virtual void clearChangeItemLog()=0;
		//virtual int getNumberOfChangeListEntries()=0;

	private:
		Property ^getPropertyAsChildObject(NDTS::SCO::Property *pCurrentProp);

	};
}}}
