diff --git a/app/src/main/java/org/cutem/cutecalendar/model/TodoItemManager.java b/app/src/main/java/org/cutem/cutecalendar/model/TodoItemManager.java index 1e3eaaa..d410c5c 100644 --- a/app/src/main/java/org/cutem/cutecalendar/model/TodoItemManager.java +++ b/app/src/main/java/org/cutem/cutecalendar/model/TodoItemManager.java @@ -1,20 +1,25 @@ package org.cutem.cutecalendar.model; import com.google.gson.GsonBuilder; +import org.cutem.cutecalendar.util.CalendarUtil; import org.jetbrains.annotations.NotNull; -import java.util.HashMap; -import java.util.HashSet; +import java.util.*; public class TodoItemManager { private static final String TODO_LIST_SAVE_NAME = "todo-list.json"; private static TodoItemManager ourInstance; + private long idCount; + private HashSet items = new HashSet<>(); + private HashMap idCache = new HashMap<>(); + private HashMap> dateCache = new HashMap<>(); + private TodoItemManager() { } @@ -25,6 +30,7 @@ public class TodoItemManager { return ourInstance; } + public long getNextId() { while (idCache.containsKey(idCount)) { ++idCount; @@ -32,29 +38,96 @@ public class TodoItemManager { return idCount++; } + private static boolean isIntersectedDuring(@NotNull TodoItem item, @NotNull Calendar from, @NotNull Calendar to) { + return !from.after(item.getEnd()) && !to.before(item.getBgn()); + } public void add(@NotNull TodoItem item) { if (idCache.containsKey(item.getId())) { - items.remove( - idCache.get(item.getId()) - ); + remove(item.getId()); } - items.add(item); idCache.put(item.getId(), item); - } - - - public void remove(long id) { - if (idCache.containsKey(id)) { - items.remove(idCache.get(id)); - idCache.remove(id); - } + items.add(item); + addDateCache(item); } public void remove(@NotNull TodoItem item) { remove(item.getId()); } + public void remove(long id) { + if (idCache.containsKey(id)) { + TodoItem item = idCache.remove(id); + items.remove(item); + removeDateCache(item); + } + } + + private void addDateCache(@NotNull TodoItem item) { + Calendar from = CalendarUtil.getWholeDayPeriod(item.getBgn())[0]; + Calendar to = CalendarUtil.getWholeDayPeriod(item.getEnd())[1]; + + while (!from.after(to)) { + String date = CalendarUtil.getDatePartString(from); + + if (!dateCache.containsKey(date)) { + dateCache.put(date, new ArrayList<>()); + } + List list = dateCache.get(date); + + if (!list.contains(item)) { + list.add(item); + } + + from.add(Calendar.DAY_OF_MONTH, 1); + } + } + + private void removeDateCache(@NotNull TodoItem item) { + Calendar from = CalendarUtil.getWholeDayPeriod(item.getBgn())[0]; + Calendar to = CalendarUtil.getWholeDayPeriod(item.getEnd())[1]; + + while (!from.after(to)) { + String date = CalendarUtil.getDatePartString(from); + List list = dateCache.getOrDefault(date, Collections.emptyList()); + + list.remove(item); + + from.add(Calendar.DAY_OF_MONTH, 1); + } + } + + public List queryTodoItemsDuring(@NotNull Calendar from, @NotNull Calendar to) { + ArrayList result = new ArrayList<>(); + + Calendar c1 = CalendarUtil.getWholeDayPeriod(from)[0]; + Calendar c2 = CalendarUtil.getWholeDayPeriod(to)[1]; + + while (!c1.after(c2)) { + String date = CalendarUtil.getDatePartString(c1); + List list = dateCache.getOrDefault(date, Collections.emptyList()); + + list.forEach(item -> { + if (isIntersectedDuring(item, from, to) + && !result.contains(item)) { + result.add(item); + } + }); + + c1.add(Calendar.DAY_OF_MONTH, 1); + } + + return result; + } + + public boolean haveTodoItemOnSomeday(@NotNull Calendar someday) { + String date = CalendarUtil.getDatePartString(someday); + List items = dateCache.getOrDefault(date, Collections.emptyList()); + + return !items.isEmpty(); + } + + String toJson() { GsonBuilder gson = new GsonBuilder(); @@ -62,4 +135,5 @@ public class TodoItemManager { return gson.create().toJson(items); } + }