Index: trunk/grails-app/domain/Period.groovy
===================================================================
--- trunk/grails-app/domain/Period.groovy	(revision 135)
+++ trunk/grails-app/domain/Period.groovy	(revision 136)
@@ -5,7 +5,9 @@
 
     static hasMany = [taskRecurringSchedules: TaskRecurringSchedule]
-// 
+    
+    static mappedBy = [taskRecurringSchedules:"recurPeriod"]
+
 //     static belongsTo = []
-// 
+
 //     static constraints = {
 // 
Index: trunk/grails-app/domain/TaskRecurringSchedule.groovy
===================================================================
--- trunk/grails-app/domain/TaskRecurringSchedule.groovy	(revision 135)
+++ trunk/grails-app/domain/TaskRecurringSchedule.groovy	(revision 136)
@@ -1,11 +1,19 @@
+import org.codehaus.groovy.runtime.TimeCategory
+
 class TaskRecurringSchedule {
 
     Task lastGeneratedSubTask
-    Period period
+    Period recurPeriod
+    Period generateAheadPeriod
+    Period taskDurationPeriod
 
     Integer recurEvery = 1
+    Integer taskDuration = 0
+    Integer generateAhead = 1
     Date startDate = new Date()
     Date lastGeneratedDate
-    Date nextDueDate
+    Date nextTargetStartDate = new Date()
+    Date nextTargetCompletionDate = new Date()
+    Date nextGenerationDate = new Date()
     boolean isEnabled = true
 
@@ -15,4 +23,8 @@
 
     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)
@@ -20,6 +32,70 @@
 
     String toString() {
-        "Recur every ${recurEvery} ${period}"
+        "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
+        }
+        
+    }
+
 }
 
