private void PoseStart()
        {
            state = CountState.Ready;
            selectionState = CountSelectionState.Idle;

            Log("Count: PoseStart");
        }
        private void LeaveWorkspace()
        {
            if (selectionState != CountSelectionState.Idle)
                CountStop();

            //GroupLeave(activeGroup);

            state = CountState.Idle;
            selectionState = CountSelectionState.Idle;
            //activeGroup = 0;
            discardedFrames = 0;
            activeHandId = -1;

            foreach (IParentObserver observer in observers)
            {
                observer.LeaveWorkspace(0);
                Log("Count: LeaveWorkspace");
            }
        }
        private void PoseEnd()
        {
            if (selectionState != CountSelectionState.Idle)
                CountStop();

            //GroupLeave(activeGroup);

            state = CountState.Tracking;
            selectionState = CountSelectionState.Idle;
            //activeGroup = 0;
            discardedFrames = 0;

            Log("Count: PoseEnd");
        }
        private void CountStop()
        {
            selectionState = CountSelectionState.Idle;
            countTotal = 0;
            countFrames = 0;
            discardedFrames = 0;

            foreach (IParentObserver observer in observers)
            {
                if (observer is ICountObserver)
                {
                    ICountObserver ic = (ICountObserver)observer;
                    ic.CountStop();
                }
            }
            // Reset selection progress
            CountProgress(0, null);

            Log("Count: CountStop");
        }
        private void EnterWorkspace(int handId, int fingers)
        {
            state = CountState.Tracking;
            selectionState = CountSelectionState.Idle;
            //activeGroup = 0;
            activeHandId = handId;

            foreach (IParentObserver observer in observers)
            {
                observer.EnterWorkspace(-1, fingers);
            }

            Log("Count: EnterWorkspace");
        }
        private void CountStart(ROI.ROI roi, int count)
        {
            state = CountState.Counting;
            selectionState = CountSelectionState.InProgress;

            countStart = DateTime.Now;
            countTotal = 0;
            countFrames = 0;

            for (int i = 0; i < observers.Count; i++ )
            {
                //if (observer.Equals(typeof(ICountObserver)))
                Log(String.Format("Observer{0}", observers[i]));
                if (observers[i] is ICountObserver)
                {
                    ICountObserver ic = (ICountObserver)observers[i];
                    ic.CountStart(null, roi, count, this, observers);
                }
            }

            Log(String.Format("Count: CountStart {0}", count));
        }
        private void CountSelect(ROI.ROI roi, DateTime time, int count)
        {
            selectionState = CountSelectionState.Complete;
            countSelectedAt = time;

            roi = FindROIWithinGroup(count);

            for (int i = 0; i < observers.Count; i++)
            {
                //if (observer.Equals(typeof(ICountObserver)))
                Log(String.Format("Observer{0}", observers[i]));
                if (observers[i] is ICountObserver)
                {
                    ICountObserver ic = (ICountObserver)observers[i];
                    ic.CountComplete(null, roi, time, count, this, observers);
                }
            }

            // Trigger a ROI set activation
            if (roi.ToActivate != null && roi.ToActivate.Length > 0)
            {
                ActivateROISet(roi.ToActivate);
                Log(String.Format("Activating ROI set: {0}", roi.ToActivate));
            }

            Log(String.Format("Count: CountSelect {0}", count));
        }
        // private int activeGroup;
        public CountDetector(LeapInterface leap, GestureSpace space)
        {
            // Initialise state machines
            state = CountState.Idle;
            selectionState = CountSelectionState.Idle;
            activeHandId = -1;
            discardedFrames = 0;
            ignoredFrames = 0;
            this.leap = leap;

               /* // Initialise groups and ROIs
            activeGroup = 0; */

            // Initialise list of observers
            observers = new List<IParentObserver>();

            // Initialise selection metadata
            countStart = DateTime.Now;

            // Register gesture workspace
            this.RegisterWorkspace(space);

            // Register this gesture detector for frame updates and keep reference of the LeapMotion controller
            this.leap.RegisterFrameListener(this);

            GestureDetector.DEBUG = false;
        }
        private void CountStart(ROI.ROI roi, int count)
        {
            state = CountState.Counting;
            selectionState = CountSelectionState.InProgress;

            countStart = DateTime.Now;
            countTotal = 0;
            countFrames = 0;

            foreach (ICountObserver observer in observers)
                observer.CountStart(null, roi, count);

            Log(String.Format("Count: CountStart {0}", count));
        }
        private void CountSelect(ROI.ROI roi, DateTime time, int count)
        {
            selectionState = CountSelectionState.Complete;
            countSelectedAt = time;

            roi = FindROIWithinGroup(count);

            foreach (ICountObserver observer in observers)
                observer.CountComplete(null, roi, time, count);

            // Trigger a ROI set activation
            if (roi.ToActivate != null && roi.ToActivate.Length > 0)
            {
                ActivateROISet(roi.ToActivate);
                Log(String.Format("Activating ROI set: {0}", roi.ToActivate));
            }

            Log(String.Format("Count: CountSelect {0}", count));
        }