private void DoNextStage()
        {
            switch (mTrackCreationState)
            {
            case trackCreationState.Step01_OuterCurve:
                mTrackCreationState = trackCreationState.Step01_OuterCurveFinished;
                SetInstructionText(false, STEP_01_OUTER_CURVE_FINISHED);
                break;

            case trackCreationState.Step01_OuterCurveFinished:
                mTrackCreationState = trackCreationState.Step02_InnerCurve;
                SetInstructionText(false, STEP_02_INNER_CURVE);
                break;

            case trackCreationState.Step02_InnerCurve:
                mTrackCreationState = trackCreationState.Step03_SaveTrack;
                SetInstructionText(false, STEP_03_SAVE_TRACK);
                break;

            case trackCreationState.Step03_SaveTrack:
                this.Frame.Navigate(typeof(MainPage));
                break;

            default:
                mTrackCreationState = trackCreationState.Error;
                SetInstructionText(true, ERROR_INTERNAL);
                break;
            }

            EnDisableSave();
        }
        /// <summary>
        /// Check if and handle the starting line intersections
        /// </summary>
        /// <returns>true: starting line has been crossed for the second time -> curve is finished, false: otherweise</returns>
        private bool handlePointerMoved_StartingLineX(Point currentPoint)
        {
            bool startingLineIntersected = VectorMath.CheckIf2LinesIntersect(mStartingLineCandidateLeftPoint, mStartingLineCandidateRightPoint, mPreviousPoint.Value, currentPoint);

            if (startingLineIntersected)
            {
                // check if we have the right angle, i.e. y coordinates must always get less
                if ((currentPoint.Y - mPreviousPoint.Value.Y) < 0)
                {
                    // right direction
                    mNrStartingLineIntersected++;
                    if (mNrStartingLineIntersected == 2)
                    {
                        // we are done the starting line has been intersected in the right direction for the second time
                        CurvePaintingFinished();
                        return(true);
                    }
                }
                else
                {
                    // wrong direction -> user needs to start drawing from scratch
                    SetInstructionText(true, ERROR_STARTING_LINE_X_WRONG_DIRECTION);
                    mTrackCreationState = trackCreationState.Error;
                }
            }

            return(false);
        }
        private void save_DoIt(StorageFile myStorageFile)
        {
            IList <Point> outerCurve = ConvertUIElementList2PointList(mOuterCurveUIElements);
            IList <Point> innerCurve = ConvertUIElementList2PointList(mInnerCurveUIElements);

            if ((outerCurve.Count == 0) || (innerCurve.Count == 0))
            {
                mTrackCreationState = trackCreationState.Error;
                SetInstructionText(true, ERROR_INTERNAL);
            }
            else
            {
                TrackLoader.SaveTrack(myStorageFile, outerCurve, innerCurve);
            }
        }
 /// <summary>
 /// Handle a pointer release (mouse click) event
 /// </summary>
 private void handlePointerReleased(object sender, PointerRoutedEventArgs eventArgs)
 {
     if (mTrackCreationState == trackCreationState.Step01_OuterCurveFinished)
     {
         // we need this for the transition of the outer curve to the inner curver
         DoNextStage();
     }
     else if ((mTrackCreationState == trackCreationState.Step01_OuterCurve) || (mTrackCreationState == trackCreationState.Step02_InnerCurve))
     {
         // check if the user has released the pointer too early
         if (mNrStartingLineIntersected < 2)
         {
             SetInstructionText(true, ERROR_STARTING_LINE_NOT_X_TWICE);
             mTrackCreationState = trackCreationState.Error;
         }
     }
 }
        /// <summary>
        /// Reset the complete drawings to enable the user to start from scratch
        /// </summary>
        private void ResetDrawings()
        {
            mTrackCreationState = trackCreationState.Step01_OuterCurve;
            SetInstructionText(false, STEP_01_OUTER_CURVE);
            EnDisableSave();

            foreach (UIElement elem in mOuterCurveUIElements)
            {
                xMyCanvas.Children.Remove(elem);
            }
            mOuterCurveUIElements.Clear();

            foreach (UIElement elem in mInnerCurveUIElements)
            {
                xMyCanvas.Children.Remove(elem);
            }
            mInnerCurveUIElements.Clear();

            ResetCurveDrawing();

            mTrackCreationState = trackCreationState.Step01_OuterCurve;
        }
        /// <summary>
        /// Validate the new Point, i.e. the new line
        /// </summary>
        /// <param name="currentPoint"></param>
        /// <returns></returns>
        private bool handlePointerMoved_Validate(Point currentPoint, out Line newLine)
        {
            bool result = true;

            // Does the new line intersect with a curve, this is not allowed
            newLine        = new Line();
            newLine.Stroke = TrackBrushDefs.trackBorderBrush;

            newLine.X1 = mPreviousPoint.Value.X;
            newLine.Y1 = mPreviousPoint.Value.Y;

            newLine.X2 = currentPoint.X;
            newLine.Y2 = currentPoint.Y;

            int position;

            if (mTrackCreationState == trackCreationState.Step01_OuterCurve)
            {
                // check for intersection with the outer curve, we however accept an intersection with the last line of outer curve,
                // because that is natural for lines that are chained together
                if (VectorMathUI.CheckIfLineIntersectsWithLineCollection(newLine, mOuterCurveUIElements, out position))
                {
                    if (position != mOuterCurveUIElements.Count - 1)
                    {
                        // invalid intersection
                        SetInstructionText(true, ERROR_INTERSECTION_OUTER);
                        mTrackCreationState = trackCreationState.Error;
                        result = false;
                    }
                }
            }
            else if (mTrackCreationState == trackCreationState.Step02_InnerCurve)
            {
                // user is currently drawing the inner curve ->
                // check for an intersection with the outer curve which is always invalid, independant of the position
                if (VectorMathUI.CheckIfLineIntersectsWithLineCollection(newLine, mOuterCurveUIElements, out position))
                {
                    // invalid intersection
                    SetInstructionText(true, ERROR_INTERSECTION_OUTER);
                    mTrackCreationState = trackCreationState.Error;
                    result = false;
                }
                if (result)
                {
                    // so far we are okay ->
                    // check for an intersection with the inner curve, we accept an intersection with the last line of inner curve,
                    // because that is natural for lines that are chained together
                    if (VectorMathUI.CheckIfLineIntersectsWithLineCollection(newLine, mInnerCurveUIElements, out position))
                    {
                        if (position != mInnerCurveUIElements.Count - 1)
                        {
                            // invalid intersection
                            SetInstructionText(true, ERROR_INTERSECTION_INNER);
                            mTrackCreationState = trackCreationState.Error;
                            result = false;
                        }
                    }
                }
            }

            return(result);
        }