public ReplaceCourseControl ( Id |
||
id | Id |
|
courseControl | ||
return | void |
// 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; }
// Change the number location for a course-control. If customLocation is false, puts the number location as automaticLocation public static void ChangeNumberLocation(EventDB eventDB, Id<CourseControl> courseControlId, bool customLocation, PointF newLocation) { CourseControl courseControl = eventDB.GetCourseControl(courseControlId); ControlPoint control = eventDB.GetControl(courseControl.control); courseControl = (CourseControl) courseControl.Clone(); courseControl.customNumberPlacement = customLocation; if (customLocation) { // Number locations are stored as a delta from the center of the control circle. courseControl.numberDeltaX = newLocation.X - control.location.X; courseControl.numberDeltaY = newLocation.Y - control.location.Y; } eventDB.ReplaceCourseControl(courseControlId, courseControl); }
// Change the control associated with a course control. Used when typing in a new existing code // directly into a description sheet. Must be a normal control. public static void ChangeControl(EventDB eventDB, Id<CourseControl> courseControlId, Id<ControlPoint> newControlId) { Debug.Assert(newControlId.IsNotNone); foreach (Id<CourseControl> variantCourseControlId in QueryEvent.AllVariationsOfCourseControl(eventDB, courseControlId)) { CourseControl courseControl = eventDB.GetCourseControl(variantCourseControlId); Debug.Assert(eventDB.GetControl(courseControl.control).kind == ControlPointKind.Normal); Debug.Assert(eventDB.GetControl(newControlId).kind == ControlPointKind.Normal); courseControl = (CourseControl)courseControl.Clone(); courseControl.control = newControlId; courseControl.customNumberPlacement = false; // any custome number placement is no longer valid eventDB.ReplaceCourseControl(variantCourseControlId, courseControl); } }
// Change if a course-control has a map exchange. public static void ChangeControlExchange(EventDB eventDB, Id<CourseControl> courseControlId, bool isExchange) { foreach (Id<CourseControl> variantCourseControlId in QueryEvent.AllVariationsOfCourseControl(eventDB, courseControlId)) { CourseControl courseControl = eventDB.GetCourseControl(variantCourseControlId); if (courseControl.exchange != isExchange) { courseControl = (CourseControl)courseControl.Clone(); courseControl.exchange = isExchange; eventDB.ReplaceCourseControl(variantCourseControlId, courseControl); } } }
// Add a start control to a given course. If the course already has a start control as the first control, replace it. // Otherwise add it as the new start control. The returned CourseControl may be new, or may be the first control with // a different control point. // If addToOtherCourses is true, the new start control is also added to all courses without an existing start control. public static Id<CourseControl> AddStartToCourse(EventDB eventDB, Id<ControlPoint> controlId, Id<Course> courseId, bool addToOtherCourses) { Course course = eventDB.GetCourse(courseId); Id<CourseControl> firstId = course.firstCourseControl; Id<CourseControl> newCourseControlId; if (firstId.IsNotNone && eventDB.GetControl(eventDB.GetCourseControl(firstId).control).kind == ControlPointKind.Start) { // First control exists and is a start control. Replace it. CourseControl first = (CourseControl) eventDB.GetCourseControl(firstId).Clone(); first.control = controlId; eventDB.ReplaceCourseControl(firstId, first); newCourseControlId = firstId; } else { // Add the control as a new start control. newCourseControlId = eventDB.AddCourseControl(new CourseControl(controlId, firstId)); course = (Course) course.Clone(); course.firstCourseControl = newCourseControlId; eventDB.ReplaceCourse(courseId, course); } if (addToOtherCourses) { List<Id<Course>> courseModificationList = new List<Id<Course>>(); // Check all courses to see if we should add the start to that course too. foreach (Id<Course> courseSearchId in eventDB.AllCourseIds) { if (!QueryEvent.HasStartControl(eventDB, courseSearchId)) { // This course does not have a start control. courseModificationList.Add(courseSearchId); } } // Add the start control to each of those courses. foreach (Id<Course> modifyCourseId in courseModificationList) AddStartToCourse(eventDB, controlId, modifyCourseId, false); } return newCourseControlId; }
public static bool AddVariation(EventDB eventDB, CourseDesignator courseDesignator, Id<CourseControl> variationCourseControlId, bool loop, int numberOfForks) { if (!QueryEvent.CanAddVariation(eventDB, courseDesignator, variationCourseControlId)) return false; CourseControl variationCourseControl = eventDB.GetCourseControl(variationCourseControlId); CourseControl newVariationCourseControl = (CourseControl)variationCourseControl.Clone(); newVariationCourseControl.split = true; newVariationCourseControl.loop = loop; newVariationCourseControl.splitEnd = loop ? variationCourseControlId : variationCourseControl.nextCourseControl; // If its a loop, we add a new course control for each loop. For a fork, we already have one leg of the fork. int newCourseControls = loop ? numberOfForks : numberOfForks - 1; CourseControl[] splitCourseControls = new CourseControl[newCourseControls + 1]; Id<CourseControl>[] splitCourseControlIds = new Id<CourseControl>[newCourseControls + 1]; splitCourseControls[0] = newVariationCourseControl; splitCourseControlIds[0] = variationCourseControlId; for (int i = 1; i <= newCourseControls; ++i) { splitCourseControls[i] = (CourseControl) newVariationCourseControl.Clone(); if (loop) splitCourseControls[i].nextCourseControl = variationCourseControlId; splitCourseControlIds[i] = eventDB.AddCourseControl(splitCourseControls[i]); } for (int i = 0; i <= newCourseControls; ++i) { splitCourseControls[i].splitCourseControls = splitCourseControlIds; eventDB.ReplaceCourseControl(splitCourseControlIds[i], splitCourseControls[i]); } return true; }
// Remove a control from a course. Caller must ensure the current is actually in this course. // Returns a list of all control points that were deleted. This will include the one asked to remove, // but might also remove others if it starts a fork or loop. public static ICollection<Id<ControlPoint>> RemoveCourseControl(EventDB eventDB, Id<Course> courseId, Id<CourseControl> courseControlIdRemove) { Course course = eventDB.GetCourse(courseId); List<Id<CourseControl>> allCourseControls = QueryEvent.EnumCourseControlIds(eventDB, new CourseDesignator(courseId)).ToList(); // This the course control to change to. Could be None. CourseControl courseControlRemove = eventDB.GetCourseControl(courseControlIdRemove); Id<CourseControl> afterRemove = courseControlRemove.nextCourseControl; if (courseControlRemove.split && !courseControlRemove.loop) { // Change next to another one of the split controls. if (courseControlRemove.splitCourseControls[0] == courseControlIdRemove) afterRemove = courseControlRemove.splitCourseControls[1]; else afterRemove = courseControlRemove.splitCourseControls[0]; } // For each course control, go throught and change referecnes to the subsequent control. foreach (Id<CourseControl> courseControlId in allCourseControls) { bool changed = false; CourseControl courseControl = eventDB.GetCourseControl(courseControlId); CourseControl clone = (CourseControl)courseControl.Clone(); if (courseControl.nextCourseControl == courseControlIdRemove) { changed = true; clone.nextCourseControl = afterRemove; } if (courseControl.split && courseControl.splitEnd == courseControlIdRemove) { changed = true; clone.splitEnd = afterRemove; if (afterRemove.IsNone) { clone.split = false; // No join control means we remove the split entirely. clone.splitCourseControls = null; } } if (clone.split && clone.splitCourseControls.Contains(courseControlIdRemove)) { changed = true; clone.splitCourseControls = clone.splitCourseControls.Where(id => id != courseControlIdRemove).ToArray(); if (clone.splitCourseControls.Length < 2) { clone.split = false; clone.loop = false; clone.splitCourseControls = null; clone.splitEnd = Id<CourseControl>.None; } } if (changed) { eventDB.ReplaceCourseControl(courseControlId, clone); } } if (course.firstCourseControl == courseControlIdRemove) { // Special case -- remove the first course control. course = (Course) course.Clone(); course.firstCourseControl = afterRemove; eventDB.ReplaceCourse(courseId, course); } // Remove a split could orphan more than one control. Go through and find orphaned ones. HashSet<Id<CourseControl>> newCourseControls = new HashSet<Id<CourseControl>>(QueryEvent.EnumCourseControlIds(eventDB, new CourseDesignator(courseId))); List<Id<CourseControl>> removedCourseControls = new List<Id<CourseControl>>(); HashSet<Id<ControlPoint>> removedControls = new HashSet<Id<ControlPoint>>(); foreach (Id<CourseControl> courseControlId in allCourseControls) { if (!newCourseControls.Contains(courseControlId)) { removedControls.Add(eventDB.GetCourseControl(courseControlId).control); removedCourseControls.Add(courseControlId); eventDB.RemoveCourseControl(courseControlId); } } if (! removedCourseControls.Contains(courseControlIdRemove)) { Debug.Fail("Did not remove the course control we were removing."); } return removedControls; }
public static void ReplaceControlInCourse(EventDB eventDB, Id<Course> courseId, Id<ControlPoint> oldControlId, Id<ControlPoint> newControlId) { foreach (Id<CourseControl> courseControlId in QueryEvent.EnumCourseControlIds(eventDB, new CourseDesignator(courseId)).ToList()) { if (eventDB.GetCourseControl(courseControlId).control == oldControlId) { // Replace the course control with a new one. CourseControl newCourseControl = (CourseControl) eventDB.GetCourseControl(courseControlId).Clone(); newCourseControl.control = newControlId; newCourseControl.customNumberPlacement = false; eventDB.ReplaceCourseControl(courseControlId, newCourseControl); } } }
// Moves a control in a course, creating a new course control referencing the old control. // Cannot move a split control. public static Id<CourseControl> MoveControlInCourse(EventDB eventDB, Id<Course> courseId, Id<CourseControl> courseControlIdToMove, Id<CourseControl> destinationBefore, Id<CourseControl> destinationAfter) { CourseControl courseControlToMove = eventDB.GetCourseControl(courseControlIdToMove); Debug.Assert(!courseControlToMove.split); // Create a new course control. Id<CourseControl> newCourseControlId = AddCourseControl(eventDB, courseControlToMove.control, courseId, destinationBefore, destinationAfter); CourseControl newCourseControl = eventDB.GetCourseControl(newCourseControlId); // Copy over applicable parts of the old course control. CourseControl update = (CourseControl) newCourseControl.Clone(); update.customNumberPlacement = courseControlToMove.customNumberPlacement; update.numberDeltaX = courseControlToMove.numberDeltaX; update.numberDeltaY = courseControlToMove.numberDeltaY; update.descTextAfter = courseControlToMove.descTextAfter; update.descTextBefore = courseControlToMove.descTextBefore; update.points = courseControlToMove.points; eventDB.ReplaceCourseControl(newCourseControlId, update); // Remove the old one. RemoveCourseControl(eventDB, courseId, courseControlIdToMove); return newCourseControlId; }
// Add a finish control to a given course. If the course already has a finish control as the last control, replace it. // Otherwise add it as the new finish control. The returned CourseControl may be new, or may be the last control with // a different control point. // If addToOtherCourses is true, the new finish control is also added to all courses without an existing finish control. public static Id<CourseControl> AddFinishToCourse(EventDB eventDB, Id<ControlPoint> controlId, Id<Course> courseId, bool addToOtherCourses) { Course course = eventDB.GetCourse(courseId); Id<CourseControl> lastId = QueryEvent.LastCourseControl(eventDB, courseId, false); Id<CourseControl> newCourseControlId; if (lastId.IsNone) { // No controls in the course. add this as the only control in the course. newCourseControlId = eventDB.AddCourseControl(new CourseControl(controlId, Id<CourseControl>.None)); course = (Course) course.Clone(); course.firstCourseControl = newCourseControlId; eventDB.ReplaceCourse(courseId, course); } else if (eventDB.GetControl(eventDB.GetCourseControl(lastId).control).kind == ControlPointKind.Finish) { // Last control exists and is a finish control. Replace it. CourseControl last = (CourseControl) eventDB.GetCourseControl(lastId).Clone(); last.control = controlId; eventDB.ReplaceCourseControl(lastId, last); newCourseControlId = lastId; } else { // Last control exist but is not a finish. Add the finish onto it. newCourseControlId = eventDB.AddCourseControl(new CourseControl(controlId, Id<CourseControl>.None)); CourseControl last = (CourseControl) eventDB.GetCourseControl(lastId).Clone(); last.nextCourseControl = newCourseControlId; eventDB.ReplaceCourseControl(lastId, last); } if (addToOtherCourses) { List<Id<Course>> courseModificationList = new List<Id<Course>>(); // Check all courses to see if we should add the finish to that course too. foreach (Id<Course> courseSearchId in eventDB.AllCourseIds) { if (!QueryEvent.HasFinishControl(eventDB, courseSearchId)) { // This course does not have a finish control. courseModificationList.Add(courseSearchId); } } // Add the finish control to each of those courses. foreach (Id<Course> modifyCourseId in courseModificationList) AddFinishToCourse(eventDB, controlId, modifyCourseId, false); } return newCourseControlId; }
// Duplicate a course with a new name, new course controls (since course controls can't be shared), // but all other attributes the same. public static Id<Course> DuplicateCourse(EventDB eventDB, Id<Course> oldCourseId, string newName) { Course oldCourse = eventDB.GetCourse(oldCourseId); int newSortOrder = oldCourse.sortOrder + 1; // Update existing sort orders after by adding one to existing course orders after the new one. foreach (Id<Course> courseToChangeId in eventDB.AllCourseIds.ToList()) { int sortOrder = eventDB.GetCourse(courseToChangeId).sortOrder; if (sortOrder >= newSortOrder) ChangeCourseSortOrder(eventDB, courseToChangeId, sortOrder + 1); } // Duplicate the course controls with blank course controls, and record the mapping. Dictionary<Id<CourseControl>, Id<CourseControl>> mapCourseControl = new Dictionary<Id<CourseControl>, Id<CourseControl>>(); foreach (Id<CourseControl> oldCourseControlId in QueryEvent.EnumCourseControlIds(eventDB, new CourseDesignator(oldCourseId))) { CourseControl newCourseControl = new CourseControl(); Id<CourseControl> newCourseControlId = eventDB.AddCourseControl(newCourseControl); mapCourseControl[oldCourseControlId] = newCourseControlId; } // Create a new course with no course controls in it and the new name, sort order. Course newCourse = (Course)oldCourse.Clone(); if (oldCourse.firstCourseControl.IsNotNone) newCourse.firstCourseControl = mapCourseControl[oldCourse.firstCourseControl]; newCourse.name = newName; newCourse.sortOrder = newSortOrder; Id<Course> newCourseId = eventDB.AddCourse(newCourse); // Now copy all the old course control, updating all the linking fields. foreach (Id<CourseControl> oldCourseControlId in QueryEvent.EnumCourseControlIds(eventDB, new CourseDesignator(oldCourseId))) { // Add a new course control to the new course. CourseControl oldCourseControl = eventDB.GetCourseControl(oldCourseControlId); CourseControl newCourseControl = (CourseControl) oldCourseControl.Clone(); if (newCourseControl.nextCourseControl.IsNotNone) newCourseControl.nextCourseControl = mapCourseControl[newCourseControl.nextCourseControl]; if (newCourseControl.splitEnd.IsNotNone) newCourseControl.splitEnd = mapCourseControl[newCourseControl.splitEnd]; if (newCourseControl.splitCourseControls != null) { for (int i = 0; i < newCourseControl.splitCourseControls.Length; ++i) { newCourseControl.splitCourseControls[i] = mapCourseControl[newCourseControl.splitCourseControls[i]]; } } eventDB.ReplaceCourseControl(mapCourseControl[oldCourseControlId], newCourseControl); } // Duplicate any specials from the old course. foreach (Id<Special> specialId in eventDB.AllSpecialIds.ToList()) { Special special = eventDB.GetSpecial(specialId); if (!special.allCourses) { List<CourseDesignator> addedCourseDesignators = new List<CourseDesignator>(); foreach (CourseDesignator designatorWithSpecial in special.courses) { if (designatorWithSpecial.CourseId == oldCourseId) { if (designatorWithSpecial.AllParts) addedCourseDesignators.Add(new CourseDesignator(newCourseId)); else addedCourseDesignators.Add(new CourseDesignator(newCourseId, designatorWithSpecial.Part)); } } if (addedCourseDesignators.Count > 0) { ChangeDisplayedCourses(eventDB, specialId, special.courses.Concat(addedCourseDesignators).ToArray()); } } } return newCourseId; }
// Change a text line associated with a course control public static void ChangeTextLine(EventDB eventDB, Id<CourseControl> courseControlId, string textLine, bool above) { CourseControl courseControl = eventDB.GetCourseControl(courseControlId); courseControl = (CourseControl) courseControl.Clone(); if (textLine == "") textLine = null; if (above) courseControl.descTextBefore = textLine; else courseControl.descTextAfter = textLine; eventDB.ReplaceCourseControl(courseControlId, courseControl); }
// Change the score for a course-control. Does not validate the score. Use 0 for no score. public static void ChangeScore(EventDB eventDB, Id<CourseControl> courseControlId, int newScore) { CourseControl courseControl = eventDB.GetCourseControl(courseControlId); Debug.Assert(!courseControl.split); // shouldn't have split course control on a course. courseControl = (CourseControl)courseControl.Clone(); courseControl.points = newScore; eventDB.ReplaceCourseControl(courseControlId, courseControl); }