/// <summary>
        /// Get samples of stroke comparison
        /// </summary>
        /// <param name="group">Answer sheet group</param>
        /// <param name="max">Maximum number</param>
        /// <returns>List of comparison result</returns>
        private List<StrokeComparisonResult> GetStrokeComparisons(AnswerSheetGroup group, int max)
        {
            List<StrokeComparisonResult> results = new List<StrokeComparisonResult>();

            List<AnswerStep> steps1 = GroupAnswerStep(group.AnswerSheetList[0].Strokes);
            List<AnswerStep> steps2 = GroupAnswerStep(group.AnswerSheetList[1].Strokes);

            int cnt = 0;
            bool limit = false;
            foreach (AnswerStep step1 in steps1)
            {
                List<AnalysisPenStroke> strokes1 = step1.GetNormalizedStrokes(AnswerSheetAnalyzer.NormarizingHeight, false);
                foreach (AnswerStep step2 in steps2)
                {
                    List<AnalysisPenStroke> strokes2 = step2.GetNormalizedStrokes(AnswerSheetAnalyzer.NormarizingHeight, false);
                    for (int i = 0, ilen = strokes1.Count; i < ilen; i++)
                    {
                        for (int k = 0, klen = strokes2.Count; k < klen; k++)
                        {
                            DPMatchingResult matchRes = CalcStrokeDistance(strokes1[i], strokes2[k]);
                            Point[] p1 = strokes1[i].GetRamerSampledPoints_NonRecursive(AnswerSheetAnalyzer.RamerSamplingDistanceThres);
                            Point[] p2 = strokes2[k].GetRamerSampledPoints_NonRecursive(AnswerSheetAnalyzer.RamerSamplingDistanceThres);
                            AnalysisPenStroke sampledStroke1 = new AnalysisPenStroke();
                            AnalysisPenStroke sampledStroke2 = new AnalysisPenStroke();
                            for (int m = 0, mlen = p1.Length; m < mlen; m++)
                            {
                                sampledStroke1.Points.Add(new AnalysisPenPoint(0, p1[m].X, p1[m].Y));
                            }
                            for (int m = 0, mlen = p2.Length; m < mlen; m++)
                            {
                                sampledStroke2.Points.Add(new AnalysisPenPoint(0, p2[m].X, p2[m].Y));
                            }
                            StrokeComparisonResult compResult = new StrokeComparisonResult(strokes1[i], strokes2[k], sampledStroke1, sampledStroke2, matchRes);
                            results.Add(compResult);

                            cnt++;
                            if (max <= cnt)
                            {
                                limit = true;
                                break;
                            }
                        }
                        if (limit) break;
                    }
                    if (limit) break;
                }
                if (limit) break;
            }

            return results;
        }
        /// <summary>
        /// Get samples of step comparison
        /// </summary>
        /// <param name="group">Answer sheet group</param>
        /// <param name="max">Maximum number</param>
        /// <returns>List of comparison result</returns>
        private List<StepComparisonResult> GetStepComparisons(AnswerSheetGroup group, int max)
        {
            List<StepComparisonResult> results = new List<StepComparisonResult>();

            // enumration of all answer sheets combination
            int cnt = 0;
            bool limit = false;
            for (int i = 0, ilen = group.AnswerSheetList.Count; i < ilen; i++)
            {
                List<AnswerStep> steps1 = GroupAnswerStep(group.AnswerSheetList[i].Strokes);
                for (int k = i + 1, klen = group.AnswerSheetList.Count; k < klen; k++)
                {
                    List<AnswerStep> steps2 = GroupAnswerStep(group.AnswerSheetList[k].Strokes);
                    foreach (AnswerStep s1 in steps1)
                    {
                        foreach (AnswerStep s2 in steps2)
                        {
                            DPMatchingResult matchRes = CalcAnswerStepDistance(s1, s2);
                            StepComparisonResult compResult = new StepComparisonResult(s1, s2, matchRes);
                            results.Add(compResult);

                            cnt++;
                            if (max <= cnt)
                            {
                                limit = true;
                                break;
                            }
                        }
                        if (limit) break;
                    }
                    if (limit) break;
                }
                if (limit) break;
            }

            return results;
        }
        /// <summary>
        /// Initialization with group information
        /// </summary>
        /// <param name="group"></param>
        /// <param name="controller"></param>
        /// <param name="w"></param>
        public AnswerGroupItemData(AnswerSheetGroup group, AnswerSheetVisualizer visualizer, AnswerGroupWindow w)
        {
            this.answerGroupData = group;
            this.groupNameLabel = group.Name;
            this.timeLabel = "Average Time: " + (group.GetAverageAnswerTime() / 1000.0).ToString("f3") + "(sec)";

            this.AnswerSheetData = new ObservableCollection<AnswerSheetItemData>();
            foreach (AnswerSheet ans in group.AnswerSheetList)
            {
                this.AnswerSheetData.Add(new AnswerSheetItemData(ans, visualizer, w));
            }

            // sort item by answer time
            this.AnswerSheetData = new ObservableCollection<AnswerSheetItemData>(this.AnswerSheetData.OrderBy(n => n.AnswerData.AnswerTime));
        }