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 = {
// 		startDate(validator: {return (it > new Date())})
        recurEvery(min:0, 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 this does not fire/pass before validation.
    //But setting defaults above and placing this code here in the hope that this will be fixed in future versions.
    def beforeInsert = {
        def now = new Date()
        
        nextTargetStartDate = startDate
        
        //nextGenerationDate
        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
        }
        
        if( nextGenerationDate < now) {nextGenerationDate = now}
        
        //nextTargetCompletionDate
        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
        }
        
    }

}

