package net.sourceforge.ganttproject.datafilter.task;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import net.sourceforge.ganttproject.GanttCalendar;
import net.sourceforge.ganttproject.datafilter.TaskGroupBase;
import net.sourceforge.ganttproject.gui.options.model.EnumerationOption;
import net.sourceforge.ganttproject.gui.options.model.IntegerOption;
import net.sourceforge.ganttproject.task.Task;
import net.sourceforge.ganttproject.task.TaskManager;
import net.sourceforge.ganttproject.time.TimeUnitStack;
import net.sourceforge.ganttproject.time.gregorian.FramerImpl;

/**
 * Implementation of TaskGroup interface. Filter existing tasks according to End Date.
 * 
 * Created 12.2007
 * 
 * @author Joanna Muras 
 */
public class EndDateTaskGroup extends TaskGroupBase {
    private final TimeUnitStack myTimeUnitStack;

    public EndDateTaskGroup(String name, TaskManager taskManager, TimeUnitStack timeUnitStack) {
        super(name, taskManager);
        myTimeUnitStack = timeUnitStack;
    }

    /**
     * Filter existing tasks according to the groups and save them as myTasks variable.
     */
    protected void filterTasks(List<Task> unfiltered, List<Task> filtered) {               

        for (Task task : unfiltered) {
            if ( includeTaskAccordingToEndDate(task.getEnd().getTime(), task.getCompletionPercentage()) ) {
                filtered.add(task); 
            }
        }
    }

    /**
     * Check to which end date group task should be added
     * @param taskEnd
     * @param if you want taskCompletion not to be check give taskCompletion<100
     * @return true if right end date group
     */
    private boolean includeTaskAccordingToEndDate(Date taskEnd, int taskCompletion) {

        /* Set dates */
        final Date today = getTimeUnitStack().getDefaultTimeUnit().adjustLeft(GregorianCalendar.getInstance().getTime());
        final Date tomorrow = getTimeUnitStack().getDefaultTimeUnit().adjustRight(today);
        final Date dayAfterTomorrow = getTimeUnitStack().getDefaultTimeUnit().adjustRight(tomorrow);

        /* If group name equals outdated and task was due to finish before today and is incomplete */
        if (getName().equals("outdated") && taskEnd.before(today) && taskCompletion<100 ) {
            return true;
        /* If group name equals today and task end is due to today and is incomplete */
        } else if (getName().equals("today") && (taskEnd.equals(today) || taskEnd.after(today)) && taskEnd.before(tomorrow) && taskCompletion<100 ) {
            return true;
        /* If group name equals tomorrow and task end is due to tomorrow and is incomplete */
        } else if (getName().equals("tomorrow") && (taskEnd.equals(tomorrow) || taskEnd.after(tomorrow)) && taskEnd.before(dayAfterTomorrow) && taskCompletion<100 ) {
            return true;
        }
        return false;
    }

    protected TimeUnitStack getTimeUnitStack() {
        return myTimeUnitStack;
    }
}

class TasksAboutToComplete extends EndDateTaskGroup {
    private final IntegerOption myTreshhold;

    TasksAboutToComplete(TaskManager taskManager, IntegerOption treshhold, TimeUnitStack timeUnitStack) {
        super("soon", taskManager, timeUnitStack);

        /* Soon defined as number of days from "today" */
        myTreshhold = treshhold;
    }

    @Override
    protected void filterTasks(List<Task> unfiltered, List<Task> filtered) {

        for (Task task : unfiltered) {
            if (includeTaskAccordingToEndDate(task.getEnd().getTime(), myTreshhold.getValue(), task.getCompletionPercentage()) ) {
                filtered.add(task); 
            }
        } 
    }

    /**
     * Check if task should be added to soon group
     * @param taskEnd
     * @param if you want taskCompletion not to be check give taskCompletion<100
     * @return true if task should be added to soon group
     */
    private boolean includeTaskAccordingToEndDate(Date taskEnd, int soonLength, int taskCompletion) {

        /* Set dates */
        final Date today = getTimeUnitStack().getDefaultTimeUnit().adjustLeft(GregorianCalendar.getInstance().getTime());
        final Date tomorrow = getTimeUnitStack().getDefaultTimeUnit().adjustRight(today);
        final Date dayAfterTomorrow = getTimeUnitStack().getDefaultTimeUnit().adjustRight(tomorrow);
        //final GanttCalendar soon = new  GanttCalendar(today.getYear(), today.getMonth(), today.getDay() + soonLength);
        Calendar soonCalendar = GregorianCalendar.getInstance();
        soonCalendar.add(Calendar.DAY_OF_YEAR, soonLength);
        final Date soon = getTimeUnitStack().getDefaultTimeUnit().adjustRight(soonCalendar.getTime());
        
        /* If task end is after tomorrow and before soon */
        if ( (taskEnd.equals(dayAfterTomorrow) || taskEnd.after(dayAfterTomorrow) && taskEnd.before(soon)) && taskCompletion<100 ) {
            return true;
        }
        return false;
    }
}
