   _removeEmptyTaskings: (tasking_plans) ->
     _.reject tasking_plans, (tasking) ->
       not (tasking.due_at and tasking.opens_at)
+
+  # Returns copies of the given property names from settings
+  # Copies are returned so that the store can be reset
+  _getClonedSettings: (id, names...) ->
+    plan = @_getPlan(id)
+    settings = {}
+    for name in names
+      settings[name] = _.clone(plan.settings[name])
+    return settings
+
+  _changeSettings: (id, attributes) ->
+    plan = @_getPlan(id)
+    @_change(id, settings: _.extend({}, plan.settings, attributes))
 
   setPeriods: (id, periods) ->
     plan = @_getPlan(id)

    @_change(id, {settings: {}})

  sortTopics: (id) ->
    plan = @_getPlan(id)
    {page_ids, exercises_count_dynamic} = plan.settings

    page_ids = sortTopics(page_ids)
    @_change(id, {settings: {page_ids, exercises_count_dynamic}})

  addTopic: (id, topicId) ->
    plan = @_getPlan(id)
    {page_ids, exercise_ids, exercises_count_dynamic} = plan.settings
    page_ids = page_ids[..] # Copy the page_ids so we can reset it back if clearChanged() is called

    page_ids.push(topicId) unless plan.settings.page_ids.indexOf(topicId) >= 0
    #sortTopics(page_ids)

    @_change(id, {settings: {page_ids, exercise_ids, exercises_count_dynamic}})

  removeTopic: (id, topicId) ->
    plan = @_getPlan(id)
    {page_ids, exercise_ids, exercises_count_dynamic} = plan.settings
    page_ids = page_ids[..] # Copy the page_ids so we can reset it back if clearChanged() is called

    index = page_ids?.indexOf(topicId)
    page_ids?.splice(index, 1)

    exercise_ids = ExerciseStore.removeTopicExercises(exercise_ids, topicId)
    @_change(id, {settings: {page_ids, exercise_ids, exercises_count_dynamic}})

  updateTopics: (id, page_ids) ->
    plan = @_getPlan(id)
    {exercise_ids, exercises_count_dynamic} = plan.settings
    @_change(id, {settings: {page_ids, exercise_ids, exercises_count_dynamic}})

  addExercise: (id, exercise) ->
    plan = @_getPlan(id)
    {page_ids, exercise_ids, exercises_count_dynamic} = plan.settings
    exercise_ids = exercise_ids[..]

    unless plan.settings.exercise_ids.indexOf(exercise.id) >= 0
      exercise_ids.push(exercise.id)

    @_change(id, {settings: {page_ids, exercise_ids, exercises_count_dynamic}})

  removeExercise: (id, exercise) ->
    plan = @_getPlan(id)
    {page_ids, exercise_ids, exercises_count_dynamic} = plan.settings
    exercise_ids = exercise_ids[..]

    index = exercise_ids?.indexOf(exercise.id)
    exercise_ids?.splice(index, 1)

    @_change(id, {settings: {page_ids, exercise_ids, exercises_count_dynamic}})

  updateExercises: (id, exercise_ids) ->
    plan = @_getPlan(id)
    {page_ids, exercises_count_dynamic} = plan.settings
    @_change(id, {settings: {page_ids, exercise_ids, exercises_count_dynamic}})
    
  moveReading: (id, topicId, step) ->
    plan = @_getPlan(id)
    {page_ids, exercises_count_dynamic} = plan.settings
    page_ids = page_ids[..]

    curIndex = page_ids?.indexOf(topicId)
    newIndex = curIndex + step


    page_ids[curIndex] = page_ids[newIndex]
    page_ids[newIndex] = topicId

    @_changeSettings(id, {page_ids})

  moveExercise: (id, exercise, step) ->
    {exercise_ids} = @_getClonedSettings(id, 'exercise_ids')
    curIndex = exercise_ids?.indexOf(exercise.id)
    newIndex = curIndex + step

