@@ -1,5 +1,6 @@
 /*
  * Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
+ * Copyright 2011 Richard Wilson <richard.wilson@tinct.net>
  *
  * This file is part of NetSurf, http://www.netsurf-browser.org/
  *
@@ -20,10 +21,9 @@
 #include <time.h>
 
 #include "desktop/browser.h"
-#include "framebuffer/schedule.h"
-
-#include "utils/log.h"
+#include "windows/schedule.h"
 #include "utils/utils.h"
+#include "utils/log.h"
 
 /* linked list of scheduled callbacks */
 static struct nscallback *schedule_list = NULL;
@@ -33,7 +33,7 @@
  */
 struct nscallback
 {
-        struct nscallback *next;
+	struct nscallback *next;
 	struct timeval tv;
 	void (*callback)(void *p);
 	void *p;
@@ -43,7 +43,7 @@
 /**
  * Schedule a callback.
  *
- * \param  tival     interval before the callback should be made / cs
+ * \param  cs_ival   interval before the callback should be made / cs
  * \param  callback  callback function
  * \param  p         user parameter, passed to callback function
  *
@@ -54,14 +54,15 @@
 void schedule(int cs_ival, void (*callback)(void *p), void *p)
 {
 	struct nscallback *nscb;
+	struct nscallback *cur_nscb;
 	struct timeval tv;
 
-        tv.tv_sec = cs_ival / 100; /* cs to seconds */
-        tv.tv_usec = (cs_ival % 100) * 10000; /* remainder to microseconds */
+	tv.tv_sec = cs_ival / 100; /* cs to seconds */
+	tv.tv_usec = (cs_ival % 100) * 10000; /* remainder to microseconds */
 
 	nscb = calloc(1, sizeof(struct nscallback));
 
-	LOG(("adding callback %p for  %p(%p) at %d cs", nscb, callback, p, cs_ival));
+	LOG(("adding callback %p for %p(%p) at %d cs", nscb, callback, p, cs_ival));
 
 	gettimeofday(&nscb->tv, NULL);
 	timeradd(&nscb->tv, &tv, &nscb->tv);
@@ -69,9 +70,18 @@
 	nscb->callback = callback;
 	nscb->p = p;
 
-        /* add to list front */
-        nscb->next = schedule_list;
-        schedule_list = nscb;
+	/* should we link at the head of the list? */
+	if ((schedule_list == NULL) || (timercmp(&schedule_list->tv, &nscb->tv, >=))) {
+		nscb->next = schedule_list;
+		schedule_list = nscb;
+		return;
+	}
+	/* find the element we should link in after */
+	cur_nscb = schedule_list;
+	while ((cur_nscb->next != NULL) && (timercmp(&cur_nscb->next->tv, &nscb->tv, <)))
+		cur_nscb = cur_nscb->next;
+	nscb->next = cur_nscb->next;
+	cur_nscb->next = nscb;
 }
 
 /**
@@ -85,42 +95,41 @@
 
 void schedule_remove(void (*callback)(void *p), void *p)
 {
-        struct nscallback *cur_nscb;
-        struct nscallback *prev_nscb;
-        struct nscallback *unlnk_nscb;
+	struct nscallback *cur_nscb;
+	struct nscallback *prev_nscb;
+	struct nscallback *unlnk_nscb;
 
-        if (schedule_list == NULL)
-                return;
+	if (schedule_list == NULL)
+		return;
 
 	LOG(("removing %p, %p", callback, p));
 
-        cur_nscb = schedule_list;
-        prev_nscb = NULL;
+	cur_nscb = schedule_list;
+	prev_nscb = NULL;
 
-        while (cur_nscb != NULL) {
-                if ((cur_nscb->callback ==  callback) &&
-                    (cur_nscb->p ==  p)) {
-                        /* item to remove */
+	while (cur_nscb != NULL) {
+		if ((cur_nscb->callback == callback) &&
+				(cur_nscb->p == p)) {
+			/* item to remove */
+			LOG(("callback entry %p removing  %p(%p)",
+					 cur_nscb, cur_nscb->callback, cur_nscb->p));
 
-                        LOG(("callback entry %p removing  %p(%p)",
-                             cur_nscb, cur_nscb->callback, cur_nscb->p));
+			/* remove callback */
+			unlnk_nscb = cur_nscb;
+			cur_nscb = unlnk_nscb->next;
 
-                        /* remove callback */
-                        unlnk_nscb = cur_nscb;
-                        cur_nscb = unlnk_nscb->next;
-
-                        if (prev_nscb == NULL) {
-                                schedule_list = cur_nscb;
-                        } else {
-                                prev_nscb->next = cur_nscb;
-                        }
-                        free (unlnk_nscb);
-                } else {
-                        /* move to next element */
-                        prev_nscb = cur_nscb;
-                        cur_nscb = prev_nscb->next;
-                }
-        }
+			if (prev_nscb == NULL) {
+				schedule_list = cur_nscb;
+			} else {
+				prev_nscb->next = cur_nscb;
+			}
+			free(unlnk_nscb);
+		} else {
+			/* move to next element */
+			prev_nscb = cur_nscb;
+			cur_nscb = prev_nscb->next;
+		}
+	}
 }
 
 /**
@@ -129,93 +138,64 @@
  * @return The number of milliseconds untill the next scheduled event
  * or -1 for no event.
  */
-int 
-schedule_run(void)
+
+int schedule_run(void)
 {
 	struct timeval tv;
-	struct timeval nexttime;
 	struct timeval rettime;
-        struct nscallback *cur_nscb;
-        struct nscallback *prev_nscb;
-        struct nscallback *unlnk_nscb;
+	struct nscallback *unlnk_nscb;
 
-        if (schedule_list == NULL)
-                return -1;
+	if (schedule_list == NULL)
+		return -1;
 
-	/* reset enumeration to the start of the list */
-        cur_nscb = schedule_list;
-        prev_nscb = NULL;
-	nexttime = cur_nscb->tv;
-
 	gettimeofday(&tv, NULL);
 
-        while (cur_nscb != NULL) {
-                if (timercmp(&tv, &cur_nscb->tv, >)) {
-                        /* scheduled time */
+	while ((schedule_list != NULL) && (timercmp(&tv, &schedule_list->tv, >=))) {
+		/* remove callback */
+		unlnk_nscb = schedule_list;
+		schedule_list = schedule_list->next;
 
-                        /* remove callback */
-                        unlnk_nscb = cur_nscb;
+		LOG(("callback entry %p running %p(%p)",
+				 unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p));
 
-                        if (prev_nscb == NULL) {
-                                schedule_list = unlnk_nscb->next;
-                        } else {
-                                prev_nscb->next = unlnk_nscb->next;
-                        }
+		/* call callback */
+		unlnk_nscb->callback(unlnk_nscb->p);
 
-                        LOG(("callback entry %p running %p(%p)",
-                             unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p));
-                        /* call callback */
-                        unlnk_nscb->callback(unlnk_nscb->p);
+		free(unlnk_nscb);
+	}
 
-                        free(unlnk_nscb);
+	if (schedule_list == NULL)
+		return -1;
 
-                        /* need to deal with callback modifying the list. */
-			if (schedule_list == NULL)
-				return -1; /* no more callbacks scheduled */
-			
-                        /* reset enumeration to the start of the list */
-                        cur_nscb = schedule_list;
-                        prev_nscb = NULL;
-			nexttime = cur_nscb->tv;
-                } else {
-			/* if the time to the event is sooner than the
-			 * currently recorded soonest event record it 
-			 */
-			if (timercmp(&nexttime, &cur_nscb->tv, >)) {
-				nexttime = cur_nscb->tv;
-			}
-                        /* move to next element */
-                        prev_nscb = cur_nscb;
-                        cur_nscb = prev_nscb->next;
-                }
-        }
-
 	/* make rettime relative to now */
-	timersub(&nexttime, &tv, &rettime);
+	timersub(&schedule_list->tv, &tv, &rettime);
 
-#if DEBUG_SCHEDULER
-	LOG(("returning time to next event as %ldms",(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000))); 
-#endif
+	/*LOG(("returning time to next event as %ldms",
+			(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000))); */
 	/* return next event time in milliseconds (24days max wait) */
-        return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
+	return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
 }
 
+/**
+ * Output a list of the current scheduled callbacks.
+ */
+
 void list_schedule(void)
 {
 	struct timeval tv;
-        struct nscallback *cur_nscb;
+	struct nscallback *cur_nscb;
 
 	gettimeofday(&tv, NULL);
 
-        LOG(("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec));
+	LOG(("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec));
 
-        cur_nscb = schedule_list;
+	cur_nscb = schedule_list;
 
-        while (cur_nscb != NULL) {
-                LOG(("Schedule %p at %ld:%ld",
-                     cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec));
-                cur_nscb = cur_nscb->next;
-        }
+	while (cur_nscb != NULL) {
+		LOG(("Schedule %p at %ld:%ld",
+				cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec));
+		cur_nscb = cur_nscb->next;
+	}
 }
 
 
