package pttodo

type Root struct {
	Todo      []Todo
	Scheduled []Todo
	Done      []Todo
}

func (root Root) Equals(other Root) bool {
	for i, slice := range [][2][]Todo{
		[2][]Todo{root.Todo, other.Todo},
		[2][]Todo{root.Scheduled, other.Scheduled},
		[2][]Todo{root.Done, other.Done},
	} {
		_ = i
		if !equalTodoSlices(slice[0], slice[1]) {
			return false
		}
	}
	return true
}

func (root *Root) AutoMove() {
	root.MoveScheduledToTodo()
	root.MoveTodoToScheduled()
}

func (root *Root) MoveTodoToScheduled() {
	for i := len(root.Todo) - 1; i >= 0; i-- {
		if root.Todo[i].Schedule != "" && !root.Todo[i].Triggered() {
			root.Scheduled = append(root.Scheduled, root.Todo[i])
			for j := i; j < len(root.Todo)-1; j++ {
				root.Todo[j] = root.Todo[j+1]
			}
			root.Todo = root.Todo[:len(root.Todo)-1]
		}
	}
}

func (root *Root) MoveScheduledToTodo() {
	for i := len(root.Scheduled) - 1; i >= 0; i-- {
		if root.Scheduled[i].Triggered() {
			root.Todo = append(root.Todo, root.Scheduled[i])
			root.Scheduled[i] = root.Scheduled[len(root.Scheduled)-1]
			root.Scheduled = root.Scheduled[:len(root.Scheduled)-1]
			if i < len(root.Scheduled)-1 {
				i += 1
			}
		}
	}
}

func (root *Root) MergeIn(root2 Root) {
	for _, listPair := range [][2]*[]Todo{
		[2]*[]Todo{&root.Todo, &root2.Todo},
		[2]*[]Todo{&root.Scheduled, &root2.Scheduled},
		[2]*[]Todo{&root.Done, &root2.Done},
	} {
		for _, candidate := range *listPair[1] {
			found := false
			for i := range *listPair[0] {
				found = found || ((*listPair[0])[i].Todo == candidate.Todo)
			}
			if !found {
				*listPair[0] = append(*listPair[0], candidate)
			}
		}
	}
}

func (root Root) MarshalYAML() (interface{}, error) {
	for i := range root.Todo {
		root.Todo[i].writeTS = false
	}
	for i := range root.Scheduled {
		root.Scheduled[i].writeTS = true
	}
	for i := range root.Done {
		root.Done[i].writeTS = true
	}
	type Alt Root
	return (Alt)(root), nil
}
