diff -urpN chatroom.dev/chatroom.admin.inc chatroom.sandbox/chatroom.admin.inc
--- chatroom.dev/chatroom.admin.inc	1969-12-31 19:00:00.000000000 -0500
+++ chatroom.sandbox/chatroom.admin.inc	2008-06-30 16:07:15.000000000 -0400
@@ -0,0 +1,149 @@
+<?php
+// $Id$
+
+/**
+ *  @file
+ *  This provides the admin settings page for the Chatroom module.
+ */
+
+/**
+ * Menu callback; display site-wide chat room settings.
+ */
+function _chatroom_admin_settings() {
+  $form['chatroom_auto_archive'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Automatically archive old messages.'),
+    '#description' => t('If there are a lot of old messages, archiving will improve chat performance.'),
+    '#default_value' => variable_get('chatroom_auto_archive', FALSE),
+  );
+  $form['chatroom_block_update_interval'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Chat room block update interval'),
+    '#default_value' => variable_get('chatroom_block_update_interval', 5),
+    '#description' => t('Determines how often blocks should update active chat rooms, active chats, and on-line users.'),
+    '#size' => 2,
+    '#validate' => array('_chatroom_element_numeric_unsigned' => array()),
+  );
+  $form['chatroom_guest_user_prefix'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Guest user prefix'),
+    '#description' => t('Prefixed to guest ID to provide user name for anonymous users.'),
+    '#default_value' => variable_get('chatroom_guest_user_prefix', t('guest-')),
+    '#size' => 20,
+  );
+  $form['chatroom_chat_date_format'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Chat date format'),
+    '#attributes' => array('class' => 'custom-format'),
+    '#default_value' => variable_get('chatroom_chat_date_format', '* \S\e\n\t \a\t G:i'),
+    '#description' => t('Format for system time messages in chats. See the <a href="@url">PHP manual</a> for available options. This format is currently set to display as <span>%date</span>.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(time(), 'custom', variable_get('chatroom_chat_date_format', '* \S\e\n\t \a\t G:i')))),
+  );
+  if (function_exists('_smileys_list')) {
+    $form['chatroom_smileys_support'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Smileys module support'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+    );
+    $form['chatroom_smileys_support']['chatroom_smileys_enabled'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Enable Smileys module support.'),
+      '#default_value' => variable_get('chatroom_smileys_enabled', FALSE),
+    );
+    $form['chatroom_smileys_support']['chatroom_smileys_showtextentry'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show smileys in text entry box.'),
+      '#default_value' => variable_get('chatroom_smileys_enabled', FALSE) && variable_get('chatroom_smileys_showtextentry', FALSE),
+      '#disabled' => !variable_get('chatroom_smileys_enabled', FALSE),
+    );
+  }
+  $form['chatroom_alerts'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Chat alerts'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['chatroom_alerts']['chatroom_alerts'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable chat alerts.'),
+    '#description' => t('Checking this box will allow users to turn on alerts for chat events.'),
+    '#default_value' => variable_get('chatroom_alerts', FALSE),
+  );
+  $form['chatroom_alerts']['chatroom_alerts_default'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Turn alerts on by default.'),
+    '#description' => t('Check this box if you want chats to open with alerts on.'),
+    '#default_value' => variable_get('chatroom_alerts', FALSE) && variable_get('chatroom_alerts_default', FALSE),
+    '#disabled' => !variable_get('chatroom_alerts', FALSE),
+  );
+  $form['chatroom_alerts']['chatroom_custom_sounds'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Use custom sounds for chat alerts.'),
+    '#description' => t('Check this box if you want to replace default chat alert sounds with your own MP3s.'),
+    '#default_value' => variable_get('chatroom_alerts', FALSE) && variable_get('chatroom_custom_sounds', FALSE),
+    '#disabled' => !variable_get('chatroom_alerts', FALSE),
+  );
+  $path = file_directory_path() .'/chatroom';
+  $js = array();
+  if (file_exists("$path/message.mp3")) {
+    $js['messageSound'] = file_create_url("$path/message.mp3");
+  }
+  if (file_exists("$path/user.mp3")) {
+    $js['userSound'] = file_create_url("$path/user.mp3");
+  }
+  $form['chatroom_alerts']['chatroom_message_alert_upload'] = array(
+    '#type' => 'file',
+    '#title' => t('Custom new message sound'),
+    '#description' => isset($js['messageSound']) ? t('Replace the custom new message sound with a new MP3. !Listen to current file.', array('!Listen' => l(t('Listen'), $js['messageSound'], array('id' => 'sound_message')))) : t('Replace the default new message sound with your own MP3.'),
+    '#size' => 30,
+  );
+  $form['chatroom_alerts']['chatroom_user_alert_upload'] = array(
+    '#type' => 'file',
+    '#title' => t('Custom new user sound'),
+    '#description' => isset($js['userSound']) ? t('Replace the custom new user sound with a new MP3. !Listen to current file.', array('!Listen' => l(t('Listen'), $js['userSound'], array('id' => 'sound_user')))) : t('Replace the default new user sound with your own MP3.'),
+    '#size' => 30,
+  );
+  if (!empty($js)) {
+    global $base_path;
+    $js['basePath'] = $base_path;
+    $js['chatroomBase'] = drupal_get_path('module', 'chatroom');
+    drupal_add_js(array('chatroom' => $js), 'setting');
+    drupal_add_js(drupal_get_path('module', 'chatroom') .'/soundmanager2.js');
+    drupal_add_js('$("#sound_message").attr("href", "javascript:Drupal.chatroom.soundManager.play(\'message\')")', 'inline', 'footer');
+    drupal_add_js('$("#sound_user").attr("href", "javascript:Drupal.chatroom.soundManager.play(\'user\')")', 'inline', 'footer');
+  }
+  $form['#attributes'] = array('enctype' => 'multipart/form-data');
+  return system_settings_form($form);
+}
+
+function _chatroom_admin_settings_validate($form_id, $form_values) {
+  $path = file_directory_path();
+  if (file_check_directory($path, FILE_CREATE_DIRECTORY)) {
+    $path .= '/chatroom';
+    if (file_check_directory($path, FILE_CREATE_DIRECTORY)) {
+      $allowed_mime_types = array('audio/mpeg', 'audio/x-mpeg', 'audio/mp3', 'audio/x-mp3', 'audio/mpeg3', 'audio/x-mpeg3', 'audio/mpg', 'audio/x-mpg', 'audio/x-mpegaudio');
+      if ($user_sound = file_check_upload('chatroom_user_alert_upload')) {
+        if (!in_array($user_sound->filemime, $allowed_mime_types) && substr($user_sound->filename, -4) != '.mp3') {
+          form_set_error('chatroom_alerts][chatroom_user_alert_upload', t('New user sound must be an MP3 file.'));
+        }
+      }
+      if ($message_sound = file_check_upload('chatroom_message_alert_upload')) {
+        if (!in_array($message_sound->filemime, $allowed_mime_types) && substr($message_sound->filename, -4) != '.mp3') {
+          form_set_error('chatroom_alerts][chatroom_message_alert_upload', t('New message sound must be an MP3 file.'));
+        }
+      }
+    }
+  }
+}
+
+function _chatroom_admin_settings_submit($form_id, $form_values) {
+  $path = file_directory_path() .'/chatroom';
+  if (file_check_upload('chatroom_user_alert_upload')) {
+    file_save_upload('chatroom_user_alert_upload', "$path/user.mp3", FILE_EXISTS_REPLACE);
+  }
+  if (file_check_upload('chatroom_message_alert_upload')) {
+    file_save_upload('chatroom_message_alert_upload', "$path/message.mp3", FILE_EXISTS_REPLACE);
+  }
+  system_settings_form_submit($form_id, $form_values);
+}
+
diff -urpN chatroom.dev/chatroom.module chatroom.sandbox/chatroom.module
--- chatroom.dev/chatroom.module	2008-05-08 10:27:44.000000000 -0400
+++ chatroom.sandbox/chatroom.module	2008-06-30 16:03:51.000000000 -0400
@@ -83,143 +83,23 @@ function chatroom_menu($may_cache) {
  * Menu callback; display site-wide chat room settings.
  */
 function chatroom_admin_settings() {
-  $form['chatroom_auto_archive'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Automatically archive old messages.'),
-    '#description' => t('If there are a lot of old messages, archiving will improve chat performance.'),
-    '#default_value' => variable_get('chatroom_auto_archive', FALSE),
-  );
-  $form['chatroom_block_update_interval'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Chat room block update interval'),
-    '#default_value' => variable_get('chatroom_block_update_interval', 5),
-    '#description' => t('Determines how often blocks should update active chat rooms, active chats, and on-line users.'),
-    '#size' => 2,
-    '#validate' => array('_chatroom_element_numeric_unsigned' => array()),
-  );
-  $form['chatroom_guest_user_prefix'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Guest user prefix'),
-    '#description' => t('Prefixed to guest ID to provide user name for anonymous users.'),
-    '#default_value' => variable_get('chatroom_guest_user_prefix', t('guest-')),
-    '#size' => 20,
-  );
-  $form['chatroom_chat_date_format'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Chat date format'),
-    '#attributes' => array('class' => 'custom-format'),
-    '#default_value' => variable_get('chatroom_chat_date_format', '* \S\e\n\t \a\t G:i'),
-    '#description' => t('Format for system time messages in chats. See the <a href="@url">PHP manual</a> for available options. This format is currently set to display as <span>%date</span>.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(time(), 'custom', variable_get('chatroom_chat_date_format', '* \S\e\n\t \a\t G:i')))),
-  );
-  if (function_exists('_smileys_list')) {
-    $form['chatroom_smileys_support'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Smileys module support'),
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-    );
-    $form['chatroom_smileys_support']['chatroom_smileys_enabled'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Enable Smileys module support.'),
-      '#default_value' => variable_get('chatroom_smileys_enabled', FALSE),
-    );
-    $form['chatroom_smileys_support']['chatroom_smileys_showtextentry'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Show smileys in text entry box.'),
-      '#default_value' => variable_get('chatroom_smileys_enabled', FALSE) && variable_get('chatroom_smileys_showtextentry', FALSE),
-      '#disabled' => !variable_get('chatroom_smileys_enabled', FALSE),
-    );
-  }
-  $form['chatroom_alerts'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Chat alerts'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['chatroom_alerts']['chatroom_alerts'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Enable chat alerts.'),
-    '#description' => t('Checking this box will allow users to turn on alerts for chat events.'),
-    '#default_value' => variable_get('chatroom_alerts', FALSE),
-  );
-  $form['chatroom_alerts']['chatroom_alerts_default'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Turn alerts on by default.'),
-    '#description' => t('Check this box if you want chats to open with alerts on.'),
-    '#default_value' => variable_get('chatroom_alerts', FALSE) && variable_get('chatroom_alerts_default', FALSE),
-    '#disabled' => !variable_get('chatroom_alerts', FALSE),
-  );
-  $form['chatroom_alerts']['chatroom_custom_sounds'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Use custom sounds for chat alerts.'),
-    '#description' => t('Check this box if you want to replace default chat alert sounds with your own MP3s.'),
-    '#default_value' => variable_get('chatroom_alerts', FALSE) && variable_get('chatroom_custom_sounds', FALSE),
-    '#disabled' => !variable_get('chatroom_alerts', FALSE),
-  );
-  $path = file_directory_path() .'/chatroom';
-  $js = array();
-  if (file_exists("$path/message.mp3")) {
-    $js['messageSound'] = file_create_url("$path/message.mp3");
-  }
-  if (file_exists("$path/user.mp3")) {
-    $js['userSound'] = file_create_url("$path/user.mp3");
-  }
-  $form['chatroom_alerts']['chatroom_message_alert_upload'] = array(
-    '#type' => 'file',
-    '#title' => t('Custom new message sound'),
-    '#description' => isset($js['messageSound']) ? t('Replace the custom new message sound with a new MP3. !Listen to current file.', array('!Listen' => l(t('Listen'), $js['messageSound'], array('id' => 'sound_message')))) : t('Replace the default new message sound with your own MP3.'),
-    '#size' => 30,
-  );
-  $form['chatroom_alerts']['chatroom_user_alert_upload'] = array(
-    '#type' => 'file',
-    '#title' => t('Custom new user sound'),
-    '#description' => isset($js['userSound']) ? t('Replace the custom new user sound with a new MP3. !Listen to current file.', array('!Listen' => l(t('Listen'), $js['userSound'], array('id' => 'sound_user')))) : t('Replace the default new user sound with your own MP3.'),
-    '#size' => 30,
-  );
-  if (!empty($js)) {
-    global $base_path;
-    $js['basePath'] = $base_path;
-    $js['chatroomBase'] = drupal_get_path('module', 'chatroom');
-    drupal_add_js(array('chatroom' => $js), 'setting');
-    drupal_add_js(drupal_get_path('module', 'chatroom') .'/soundmanager2.js');
-    drupal_add_js('$("#sound_message").attr("href", "javascript:Drupal.chatroom.soundManager.play(\'message\')")', 'inline', 'footer');
-    drupal_add_js('$("#sound_user").attr("href", "javascript:Drupal.chatroom.soundManager.play(\'user\')")', 'inline', 'footer');
-  }
-  $form['#attributes'] = array('enctype' => 'multipart/form-data');
-  return system_settings_form($form);
+  include_once(drupal_get_path('module', 'chatroom') .'/chatroom.admin.inc');
+  return _chatroom_admin_settings();
 }
 
 function chatroom_admin_settings_validate($form_id, $form_values) {
-  $path = file_directory_path();
-  if (file_check_directory($path, FILE_CREATE_DIRECTORY)) {
-    $path .= '/chatroom';
-    if (file_check_directory($path, FILE_CREATE_DIRECTORY)) {
-      $allowed_mime_types = array('audio/mpeg', 'audio/x-mpeg', 'audio/mp3', 'audio/x-mp3', 'audio/mpeg3', 'audio/x-mpeg3', 'audio/mpg', 'audio/x-mpg', 'audio/x-mpegaudio');
-      if ($user_sound = file_check_upload('chatroom_user_alert_upload')) {
-        if (!in_array($user_sound->filemime, $allowed_mime_types) && substr($user_sound->filename, -4) != '.mp3') {
-          form_set_error('chatroom_alerts][chatroom_user_alert_upload', t('New user sound must be an MP3 file.'));
-        }
-      }
-      if ($message_sound = file_check_upload('chatroom_message_alert_upload')) {
-        if (!in_array($message_sound->filemime, $allowed_mime_types) && substr($message_sound->filename, -4) != '.mp3') {
-          form_set_error('chatroom_alerts][chatroom_message_alert_upload', t('New message sound must be an MP3 file.'));
-        }
-      }
-    }
-  }
+  include_once(drupal_get_path('module', 'chatroom') .'/chatroom.admin.inc');
+  return _chatroom_admin_settings_validate($form_id, $form_values);
 }
 
 function chatroom_admin_settings_submit($form_id, $form_values) {
-  $path = file_directory_path() .'/chatroom';
-  if (file_check_upload('chatroom_user_alert_upload')) {
-    file_save_upload('chatroom_user_alert_upload', "$path/user.mp3", FILE_EXISTS_REPLACE);
-  }
-  if (file_check_upload('chatroom_message_alert_upload')) {
-    file_save_upload('chatroom_message_alert_upload', "$path/message.mp3", FILE_EXISTS_REPLACE);
-  }
-  system_settings_form_submit($form_id, $form_values);
+  include_once(drupal_get_path('module', 'chatroom') .'/chatroom.admin.inc');
+  return _chatroom_admin_settings_submit($form_id, $form_values);
 }
 
+/**
+ *  Callback for $form['chatroom_block_update_interval']['#validate'] in chatroom_admin_settings
+ */
 function _chatroom_element_numeric_unsigned($element) {
   if (is_numeric($element['#value'])) {
     if ($element['#value'] == 0) {
@@ -234,6 +114,11 @@ function _chatroom_element_numeric_unsig
   }
 }
 
+/**
+ *  Implement hook_file_download.
+ *  Header for mp3 files on sound events.
+ *  @TODO: move this to chatroom_sound.module (or some other helper)
+ */
 function chatroom_file_download($file) {
   if (strpos($file, 'chatroom/') === 0 && pathinfo($file, PATHINFO_EXTENSION) == 'mp3') {
     return array('Content-type: audio/mpeg');
@@ -257,227 +142,44 @@ function chatroom_node_info() {
  * Implementation of hook_form().
  */
 function chatroom_form(&$node) {
-  global $user;
-  $form['title'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Name'),
-    '#default_value' => check_plain($node->title),
-    '#required' => TRUE
-  );
-  $form['body_filter']['body'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Description'),
-    '#default_value' => $node->body,
-    '#rows' => 3,
-    '#description' => t('Describe your chat room so other people will know if they want to join.'),
-  );
-  $form['body_filter']['format'] = filter_form($node->format);
-  $form['kicked_out_message'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Chat room kicked out message'),
-    '#default_value' => $node->chatroom->kicked_out_message,
-    '#rows' => 3,
-    '#description' => t('This text will appear on the page kicked out users are sent to. Defaults to, "You have been kicked out of %chat for misbehaving."', array('%chat' => t('chat-name'))),
-  );
-  $form['banned_message'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Chat room banned message'),
-    '#default_value' => $node->chatroom->banned_message,
-    '#rows' => 3,
-    '#description' => t('This text will appear on the page banned users are sent to. Defaults to, "You have been banned from %chatroom."', array('%chatroom' => t('chat-room'))),
-  );
-  if (!empty($node->chatroom->banned_users)) {
-    $form['chatroom_banned_users'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Manage banned users'),
-      '#collapsible' => TRUE,
-    );
-    foreach ($node->chatroom->banned_users as $banned_user) {
-      $banned_users[$banned_user->uid] = check_plain($banned_user->name);
-    }
-    $form['chatroom_banned_users']['unban_list'] = array(
-      '#type' => 'checkboxes',
-      '#options' => $banned_users,
-      '#description' => t('Check the users you would like to unban')
-    );
-  }
-  $form['chat_settings'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Chat settings'),
-    '#collapsible' => TRUE,
-  );
-  $form['chat_settings']['poll_freq'] = array(
-    '#type' => 'select',
-    '#title' => t('Update frequency'),
-    '#default_value' => empty($node->chatroom->poll_freq) ? 1 : $node->chatroom->poll_freq / 1000,
-    '#options' => drupal_map_assoc(range(1,10)),
-    '#description' => t('How many seconds between each request for updates from the server.'),
-  );
-  $form['chat_settings']['idle_freq'] = array(
-    '#type' => 'select',
-    '#title' => t('Idle time'),
-    '#default_value' => empty($node->chatroom->idle_freq) ? 60 : $node->chatroom->idle_freq / 1000,
-    '#options' => drupal_map_assoc(array(20, 40, 60, 80, 100, 120, 140, 160, 180)),
-    '#description' => t('How many seconds between each message before a last message time is shown in the chat.'),
-  );
-  $old_msg_range = array();
-  for ($i = 1; $i <= 25; $i++) {
-    $old_msg_range[$i] = $i * 10;
-  }
-  $form['chat_settings']['old_msg_count'] = array(
-    '#type' => 'select',
-    '#title' => t('Old messages'),
-    '#description' => t('How many old messages to show when entering a chat.'),
-    '#default_value' => empty($node->chatroom->old_msg_count) ? 20 : $node->chatroom->old_msg_count,
-    '#options' => drupal_map_assoc($old_msg_range),
-  );
-  if (!empty($node->chatroom->chats)) {
-    foreach ($node->chatroom->chats as $chat) {
-      if ($chat->section != 'archives') {
-        $chats[$chat->ccid] = check_plain($chat->chatname);
-      }
-      else {
-        $closed_chats[$chat->ccid] = check_plain($chat->chatname);
-      }
-    }
-    if (!empty($chats)) {
-      $form['chatroom_chats'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Manage open chats'),
-        '#collapsible' => TRUE,
-        '#collapsed' => FALSE,
-      );
-      $form['chatroom_chats']['chat_list'] = array(
-        '#type' => 'checkboxes',
-        '#options' => $chats,
-        '#description' => t('Check the chats you would like to close')
-      );
-    }
-    if (!empty($closed_chats)) {
-      $form['closed_chats'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Manage archived chats'),
-        '#collapsible' => TRUE,
-        '#collapsed' => FALSE,
-      );
-      $form['closed_chats']['closed_chat_list'] = array(
-        '#type' => 'checkboxes',
-        '#options' => $closed_chats,
-        '#description' => t('Check the chats you would like to delete')
-      );
-    }
-  }
-  return $form;
+  include_once(drupal_get_path('module', 'chatroom') .'/chatroom.node.inc');
+  return _chatroom_form($node);
 }
 
 /**
  * Implementation of hook_insert()
  */
 function chatroom_insert($node) {
-  $result = db_query("
-    INSERT INTO {chatroom}
-    (nid, poll_freq, idle_freq, old_msg_count, kicked_out_message, banned_message, modified)
-    VALUES (%d, %d, %d, %d, '%s', '%s', %d)
-  ", array(
-    $node->nid,
-    1000 * $node->poll_freq,
-    1000 * $node->idle_freq,
-    $node->old_msg_count,
-    $node->kicked_out_message,
-    $node->banned_message,
-    time()
-  ));
-  if ($result) {
-    chatroom_block_update_cache('chatrooms');
-  }
+  include_once(drupal_get_path('module', 'chatroom') .'/chatroom.node.inc');
+  return _chatroom_insert($node);
 }
 
 /**
  * Implementation of hook_update()
  */
 function chatroom_update($node) {
-  db_query("
-    UPDATE {chatroom}
-    SET
-      poll_freq = %d,
-      idle_freq = %d,
-      old_msg_count = %d,
-      kicked_out_message = '%s',
-      banned_message = '%s',
-      modified = %d
-    WHERE nid = %d
-  ", array(
-    1000 * $node->poll_freq,
-    1000 * $node->idle_freq,
-    $node->old_msg_count,
-    $node->kicked_out_message,
-    $node->banned_message,
-    time(),
-    $node->nid,
-  ));
-  if (isset($node->chat_list)) {
-    foreach ($node->chat_list as $chat_id) {
-      if ($chat_id > 0) {
-        chatroom_archive_chat($chat_id);
-        file_delete(_chatroom_get_cache_file("chat.$chat_id"));
-        db_query("
-          INSERT INTO {chatroom_msg_archive} (cmid, ccid, uid, msg_type, msg, session_id, recipient, modified)
-          SELECT * FROM {chatroom_msg} WHERE ccid = %d
-        ", $chat_id);
-      }
-    }
-    chatroom_block_update_cache('chatrooms');
-    chatroom_block_update_cache('chats');
-  }
-  if (isset($node->closed_chat_list)) {
-    foreach ($node->closed_chat_list as $chat_id) {
-      if (!empty($chat_id)) {
-        chatroom_chat_delete($chat_id);
-      }
-    }
-  }
-  if (isset($node->unban_list)) {
-    db_query('DELETE FROM {chatroom_ban_list} WHERE crid = %d AND uid IN (%s)', $node->chatroom->crid, implode(',', $node->unban_list));
-  }
+  include_once(drupal_get_path('module', 'chatroom') .'/chatroom.node.inc');
+  return _chatroom_update($node);
 }
 
 /**
  * Implementation of hook_delete().
  */
 function chatroom_delete(&$node) {
-  db_query('DELETE FROM {chatroom} WHERE nid = %d', $node->nid);
-  db_query("DELETE FROM {chatroom_chat} WHERE crid = %d", $node->chatroom->crid);
-  db_query('DELETE FROM {chatroom_ban_list} WHERE crid = %d', $node->chatroom->crid);
-  if (isset($node->chatroom) && !empty($node->chatroom->chats)) {
-    $ccids = implode(',', array_keys($node->chatroom->chats));
-    db_query('DELETE FROM {chatroom_msg} WHERE ccid IN (%s)', $ccids);
-    db_query('DELETE FROM {chatroom_online_list} WHERE ccid IN (%s)', $ccids);
-    db_query('DELETE FROM {chatroom_msg_archive} WHERE ccid IN (%s)', $ccids);
-    foreach ($node->chatroom->chats as $chat_id => $name) {
-      file_delete(_chatroom_get_cache_file("chat.$chat_id"));
-    }
-  }
-  chatroom_block_update_cache('chatrooms');
-  chatroom_block_update_cache('chats');
+  include_once(drupal_get_path('module', 'chatroom') .'/chatroom.node.inc');
+  return _chatroom_delete($node);
 }
 
 /**
  * Implementation of hook_load().
  */
 function chatroom_load($node) {
-  $chatroom->chatroom = db_fetch_object(db_query('SELECT * FROM {chatroom} WHERE nid = %d', $node->nid));
-  if (!empty($chatroom->chatroom)) {
-    $chatroom->chatroom->banned_users = chatroom_get_banned_users($chatroom->chatroom->crid);
-    // If the user is banned, don't load chats.
-    if (!chatroom_is_banned_user($chatroom->chatroom->crid)) {
-      $chatroom->chatroom->chats = chatroom_get_room_summary($chatroom->chatroom->crid);
-    }
-  }
-  return $chatroom;
+  include_once(drupal_get_path('module', 'chatroom') .'/chatroom.node.inc');
+  return _chatroom_load($node);
 }
 
 /**
- * returns a the list of chats for a given room
+ * returns a the list of channels for a given room
  */
 function chatroom_get_room_summary($room_id) {
   $result = db_query("
@@ -532,6 +234,7 @@ function chatroom_get_room_summary($room
 
 /**
  * Format a message for display in a summary table.
+ * @TODO: we'll allow a $msg to be altered for smilies & the like.
  */
 function chatroom_get_msg_info($msg) {
   if (function_exists('_smileys_list') && variable_get('chatroom_smileys_enabled', FALSE)) {
@@ -561,64 +264,8 @@ function chatroom_get_banned_users($crid
  * Implementation of hook_view().
  */
 function chatroom_view($node, $teaser = FALSE, $page = FALSE) {
-  $node = node_prepare($node);
-
-  if ($page) {
-    $bc = drupal_get_breadcrumb();
-    if (!empty($bc)) {
-      $bc[] = l('Chat rooms', 'chatrooms');
-      drupal_set_breadcrumb($bc);
-    }
-  }
-  if (!$teaser) {
-    // if the user is banned, just tell them why
-    if (chatroom_is_banned_user($node->chatroom->crid)) {
-      $node->content['body']['#value'] = !empty($node->chatroom->banned_message) ? $node->chatroom->banned_message : t('You have been banned from %chatroom.', array('%chatroom' => $node->title));
-    }
-    else {
-      // if the user can create chats, show the form
-      if (user_access('create chats')) {
-        $node->content['add_chat'] = array(
-          '#value' => drupal_get_form('chatroom_create_chat_form', $node->chatroom->crid),
-          '#weight' => 1,
-        );
-      }
-      // if there are some chats, build some tables to display them
-      if (!empty($node->chatroom->chats) > 0) {
-        foreach ($node->chatroom->chats as $chat) {
-          $type = $chat->section == 'chat' ? 'open' : 'archived';
-          $rows[$type][] = array(
-            array('data' => l($chat->chatname, "chatrooms/$chat->section/$chat->ccid")),
-            array('data' => $chat->msg_count),
-            array('data' => $chat->msg_info)
-          );
-        }
-        if (!empty($rows['open'])) {
-          $node->content['open_chats']['#weight'] = 2;
-          $node->content['open_chats']['title'] = array(
-            '#value' => '<h2>'. t('Open chats in this room') .'</h2>',
-            '#weight' => 0,
-          );
-          $node->content['open_chats']['table'] = array(
-            '#value' => theme('table', array(t('Chat name'), t('Message count'), t('Last message')), $rows['open']),
-            '#weight' => 1,
-          );
-        }
-        if (!empty($rows['archived'])) {
-          $node->content['archived_chats']['#weight'] = 3;
-          $node->content['archived_chats']['header'] = array(
-            '#value' => '<h2>'. t('Archived chats in this room') .'</h2>',
-            '#weight' => 0,
-          );
-          $node->content['archived_chats']['table'] = array(
-            '#value' => theme('table', array(t('Chat name'), t('Message count'), t('When archived')), $rows['archived']),
-            '#weight' => 1,
-          );
-        }
-      }
-    }
-  }
-  return $node;
+  include_once(drupal_get_path('module', 'chatroom') .'/chatroom.node.inc');
+  return chatroom_view($node, $teaser, $page);
 }
 
 /**
diff -urpN chatroom.dev/chatroom.node.inc chatroom.sandbox/chatroom.node.inc
--- chatroom.dev/chatroom.node.inc	1969-12-31 19:00:00.000000000 -0500
+++ chatroom.sandbox/chatroom.node.inc	2008-06-30 16:09:13.000000000 -0400
@@ -0,0 +1,295 @@
+<?php
+// $Id$
+
+/**
+ *  @file
+ *  This file defines various node hook functions, to create functionality concerning Chatroom type nodes.
+ */
+
+/**
+ * Implementation of hook_form().
+ */
+function _chatroom_form(&$node) {
+  global $user;
+  $form['title'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Name'),
+    '#default_value' => check_plain($node->title),
+    '#required' => TRUE
+  );
+  $form['body_filter']['body'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Description'),
+    '#default_value' => $node->body,
+    '#rows' => 3,
+    '#description' => t('Describe your chat room so other people will know if they want to join.'),
+  );
+  $form['body_filter']['format'] = filter_form($node->format);
+  $form['kicked_out_message'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Chat room kicked out message'),
+    '#default_value' => $node->chatroom->kicked_out_message,
+    '#rows' => 3,
+    '#description' => t('This text will appear on the page kicked out users are sent to. Defaults to, "You have been kicked out of %chat for misbehaving."', array('%chat' => t('chat-name'))),
+  );
+  $form['banned_message'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Chat room banned message'),
+    '#default_value' => $node->chatroom->banned_message,
+    '#rows' => 3,
+    '#description' => t('This text will appear on the page banned users are sent to. Defaults to, "You have been banned from %chatroom."', array('%chatroom' => t('chat-room'))),
+  );
+  if (!empty($node->chatroom->banned_users)) {
+    $form['chatroom_banned_users'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Manage banned users'),
+      '#collapsible' => TRUE,
+    );
+    foreach ($node->chatroom->banned_users as $banned_user) {
+      $banned_users[$banned_user->uid] = check_plain($banned_user->name);
+    }
+    $form['chatroom_banned_users']['unban_list'] = array(
+      '#type' => 'checkboxes',
+      '#options' => $banned_users,
+      '#description' => t('Check the users you would like to unban')
+    );
+  }
+  $form['chat_settings'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Chat settings'),
+    '#collapsible' => TRUE,
+  );
+  $form['chat_settings']['poll_freq'] = array(
+    '#type' => 'select',
+    '#title' => t('Update frequency'),
+    '#default_value' => empty($node->chatroom->poll_freq) ? 1 : $node->chatroom->poll_freq / 1000,
+    '#options' => drupal_map_assoc(range(1,10)),
+    '#description' => t('How many seconds between each request for updates from the server.'),
+  );
+  $form['chat_settings']['idle_freq'] = array(
+    '#type' => 'select',
+    '#title' => t('Idle time'),
+    '#default_value' => empty($node->chatroom->idle_freq) ? 60 : $node->chatroom->idle_freq / 1000,
+    '#options' => drupal_map_assoc(array(20, 40, 60, 80, 100, 120, 140, 160, 180)),
+    '#description' => t('How many seconds between each message before a last message time is shown in the chat.'),
+  );
+  $old_msg_range = array();
+  for ($i = 1; $i <= 25; $i++) {
+    $old_msg_range[$i] = $i * 10;
+  }
+  $form['chat_settings']['old_msg_count'] = array(
+    '#type' => 'select',
+    '#title' => t('Old messages'),
+    '#description' => t('How many old messages to show when entering a chat.'),
+    '#default_value' => empty($node->chatroom->old_msg_count) ? 20 : $node->chatroom->old_msg_count,
+    '#options' => drupal_map_assoc($old_msg_range),
+  );
+  if (!empty($node->chatroom->chats)) {
+    foreach ($node->chatroom->chats as $chat) {
+      if ($chat->section != 'archives') {
+        $chats[$chat->ccid] = check_plain($chat->chatname);
+      }
+      else {
+        $closed_chats[$chat->ccid] = check_plain($chat->chatname);
+      }
+    }
+    if (!empty($chats)) {
+      $form['chatroom_chats'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Manage open chats'),
+        '#collapsible' => TRUE,
+        '#collapsed' => FALSE,
+      );
+      $form['chatroom_chats']['chat_list'] = array(
+        '#type' => 'checkboxes',
+        '#options' => $chats,
+        '#description' => t('Check the chats you would like to close')
+      );
+    }
+    if (!empty($closed_chats)) {
+      $form['closed_chats'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Manage archived chats'),
+        '#collapsible' => TRUE,
+        '#collapsed' => FALSE,
+      );
+      $form['closed_chats']['closed_chat_list'] = array(
+        '#type' => 'checkboxes',
+        '#options' => $closed_chats,
+        '#description' => t('Check the chats you would like to delete')
+      );
+    }
+  }
+  return $form;
+}
+
+/**
+ * Implementation of hook_insert()
+ */
+function _chatroom_insert($node) {
+  $result = db_query("
+    INSERT INTO {chatroom}
+    (nid, poll_freq, idle_freq, old_msg_count, kicked_out_message, banned_message, modified)
+    VALUES (%d, %d, %d, %d, '%s', '%s', %d)
+  ", array(
+    $node->nid,
+    1000 * $node->poll_freq,
+    1000 * $node->idle_freq,
+    $node->old_msg_count,
+    $node->kicked_out_message,
+    $node->banned_message,
+    time()
+  ));
+  if ($result) {
+    chatroom_block_update_cache('chatrooms');
+  }
+}
+
+/**
+ * Implementation of hook_update()
+ */
+function _chatroom_update($node) {
+  db_query("
+    UPDATE {chatroom}
+    SET
+      poll_freq = %d,
+      idle_freq = %d,
+      old_msg_count = %d,
+      kicked_out_message = '%s',
+      banned_message = '%s',
+      modified = %d
+    WHERE nid = %d
+  ", array(
+    1000 * $node->poll_freq,
+    1000 * $node->idle_freq,
+    $node->old_msg_count,
+    $node->kicked_out_message,
+    $node->banned_message,
+    time(),
+    $node->nid,
+  ));
+  if (isset($node->chat_list)) {
+    foreach ($node->chat_list as $chat_id) {
+      if ($chat_id > 0) {
+        chatroom_archive_chat($chat_id);
+        file_delete(_chatroom_get_cache_file("chat.$chat_id"));
+        db_query("
+          INSERT INTO {chatroom_msg_archive} (cmid, ccid, uid, msg_type, msg, session_id, recipient, modified)
+          SELECT * FROM {chatroom_msg} WHERE ccid = %d
+        ", $chat_id);
+      }
+    }
+    chatroom_block_update_cache('chatrooms');
+    chatroom_block_update_cache('chats');
+  }
+  if (isset($node->closed_chat_list)) {
+    foreach ($node->closed_chat_list as $chat_id) {
+      if (!empty($chat_id)) {
+        chatroom_chat_delete($chat_id);
+      }
+    }
+  }
+  if (isset($node->unban_list)) {
+    db_query('DELETE FROM {chatroom_ban_list} WHERE crid = %d AND uid IN (%s)', $node->chatroom->crid, implode(',', $node->unban_list));
+  }
+}
+
+/**
+ * Implementation of hook_delete().
+ */
+function _chatroom_delete(&$node) {
+  db_query('DELETE FROM {chatroom} WHERE nid = %d', $node->nid);
+  db_query("DELETE FROM {chatroom_chat} WHERE crid = %d", $node->chatroom->crid);
+  db_query('DELETE FROM {chatroom_ban_list} WHERE crid = %d', $node->chatroom->crid);
+  if (isset($node->chatroom) && !empty($node->chatroom->chats)) {
+    $ccids = implode(',', array_keys($node->chatroom->chats));
+    db_query('DELETE FROM {chatroom_msg} WHERE ccid IN (%s)', $ccids);
+    db_query('DELETE FROM {chatroom_online_list} WHERE ccid IN (%s)', $ccids);
+    db_query('DELETE FROM {chatroom_msg_archive} WHERE ccid IN (%s)', $ccids);
+    foreach ($node->chatroom->chats as $chat_id => $name) {
+      file_delete(_chatroom_get_cache_file("chat.$chat_id"));
+    }
+  }
+  chatroom_block_update_cache('chatrooms');
+  chatroom_block_update_cache('chats');
+}
+
+/**
+ * Implementation of hook_load().
+ */
+function _chatroom_load($node) {
+  $chatroom->chatroom = db_fetch_object(db_query('SELECT * FROM {chatroom} WHERE nid = %d', $node->nid));
+  if (!empty($chatroom->chatroom)) {
+    $chatroom->chatroom->banned_users = chatroom_get_banned_users($chatroom->chatroom->crid);
+    // If the user is banned, don't load chats.
+    if (!chatroom_is_banned_user($chatroom->chatroom->crid)) {
+      $chatroom->chatroom->chats = chatroom_get_room_summary($chatroom->chatroom->crid);
+    }
+  }
+  return $chatroom;
+}
+
+/**
+ * Implementation of hook_view().
+ */
+function _chatroom_view($node, $teaser = FALSE, $page = FALSE) {
+  $node = node_prepare($node);
+
+  if ($page) {
+    $bc = drupal_get_breadcrumb();
+    if (!empty($bc)) {
+      $bc[] = l('Chat rooms', 'chatrooms');
+      drupal_set_breadcrumb($bc);
+    }
+  }
+  if (!$teaser) {
+    // if the user is banned, just tell them why
+    if (chatroom_is_banned_user($node->chatroom->crid)) {
+      $node->content['body']['#value'] = !empty($node->chatroom->banned_message) ? $node->chatroom->banned_message : t('You have been banned from %chatroom.', array('%chatroom' => $node->title));
+    }
+    else {
+      // if the user can create chats, show the form
+      if (user_access('create chats')) {
+        $node->content['add_chat'] = array(
+          '#value' => drupal_get_form('chatroom_create_chat_form', $node->chatroom->crid),
+          '#weight' => 1,
+        );
+      }
+      // if there are some chats, build some tables to display them
+      if (!empty($node->chatroom->chats) > 0) {
+        foreach ($node->chatroom->chats as $chat) {
+          $type = $chat->section == 'chat' ? 'open' : 'archived';
+          $rows[$type][] = array(
+            array('data' => l($chat->chatname, "chatrooms/$chat->section/$chat->ccid")),
+            array('data' => $chat->msg_count),
+            array('data' => $chat->msg_info)
+          );
+        }
+        if (!empty($rows['open'])) {
+          $node->content['open_chats']['#weight'] = 2;
+          $node->content['open_chats']['title'] = array(
+            '#value' => '<h2>'. t('Open chats in this room') .'</h2>',
+            '#weight' => 0,
+          );
+          $node->content['open_chats']['table'] = array(
+            '#value' => theme('table', array(t('Chat name'), t('Message count'), t('Last message')), $rows['open']),
+            '#weight' => 1,
+          );
+        }
+        if (!empty($rows['archived'])) {
+          $node->content['archived_chats']['#weight'] = 3;
+          $node->content['archived_chats']['header'] = array(
+            '#value' => '<h2>'. t('Archived chats in this room') .'</h2>',
+            '#weight' => 0,
+          );
+          $node->content['archived_chats']['table'] = array(
+            '#value' => theme('table', array(t('Chat name'), t('Message count'), t('When archived')), $rows['archived']),
+            '#weight' => 1,
+          );
+        }
+      }
+    }
+  }
+  return $node;
+}
+
