/// <summary>
        /// Compute the min DTW distance between seq2 and all possible endings of seq1.
        /// </summary>
        /// <param name="seq1">The master array of sequences to compare</param>
        /// <param name="seq2">The learner array of sequences to compare</param>
        /// <returns>The best match</returns>
        public double DtwComputation(ArrayList seq1, ArrayList seq2, ArrayList learnerframe, ArrayList learnercolorframe, string path, double anglethreshold)
        {
            // Init
            var seq1R = new ArrayList(seq1);
            //seq1R.Reverse();
            var seq2R = new ArrayList(seq2);

            var learnerf = new ArrayList();

            var learnerc = new ArrayList();
            //seq2R.Reverse();

            var tab = new double[seq1R.Count, seq2R.Count];

            for (int i = 0; i < seq1R.Count; i++)
            {
                for (int j = 0; j < seq2R.Count; j++)
                {
                    //tab[i, j] = Double.PositiveInfinity;
                    tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold);
                }
            }
            tab[0, 0] = 0;

            if (_learnerskeletonstream != null)
                _learnerskeletonstream.Close();
            while (FileDelete(@path + "LearnerSelected")) ;
            _learnerskeletonstream = File.Create(@path + "LearnerSelected");
            _lrecorder = new KinectRecorder(KinectRecordOptions.Skeletons, _learnerskeletonstream);

            if (_learnercolorstream != null)
                _learnercolorstream.Close();
            while (FileDelete(@path + "LearnerSelectedColor")) ;
            _learnercolorstream = File.Create(@path + "LearnerSelectedColor");
            _lcolorrecorder = new BinaryWriter( _learnercolorstream);

            int []max_slope = new int [3];

            // Dynamic computation of the DTW matrix.
            for (int i = 1; i < seq1R.Count; i++)
            {
                for (int j = 1; j < seq2R.Count; j++)
                {
                    switch (min(tab[i, j - 1], tab[i - 1, j - 1], tab[i - 1, j]))
                    {
                        case 1:
                            if(max_slope[0]++ %6 != 0)
                             tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold) + tab[i, j - 1];
                            else tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold) + tab[i - 1, j - 1];
                            max_slope[1] = 0;
                            max_slope[2] = 0;
                            break;
                        case 2:
                            tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold) + tab[i - 1, j - 1];
                            max_slope[0] = 0;
                            max_slope[2] = 0;
                            break;
                        case 3:
                            if (max_slope[2]++ % 6 != 0)
                            tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold) + tab[i - 1, j - 1];
                            else tab[i, j] = Marker((System.Windows.Point[])seq1R[i], (System.Windows.Point[])seq2R[j], anglethreshold) + tab[i - 1, j];
                            max_slope[0] = 0;
                            max_slope[1] = 0;
                            break;
                        default:
                            tab[i, j] = double.PositiveInfinity;
                            break;
                    }
                }
            }

            int totalframe = 0;
            int correctframe = 0;
            bool chosen = false;
            //Reconstruct the best matched path  //int currentI = bestMatchI;
            //int currentJ = bestMatchI;
            int currentI = seq1R.Count - 1;
            int currentJ = seq2R.Count - 1;
            while (currentI != 0 && currentJ != 0)
            {
                //Console.WriteLine(target.I + " " + target.J);
                switch (min(tab[currentI, currentJ - 1], tab[currentI - 1, currentJ - 1], tab[currentI - 1, currentJ]))
                {
                    case 1:
                        currentJ--;
                        chosen = false;
                        break;
                    case 2:
                        currentI--;
                        currentJ--;
                        learnerf.Add((SkeletonFrame)learnerframe[currentJ]);
                        if (currentJ < learnercolorframe.Count) learnerc.Add((int)learnercolorframe[currentJ]);
                        correctframe++;
                        chosen = false;
                        break;
                    case 3:
                        currentI--;
                        learnerf.Add((SkeletonFrame)learnerframe[currentJ]);
                        if(currentJ < learnercolorframe.Count) learnerc.Add((int)learnercolorframe[currentJ]);// sometimes the color image frame number is smaller
                        if(!chosen) correctframe++;
                        chosen = true;
                        break;
                    default:
                        currentJ--;
                        chosen = false;
                        break;
                }
                totalframe++;
            }

            while (learnerf.Count != 0)
            {
                _lrecorder.Record((SkeletonFrame)learnerf[learnerf.Count - 1]);
                learnerf.RemoveAt(learnerf.Count - 1);
            }

            using (FileStream fs = File.OpenRead(".\\colorStream"))
            {
                using (BinaryReader reader = new BinaryReader(fs))
                {
                    int temp = reader.ReadInt32();
                    _lcolorrecorder.Write(temp);
                    CreateFromReader(reader);
                    while (learnerc.Count != 0)
                    {
                        if (FrameNumber == (int)learnerc[learnerc.Count - 1])
                        {
                            Record(_lcolorrecorder);
                            learnerc.RemoveAt(learnerc.Count - 1);
                        }
                        else
                        {
                            CreateFromReader(reader);
                        }
                    }
                }
            }

            _learnerskeletonstream.Close();
            _lrecorder.Stop();
            _learnercolorstream.Close();
            _lcolorrecorder.Close();
            return (Double)correctframe / (Double)totalframe * 100;
        }
        /// <summary>
        /// Stores our gesture to the DTW sequences list
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">Routed Event Args</param>
        private void tcStoreClick(object sender, RoutedEventArgs e)
        {
            // Set the buttons enabled state
            //dtwRead.IsEnabled = false;
            tcCapture.IsEnabled = true;
            tcStore.IsEnabled = false;
            tcReplay.IsEnabled = true;
            tcStartLearning.IsEnabled = true;
            tcPlayBack.IsEnabled = true;
            tcPlaybackMaster.IsEnabled = true;
            // Set the capturing? flag
            _learning = false;
            _capturing = false;
            _recorder = null;
            _colorrecorder = null;

            paragraph.Inlines.Clear();

            /*
            const string message = "Are you sure that you would like to store the TaiChi motion?";
            const string caption = "Confirmation";
            var result = System.Windows.Forms.MessageBox.Show(message, caption,
                                         MessageBoxButtons.YesNo,
                                         MessageBoxIcon.Question);

            // If the no button was pressed ...
            if (result == System.Windows.Forms.DialogResult.Yes)
            {*/
                status.Text = "Remembering " + gestureList.Text + ", please stay there until the saving process finished :)";

                string path = ".\\Records\\" + gestureList.Text + "\\";
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                if (_recordcolorstream != null)
                    _recordcolorstream.Close();
                if (_recordskeletonstream != null)
                    _recordskeletonstream.Close();

                if (File.Exists(@path + "skeleton")) while (FileDelete(@path + "skeleton")) ;
                if (File.Exists(@path + "colorStream")) while (FileDelete(@path + "colorStream")) ;
                if (File.Exists(@path + "frame_number")) while (FileDelete(@path + "frame_number")) ;

                File.Copy(@_temppath + "skeleton", @path + "skeleton");
                File.Copy(@_temppath + "colorStream", @path + "colorStream");

                /*
                while (IsFileClosed(@_temppath + "colorStream") && IsFileClosed(@path + "colorStream"))
                {
                    Thread.Sleep(1000);
                }
                 * */

                using (FileStream fs = File.Create(@path + "frame_number"))
                {
                    using (BinaryWriter sw = new BinaryWriter(fs))
                    {
                        sw.Write(_finalframeno);
                    }
                }
                status.Text = gestureList.Text + " added";
               // }
               // else
               // {
            //    _recordskeletonstream.Close();
               //     _recordcolorstream.Close();
            //    return;
               // }
        }
        /// <summary>
        /// Capture mode. Sets our control variables and button enabled states
        /// </summary>
        private void StartCapture()
        {
            _capturing = true;

            paragraph.Inlines.Clear();
            paragraph.Inlines.Add("Start ...");
            // Clear the _video buffer and start from the beginning
            //test _video = new ArrayList();
            if (File.Exists(@_temppath + "skeleton")) while (FileDelete(@_temppath + "skeleton")) ;
            if (File.Exists(@_temppath + "colorStream")) while (FileDelete(@_temppath + "colorStream")) ;
            if (_learning)
            {
                if (_learnercolorstream != null)
                    _learnercolorstream.Close();
                if (_learnerskeletonstream != null)
                    _learnerskeletonstream.Close();
                _learnerskeletonstream = File.Create(@_temppath + "skeleton");
                _learnercolorstream = File.Create(@_temppath + "colorStream");
                _recorder = new KinectRecorder(KinectRecordOptions.Skeletons, _learnerskeletonstream);
                _colorrecorder = new KinectRecorder(KinectRecordOptions.Color, _learnercolorstream);
            }
            else
            {
                tcStore.IsEnabled = true;
                // Set the capturing? flag
                status.Text = "Recording motion " + gestureList.Text;
                if (_recordcolorstream != null)
                    _recordcolorstream.Close();
                if (_recordskeletonstream != null)
                    _recordskeletonstream.Close();
                _recordskeletonstream = File.Create(@_temppath + "skeleton");
                _recordcolorstream = File.Create(@_temppath + "colorStream");
                _recorder = new KinectRecorder(KinectRecordOptions.Skeletons, _recordskeletonstream);
                _colorrecorder = new KinectRecorder(KinectRecordOptions.Color, _recordcolorstream);
            }
        }
        /// <summary>
        /// Event handler for the stop learning click
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tcStopLearningClick(object sender, RoutedEventArgs e)
        {
            status.Text = "Stopped learning, waiting for process complete.";
            tcCapture.IsEnabled = true;
            tcStopReplay.IsEnabled = false;
            tcStartLearning.IsEnabled = true;
            tcStopLearning.IsEnabled = false;
            tcReplay.IsEnabled = true;
            tcPlayBack.IsEnabled = true;
            tcPlaybackMaster.IsEnabled = true;
            _learning = false;
            _capturing = false;

            _replay.Stop();
            _colorreplay.Stop();
            MasterSkeletonCanvas.Children.Clear();
            RealTimeSkeletonCanvas.Children.Clear();
            TempReplayImage.Source = ReplayImage.Source;
            ReplayImage.Source = null;
            _recorder = null;
            _colorrecorder = null;

            /*
            const string message = "Are you satisfied with your performance this time, save or not?";
            const string caption = "Confirmation";
            var result = System.Windows.Forms.MessageBox.Show(message, caption,
                                         MessageBoxButtons.YesNo,
                                         MessageBoxIcon.Question);
            // If the no button was pressed ...
            if (result == System.Windows.Forms.DialogResult.Yes)

            {*/
            paragraph.Inlines.Clear();
                status.Text = "Remembering " + gestureList.Text + ", please stay there until the saving process finished :)";

                string path = ".\\Learnings\\" + gestureList.Text + "\\";
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                if (_learnercolorstream != null)
                    _learnercolorstream.Close();
                if (_learnerskeletonstream != null)
                    _learnerskeletonstream.Close();

                if (File.Exists(@path + "skeleton")) while (FileDelete(@path + "skeleton")) ;
                if (File.Exists(@path + "colorStream")) while (FileDelete(@path + "colorStream")) ;

                using (FileStream fs = File.Create(@path + "frame_number"))
                {
                    using (BinaryWriter sw = new BinaryWriter(fs))
                    {
                        sw.Write(_finalframeno2);
                    }
                }

                if (_learnerseqFrame.Count > 0)
                {
                    _dTWresult = _dtw.DtwComputation(_masterseq, _learnerseq, _learnerseqFrame, _learnercolorFrame, path, threshold);

                    if (_dTWresult > 80.0)
                    {
                        paragraph.Inlines.Add("Excellent, your learning score is " + (int)_dTWresult);
                    }
                    else if (_dTWresult > 60.0)
                    {
                        paragraph.Inlines.Add("Good, your learning score is " + (int)_dTWresult);
                    }
                    else if (_dTWresult > 40.0)
                    {
                        paragraph.Inlines.Add("Please work harder, your learning score is " + (int)_dTWresult);
                    }
                    else
                    {
                        paragraph.Inlines.Add("Too bad, your learning score is " + (int)_dTWresult);
                    }
                }

                File.Copy(@_temppath + "skeleton", @path + "skeleton");
                File.Copy(@_temppath + "colorStream", @path + "colorStream");

                status.Text = gestureList.Text + " added";
               // }
            //else
               // {
            //    _learnerskeletonstream.Close();
               //     _learnercolorstream.Close();
               // }
        }