+
+ /** Return root message of the given thread
+ * @param id INTEGER id of a message
+ */
+ public function &root($id)
+ {
+ $parent =& $this->overview[$id];
+ while (!is_null($parent->parent)) {
+ $parent =& $parent->parent;
+ }
+ return $parent;
+ }
+
+ /** Return the last post id with the given subject
+ * @param subject
+ */
+ public function getPostId($subject)
+ {
+ $subject = trim($subject);
+ $id = max(array_keys($this->overview));
+ while (isset($this->overview[$id])) {
+ $test = $this->overview[$id]->subject;
+ if (function_exists('hook_formatDisplayHeader')) {
+ $val = hook_formatDisplayHeader('subject', $test, true);
+ if (is_array($val)) {
+ $test = banana_html_entity_decode($val[0]);
+ } else {
+ $test = banana_html_entity_decode($val);
+ }
+ }
+ $test = trim($test);
+ if ($test == $subject) {
+ return $id;
+ }
+ $id--;
+ }
+ return -1;
+ }
+
+ /** Returns previous thread root index
+ * @param id INTEGER message number
+ */
+ public function prevThread($id)
+ {
+ $root =& $this->root($id);
+ $last = null;
+ foreach ($this->roots as &$i) {
+ if ($i === $root) {
+ return $last;
+ }
+ $last = $i->id;
+ }
+ return $last;
+ }
+
+ /** Returns next thread root index
+ * @param id INTEGER message number
+ */
+ public function nextThread($id)
+ {
+ $root =& $this->root($id);
+ $ok = false;
+ foreach ($this->roots as &$i) {
+ if ($ok) {
+ return $i->id;
+ }
+ if ($i === $root) {
+ $ok = true;
+ }
+ }
+ return null;
+ }
+
+ /** Return prev post in the thread
+ * @param id INTEGER message number
+ */
+ public function prevPost($id)
+ {
+ $parent =& $this->overview[$id]->parent;
+ if (is_null($parent)) {
+ return null;
+ }
+ $last = $parent->id;
+ foreach ($parent->children as &$child) {
+ if ($child->id == $id) {
+ return $last;
+ }
+ $last = $child->id;
+ }
+ return null;
+ }
+
+ /** Return next post in the thread
+ * @param id INTEGER message number
+ */
+ public function nextPost($id)
+ {
+ $cur =& $this->overview[$id];
+ if (count($cur->children) != 0) {
+ return $cur->children[0]->id;
+ }
+
+ $parent =& $cur;
+ while (true) {
+ $parent =& $cur->parent;
+ if (is_null($parent)) {
+ return null;
+ }
+ $ok = false;
+ foreach ($parent->children as &$child) {
+ if ($ok) {
+ return $child->id;
+ }
+ if ($child === $cur) {
+ $ok = true;
+ }
+ }
+ $cur =& $parent;
+ }
+ return null;
+ }
+
+ /** Look for an unread message in the thread rooted by the message
+ * @param id INTEGER message number
+ */
+ private function _nextUnread(BananaSpoolHead &$cur)
+ {
+ if (!$cur->isread) {
+ return $cur->id;
+ }
+ foreach ($cur->children as &$child) {
+ $unread = $this->_nextUnread($child);
+ if (!is_null($unread)) {
+ return $unread;
+ }
+ }
+ return null;
+ }
+
+ /** Find next unread message
+ * @param id INTEGER message number
+ */
+ public function nextUnread($id = null)
+ {
+ if (!$this->unreadnb) {
+ return null;
+ }
+
+ if (!is_null($id)) {
+ // Look in message children
+ foreach ($this->overview[$id]->children as &$child) {
+ $next = $this->_nextUnread($child);
+ if (!is_null($next)) {
+ return $next;
+ }
+ }
+ }
+
+ // Look in current thread
+ if (is_null($id)) {
+ $cur = null;
+ } else {
+ $cur =& $this->overview[$id];
+ }
+ do {
+ if (is_null($cur)) {
+ $parent =& $cur;
+ $ok = true;
+ } else {
+ $parent =& $cur->parent;
+ $ok = false;
+ }
+ if (!is_null($parent)) {
+ $array =& $parent->children;
+ } else {
+ $array =& $this->roots;
+ }
+ foreach ($array as &$child) {
+ if ($ok) {
+ $next = $this->_nextUnread($child);
+ if (!is_null($next)) {
+ return $next;
+ }
+ }
+ if ($child === $cur) {
+ $ok = true;
+ }
+ }
+ $cur =& $parent;
+ } while(!is_null($cur));
+ return null;
+ }