private List <NavigationOption> getNetworkOptions(navigationtype nType)
        {
            sm("Configuring Network options " + nType.ToString());
            List <NavigationOption> options = new List <NavigationOption>();

            options.Add(NavigationOption.StartPointLocationOption());


            switch (nType)
            {
            case navigationtype.e_flowpath:
                options.Add(NavigationOption.LimitOption());
                break;

            case navigationtype.e_networkpath:
                options.Insert(1, NavigationOption.EndPointLocationOption());
                break;

            case navigationtype.e_networktrace:
                options.Insert(1, NavigationOption.DirectionOption());
                options.Insert(2, NavigationOption.QuerySourceOption());
                options.Add(NavigationOption.LimitOption());
                break;

            default:
                sm("No navigation options exist " + nType);
                break;
            }
            return(options);
        }
예제 #2
0
        private async Task <ActivationResult> LoadAsync(SceneArgs args, NavigationOption option = NavigationOption.None, IProgress <float> progress = null)
        {
            var asyncOperation = SceneManager.LoadSceneAsync(args.SceneName, LoadSceneMode.Additive);

            progress?.Report(0f);
            while (!asyncOperation.isDone)
            {
                progress?.Report(asyncOperation.progress);
                await Task.Delay(TimeSpan.FromSeconds(Time.fixedDeltaTime));
            }
            progress?.Report(1f);

            var result = Activate(args, option);

            // ここに来たという事は新規
            result.TransitionMode |= TransitionMode.New;

            if (!this._scenesByName.TryAdd(args.SceneName, result.ActivatedScene))
            {
                this._logger.LogException(new NavigationFailureException("シーンをテーブルに追加できませんでした"));
                return(null);
            }

            // ロード時にCanvasの調整をする
            if (this._canvasCustomizer != null)
            {
                this._canvasCustomizer.Customize(result.ActivatedScene.RootCanvas);
            }

            return(result);
        }
        public int GetOrder(int parentOrder, NavigationOption option)
        {
            if (option.HasFlag(NavigationOption.Override))
            {
                return(parentOrder + 1);
            }

            return(parentOrder);
        }
예제 #4
0
 private bool NavigationOptionContains(NavigationOption obj)
 {
     return((this.NavigationOptions & obj) == obj);
 }
예제 #5
0
        private NavigationResult Activate(ISceneArgs args, NavigationOption option = NavigationOption.None)
        {
            var result = new NavigationResult();

            if (this._currentScene != null)
            {
                var currentUnityScene = SceneManager.GetSceneByName(this._currentScene.SceneArgs.SceneName);
                if (!currentUnityScene.isLoaded)
                {
                    throw new NavigationFailureException("無効なシーンが設定されています", args);
                }

                result.PreviousScene = this._currentScene;
            }

            // シーンマネージャの方から次のSceneを取得
            var nextUnityScene = SceneManager.GetSceneByName(args.SceneName);

            if (!nextUnityScene.isLoaded)
            {
                throw new NavigationFailureException("シーンの読み込みに失敗しました", args);
            }
            if (nextUnityScene.rootCount != 1)
            {
                throw new NavigationFailureException("シーンのRootObjectが複数あります", args);
            }

            // SceneからINavigatableSceneを取得
            var rootObjects = nextUnityScene.GetRootGameObjects();

            if (rootObjects.Length == 0)
            {
                throw new NavigationFailureException("RootObjectが存在しません", args);
            }
            if (rootObjects.Length > 1)
            {
                throw new NavigationFailureException("RootObjectが複数あります", args);
            }

            var containsCanvases = rootObjects[0].GetComponentsInChildren <Canvas>();

            if (containsCanvases.Length == 0)
            {
                throw new NavigationFailureException("Canvasが見つかりませんでした", args);
            }

            var sceneBases = rootObjects[0].GetComponents <SceneBase>();

            if (sceneBases.Length == 0)
            {
                throw new NavigationFailureException("SceneBaseコンポーネントがRootObjectに存在しません", args);
            }
            if (sceneBases.Length > 1)
            {
                throw new NavigationFailureException("SceneBaseコンポーネントが複数あります", args);
            }

            // 進む場合、新しいシーンは非表示にしておく
            if (!option.HasFlag(NavigationOption.Pop))
            {
                rootObjects[0].SetActive(false);
            }

            // 次のシーンに諸々引数を渡す
            var nextScene = sceneBases[0] as INavigatableScene;

            nextScene.SceneArgs = args;
            nextScene.SetNavigator(this);
            if (this._currentScene != null)
            {
                nextScene.SetParentSceneArgs(this._currentScene.SceneArgs);
            }

            // 進む場合、ソートを整える
            if (!option.HasFlag(NavigationOption.Pop))
            {
                if (this._currentScene != null)
                {
                    this._canvasOrderArranger.ArrangeOrder(this._currentScene.RootCanvases, option);
                }
                else
                {
                    for (var i = 0; i < nextScene.RootCanvases.Count; ++i)
                    {
                        nextScene.RootCanvases[i].sortingOrder = this._canvasOrderArranger.InitialOrder;
                    }
                }
            }

            // 次のシーンにnextSceneを設定
            this._currentScene = result.NextScene = nextScene;

            // TransitionModeの調整
            if (option.HasFlag(NavigationOption.Override))
            {
                result.TransitionMode |= TransitionMode.KeepCurrent;
            }
            if (option.HasFlag(NavigationOption.Pop))
            {
                result.TransitionMode |= TransitionMode.Back;
            }

            return(result);
        }
예제 #6
0
        private async UniTask <NavigationResult> LoadAsync(ISceneArgs args, CancellationToken token, NavigationOption option = NavigationOption.None, IProgress <float> progress = null)
        {
            var asyncOperation = SceneManager.LoadSceneAsync(args.SceneName, LoadSceneMode.Additive);

            progress?.Report(0f);
            while (!asyncOperation.isDone)
            {
                progress?.Report(asyncOperation.progress);
                await UniTask.Delay(TimeSpan.FromSeconds(Time.fixedDeltaTime));

                if (token.IsCancellationRequested)
                {
                    throw new OperationCanceledException("遷移処理がキャンセルされました", new NavigationFailureException("遷移処理がキャンセルされました", args), token);
                }
            }
            progress?.Report(1f);

            var result = Activate(args, option);

            // ここに来たという事は新規
            result.TransitionMode |= TransitionMode.New;

            if (this._scenesByName.ContainsKey(args.SceneName))
            {
                throw new NavigationFailureException("シーンを重複して読み込もうとしています", args);
            }
            this._scenesByName[args.SceneName] = result.NextScene;

            // ロード時にCanvasの調整をする
            if (this._canvasCustomizer != null)
            {
                this._canvasCustomizer.Customize(result.NextScene.RootCanvases);
            }

            return(result);
        }
예제 #7
0
        private async UniTask <NavigationResult> NavigateCoreAsync(ISceneArgs args, NavigationOption option = NavigationOption.None, IProgress <float> progress = null)
        {
            if (this._currentSubScenesByName.ContainsKey(args.SceneName))
            {
                throw new NavigationFailureException($"{args.SceneName}は既にサブシーンとしてロードされています。サブシーンを通常シーンに変更することはできません。", args);
            }

            using (var internalProgresses = new NavigationInternalProgressGroup(progress, 6))
                using (NavigationLock.Acquire(args))
                {
                    var loadingDisplay = default(ILoadingDisplay);

                    if (this._loadingDisplaySelector != null)
                    {
                        if (this._loadingDisplaysByOption.ContainsKey((int)option))
                        {
                            loadingDisplay = this._loadingDisplaysByOption[(int)option];
                        }
                        else
                        {
                            loadingDisplay = this._loadingDisplaysByOption[(int)option] = this._loadingDisplaySelector.SelectDisplay(option);
                        }
                    }

                    if (loadingDisplay != null)
                    {
                        loadingDisplay.Show();
                    }

                    var cancellationToken = this._currentScene?.SceneLifeCancellationToken ?? new CancellationTokenSource().Token;

                    // まずサブシーンを処理する
                    var subSceneTransitions = await NavigateSubScenesCoreAsync(args, cancellationToken, internalProgresses[0]);

                    internalProgresses[0].Report(1f);

                    NavigationResult activationResult;
                    if (this._scenesByName.ContainsKey(args.SceneName))
                    {
                        // 既にInitialize済みのSceneであればActivateするだけでOK
                        activationResult = this.Activate(args, option);
                    }
                    else
                    {
                        activationResult = await this.LoadAsync(args, cancellationToken, option, internalProgresses[1]);
                    }
                    internalProgresses[1].Report(1f);

                    // ここでダメな場合は既にActivateAsyncでエラーを吐いてるハズ
                    if (activationResult == null || activationResult.NextScene == null)
                    {
                        return(null);
                    }

                    if (option.HasFlag(NavigationOption.Push))
                    {
                        // 新しいシーンをスタックに積む
                        this._navigateHistoryStack.Push(new NavigationStackElement()
                        {
                            SceneName = args.SceneName, TransitionMode = activationResult.TransitionMode
                        });
                    }

                    // 新しいシーンをリセットする
                    await activationResult.NextScene.ResetAsync(args, activationResult.TransitionMode, internalProgresses[2]);

                    internalProgresses[2].Report(1f);

                    if (activationResult.NextScene.SceneLifeCancellationToken.IsCancellationRequested)
                    {
                        throw new OperationCanceledException("遷移処理がキャンセルされました", new NavigationFailureException("遷移処理がキャンセルされました", args), activationResult.NextScene.SceneLifeCancellationToken);
                    }

                    // 新規シーンなら初期化する
                    if (activationResult.TransitionMode.HasFlag(TransitionMode.New))
                    {
                        activationResult.NextScene.Initialize();
                    }

                    // 新規シーンに入る
                    await activationResult.NextScene.EnterAsync(activationResult.TransitionMode, internalProgresses[3]);

                    internalProgresses[3].Report(1f);
                    if (activationResult.NextScene.SceneLifeCancellationToken.IsCancellationRequested)
                    {
                        throw new OperationCanceledException("遷移処理がキャンセルされました", new NavigationFailureException("遷移処理がキャンセルされました", args), activationResult.NextScene.SceneLifeCancellationToken);
                    }

                    // 古いシーンから出る
                    if (activationResult.PreviousScene != null)
                    {
                        await activationResult.PreviousScene.LeaveAsync(activationResult.TransitionMode, internalProgresses[4]);

                        internalProgresses[4].Report(1f);
                    }

                    // 新規シーンに入ったら外部の遷移処理を呼ぶ
                    async UniTask enterNext()
                    {
                        for (var i = 0; i < activationResult.NextScene.RootCanvases.Count; ++i)
                        {
                            activationResult.NextScene.RootCanvases[i].enabled = false;
                        }
                        activationResult.NextScene.RootObject.SetActive(true);

                        await this._afterTransition.OnEnteredAsync(activationResult, activationResult.NextScene.SceneLifeCancellationToken, new Progress <float>());

                        if (activationResult.NextScene.SceneLifeCancellationToken.IsCancellationRequested)
                        {
                            throw new OperationCanceledException("遷移処理がキャンセルされました", new NavigationFailureException("遷移処理がキャンセルされました", args), activationResult.NextScene.SceneLifeCancellationToken);
                        }

                        for (var i = 0; i < activationResult.NextScene.RootCanvases.Count; ++i)
                        {
                            activationResult.NextScene.RootCanvases[i].enabled = true;
                        }
                    }

                    // 古いシーンの遷移処理を呼ぶ
                    async UniTask leavePrevious()
                    {
                        if (activationResult.PreviousScene != null)
                        {
                            await this._afterTransition.OnLeftAsync(activationResult, activationResult.NextScene.SceneLifeCancellationToken, new Progress <float>());

                            if (activationResult.NextScene.SceneLifeCancellationToken.IsCancellationRequested)
                            {
                                throw new OperationCanceledException("遷移処理がキャンセルされました", new NavigationFailureException("遷移処理がキャンセルされました", args), activationResult.NextScene.SceneLifeCancellationToken);
                            }

                            // 上に乗せるフラグが無ければ非アクティブ化
                            if (!option.HasFlag(NavigationOption.Override))
                            {
                                activationResult.PreviousScene.RootObject.SetActive(false);
                            }

                            // Popするならアンロードも行う
                            if (option.HasFlag(NavigationOption.Pop))
                            {
                                // シーンのファイナライズ処理
                                activationResult.PreviousScene.Collapse();

                                // 古いシーンをスタックから抜いてアンロード
                                var popObject = this._navigateHistoryStack.Pop();
                                await UnloadAsync(activationResult.PreviousScene.SceneArgs, activationResult.NextScene.SceneLifeCancellationToken, internalProgresses[5]);

                                if (activationResult.NextScene.SceneLifeCancellationToken.IsCancellationRequested)
                                {
                                    throw new OperationCanceledException("遷移処理がキャンセルされました", new NavigationFailureException("遷移処理がキャンセルされました", args), activationResult.NextScene.SceneLifeCancellationToken);
                                }
                            }
                        }

                        internalProgresses[5].Report(1f);
                    }

                    // 遷移処理は同時に進行
                    await UniTask.WhenAll(
                        enterNext(),
                        leavePrevious(),
                        subSceneTransitions.OnEnteredAsync(activationResult.NextScene.SceneLifeCancellationToken),
                        subSceneTransitions.OnLeftAsync(activationResult.NextScene.SceneLifeCancellationToken));

                    if (activationResult.NextScene.SceneLifeCancellationToken.IsCancellationRequested)
                    {
                        throw new OperationCanceledException("遷移処理がキャンセルされました", new NavigationFailureException("遷移処理がキャンセルされました", args), activationResult.NextScene.SceneLifeCancellationToken);
                    }

                    if (loadingDisplay != null)
                    {
                        loadingDisplay.Hide();
                    }

                    return(activationResult);
                }
        }
        private bool isValid(NavigationOption option)
        {
            try
            {
                NavigationOption.navigationoptiontype sType = (NavigationOption.navigationoptiontype)option.ID;
                switch (sType)
                {
                case NavigationOption.navigationoptiontype.e_startpoint:
                case NavigationOption.navigationoptiontype.e_endpoint:
                    // is valid geojson point
                    Point point = JsonConvert.DeserializeObject <Point>(JsonConvert.SerializeObject(option.Value));
                    if (point == null)
                    {
                        break;
                    }
                    addRouteFeature(getFeatureName((routeoptiontype)option.ID, navigationfeaturetype.e_point), new Feature(point)
                    {
                        CRS = point.CRS
                    });
                    return(true);

                case NavigationOption.navigationoptiontype.e_distance:
                    double result;
                    if (!Double.TryParse(option.Value.ToString(), out result))
                    {
                        break;
                    }
                    this.distanceLimit = result;
                    return(true);

                case NavigationOption.navigationoptiontype.e_trunkatingpolygon:
                    // is valid geojson polygon
                    IGeometryObject poly = JsonConvert.DeserializeObject <IGeometryObject>(JsonConvert.SerializeObject(option.Value), new GeometryConverter());
                    if (poly == null)
                    {
                        break;
                    }
                    this.clipGeometry = poly;
                    return(true);

                case NavigationOption.navigationoptiontype.e_navigationdirection:
                    if (Enum.IsDefined(typeof(NavigationOption.directiontype), option.Value))
                    {
                        return(true);
                    }
                    break;

                case NavigationOption.navigationoptiontype.e_querysource:
                    //loop over and ensure all is defined
                    option.Value = ((JArray)option.Value).ToObject <List <string> >();
                    if (((List <string>)option.Value).All(s => Enum.IsDefined(typeof(NavigationOption.querysourcetype), s)))
                    {
                        return(true);
                    }
                    break;

                default:    // limit
                    var value = JsonConvert.DeserializeObject <NavigationOption>(JsonConvert.SerializeObject(option.Value));
                    if ((value.ID == (int)NavigationOption.navigationoptiontype.e_distance ||
                         value.ID == (int)NavigationOption.navigationoptiontype.e_trunkatingpolygon) &&
                        isValid(value))
                    {
                        return(true);
                    }
                    break;
                }
                sm(option.Name + " is invalid. Please provide a valid " + option.Name, MessageType.warning);
                return(false);
            }
            catch (Exception ex)
            {
                sm("Error occured while validating " + option.Name + " " + ex.Message, MessageType.error);
                return(false);
            }
        }
        private bool isValid(int navigationtypeID, List <NavigationOption> options)
        {
            NavigationOption option = null;

            try
            {
                navigationtype ntype = (navigationtype)navigationtypeID;
                switch (ntype)
                {
                case navigationtype.e_flowpath:
                    // requires valid startpoint
                    option = options.FirstOrDefault(x => x.ID == (int)NavigationOption.navigationoptiontype.e_startpoint);
                    if (option == null || !isValid(option))
                    {
                        return(false);
                    }

                    //limit
                    option = options.FirstOrDefault(x => x.ID == 0);
                    if (option != null && !isValid(option))
                    {
                        return(false);
                    }

                    break;

                case navigationtype.e_networkpath:
                    // requires valid startpoint and endpoint
                    option = options.FirstOrDefault(x => x.ID == (int)NavigationOption.navigationoptiontype.e_startpoint);
                    if (option == null || !isValid(option))
                    {
                        return(false);
                    }
                    option = options.FirstOrDefault(x => x.ID == (int)NavigationOption.navigationoptiontype.e_endpoint);
                    if (option == null || !isValid(option))
                    {
                        return(false);
                    }

                    //limit
                    option = options.FirstOrDefault(x => x.ID == 0);
                    if (option != null && !isValid(option))
                    {
                        return(false);
                    }

                    break;

                case navigationtype.e_networktrace:
                    // requires valid startpoint and upstream/dowstream and data query
                    option = options.FirstOrDefault(x => x.ID == (int)NavigationOption.navigationoptiontype.e_startpoint);
                    if (option == null || !isValid(option))
                    {
                        return(false);
                    }
                    option = options.FirstOrDefault(x => x.ID == (int)NavigationOption.navigationoptiontype.e_navigationdirection);
                    if (option == null || !isValid(option))
                    {
                        return(false);
                    }
                    option = options.FirstOrDefault(x => x.ID == (int)NavigationOption.navigationoptiontype.e_querysource);
                    if (option == null || !isValid(option))
                    {
                        return(false);
                    }

                    //limit
                    option = options.FirstOrDefault(x => x.ID == 0);
                    if (option != null && !isValid(option))
                    {
                        return(false);
                    }

                    break;

                default:
                    break;
                }

                sm("Options are valid");
                return(true);
            }
            catch (Exception ex)
            {
                sm("Error occured while validating " + ex.Message, MessageType.error);
                return(false);

                throw;
            }
        }
예제 #10
0
        private async Task <ActivationResult> NavigateCoreAsync(SceneArgs args, NavigationOption option = NavigationOption.None, IProgress <float> progress = null)
        {
            var loadingDisplay = this._loadingDisplaySelector != null?this._loadingDisplaysByOption.GetOrAdd((int)option, this._loadingDisplaySelector.SelectDisplay(option)) : null;

            if (loadingDisplay != null)
            {
                loadingDisplay.Show();
            }

            ActivationResult activationResult;

            if (this._scenesByName.ContainsKey(args.SceneName))
            {
                // 既にInitialize済みのSceneであればActivateするだけでOK
                activationResult = Activate(args, option);
            }
            else
            {
                activationResult = await LoadAsync(args, option, progress);
            }
            // ここでダメな場合は既にActivateAsyncでエラーを吐いてるハズ
            if (activationResult == null || activationResult.ActivatedScene == null)
            {
                return(null);
            }

            if (option.HasFlag(NavigationOption.Push))
            {
                // 新しいシーンをスタックに積む
                this._navigateHistoryStack.Push(new NavigationStackElement()
                {
                    SceneName = args.SceneName, TransitionMode = activationResult.TransitionMode
                });
            }

            // 新しいシーンをリセットする
            await activationResult.ActivatedScene.ResetAsync(args, activationResult.TransitionMode);

            // 新規シーンなら初期化する
            if (activationResult.TransitionMode.HasFlag(TransitionMode.New))
            {
                activationResult.ActivatedScene.Initialize();
            }

            // 新規シーンに入る
            activationResult.ActivatedScene.RootObject.SetActive(true);
            await activationResult.ActivatedScene.EnterAsync(activationResult.TransitionMode);

            // 入ったらイベント発火
            if (this.OnNavigatedAsync != null)
            {
                await this.OnNavigatedAsync(activationResult.ActivatedScene, activationResult.DisactivatedScene, activationResult.TransitionMode);
            }

            // 古いシーンから出る
            if (activationResult.DisactivatedScene != null)
            {
                await activationResult.DisactivatedScene.LeaveAsync(activationResult.TransitionMode);

                // 上に乗せるフラグが無ければ非アクティブ化
                if (!option.HasFlag(NavigationOption.Override))
                {
                    activationResult.DisactivatedScene.RootObject.SetActive(false);
                }

                // Popするならアンロードも行う
                if (option.HasFlag(NavigationOption.Pop))
                {
                    // 古いシーンをスタックから抜いてアンロード
                    var popObject = default(NavigationStackElement);
                    this._navigateHistoryStack.TryPop(out popObject);
                    await UnloadAsync(activationResult.DisactivatedScene.SceneArgs, progress);
                }
            }

            if (loadingDisplay != null)
            {
                loadingDisplay.Hide();
            }

            return(activationResult);
        }
예제 #11
0
 public void ArrangeOrder(IReadOnlyList <Canvas> canvas, NavigationOption option)
 {
 }
예제 #12
0
        public void DisplayQuestion (NavigationOption option)
        {
            lbl_question_number.Visible = true;
            lbl_answer_explanation.Visible = false;
            lbl_section_title.Visible = true;
            label2.Visible = true;
            label3.Visible = true;
            txt_question.Visible = true;
            pic_image.Visible = true;
            
            if (option == NavigationOption.Begin)
            {
                currentQuestionIndex = 0;
                Question question = questions.ElementAt(currentQuestionIndex);
                lbl_question_number.Text = question.QuestionNumber.ToString();
                lbl_section_title.Text = question.SectionTitle;
                txt_question.Text = question.QuestionText;
                lbl_answer_explanation.Text = question.AnswerExplanation;
                if (!(string.IsNullOrWhiteSpace(question.QuestionImagePath)))
                {
                    string imagePath = Path.Combine(GlobalPathVariables.GetExamFilesFolder(filename), question.QuestionImagePath);
                    pic_image.ImageLocation = imagePath;
                }
                for (int i = 0; i < question.QuestionOptions.Count; i++)
                {
                    RadioButton rdb = new RadioButton();
                    rdb.AutoSize = true;
                    rdb.Text = question.QuestionOptions.ElementAt(i).Key + ". - " + question.QuestionOptions.ElementAt(i).Value;
                    rdb.Name = "rdb_" + question.QuestionOptions.ElementAt(i).Key;
                    rdb.Location = new Point(51, 464 + (i * 22));
                    pan_display.Controls.Add(rdb);
                }
                if ((Exam_Settings.ExamType.SelectedSections.ToString() == Properties.Settings.Default.ExamType && questions.Count == 1) || (Exam_Settings.ExamType.SelectedNumber.ToString() == Properties.Settings.Default.ExamType && Properties.Settings.Default.NumOfQuestions == 1))
                    btn_next.Enabled = false;
                this.Invalidate();
            }

            if (option == NavigationOption.Previous)
            {
                //determine the selected answer for this question and save it before moving to the previous question
                for (int j = pan_display.Controls.OfType<RadioButton>().Count() - 1; j >= 0; --j)
                {
                    var ctrls = pan_display.Controls.OfType<RadioButton>();
                    var ctrl = ctrls.ElementAt(j);
                    if (((RadioButton)ctrl).Checked)
                    {
                        givenAnswers[currentQuestionIndex] = Convert.ToChar(ctrl.Name.Replace("rdb_", ""));
                    }
                    pan_display.Controls.Remove(ctrl);
                    ctrl.Dispose();
                }
                if (currentQuestionIndex > 0)
                {
                    currentQuestionIndex -= 1;
                    Question question = questions.ElementAt(currentQuestionIndex);
                    lbl_question_number.Text = question.QuestionNumber.ToString();
                    lbl_section_title.Text = question.SectionTitle;
                    txt_question.Text = question.QuestionText;
                    lbl_answer_explanation.Text = question.AnswerExplanation;
                    if (string.IsNullOrWhiteSpace(question.QuestionImagePath))
                    {
                        pic_image.ImageLocation = "";
                    }
                    else
                    {
                        pic_image.ImageLocation = Path.Combine(GlobalPathVariables.GetExamFilesFolder(filename), question.QuestionImagePath);
                    }
                    for (int i = 0; i < question.QuestionOptions.Count; i++)
                    {
                        RadioButton rdb = new RadioButton();
                        rdb.AutoSize = true;
                        rdb.Text = question.QuestionOptions.ElementAt(i).Key + ". - " + question.QuestionOptions.ElementAt(i).Value;
                        rdb.Name = "rdb_" + question.QuestionOptions.ElementAt(i).Key;
                        rdb.Location = new Point(51, 464 + (i * 22));
                        if (question.QuestionOptions.ElementAt(i).Key == givenAnswers[currentQuestionIndex])
                            rdb.Checked = true;
                        pan_display.Controls.Add(rdb);
                    }
                    if (currentQuestionIndex == 0)
                    {
                        btn_previous.Enabled = false;
                    }
                }
            }

            if (option == NavigationOption.Next)
            {
                //determine the selected answer for this question and save it before moving to the next question
                for (int j = pan_display.Controls.OfType<RadioButton>().Count() - 1; j >= 0; --j)
                {
                    var ctrls = pan_display.Controls.OfType<RadioButton>();
                    var ctrl = ctrls.ElementAt(j);
                    if (((RadioButton)ctrl).Checked)
                    { 
                        givenAnswers[currentQuestionIndex] = Convert.ToChar(ctrl.Name.Replace("rdb_", ""));
                    }
                    pan_display.Controls.Remove(ctrl);
                    ctrl.Dispose();
                }
                currentQuestionIndex += 1;
                Question question = questions.ElementAt(currentQuestionIndex);
                lbl_question_number.Text = question.QuestionNumber.ToString();
                lbl_section_title.Text = question.SectionTitle;
                txt_question.Text = question.QuestionText;
                lbl_answer_explanation.Text = question.AnswerExplanation;
                if (string.IsNullOrWhiteSpace(question.QuestionImagePath))
                {
                    pic_image.ImageLocation = "";
                }
                else
                {
                    pic_image.ImageLocation = Path.Combine(GlobalPathVariables.GetExamFilesFolder(filename), question.QuestionImagePath);
                }
                for (int i = 0; i < question.QuestionOptions.Count; i++)
                {
                    RadioButton rdb = new RadioButton();
                    rdb.AutoSize = true;
                    rdb.Text = question.QuestionOptions.ElementAt(i).Key + ". - " + question.QuestionOptions.ElementAt(i).Value;
                    rdb.Name = "rdb_" + question.QuestionOptions.ElementAt(i).Key;
                    rdb.Location = new Point(51, 464 + (i * 22));
                    if (question.QuestionOptions.ElementAt(i).Key == givenAnswers[currentQuestionIndex])
                        rdb.Checked = true;
                    pan_display.Controls.Add(rdb);
                }
                btn_previous.Enabled = true;
                if ((Exam_Settings.ExamType.SelectedSections.ToString() == Properties.Settings.Default.ExamType && currentQuestionIndex == questions.Count - 1) || (Exam_Settings.ExamType.SelectedNumber.ToString() == Properties.Settings.Default.ExamType && currentQuestionIndex == Properties.Settings.Default.NumOfQuestions))
                    btn_next.Enabled = false;
                this.Invalidate();
            }           
 
            if (option == NavigationOption.End)
            {
                //determine the selected answer for this question and save it before ending the exam
                for (int j = pan_display.Controls.OfType<RadioButton>().Count() - 1; j >= 0; --j)
                {
                    var ctrls = pan_display.Controls.OfType<RadioButton>();
                    var ctrl = ctrls.ElementAt(j);
                    if (((RadioButton)ctrl).Checked)
                    {
                        givenAnswers[currentQuestionIndex] = Convert.ToChar(ctrl.Name.Replace("rdb_", ""));
                    }
                    pan_display.Controls.Remove(ctrl);
                    ctrl.Dispose();
                }
                //Stop the countdown timer
                timer.Stop();
                //determine how many answers are correct and get section details
                int numOfCorrect = 0;
                int total;
                Dictionary<string, int> totalQuestionsPerSection = new Dictionary<string, int>();
                Dictionary<string, int> rightQuestionsPerSection = new Dictionary<string, int>();
                for (int i = 0; i < questions.Count; i++)
                {
                    if (totalQuestionsPerSection.ContainsKey(questions.ElementAt(i).SectionTitle))
                    {
                        totalQuestionsPerSection[questions.ElementAt(i).SectionTitle] += 1;
                    }
                    else
                    {
                        totalQuestionsPerSection.Add(questions.ElementAt(i).SectionTitle, 1);
                    }
                    if (rightQuestionsPerSection.ContainsKey(questions.ElementAt(i).SectionTitle))
                    {
                        if (questions.ElementAt(i).QuestionAnswer == givenAnswers[i])
                        {
                            rightQuestionsPerSection[questions.ElementAt(i).SectionTitle] += 1;
                            numOfCorrect += 1;
                        }
                    }
                    else
                    {
                        rightQuestionsPerSection.Add(questions.ElementAt(i).SectionTitle, 0);
                        if (questions.ElementAt(i).QuestionAnswer == givenAnswers[i])
                        {
                            rightQuestionsPerSection[questions.ElementAt(i).SectionTitle] += 1;
                            numOfCorrect += 1;
                        }
                    }
                }
                total = questions.Count;
                Score_Sheet scs;
                if (Properties.Settings.Default.ExamType == Exam_Settings.ExamType.SelectedNumber.ToString())
                {
                    scs = new Score_Sheet(totalSeconds / 60.0, examCode, ((numOfCorrect * 1000) / Properties.Settings.Default.NumOfQuestions), totalQuestionsPerSection, rightQuestionsPerSection);
                }
                else
                {
                    scs = new Score_Sheet(totalSeconds / 60.0, examCode, ((numOfCorrect * 1000) / total), totalQuestionsPerSection, rightQuestionsPerSection);
                }
                this.Hide();
                scs.ShowDialog();
                this.Close();
            }
        }