/// <summary>
        ///  Shows each respondent's answer to each question in a survey
        /// </summary>
        /// <param name="ResponseResultList">A list of responses from each person who responded to the survey</param>
        /// <param name="RespondentList">A list of respondents who answered the survey</param>
        /// <param name="SurveyQuestions">Contains a list of questions and a list of answers for each question/param>
        public void Flatten(GetResponsesResult[] ResponseResultList, RespondentInfo[] RespondentList, SurveyQuestionView SurveyQuestions)
        {
            List<ResponseWithAnswer> rwaList = new List<ResponseWithAnswer>();

            foreach (GetResponsesResult response in ResponseResultList)
            {
                List<RespondentInfo> rList = RespondentList.Where(e => e.RespondentID == response.RespondentID).ToList<RespondentInfo>();
                if (rList != null)
                {
                    RespondentInfo respondant = rList[0];
                    foreach (QuestionInfo qInfo in response.QuestionList)
                    {
                        List<QuestionInfo> question = SurveyQuestions.QuestionList.Where(e => e.QuestionID == qInfo.QuestionID).ToList<QuestionInfo>();
                        QuestionInfo responseQuestion = question[0];
                        qInfo.QuestionType = responseQuestion.QuestionType;

                        foreach (AnswerInfo aInfo in qInfo.QuestionAnswerList)
                        {


                            ResponseWithAnswer rwa = new ResponseWithAnswer();

                            AnswerInfo qi = new AnswerInfo();
                            QuestionFamilyEnum qaFamily = responseQuestion.QuestionType.Family;
                            switch (qaFamily)
                            {
                                case QuestionFamilyEnum.SingleChoice:
                                    rwa.Answer = ProcessAnswer(responseQuestion, aInfo);
                                    break;
                                case QuestionFamilyEnum.MultipleChoice:
                                    rwa.Answer = ProcessAnswer(responseQuestion, aInfo);
                                    break;
                                case QuestionFamilyEnum.Matrix:
                                    rwa.Row = ProcessRow(responseQuestion, aInfo);
                                    rwa.Answer = ProcessAnswer(responseQuestion, aInfo);
                                    break;
                                case QuestionFamilyEnum.OpenEnded:
                                    rwa.Answer = aInfo.Text;
                                    break;
                                case QuestionFamilyEnum.DateTime:
                                    rwa.Row = ProcessRow(responseQuestion, aInfo);
                                    rwa.Answer = aInfo.Text;
                                    break;
                                case QuestionFamilyEnum.Demographic:
                                    rwa.Row = ProcessRow(responseQuestion, aInfo);
                                    rwa.Answer = aInfo.Text;
                                    break;
                                case QuestionFamilyEnum.NotSet:
                                    break;
                                case QuestionFamilyEnum.Presentation:
                                    break;
                                case QuestionFamilyEnum.CustomVariable:
                                    break;
                                default: rwa.Answer = "Answer choice cannot be found in answer bank for this question";
                                    break;

                            }

                            rwa.Question = responseQuestion.Heading;
                            rwa.QuestionID = responseQuestion.QuestionID;
                            rwa.QuestionSubtype = responseQuestion.QuestionType.Subtype;
                            rwa.QuestionType = qaFamily;


                            rwa.User = respondant.Email;
                            rwa.RespondentID = respondant.RespondentID;
                            rwa.RecipientID = respondant.RecipientID;
                            rwaList.Add(rwa);

                        }
                    }
                }
            }

            ResponseAnswerList = rwaList;
        }
        /// <summary>
        /// Gets the count and rankAverage for a question answer
        /// </summary>
        /// <param name="qaf">The question answer choice to get a summary of responses about</param>
        /// <param name="ResponseResultList">A list of responses from each person who responded to the survey</param>
        /// <param name="surveyQuestions">Contains a list of questions and a list of answers for each question</param>
        /// <returns>An object that holds both the count and rank average for the question answer</returns>
        public CountAndAverage GetCountAndAverage(QuestionAnswerFlat qaf, GetResponsesResult[] ResponseResultList, SurveyQuestionView surveyQuestions)
        {
            int count = 0;
            double rankSum = 0;
            int NAresponses = 0; // Count to ignore N/A responses when calculating average
            CountAndAverage caa = new CountAndAverage();

            foreach (GetResponsesResult response in ResponseResultList)
            {
                foreach (QuestionInfo qInfo in response.QuestionList)
                {
                    List<AnswerInfo> SQSelect = qInfo.QuestionAnswerList.Where(e => e.Row == qaf.AnswerID || e.Column == qaf.AnswerID).ToList<AnswerInfo>();
                    int SQCount = SQSelect.Count;

                    count += AddCount(qaf, qInfo, SQCount);

                    // for calculating average for rankings and ratings
                    if (SQSelect.Count > 0 && (qaf.QuestionSubtype == QuestionSubtypeEnum.Ranking || qaf.QuestionSubtype == QuestionSubtypeEnum.Rating)
                        && qaf.AnswerType == AnswerTypeEnum.Row)
                    {
                        List<QuestionAnswerFlat> RankSelect = surveyQuestions.SurveyWithAnswers
                                                                .Where(e => e.AnswerID == SQSelect[0].Column)
                                                                .ToList<QuestionAnswerFlat>();

                        rankSum += AddRankSum(qaf, SQSelect, surveyQuestions);

                        if (RankSelect[0].AnswerText == "N/A")
                        {
                            NAresponses++;
                        }

                    }
                }
            }
            caa.Count = count;
            caa.RankAvg = GetRankAvg(rankSum, count, NAresponses, qaf.TotalResponses);
            return caa;
        }
        /// <summary>
        /// Gets a summary of the responses for a particular question answer, including counts and averages based on survey responses
        /// </summary>
        /// <param name="qaf">The question answer choice to get a summary of responses about</param>
        /// <param name="ResponseResultList">A list of responses from each person who responded to the survey</param>
        /// <param name="surveyQuestions">Contains a list of questions and a list of answers for each question</param>
        /// <param name="calcTotalResponses">"True" when the totalResponses for this question is unknown</param>
        /// <returns>An object that contains all of the summary data</returns>
        public QuestionAnswerFlat GetQuestionAnswerSummary(QuestionAnswerFlat qaf, GetResponsesResult[] ResponseResultList, SurveyQuestionView surveyQuestions, bool calcTotalResponses = true)
        {
            // Calculate total number of responses if it is not provided
            if (qaf.TotalResponses == 0)
            {
                qaf.TotalResponses = GetTotalResponses(qaf, ResponseResultList);
            }

            CountAndAverage caa = GetCountAndAverage(qaf, ResponseResultList, surveyQuestions);

            qaf.Count = caa.Count; 
            qaf.RankAvg = caa.RankAvg;
            qaf.RankType = GetRankType(qaf);

            return qaf;
        }
        /// <summary>
        /// Gets the number of responses for the particular question of the questionAnswer
        /// </summary>
        /// <param name="qaf">The question answer choice to get a summary of responses about</param>
        /// <param name="ResponseResultList">A list of responses from each person who responded to the survey</param>
        /// <returns>The number of total responses to this question</returns>
        public int GetTotalResponses(QuestionAnswerFlat qaf, GetResponsesResult[] ResponseResultList)
        {
            int totalResponses = 0;
            foreach (GetResponsesResult response in ResponseResultList)
            {
                List<QuestionInfo> QuestionResponsesList = response.QuestionList.Where(e => e.QuestionID == qaf.QuestionID).ToList<QuestionInfo>();

                if (QuestionResponsesList.Count > 0)
                {
                    // Do not count answers with optional comments
                    if (qaf.QuestionSubtype == QuestionSubtypeEnum.Rating || qaf.QuestionSubtype == QuestionSubtypeEnum.Ranking)
                    {
                        // optional comments have no column value, all other answers in a Matrix have both a column and row value
                        List<AnswerInfo> QuestionResponsesWithoutOptionalCommentsList = QuestionResponsesList[0].QuestionAnswerList.Where(e => e.Column != null).ToList<AnswerInfo>();
                        totalResponses += QuestionResponsesWithoutOptionalCommentsList.Count;
                    }
                    else
                        if (qaf.QuestionType == QuestionFamilyEnum.Demographic || qaf.QuestionType == QuestionFamilyEnum.DateTime)
                        {
                            totalResponses = ResponseResultList.Length;
                            break;
                        }
                        else
                        {
                            totalResponses += QuestionResponsesList[0].QuestionAnswerList.Length;
                        }
                }
            }
            return totalResponses;
        }
        /// <summary>
        /// Loads a summary of the responses to each question answer, including counts and averages based on survey responses
        /// </summary>
        /// <param name="ResponseResultList">A list of responses from each person who responded to the survey</param>
        /// <param name="surveyQuestions">Contains a list of questions and a list of answers for each question/param>
        public void LoadResponseSummary(GetResponsesResult[] ResponseResultList, SurveyQuestionView surveyQuestions)
        {
            List<QuestionInfo> qList = new List<QuestionInfo>();
            List<QuestionAnswerFlat> qafList = new List<QuestionAnswerFlat>();
            string qafQuestionID = "";
            int totalResponses = 0;

            foreach (QuestionAnswerFlat qaf in surveyQuestions.SurveyWithAnswers)
            {
                if(qafQuestionID != qaf.QuestionID) // only recalculate if it is a new question
                {
                    // Calculate total number of responses for each question in case not everyone answers every question
                    qafQuestionID = qaf.QuestionID;
                    totalResponses = GetTotalResponses(qaf, ResponseResultList);
                }
                qaf.TotalResponses = totalResponses;
                QuestionAnswerFlat qafSummary = GetQuestionAnswerSummary(qaf, ResponseResultList, surveyQuestions, false);

                qafList.Add(qaf);
            }

            SurveyWithAnswers = qafList;
        }