SIL.FieldWorks.IText.InterlinDocForAnalysis.DetectUpMove C# (CSharp) Method

DetectUpMove() private method

Detect that upward movement out of this segment or to an analysis in this same segment is needed. Considerations: Configured analysis lines preceed translation or note lines (currently). Analyses are stored as a sequence in the segement. Some analyses are punctuation that are skipped by the IP. Only analyses that have a word in them are considered "real". "Annotation" lines include translation lines (free and literal) and notes. Each translation or note in a diffeerent ws is a different line. Translations are stored in a segment as a multistring while notes are in a sequence of multistrings. Each note is repeated in each note line of a different ws. So, the IP may be in the first configured note, but not in the first note.
private DetectUpMove ( KeyEventArgs e, IEnumerable lines, int lineNum, ISegment curSeg, int curNoteIndex, WhichEnd where, bool isRightToLeft, bool &isUpNewSeg ) : bool
e System.Windows.Forms.KeyEventArgs The keyboard event being handled.
lines IEnumerable The configured interlinear lines in display order.
lineNum int The current line in lines that has the selection (or IP).
curSeg ISegment The segment that has the selection.
curNoteIndex int The note that is selected in the sequence.
where WhichEnd Indicates where the IP is in the selected text if any.
isRightToLeft bool true if the current line is RTL
isUpNewSeg bool Output set to true if moving out of this segment.
return bool
		private bool DetectUpMove(KeyEventArgs e, IEnumerable<InterlinLineSpec> lines, int lineNum,
			ISegment curSeg, int curNoteIndex, WhichEnd where, bool isRightToLeft,
			out bool isUpNewSeg)
		{
			var linesBefore = lines.Take(lineNum);
			var annotationsBefore = linesBefore;
			bool hasPreviousAnalysis = false;
			if (linesBefore.Any()) // will have some lines if there are analyses
			{
				annotationsBefore = linesBefore.SkipWhile(line => line.WordLevel);
				hasPreviousAnalysis = linesBefore.Any(line => line.WordLevel);
			}
			bool hasPrevAnnotation = false;
			if (annotationsBefore.Any()) // if this is the first annotation, annotationsBefore is empty
			{
				bool hasNotesBefore = annotationsBefore.Any(line => line.Flid == InterlinLineChoices.kflidNote);
				hasPrevAnnotation = HasVisibleTranslationOrNote(curSeg, annotationsBefore);
			}
			else
			{	// this is the first translation or note and it can't be a null note because it was selected
				bool noteIsFirstAnnotation = lines.ToArray()[lineNum].Flid == InterlinLineChoices.kflidNote;
				hasPrevAnnotation = noteIsFirstAnnotation && curNoteIndex > 0; // can have notes or empty notes before it
			}
			bool hasUpMotion = (e.KeyCode == Keys.Up) ||
				(TextIsRightToLeft ?
					(e.KeyCode == Keys.Right && (where == WhichEnd.Right || where == WhichEnd.Both)) :
					(e.KeyCode == Keys.Left && (where == WhichEnd.Left || where == WhichEnd.Both)));
			bool isUpMove = hasUpMotion && !hasPrevAnnotation;
			isUpNewSeg = isUpMove && !isThereRealAnalysisInSegment(curSeg); // no puctuation, or analysis ws
			return isUpMove;
		}
InterlinDocForAnalysis