package com.jdbernard.timeanalyzer import org.joda.time.Duration /** * A category represents a collection of like events. */ public abstract class Category implements Comparable<Category> { public List<Event> events public List<Category> categories public List<CategorizationPlan> categorizationPlans public String description public Category() { events = [] categories = [] categorizationPlans = [] description = "Unnamed Category" } public Category(String description) { events = [] categories = [] categorizationPlans = [] this.description = description } public abstract boolean matchesEvent(Event e) public void addEvent(Event event) { // see if we have or can create a subcategory that will hold this event Event addedEvent = addToSubcategory(event) // no, let's just add it on ourself if (!addedEvent) { events << event addedEvent = event } return addedEvent } public boolean addToSubcategory(Event e) { // find all matching subcategories def matchingCategories = categories.findAll { it.matchesEvent(e) } if (matchingCategories) return matchingCategories[0].addEvent(e) // no matching subcategories, can we create a new one based on one // of our plans? def matchingPlans = categorizationPlans.findAll { it.deservesNewCategory(e, events) } if (matchingPlans) { // create the new category def newCategory = matchingPlans[0].newCategory(e, events) // add it to our list of cateogries categories << newCategory // add the new event to the category def addedEvent = newCategory.addEvent(e) // move all the events that match the new category over def existingEvents = matchingPlans[0].findEventsToRecategorize(e, events) events -= existingEvents existingEvents.each { newCategory.addEvent(it) } // return the new entry return addedEvent } return null } public Category filter(List<CategoryFilters> filters) { // create new filtered category FilteredCategory fc = new FilteredCategory(description) fc.filters = filters // filter all events and add them to the category fc.events // TODO } public Category filter(CategoryFilter filter) { return filter([filter]) } public Category filter(Closure c) { return filter(c as CategoryFilter) } public Duration getDuration() { return categories.sum(new Duration(0)) { it.duration } + events.sum(new Duration(0)) { it.duration } } public int compareTo(Category other) { return this.getDuration().compareTo(other.getDuration()) } public String toString() { return description } }