using System;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

using Telerik.WebControls;

namespace WizardInterface
{
    public partial class _Default : System.Web.UI.Page
    {
        #region properties
        public ExamDataset Exam
        {
            get
            {
                ExamDataset examDataSet = (ExamDataset)Cache["Exam"];
                if (examDataSet == null)
                {
                    examDataSet = new ExamDataset();
                    examDataSet.ReadXml(Server.MapPath("exam.xml"));
                    Cache["Exam"] = examDataSet;
                }
                return examDataSet;
            }
        }

        public bool IsLastPage
        {
            get
            {
                return RadMultiPage1.SelectedIndex == RadMultiPage1.PageViews.Count - 1;
            }
        }

        public bool IsFirstPage
        {
            get
            {
                return RadMultiPage1.SelectedIndex == 0;
            }
        }

        public PageView CurrentPageView
        {
            get
            {
                return RadMultiPage1.PageViews[RadMultiPage1.SelectedIndex];
            }
        }

        #endregion

        #region page events
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                BindMultiPage();
            }
        }

        protected void StartButton_Click(object sender, EventArgs e)
        {
            Page.Validate();
            if (Page.IsValid)
            {
                RadMultiPage1.SelectedIndex += 1;
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            btnNext.Text = IsFirstPage ? "Start" : "Next";
            btnNext.Visible = !IsLastPage;
        }


        protected void RadMultiPage1_PageViewItemCreated(PageView view, int viewIndex)
        {
            int id = 0;
            if (int.TryParse(view.ID, out id))
            {
                switch (id)
                {
                    case -1: BuildStartPage(view); break;
                    case -2: BuildEndPage(view); break;
                    default: BuildPageViewContents(view, GetQuestionRow(view)); break;
                }
            }
        }

        void valResponses_ServerValidate(object source, ServerValidateEventArgs args)
        {
            ExamDataset.QuestionRow question = GetQuestionRow(this.CurrentPageView);
            Control list = this.CurrentPageView.FindControl("List" + question.QuestionID);
            bool isSingleResponse = (question.QuestionTypeID == 1);
            args.IsValid = isSingleResponse ? (list as RadioButtonList).SelectedIndex != -1 : (list as CheckBoxList).SelectedIndex != -1;
        }

        #endregion
        
        #region private methods

        private void BindMultiPage()
        {
            PageView startPageView = new PageView();
            startPageView.ID = "-1";
            BuildStartPage(startPageView);
            RadMultiPage1.PageViews.Add(startPageView);

            foreach (ExamDataset.QuestionRow question in this.Exam.Question)
            {
                PageView pageView = new PageView();
                pageView.ID = question.QuestionID.ToString();
                BuildPageViewContents(pageView, question);
                RadMultiPage1.PageViews.Add(pageView);
            }

            PageView endPageView = new PageView();
            endPageView.ID = "-2";
            BuildEndPage(endPageView);
            RadMultiPage1.PageViews.Add(endPageView);

            RadMultiPage1.SelectedIndex = 0;
        }

        private void BuildStartPage(PageView pageView)
        {
            const string format = "Welcome to the {0} test.<br>There are {1} questions. Press start to begin the test.";
            string message = string.Format(format, this.Exam._Exam[0].ExamTitle, this.Exam.Question.Count);
            pageView.Controls.Add(new LiteralControl(message));
        }

        private void BuildEndPage(PageView pageView)
        {
            const string format = "This concludes the {0} test.";
            string message = string.Format(format, this.Exam._Exam[0].ExamTitle);
            pageView.Controls.Add(new LiteralControl(message));
        }

        private void LoadResponses(PageView pageView, ExamDataset.QuestionRow question)
        {
            string filter = "QuestionID = " + question.QuestionID.ToString();
            string controlID = "List" + question.QuestionID;
            DataRow[] responses = this.Exam.Response.Select(filter);

            if (question.QuestionTypeID == 1) // single response
            {
                RadioButtonList radioButtonList = new RadioButtonList();
                radioButtonList.ID = controlID;
                foreach (ExamDataset.ResponseRow row in responses)
                    radioButtonList.Items.Add(new ListItem(row.ResponseText, row.ResponseID.ToString()));
                pageView.Controls.Add(radioButtonList);
            }
            else // multiple response
            {
                CheckBoxList checkBoxList = new CheckBoxList();
                checkBoxList.ID = controlID;
                foreach (ExamDataset.ResponseRow row in responses)
                    checkBoxList.Items.Add(new ListItem(row.ResponseText, row.ResponseID.ToString()));
                pageView.Controls.Add(checkBoxList); 
            }

            CustomValidator valResponses = new CustomValidator();
            valResponses.ErrorMessage = "A response is required.";
            valResponses.ServerValidate += new ServerValidateEventHandler(valResponses_ServerValidate);
            pageView.Controls.Add(valResponses);
        }

        private ExamDataset.QuestionRow GetQuestionRow(PageView view)
        {
            DataRow[] row = Exam.Question.Select("QuestionID = " + view.ID);
            return (ExamDataset.QuestionRow)row[0];
        }

        private void BuildPageViewContents(PageView pageView, ExamDataset.QuestionRow question)
        {
            // Load the question
            pageView.Controls.Add(new LiteralControl(question.QuestionText));
            pageView.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));
            // Load responses to the question
            LoadResponses(pageView, question);
        } 
        #endregion
    }
}
