// Add a new course control to a course. Adds a new CourseControl referencing controlId into courseId. The place to insert is // given by courseControl1 and courseControl2. These control should have been gotten by calling FindControlInsertionPoint. public static Id<CourseControl> AddCourseControl(EventDB eventDB, Id<ControlPoint> controlId, Id<Course> courseId, Id<CourseControl> courseControl1, Id<CourseControl> courseControl2) { CourseControl newCourseControl; Id<CourseControl> newCourseControlId; // When adding a new course controls, they fit into variations fine because we are never adding or changing an split, just // fitting into existing splits. if (courseControl1.IsNone) { // Adding at start. Course course = (Course) eventDB.GetCourse(courseId).Clone(); Debug.Assert(courseControl2 == course.firstCourseControl); newCourseControl = new CourseControl(controlId, course.firstCourseControl); newCourseControlId = eventDB.AddCourseControl(newCourseControl); course.firstCourseControl = newCourseControlId; eventDB.ReplaceCourse(courseId, course); } else { // Adding after courseControl1. CourseControl before = (CourseControl) eventDB.GetCourseControl(courseControl1).Clone(); Debug.Assert(courseControl2 == before.nextCourseControl); newCourseControl = new CourseControl(controlId, before.nextCourseControl); newCourseControlId = eventDB.AddCourseControl(newCourseControl); before.nextCourseControl = newCourseControlId; eventDB.ReplaceCourseControl(courseControl1, before); } return newCourseControlId; }
public void WriteXml(string filename, RelayVariations relayVariations, EventDB eventDB, Id<Course> courseId) { this.relayVariations = relayVariations; this.eventDB = eventDB; this.courseId = courseId; this.modificationDate = DateTimeOffset.Now; this.courseName = eventDB.GetCourse(courseId).name; // Create the XML writer. XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.Encoding = new UTF8Encoding(false); xmlWriter = XmlWriter.Create(filename, settings); WriteStart(); for (int teamNumber = 1; teamNumber < relayVariations.NumberOfTeams; ++teamNumber) { WriteTeam(teamNumber); } WriteEnd(); // And done. xmlWriter.Close(); eventDB = null; xmlWriter = null; }
public SelectVariations(EventDB eventDB, Id<Course> courseId) { InitializeComponent(); this.eventDB = eventDB; this.courseId = courseId; Course course = eventDB.GetCourse(courseId); if (course.relayTeams > 0) lastTeam = course.relayTeams; else lastTeam = null; comboBoxVariations.SelectedIndex = 0; if (lastTeam.HasValue) { upDownFirstTeam.Maximum = upDownLastTeam.Maximum = lastTeam.Value; upDownFirstTeam.Minimum = upDownLastTeam.Minimum = 1; upDownFirstTeam.Value = 1; upDownLastTeam.Value = lastTeam.Value; labelNumberOfTeams.Text = string.Format(labelNumberOfTeams.Text, lastTeam.Value); } UpdateControls(); }
// ----------- Static methods to create a new CourseView. ----------------- // Create a normal course view -- the standard view in order, from start control to finish control. courseId may NOT be None. private static CourseView CreateCourseView(EventDB eventDB, CourseDesignator courseDesignator, bool addNonDescriptionSpecials, bool addDescriptionSpecials) { Debug.Assert(! courseDesignator.IsAllControls); Course course = eventDB.GetCourse(courseDesignator.CourseId); CourseView courseView; if (course.kind == CourseKind.Score) courseView = CreateScoreCourseView(eventDB, courseDesignator); else if (course.kind == CourseKind.Normal) { if (QueryEvent.HasVariations(eventDB, courseDesignator.CourseId) && !courseDesignator.IsVariation) courseView = CreateAllVariationsCourseView(eventDB, courseDesignator); else courseView = CreateStandardCourseView(eventDB, courseDesignator); } else { Debug.Fail("Bad course kind"); return null; } courseView.AddSpecials(courseDesignator, addNonDescriptionSpecials, addDescriptionSpecials); return courseView; }
// Create the standard view onto a regular course, or a single variation of a variation course. private static CourseView CreateStandardCourseView(EventDB eventDB, CourseDesignator courseDesignator) { Course course = eventDB.GetCourse(courseDesignator.CourseId); if (QueryEvent.HasVariations(eventDB, courseDesignator.CourseId) && courseDesignator.VariationInfo == null) throw new ApplicationException("Cannot create course view without specifying which variation"); // Get sub-part of the course. firstCourseControls is the first control to process, lastCourseControl is the last one to // process, or None if process to the end of the course. Id<CourseControl> firstCourseControl, lastCourseControl; if (courseDesignator.AllParts) { firstCourseControl = course.firstCourseControl; lastCourseControl = Id<CourseControl>.None; } else { QueryEvent.GetCoursePartBounds(eventDB, courseDesignator, out firstCourseControl, out lastCourseControl); } CourseView courseView = new CourseView(eventDB, courseDesignator); int ordinal; courseView.courseName = course.name; courseView.scoreColumn = -1; ordinal = 1; ordinal = course.firstControlOrdinal; // To get the ordinals correct, we get the course control ids for all parts. List<Id<CourseControl>> courseControls = QueryEvent.EnumCourseControlIds(eventDB, courseDesignator.WithAllParts()).ToList(); int index = 0; // Increase the ordinal value for each normal control before the first one we're considering. while (index < courseControls.Count && courseControls[index] != firstCourseControl) { CourseControl courseControl = eventDB.GetCourseControl(courseControls[index]); ControlPoint control = eventDB.GetControl(courseControl.control); if (control.kind == ControlPointKind.Normal) ++ordinal; ++index; } for (; index < courseControls.Count; ++index) { Id<CourseControl> courseControlId = courseControls[index]; ControlView controlView = new ControlView(); CourseControl courseControl = eventDB.GetCourseControl(courseControlId); ControlPoint control = eventDB.GetControl(courseControl.control); controlView.courseControlIds = new[] { courseControlId }; controlView.controlId = courseControl.control; // Set the ordinal number. if (control.kind == ControlPointKind.Normal) controlView.ordinal = ordinal++; else if (control.kind == ControlPointKind.Start || control.kind == ControlPointKind.MapExchange) controlView.ordinal = 0; else controlView.ordinal = -1; controlView.joinIndex = -1; // Don't show the map exchange for the next part at the end of this part. if (courseControlId == lastCourseControl && !courseDesignator.AllParts && control.kind == ControlPointKind.MapExchange) { controlView.hiddenControl = true; } // Set the legTo array with the next courseControlID. This is later updated // to the indices. if (index < courseControls.Count - 1 && courseControlId != lastCourseControl) { Id<CourseControl> nextCourseControl = courseControls[index + 1]; controlView.legTo = new int[1] { nextCourseControl.id }; // legTo initially holds course control ids, later changed. } // Add the controlview. courseView.controlViews.Add(controlView); if (courseControlId == lastCourseControl) break; } // If this is a part that should also have the finish on it, and it isn't the last part, then // add the finish. if (courseDesignator.IsNotAllControls && !courseDesignator.AllParts && courseDesignator.Part != QueryEvent.CountCourseParts(eventDB, courseDesignator.CourseId) - 1 && QueryEvent.GetPartOptions(eventDB, courseDesignator).ShowFinish) { if (QueryEvent.HasFinishControl(eventDB, courseDesignator.CourseId)) courseView.extraCourseControls.Add(QueryEvent.LastCourseControl(eventDB, courseDesignator.CourseId, false)); } courseView.Finish(); return courseView; }
// Get the print area for a course, or for all controls if CourseId is none. public static PrintArea GetPrintArea(EventDB eventDB, CourseDesignator courseDesignator) { PrintArea printArea; if (courseDesignator.IsAllControls) printArea = eventDB.GetEvent().printArea; else { Course course = eventDB.GetCourse(courseDesignator.CourseId); printArea = course.printArea; if (!courseDesignator.AllParts && course.partPrintAreas.ContainsKey(courseDesignator.Part)) printArea = course.partPrintAreas[courseDesignator.Part]; } return printArea; }
// Given a VariationChoices, select all the course designators that match. public static IEnumerable<CourseDesignator> GetDesignatorsFromVariationChoices(EventDB eventDB, Id<Course> courseId, VariationChoices variationChoices) { switch (variationChoices.Kind) { case VariationChoices.VariationChoicesKind.Combined: return new[] { new CourseDesignator(courseId) }; case VariationChoices.VariationChoicesKind.AllVariations: return (from vi in GetAllVariations(eventDB, courseId) select new PurplePen.CourseDesignator(courseId, vi)).ToArray(); case VariationChoices.VariationChoicesKind.ChosenVariations: return (from vi in GetAllVariations(eventDB, courseId) where variationChoices.ChosenVariations.Contains(vi.CodeString) select new PurplePen.CourseDesignator(courseId, vi)).ToArray(); case VariationChoices.VariationChoicesKind.ChosenTeams: Course course = eventDB.GetCourse(courseId); RelayVariations relayVariations = new RelayVariations(eventDB, courseId, course.relayTeams, course.relayLegs); List<CourseDesignator> result = new List<CourseDesignator>(); for (int team = variationChoices.FirstTeam; team <= variationChoices.LastTeam; ++team) { for (int leg = 1; leg <= relayVariations.NumberOfLegs; ++leg) { result.Add(new CourseDesignator(courseId, relayVariations.GetVariation(team, leg))); } } return result; default: Debug.Fail("Bad variation choices kind"); return null; } }
// What is the sort order for this course. Order is integer > 0. public static int GetCourseSortOrder(EventDB eventDB, Id<Course> courseId) { return eventDB.GetCourse(courseId).sortOrder; }
// Get all the possible variations for a given course, based on the loops/forks. Returns a list of VariationInfo, // giving the code string, VariationPath, and name. Sorted by code string. public static IEnumerable<VariationInfo> GetAllVariations(EventDB eventDB, Id<Course> courseId) { HashSet<Id<CourseControl>> alreadyVisited = new HashSet<PurplePen.Id<PurplePen.CourseControl>>(); CourseDesignator courseDesignator = new CourseDesignator(courseId); Dictionary<Id<CourseControl>, char> variationMapper = GetVariantCodeMapping(eventDB, courseDesignator); List<List<Id<CourseControl>>> variations = GetVariations(eventDB, courseDesignator, eventDB.GetCourse(courseId).firstCourseControl, alreadyVisited); List<VariationInfo> result = new List<VariationInfo>(); // Check for no variations. if (variations.Count == 1 && variations[0].Count == 0) return result; foreach (var choices in variations) { string variationString = GetVariationString(eventDB, choices, variationMapper); VariationInfo.VariationPath variationPath = new VariationInfo.VariationPath(choices); result.Add(new VariationInfo(variationString, variationPath)); } result.Sort((vi1, vi2) => string.Compare(vi1.CodeString, vi2.CodeString, StringComparison.OrdinalIgnoreCase)); return result; }
// See if course has any variations. public static bool HasVariations(EventDB eventDB, Id<Course> courseId) { if (courseId.IsNone) return false; // All Control has no variations. Course course = eventDB.GetCourse(courseId); if (course.kind == CourseKind.Score) return false; // Score courses don't have variations. return EnumCourseControlIds(eventDB, new CourseDesignator(courseId)).Any(courseControlId => eventDB.GetCourseControl(courseControlId).split); }
// Does the course have a start control? public static bool HasStartControl(EventDB eventDB, Id<Course> courseId) { Id<CourseControl> firstId = eventDB.GetCourse(courseId).firstCourseControl; if (firstId.IsNone || eventDB.GetControl(eventDB.GetCourseControl(firstId).control).kind != ControlPointKind.Start) return false; else return true; }
// Returns true if the course designator is a specific part and that part has a custom print area // just for that part. public static bool HasPartSpecificPrintArea(EventDB eventDB, CourseDesignator courseDesignator) { if (courseDesignator.IsAllControls) return false; else { return (!courseDesignator.AllParts && eventDB.GetCourse(courseDesignator.CourseId).partPrintAreas.ContainsKey(courseDesignator.Part)); } }
// Get the text for a list of courses. Returns "None" for no courses. Returns "All courses" for all courses. // The list of course names is sorted. private static string CourseListText(EventDB eventDB, Id<Course>[] courseIds) { if (courseIds.Length == 0) return SelectionDescriptionText.CourseList_None; if (courseIds.Length == QueryEvent.CountCourses(eventDB)) return SelectionDescriptionText.CourseList_AllCourses; StringBuilder builder = new StringBuilder(); string[] courseNames = new string[courseIds.Length]; for (int i = 0; i < courseIds.Length; ++i) { courseNames[i] = eventDB.GetCourse(courseIds[i]).name; } Array.Sort(courseNames); for (int i = 0; i < courseNames.Length; ++i) { if (i != 0) builder.Append(", "); builder.Append(courseNames[i]); } return builder.ToString(); }
// Get missing points. List<MissingThing> MissingScores(EventDB eventDB) { List<MissingThing> missingScores = new List<MissingThing>(); foreach (Id<Course> courseId in QueryEvent.SortedCourseIds(eventDB)) { Course course = eventDB.GetCourse(courseId); bool anyScores = false; List<MissingThing> missingScoresThisCourse = new List<MissingThing>(); if (course.kind == CourseKind.Score) { for (Id<CourseControl> courseControlId = course.firstCourseControl; courseControlId.IsNotNone; courseControlId = eventDB.GetCourseControl(courseControlId).nextCourseControl) { CourseControl courseControl = eventDB.GetCourseControl(courseControlId); if (eventDB.GetControl(courseControl.control).kind == ControlPointKind.Normal) { if (courseControl.points <= 0) missingScoresThisCourse.Add(new MissingThing(courseId, courseControl.control, ReportText.EventAudit_MissingScore)); else anyScores = true; } } if (anyScores) missingScores.AddRange(missingScoresThisCourse); // only report missing scores if some control in this course has a score. } } return missingScores; }
// Get missing things in courses. Sorted in correct course sort order. List<MissingThing> MissingCourseThings(EventDB eventDB) { List<MissingThing> list = new List<MissingThing>(); bool checkLoad = QueryEvent.AnyCoursesHaveLoads(eventDB); // only check load if some courses have it. foreach (Id<Course> courseId in QueryEvent.SortedCourseIds(eventDB)) { Course course = eventDB.GetCourse(courseId); if (course.kind == CourseKind.Normal) AddMissingThingsInRegularCourse(eventDB, courseId, list); else if (course.kind == CourseKind.Score) AddMissingThingsInScoreCourse(eventDB, courseId, list); else Debug.Fail("bad course kind"); if (checkLoad && eventDB.GetCourse(courseId).load < 0) list.Add(new MissingThing(courseId, ReportText.ColumnHeader_Load, ReportText.EventAudit_MissingLoad)); } return list; }
public static IEnumerable<LegInfo> EnumLegs(EventDB eventDB, CourseDesignator courseDesignator) { if (courseDesignator.IsAllControls) yield break; Id<Course> courseId = courseDesignator.CourseId; // Score courses, by definition, have no legs. if (eventDB.GetCourse(courseId).kind == CourseKind.Score) yield break; bool first = true; foreach (Id<CourseControl> courseControlId in EnumCourseControlIds(eventDB, courseDesignator)) { CourseControl courseControl = eventDB.GetCourseControl(courseControlId); if (first || courseDesignator.AllParts || !courseControl.exchange) { Id<CourseControl> nextCourseControlId = GetNextControl(eventDB, courseDesignator, courseControlId); if (nextCourseControlId.IsNotNone) { yield return new LegInfo(courseControlId, nextCourseControlId); } } first = false; } }
// Finds where a new regular control would be inserted into an existing course. courseControl1 and courseControl2 can either or both be none, to identify // a leg to insert into, a control to insert after, or no information about where to insert. Updates courseControl1 and courseControl2 to identify exactly // where on the course the control should be inserted as follows: // If inserting between two course controls -- these are denoted by courseControl1 and courseControl2 // If inserting as last course control -- courseControl1 is the current last control and courseControl2 is None (only occurs when there is no finish) // If inserting as first course control -- courseControl2 is None and courseControl2 is current first control (only occurs when there is no start) // If inserting as only course control -- both are none (only occurs if course is currently empty) public static void FindControlInsertionPoint(EventDB eventDB, CourseDesignator courseDesignator, ref Id<CourseControl> courseControl1, ref Id<CourseControl> courseControl2) { Id<Course> courseId = courseDesignator.CourseId; if (courseControl1.IsNotNone && courseControl2.IsNotNone) { CourseControl cc1 = eventDB.GetCourseControl(courseControl1); CourseControl cc2 = eventDB.GetCourseControl(courseControl2); if (cc1.nextCourseControl != courseControl2) { Debug.Assert(cc2.split && cc2.splitCourseControls.Contains(courseControl2)); courseControl2 = cc1.nextCourseControl; } return; } else { // Adding after courseControl1. If none, or a finish control, add at end, before the finish control if any. if (courseControl1.IsNone || eventDB.GetControl(eventDB.GetCourseControl(courseControl1).control).kind == ControlPointKind.Finish) courseControl1 = QueryEvent.LastCourseControl(eventDB, courseId, true); if (courseControl1.IsNone) { // Empty course or adding at start. courseControl2 = eventDB.GetCourse(courseId).firstCourseControl; return; } else { // Adding after courseControl1. CourseControl before = (CourseControl)eventDB.GetCourseControl(courseControl1); courseControl2 = before.nextCourseControl; return; } } }
public static bool CanAddVariation(EventDB eventDB, CourseDesignator courseDesignator, Id<CourseControl> courseControlId) { // Can't be all controls or score course. if (courseDesignator.IsAllControls) return false; Id<Course> courseId = courseDesignator.CourseId; if (eventDB.GetCourse(courseId).kind == CourseKind.Score) return false; if (courseControlId.IsNone) return false; // Must not be the last control in the course. if (QueryEvent.LastCourseControl(eventDB, courseId, false) == courseControlId) return false; // Can't already have a variation there. CourseControl courseControl = eventDB.GetCourseControl(courseControlId); if (courseControl.split) return false; return true; }
// What is the load for this course. Return -1 if not set. public static int GetCourseLoad(EventDB eventDB, Id<Course> courseId) { int load = eventDB.GetCourse(courseId).load; if (load >= 0) return load; else return -1; }
// Get all course IDs, in the correct sorted order. public static Id<Course>[] SortedCourseIds(EventDB eventDB) { List<Id<Course>> allCourseIds = new List<Id<Course>>(); foreach (Id<Course> courseId in eventDB.AllCourseIds) { allCourseIds.Add(courseId); } // Sort by sortOrder field on the Course objects. allCourseIds.Sort(delegate (Id<Course> courseId1, Id<Course> courseId2) { return eventDB.GetCourse(courseId1).sortOrder.CompareTo(eventDB.GetCourse(courseId2).sortOrder); }); return allCourseIds.ToArray(); }
// What is the default description kind for this course. Can be None, which gets // All Controls print scale. public static DescriptionKind GetDefaultDescKind(EventDB eventDB, Id<Course> courseId) { if (courseId.IsNone) return eventDB.GetEvent().allControlsDescKind; else return eventDB.GetCourse(courseId).descKind; }
// Given an array of courses, compute the control load. Return -1 if no control load set for any containing courses, or array is empty. private static int ComputeLoad(EventDB eventDB, Id<Course>[] courses) { bool anyLoadFound = false; int totalLoad = 0; foreach (Id<Course> courseId in courses) { int load = eventDB.GetCourse(courseId).load; if (load >= 0) { anyLoadFound = true; totalLoad += load; } } if (anyLoadFound) return totalLoad; else return -1; }
// Get the part options for a specific course part. Returns null for all controls. public static PartOptions GetPartOptions(EventDB eventDB, CourseDesignator courseDesignator) { if (courseDesignator.IsAllControls) return null; Course course = eventDB.GetCourse(courseDesignator.CourseId); PartOptions partOptions; if (!course.partOptions.TryGetValue(courseDesignator.Part, out partOptions)) { partOptions = PartOptions.Default; } // Show Finish is always true for the last part of the course. if (courseDesignator.Part == QueryEvent.CountCourseParts(eventDB, courseDesignator.CourseId) - 1) { partOptions = partOptions.Clone(); partOptions.ShowFinish = true; } return partOptions; }
// Enumerate all the course controls id and corresponding split starts for a particular course. private static List<CourseControlAndSplitStart> EnumCourseControlsAndSplitStarts(EventDB eventDB, Id<Course> courseId) { Debug.Assert(courseId.IsNotNone); Id<CourseControl> firstCourseControlId = eventDB.GetCourse(courseId).firstCourseControl; return EnumCourseControlsAndSplitStartsToJoin(eventDB, courseId, firstCourseControlId, Id<CourseControl>.None, Id<CourseControl>.None); }
// What is the print scale for this course? Can be None, which gets All Controls print scale. public static float GetPrintScale(EventDB eventDB, Id<Course> courseId) { if (courseId.IsNone) return eventDB.GetEvent().allControlsPrintScale; else return eventDB.GetCourse(courseId).printScale; }
// Get a textual version of a list of courses. public static string CourseList(EventDB eventDB, IEnumerable<Id<Course>> courses) { StringBuilder courseNames = new StringBuilder(); bool first = true; foreach (Id<Course> courseId in courses) { if (!first) courseNames.Append(", "); courseNames.Append(eventDB.GetCourse(courseId).name); first = false; } return courseNames.ToString(); }
// Create the view of all variations of a course with variations. Cannot be a single part of a multi-part course. // Does not contain ordinals. private static CourseView CreateAllVariationsCourseView(EventDB eventDB, CourseDesignator courseDesignator) { Course course = eventDB.GetCourse(courseDesignator.CourseId); if (!courseDesignator.AllParts) throw new ApplicationException("Cannot create all variations of a single part"); CourseView courseView = new CourseView(eventDB, courseDesignator); courseView.courseName = course.name; courseView.scoreColumn = -1; // To get the ordinals correct, we get the course control ids for all parts. List<Id<CourseControl>> courseControls = QueryEvent.EnumCourseControlIds(eventDB, courseDesignator).ToList(); for (int index = 0; index < courseControls.Count; ++index) { Id<CourseControl> courseControlId = courseControls[index]; CourseControl courseControl = eventDB.GetCourseControl(courseControlId); // We add each split control only once, even though it has multiple variations. Check to see if we have already // handled it. bool alreadyHandled = false; if (courseControl.split) { foreach (ControlView cv in courseView.controlViews) { if (cv.courseControlIds.Contains(courseControlId)) alreadyHandled = true; } } if (!alreadyHandled) { ControlView controlView = new ControlView(); controlView.controlId = courseControl.control; // Set the ordinal number. All variations does not include an ordinal. controlView.ordinal = -1; // Set all course control ids associated with split control, or a single one for a non-split control. // Set the legTo array with the next courseControlID(s). This is later updated // to the indices. if (courseControl.split) { controlView.courseControlIds = QueryEvent.AllVariationsOfCourseControl(eventDB, courseControlId).ToArray(); if (courseControl.nextCourseControl.IsNotNone) { controlView.legTo = new int[controlView.courseControlIds.Length]; for (int i = 0; i < controlView.legTo.Length; ++i) { controlView.legTo[i] = eventDB.GetCourseControl(controlView.courseControlIds[i]).nextCourseControl.id; } } if (courseControl.loop) controlView.joinIndex = courseControlId.id; else controlView.joinIndex = courseControl.splitEnd.id; } else { controlView.courseControlIds = new[] { courseControlId }; if (courseControl.nextCourseControl.IsNotNone) controlView.legTo = new int[1] { courseControl.nextCourseControl.id }; // legTo initially holds course control ids, later changed. controlView.joinIndex = -1; } // Add the controlview. courseView.controlViews.Add(controlView); } } courseView.Finish(); return courseView; }
// Get the full output file name. Uses the name of the course, removes bad characters, // checks for duplication of the map file name. // If courseDesignator is null, uses the event title insteand. public static string CreateOutputFileName(EventDB eventDB, CourseDesignator courseDesignator, string filePrefix, string fileSuffix, string extension) { string basename; // Get the course name. if (courseDesignator == null) basename = GetEventTitle(eventDB, " "); else if (courseDesignator.IsAllControls) basename = MiscText.AllControls; else basename = eventDB.GetCourse(courseDesignator.CourseId).name; // Add prefix, if requested. if (!string.IsNullOrEmpty(filePrefix)) basename = filePrefix + "-" + basename; // Add variation. if (courseDesignator != null && courseDesignator.IsVariation) { basename = basename + " " + courseDesignator.VariationInfo.Name; } // Add part. if (courseDesignator != null && !courseDesignator.AllParts) { basename = basename + "-" + (courseDesignator.Part + 1).ToString(); } if (!string.IsNullOrEmpty(fileSuffix)) basename = basename + fileSuffix; // Remove bad characters. basename = Util.FilterInvalidPathChars(basename); basename += extension; // add OCAD extension. return basename; }
// Create the normal view onto a score course private static CourseView CreateScoreCourseView(EventDB eventDB, CourseDesignator courseDesignator) { Course course = eventDB.GetCourse(courseDesignator.CourseId); CourseView courseView = new CourseView(eventDB, courseDesignator); Id<CourseControl> courseControlId; courseView.courseName = course.name; courseView.scoreColumn = course.scoreColumn; courseControlId = course.firstCourseControl; while (courseControlId.IsNotNone) { ControlView controlView = new ControlView(); CourseControl courseControl = eventDB.GetCourseControl(courseControlId); controlView.courseControlIds = new[] { courseControlId }; controlView.controlId = courseControl.control; // Ordinals assigned after sorting. controlView.ordinal = -1; controlView.joinIndex = -1; // Move to the next control. courseView.controlViews.Add(controlView); courseControlId = courseControl.nextCourseControl; } // Sort the control views: first by kind, then by score, then by code. courseView.controlViews.Sort(delegate(ControlView view1, ControlView view2) { ControlPoint control1 = eventDB.GetControl(view1.controlId); ControlPoint control2 = eventDB.GetControl(view2.controlId); CourseControl courseControl1 = eventDB.GetCourseControl(view1.courseControlIds[0]); CourseControl courseControl2 = eventDB.GetCourseControl(view2.courseControlIds[0]); if (control1.kind < control2.kind) return -1; else if (control1.kind > control2.kind) return 1; if (courseControl1.points != courseControl2.points) return courseControl1.points.CompareTo(courseControl2.points); int result = Util.CompareCodes(control1.code, control2.code); if (result != 0) return result; return view1.controlId.id.CompareTo(view2.controlId.id); }); // Assign ordinals, if applicable. If scores in column A, then no ordinals will be assigned. if (courseView.scoreColumn != 0) { int ordinal = course.firstControlOrdinal; foreach (ControlView control in courseView.controlViews) { if (eventDB.GetControl(control.controlId).kind == ControlPointKind.Normal) control.ordinal = ordinal++; } } courseView.Finish(); return courseView; }
// Enumerate all the course controls ids for a particular course. public static IEnumerable<Id<CourseControl>> EnumCourseControlIds(EventDB eventDB, CourseDesignator courseDesignator) { Debug.Assert(courseDesignator.IsNotAllControls); Id<Course> courseId = courseDesignator.CourseId; int part = courseDesignator.Part; Id<CourseControl> firstCourseControlId = eventDB.GetCourse(courseId).firstCourseControl; int currentPart = 0; IEnumerable<Id<CourseControl>> variationChoices; if (! courseDesignator.IsVariation) variationChoices = null; else variationChoices = courseDesignator.VariationInfo.Path.Choices; return EnumCourseControlsToJoin(eventDB, courseDesignator, firstCourseControlId, Id<CourseControl>.None, variationChoices, false, currentPart); }