import org.codehaus.groovy.runtime.TimeCategory

class TaskRecurringSchedule {

    Task lastGeneratedSubTask
    Period recurPeriod
    Period generateAheadPeriod
    Period taskDurationPeriod

    Integer recurEvery = 1
    Integer taskDuration = 0
    Integer generateAhead = 1
    Date startDate = new Date()
    Date lastGeneratedDate
    Date nextTargetStartDate = new Date()
    Date nextTargetCompletionDate = new Date()
    Date nextGenerationDate = new Date()
    boolean isEnabled = true

//     static hasMany = []

    static belongsTo = [task: Task]

    static constraints = {
        recurEvery(min:1, max:365)
        taskDuration(min:0, max:365)
        generateAhead(min:0, max:365)
        lastGeneratedDate(blank:true, nullable:true)
        lastGeneratedSubTask(blank:true, nullable:true)
    }

    String toString() {
        "Recur every ${recurEvery} ${recurPeriod}"
    }
    
    // As of Grails 1.1.1 this does not fire/pass before validation.
    // But setting some defaults above to pass validation and placing this code here 
	// in the hope that this will be fixed in future versions.
    def beforeInsert = {
        nextTargetStartDate = startDate
        setNextGenerationDate()
        setNextTargetCompletionDate()
    }
    
    public void setNextGenerationDate() {
        switch (generateAheadPeriod.period) {
            case "Day(s)":
                use(TimeCategory) {
                    nextGenerationDate = nextTargetStartDate - generateAhead.days
                }
                break
            case "Week(s)":
                use(TimeCategory) {
                    nextGenerationDate = nextTargetStartDate - generateAhead.weeks
                }
                break
            case "Month(s)":
                use(TimeCategory) {
                    nextGenerationDate = nextTargetStartDate - generateAhead.months
                }
                break
            case "Year(s)":
                use(TimeCategory) {
                    nextGenerationDate = nextTargetStartDate - generateAhead.years
                }
                break
        default:
                break
        }
        def now = new Date()
        if( nextGenerationDate < now) {nextGenerationDate = now}
    }
    
    public void setNextTargetCompletionDate() {
        switch (taskDurationPeriod.period) {
            case "Day(s)":
                use(TimeCategory) {
                    nextTargetCompletionDate = nextTargetStartDate + taskDuration.days
                }
                break
            case "Week(s)":
                use(TimeCategory) {
                    nextTargetCompletionDate = nextTargetStartDate + taskDuration.weeks
                }
                break
            case "Month(s)":
                use(TimeCategory) {
                    nextTargetCompletionDate = nextTargetStartDate + taskDuration.months
                }
                break
            case "Year(s)":
                use(TimeCategory) {
                    nextTargetCompletionDate = nextTargetStartDate + taskDuration.years
                }
                break
            default:
                break
        }
    }
    
}

