public void Update(Point leftEyeLocation, Point rightEyeLocation, int xDistBetweenEyes,
                           FastBitmap img, bool performClicks)
        {
            UpdateData temp = new UpdateData(leftEyeLocation, rightEyeLocation, xDistBetweenEyes, img, performClicks);

            lock ( updateDataMutex )
            {
                if (updateData != null)
                {
                    updateData.Dispose();
                }
                updateData = temp;
                waitHandler.Set();
            }
        }
        public void Update()
        {
            lock ( workerUpdateDataMutex )
            {
                if (workerUpdateData == null)
                {
                    return;
                }


                if (firstUpdate)
                {
                    firstUpdate  = false;
                    CurrentStage = Stages.Start;
                    timer.Reset();
                    timer.Start();
                }

                if (!xDistanceBetweenEyesSet)
                {
                    xDistanceBetweenEyesSet = true;
                    SetXDistanceBetweenEyes(workerUpdateData.XDistBetweenEyes);
                }

                float elapsedTime = timer.ElapsedMilliseconds;
                timer.Reset();
                timer.Start();

                stageTime += elapsedTime;

                if (currentStage == Stages.Running || currentStage == Stages.Initialization)
                {
                    leftEyeBlinkDetector.Update(workerUpdateData.Image,
                                                blinkLinkEyeClickData.SwitchEyes ? workerUpdateData.RightEyeLocation : workerUpdateData.LeftEyeLocation, elapsedTime);

                    rightEyeBlinkDetector.Update(workerUpdateData.Image,
                                                 blinkLinkEyeClickData.SwitchEyes ? workerUpdateData.LeftEyeLocation : workerUpdateData.RightEyeLocation, elapsedTime);
                }

                switch (currentStage)
                {
                case Stages.Initialization:
                {
                    if (leftEyeBlinkDetector.IsReady && rightEyeBlinkDetector.IsReady)
                    {
                        SystemSounds.Beep.Play();
                        CurrentStage = Stages.Running;
                    }
                }
                break;

                case Stages.Start:
                {
                    if (stageTime > TimeToDisplayStartMessage)
                    {
                        CurrentStage = Stages.Initialization;
                    }
                }
                break;

                case Stages.Running:
                {
                    stageTime = 0;

                    SetEyeImages();

                    if (workerUpdateData.PerformClicks)
                    {
                        clickerFSM.Update(leftEyeBlinkDetector.EyeOpen, rightEyeBlinkDetector.EyeOpen, elapsedTime);
                    }
                    else
                    {
                        clickerFSM.Reset();
                    }
                }
                break;

                default:
                {
                    Debug.Assert(false);
                }
                break;
                }

                workerUpdateData.Dispose();
            }
        }