//called during GMV calculation in mainwindow.xaml.cs
        //if enough time has passed and there is information in the serial port then read that information and send information back to the mainwindow
        //also saves the serial port info to file
        public bool checkSerialInput(double totalSecondsElapsed)
        {
            bool receivedTreat = false;

            if (usingSerial)
            {
                if ((lastSerialRead) < totalSecondsElapsed - .5)
                {
                    try
                    {
                        lastTreat = serialPort1.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        lastTreat = null;
                        Console.WriteLine(ex.ToString());
                    }
                    lastSerialRead = totalSecondsElapsed;
                    if (lastTreat != null)
                    {
                        receivedTreat = true;
                        fileHandler.SaveEventData(totalSecondsElapsed, lastTreat);
                    }
                }
            }
            return(receivedTreat);
        }
        //called from within ProcessDepthFrameData iff the frame is the nth frame of n = frameAcceptance
        //calculates movement, checks for events from arduino, and sends email updates
        private void calculateMovement(int[] depth, int fwidth, int fheight)
        {
            #region GMVCalculation

            //breaks the area of interest into a set number of quadrands
            //calculates the leftmost, rightmost, topmost, bottommost, closest, and furthest pixels associated with the viewable object
            //adds the magnitude of these values together for each quadrant to create the GMV
            //This section can be easily adapted for more complex behavioral measurements
            int numberofQuadrants = quadrantDiv * quadrantDiv;
            int quadHeight        = (quadMarginYB - quadMarginYT) / quadrantDiv;
            int quadWidth         = (quadMarginXR - quadMarginXL) / quadrantDiv;

            int[] iLeftPos         = new int[numberofQuadrants];
            int[] iRightPos        = new int[numberofQuadrants];
            int[] iTopPos          = new int[numberofQuadrants];
            int[] iBotPos          = new int[numberofQuadrants];
            int[] iDepthMin        = new int[numberofQuadrants];
            int[] iDepthMax        = new int[numberofQuadrants];
            int[] allMovementValue = new int[numberofQuadrants];

            for (int quadY = 0; quadY < quadrantDiv; quadY++)
            {
                for (int quadX = 0; quadX < quadrantDiv; quadX++)
                {
                    int yStart  = (quadY * quadHeight + quadMarginYT);
                    int yMax    = (quadY * quadHeight + quadHeight + quadMarginYT);
                    int quadDex = quadX + quadY * quadrantDiv;

                    for (int iiy = yStart; iiy < yMax; iiy++)
                    {
                        int xStart = (quadX * quadWidth + quadMarginXL);
                        int xMax   = (quadX * quadWidth + quadWidth + quadMarginXL);
                        for (int iii = xStart; iii < xMax; iii++)
                        {
                            int depthIndex = iii + iiy * fwidth;
                            if (depth[depthIndex] != 0)      //only use values that have a depth value (if above or below depth thresholds=> gets set to zero)
                            {
                                if (iii < iLeftPos[quadDex]) //if a value is "more left" than the current value then update the value
                                {
                                    iLeftPos[quadDex] = iii;
                                }
                                if (iii > iRightPos[quadDex])
                                {
                                    iRightPos[quadDex] = iii;
                                }
                                if (iTopPos[quadDex] == 0) //can just grab first value since starting at the top right corner
                                {
                                    iTopPos[quadDex] = iiy;
                                }
                                if (iiy > iBotPos[quadDex]) //if a value is "lower" than the current value then update the value
                                {
                                    iBotPos[quadDex] = iiy;
                                }
                                if (depth[depthIndex] < iDepthMin[quadDex]) //if a value is "further forward" than the current value then update the value
                                {
                                    iDepthMin[quadDex] = depth[depthIndex];
                                }
                                if (depth[depthIndex] > iDepthMax[quadDex])//if a value is "further back" than the current value then update the value
                                {
                                    iDepthMax[quadDex] = depth[depthIndex];
                                }
                            }
                        }
                    }
                }
            }

            // initializer when no previous depth value exists
            if (iLeftPosOld == null)
            {
                iLeftPosOld  = iLeftPos;
                iRightPosOld = iRightPos;
                iTopPosOld   = iTopPos;
                iBotPosOld   = iBotPos;
                iDepthMinOld = iDepthMin;
                iDepthMaxOld = iDepthMax;
            }

            //calculate the difference between the old and new frame values for each quadrant and add them together
            int iMovementValue = 0;
            for (int quadY = 0; quadY < quadrantDiv; quadY++)
            {
                for (int quadX = 0; quadX < quadrantDiv; quadX++)
                {
                    int quadDex      = quadX + quadY * quadrantDiv;
                    int leftDiff     = 0;
                    int rightDiff    = 0;
                    int topDiff      = 0;
                    int botDiff      = 0;
                    int depthMinDiff = 0;
                    int depthMaxDiff = 0;

                    //dont want to subtract zero values from old or new since zero value means invalid calculation (above noise threshold)
                    if (iLeftPos[quadDex] != 0 && iLeftPosOld[quadDex] != 0)
                    {
                        leftDiff = Math.Abs(iLeftPos[quadDex] - iLeftPosOld[quadDex]);
                    }

                    if (iRightPos[quadDex] != 0 && iRightPosOld[quadDex] != 0)
                    {
                        rightDiff = Math.Abs(iRightPos[quadDex] - iRightPosOld[quadDex]);
                    }

                    if (iTopPos[quadDex] != 0 && iTopPosOld[quadDex] != 0)
                    {
                        topDiff = Math.Abs(iTopPos[quadDex] - iTopPosOld[quadDex]);
                    }

                    if (iBotPos[quadDex] != 0 && iBotPosOld[quadDex] != 0)
                    {
                        botDiff = Math.Abs(iBotPos[quadDex] - iBotPosOld[quadDex]);
                    }

                    if (iDepthMin[quadDex] != 0 && iDepthMinOld[quadDex] != 0)
                    {
                        depthMinDiff = Math.Abs(iDepthMin[quadDex] - iDepthMinOld[quadDex]);
                    }

                    if (iDepthMax[quadDex] != 0 && iDepthMaxOld[quadDex] != 0)
                    {
                        depthMaxDiff = Math.Abs(iDepthMax[quadDex] - iDepthMaxOld[quadDex]);
                    }

                    if (leftDiff < noiseCutOff && rightDiff < noiseCutOff && topDiff < noiseCutOff && botDiff < noiseCutOff && depthMinDiff < noiseCutOff && depthMaxDiff < noiseCutOff)
                    {
                        allMovementValue[quadDex] = leftDiff + rightDiff + topDiff + depthMinDiff;
                    }

                    iMovementValue += allMovementValue[quadDex]; //calculate final movement value
                }
            }

            //display GMV on UI
            this.DepthDiff.Dispatcher.BeginInvoke(new Action(() =>
            {
                DepthDiff.Text = string.Format("GMV: {0}", iMovementValue);
            }));



            //assign old values for next frame comparison
            iLeftPosOld  = iLeftPos;
            iRightPosOld = iRightPos;
            iTopPosOld   = iTopPos;
            iBotPosOld   = iBotPos;
            iDepthMinOld = iDepthMin;
            iDepthMaxOld = iDepthMax;

            #endregion

            //update UI display with elapsed time information
            TimeSpan elapsed = DateTime.Now.Subtract(timeStart);
            this.TimeElapsed.Dispatcher.BeginInvoke(new Action(() =>
            {
                int s            = (int)elapsed.TotalSeconds;
                int ds           = (int)(elapsed.TotalSeconds * 10 % 10);
                TimeElapsed.Text = "elapsed: " + s.ToString() + "." + ds.ToString() + "s";
            }));

            //send flag to email handler to send email (will only send if enough time has passed since last email)
            double currentTimeElapsed = Math.Floor(elapsed.TotalSeconds);
            emailHandler.CheckEmailSend(currentTimeElapsed, counter);

            //save the movement data to file
            fileHandler.SaveMovementData(elapsed.TotalMilliseconds, allMovementValue);

            //check to see if there was a control hub trigger send to the portHandler, if so then increment the event counter and flip the saving video flag
            if (!savingVideo && saveVideoOnEvent) //only can occur if not already saving video
            {
                bool KinectFeederTrigger = portHandler.checkSerialInput(DateTime.Now.Subtract(timeStart).TotalSeconds);
                if (KinectFeederTrigger) //
                {
                    counter++;
                    fileHandler.SaveEventData(elapsed.TotalMilliseconds, "TIEvent");
                    this.TimeElapsed.Dispatcher.BeginInvoke(new Action(() =>
                                                                       { Counter.Text = string.Format("{0} Events", counter); }));
                    savingVideo = true;
                }
            }

            // This is also the place to modify the system to set up a behavior contingency on the feeder.
            //For example -> if GMV> threshold then could trigger the feeder, or could "turn on" the control hub such that other events can allow for the feeder to trigger
            //  this could allow for experiments where movement and a neural event must both be above a threshold to train complex behaviors or movement/activity dissociation
        }