package net.sourceforge.ganttproject.datafilter.task;

import java.util.ArrayList;
import java.util.List;

import net.sourceforge.ganttproject.IGanttProject;
import net.sourceforge.ganttproject.datafilter.AutoFix;
import net.sourceforge.ganttproject.datafilter.AutoFixCompleted;
import net.sourceforge.ganttproject.datafilter.AutoFixRescheduleForNextDay;
import net.sourceforge.ganttproject.datafilter.FilterOptionGroup;
import net.sourceforge.ganttproject.datafilter.TaskGroup;
import net.sourceforge.ganttproject.gui.options.model.DefaultIntegerOption;
import net.sourceforge.ganttproject.gui.options.model.GPOption;
import net.sourceforge.ganttproject.gui.options.model.GPOptionGroup;
import net.sourceforge.ganttproject.task.Task;
import net.sourceforge.ganttproject.task.TaskManager;
import net.sourceforge.ganttproject.time.TimeUnitStack;


/**
 * Implementation of FilteredTasks interface. Create task groups for End Date task filter.
 * 
 * Created 12.2007
 * 
 * @author Joanna Muras 
 */
public class EndDateFilteredTasks extends FilteredTasksBase {

    private final List<EndDateTaskGroup> myTaskGroups = new ArrayList<EndDateTaskGroup>();
    /** Keep options available for filter */
    private final List<FilterOptionGroup> mySettings = new ArrayList<FilterOptionGroup>();
    /** Keep quick fixes available for filter */
    private final List<AutoFix> myAutoFixList = new ArrayList<AutoFix>();
    private final DefaultIntegerOption mySoonLengthOption;

    private EndDateFilteredTasks(final TaskManager taskManager, TimeUnitStack timeUnitStack) {
        super("endDate");
        mySoonLengthOption = new DefaultIntegerOption("datafilter.soonLength", 6); 

        /* Create 4 task groups for End Dates - outdated, today, tomorrow, and soon */
        myTaskGroups.add(new EndDateTaskGroup("outdated", taskManager, timeUnitStack));
        myTaskGroups.add(new EndDateTaskGroup("today", taskManager, timeUnitStack));
        myTaskGroups.add(new EndDateTaskGroup("tomorrow", taskManager, timeUnitStack));
        myTaskGroups.add(new TasksAboutToComplete(taskManager, mySoonLengthOption, timeUnitStack));
        for (EndDateTaskGroup group : myTaskGroups) {
            group.filterTasks();
        }

        /* Set particular filter options - End Date Filter */
        mySettings.addAll(getFilterSettings());
        
        /* Set listener on committing changes */
        if (mySettings.size()>0) {
            mySettings.get(0).addOptionChangeEventListener(this);
        }
    }
    
    /**
     * Create auto fix list for task in filter tree
     */
    public void updateAutoFixList() {
        myAutoFixList.clear();
        for (TaskGroup taskGroup : myTaskGroups) {
            for (Task task: taskGroup.getTasks()) {
                if (taskGroup.getName().equals("outdated")) {
                    myAutoFixList.add(new AutoFixCompleted(task));
                }else if (taskGroup.getName().equals("today")) {
                    myAutoFixList.add(new AutoFixRescheduleForNextDay(task));
                    myAutoFixList.add(new AutoFixCompleted(task));
                }
            }
        }
    }  
    
    public List<AutoFix> getAutoFixList() {
        return myAutoFixList;
    }
    
    /**
     * Get settings for particular filter - End Date Filter
     */
    private List<FilterOptionGroup> getFilterSettings() {
        /* Create option groups for all filters */
        List<FilterOptionGroup> settings = new ArrayList<FilterOptionGroup>();
        /* Options for visibility of tasks depending on completion */
        /* Add option for maximum days for "soon" */
        GPOption[] options = new GPOption[] {
                mySoonLengthOption
        };
        settings.add(new FilterOptionGroup("datafilter.endDate", options));
        return settings;
    }
    
    @Override
    public TaskGroup[] getTaskGroups() {
        return myTaskGroups.toArray(new TaskGroup[0]);
    }
    
    public GPOptionGroup[] getSettings() {
        return mySettings.toArray(new GPOptionGroup[0]);
    }
    
    public static class Factory implements TaskFilterFactory {
        public FilteredTasks createFilter(IGanttProject project) {
            return new EndDateFilteredTasks(project.getTaskManager(), project.getTimeUnitStack());
        }
    }    
}
