diff --git ecard/ecard.install ecard/ecard.install
index 4ab4f60..0bfe9b2 100644
--- ecard/ecard.install
+++ ecard/ecard.install
@@ -40,6 +40,13 @@ function ecard_schema() {
         'not null' => TRUE,
         'default' => 0,
       ),
+      'field_name' => array(
+        'description' => 'The field name of the ecard field.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
       'uid' => array(
         'description' => 'The user id of the author of the ecard.',
         'type' => 'int',
@@ -87,8 +94,20 @@ function ecard_schema() {
         'not null' => TRUE,
         'default' => 0,
       ),
-      'timestamp' => array(
-        'description' => 'The timestamp of the ecard.',
+      'created' => array(
+        'description' => 'The timestamp the ecard was created.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'sent_time' => array(
+        'description' => 'The timestamp the ecard was sent.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'scheduled_time' => array(
+        'description' => 'The timestamp the ecard is/was scheduled to be sent at.',
         'type' => 'int',
         'not null' => TRUE,
         'default' => 0,
@@ -222,3 +241,39 @@ function ecard_update_7002() {
   db_add_field('ecard', 'notify', $spec);
 }
 
+/**
+ * Rename 'timestamp' to 'created', and add in 'sent_time' and 'scheduled_time'
+ * fields.
+ */
+function ecard_update_7003() {
+  $spec = array(
+    'description' => 'The timestamp the ecard was created.',
+    'type' => 'int',
+    'not null' => TRUE,
+    'default' => 0,
+  );
+  db_change_field('ecard', 'timestamp', 'created', $spec);
+  $spec = array(
+    'description' => 'The timestamp the ecard was sent.',
+    'type' => 'int',
+    'not null' => TRUE,
+    'default' => 0,
+  );
+  db_add_field('ecard', 'sent_time', $spec);
+  $spec = array(
+    'description' => 'The timestamp the ecard is/was scheduled to be sent at.',
+    'type' => 'int',
+    'not null' => TRUE,
+    'default' => 0,
+  );
+  db_add_field('ecard', 'scheduled_time', $spec);
+  $spec = array(
+    'description' => 'The field name of the ecard field.',
+    'type' => 'varchar',
+    'length' => 128,
+    'not null' => TRUE,
+    'default' => '',
+  );
+  db_add_field('ecard', 'field_name', $spec);
+}
+
diff --git ecard/ecard.module ecard/ecard.module
index 6a41ba1..1d7061d 100644
--- ecard/ecard.module
+++ ecard/ecard.module
@@ -42,6 +42,55 @@ function ecard_permission() {
 }
 
 /**
+ * Implements hook_cron().
+ */
+function ecard_cron() {
+  $hashes = db_select('ecard', 'e')
+    ->fields('e', array('hash'))
+    ->condition('e.sent', 0)
+    ->condition('e.scheduled_time', 0, '<>')
+    ->condition('e.scheduled_time', REQUEST_TIME, '<')
+    ->orderBy('e.scheduled_time', 'ASC')
+    ->orderBy('e.created', 'ASC')
+    ->range(0, 50) // @todo - make this configurable?
+    ->execute()
+    ->fetchCol();
+  if (empty($hashes)) {
+    return;
+  }
+
+  $ecards = ecard_read($hashes);
+  if (!empty($ecards)) {
+    $queue = DrupalQueue::get('ecard_scheduled_mails');
+    foreach ($ecards as $ecard) {
+      // Configure some useful variables used when sending the ecard.
+      $ecard_entity = entity_load($ecard->entity_type, array($ecard->entity_id));
+      $entity = array_shift($ecard_entity);
+      $entity_uri = entity_uri($ecard->entity_type, $entity);
+      $field = field_info_instance($ecard->entity_type, $ecard->field_name, $ecard->bundle);
+      $ecard->mail = $field['settings'];
+      $ecard->entity_path = $entity_uri['path'];
+      $ecard->ecard_url = url($ecard->entity_path, array('query' => array('ecard' => $ecard->hash), 'absolute' => TRUE));
+      $ecard->ecard_copy_url = url($ecard->entity_path, array('query' => array('ecard' => $ecard->hash, 'preview' => 1), 'absolute' => TRUE));
+      $ecard->site_name = variable_get('site_name', 'Default site name');
+
+      // Queue the ecard for sending.
+      $queue->createItem($ecard);
+    }
+  }
+}
+
+/**
+ * Implements hook_cron_queue_info().
+ */
+function ecard_cron_queue_info() {
+  $queues['ecard_scheduled_mails'] = array(
+    'worker callback' => 'ecard_mail_send_ecard', 
+  );
+  return $queues;
+}
+
+/**
  * Implements views_api().
  */
 function ecard_views_api() {
diff --git ecard/includes/ecard.entity.inc ecard/includes/ecard.entity.inc
index 4509399..51548ec 100644
--- ecard/includes/ecard.entity.inc
+++ ecard/includes/ecard.entity.inc
@@ -37,17 +37,19 @@ function ecard_entity_info() {
  *    text:       the content of the ecard.
  *
  *   Optional keys:
- *    hash:       the unique identifier of the ecard. Pass for update.
- *    pick_up:    flag if the ecard already picked up. Default 0.
- *    sent:       flag if the ecard is sent. Default 0.
- *    notify:     flag if the sender should be notified when the ecard is picked up. Default 0.
+ *    hash:            the unique identifier of the ecard. Pass for update.
+ *    pick_up:         flag if the ecard already picked up. Default 0.
+ *    sent:            flag if the ecard is sent. Default 0.
+ *    notify:          flag if the sender should be notified when the ecard is picked up. Default 0.
+ *    sent_time:       timestamp of when the card was sent. Default to 0.
+ *    scheduled_time:  timestamp of when the card is/was scheduled to be sent. Default to 0.
  *
  * @return
  *  Returns the ecard object if the entity was saved successfully.
  *  Otherwise it returns FALSE.
  */
 function ecard_create($ecard) {
-  $ecard['timestamp'] = time();
+  $ecard['created'] = time();
   if (!ecard_check_hash($ecard)) {
     $hash_base = $ecard['mail_from'] . uniqid();
     $ecard['hash'] = md5($hash_base);
diff --git ecard/includes/ecard.field.inc ecard/includes/ecard.field.inc
index 752956a..23b980a 100644
--- ecard/includes/ecard.field.inc
+++ ecard/includes/ecard.field.inc
@@ -168,6 +168,11 @@ function ecard_field_instance_settings_form($field, $instance) {
     '#title' => t('Automatically fill in sender name and e-mail for logged in users.'),
     '#default_value' => isset($instance['settings']['ecard_settings']['ecard_fill_in_name_e-mail']) ? $instance['settings']['ecard_settings']['ecard_fill_in_name_e-mail'] : 0,
   );
+  $form['ecard_settings']['ecard_enable_scheduling'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Allow the sender to choose the date when the ecard should be sent.'),
+    '#default_value' => isset($instance['settings']['ecard_settings']['ecard_enable_scheduling']) ? $instance['settings']['ecard_settings']['ecard_enable_scheduling'] : 0,
+  );
 
   // Ecard Delivery message.
   $form['letter'] = array('#title' => t('Delivery message'), '#type' => 'fieldset', '#collapsed' => TRUE, '#collapsible' => TRUE);
@@ -431,9 +436,8 @@ function ecard_field_formatter_view($entity_type, $entity, $field, $instance, $l
         // Send notice email if necessary.
         $notice = $instance['settings']['notice'];
         if ($notice['ecard_notice_enabled'] && $ecard->notify) {
-          $uri = entity_uri($instance['entity_type'], $entity);
-          $ecard->entity_path = $uri['path'];
-          $ecard->ecard_url = url($ecard->entity_path, array('query' => array('ecard' => $ecard->hash), 'absolute' => TRUE));
+          $ecard->entity_path = $args['path'];
+          $ecard->ecard_url = url($args['entity_path'], array('query' => array('ecard' => $ecard->hash), 'absolute' => TRUE));
           $ecard->site_name = variable_get('site_name', 'Default site name');
           $ecard->mail = array(
             'letter' => $instance['settings']['letter'],
@@ -485,6 +489,7 @@ function ecard_get_args($entity_type, $entity, $field, $instance) {
     'bundle' => $instance['bundle'],
     'entity_id' => $entity_ids[0],
     'entity_path' => $entity_uri['path'],
+    'field_name' => $field['field_name'],
   );
 
   if (!empty($instance['settings']['ecard_settings']['ecard_redirect'])) {
@@ -559,6 +564,14 @@ function ecard_form_create_ecard($form, &$form_state, $settings = array()) {
     //'#tree' => FALSE,
   );
 
+  if ($settings['settings']['ecard_enable_scheduling']) {
+    $form['ecard_scheduled_date'] = array(
+      '#title' => t('Schedule your ecard for sending'),
+      '#type' => 'date',
+      '#description' => t("Enter today's date or leave blank to send the card immediately"),
+    );
+  }
+
   if ($settings['mail']['notice']['ecard_notice_enabled']) {
     $form['ecard_send_notice'] = array(
       '#title' => t('Notify me when the e-card is picked up'),
@@ -584,12 +597,25 @@ function ecard_form_create_ecard($form, &$form_state, $settings = array()) {
  * Validation of the form ecard_form_create_ecard.
  */
 function ecard_form_create_ecard_validate($form, &$form_state) {
-  if (!valid_email_address($form['mail_from']['#value'])) {
+  if (!valid_email_address($form_state['values']['mail_from'])) {
     form_set_error('', t('You must enter a valid e-mail adress.'));
   }
-  if (!valid_email_address($form['mail_to']['#value'])) {
+  if (!valid_email_address($form_state['values']['mail_to'])) {
     form_set_error('', t('You must enter a valid e-mail adress.'));
   }
+  if (!empty($form_state['values']['ecard_scheduled_date'])) {
+    $date = $form_state['values']['ecard_scheduled_date'];
+    // Check date is not yesterday or before, but still allow today.
+    $formatted_date = mktime(23, 59, 59, $date['month'], $date['day'], $date['year']);
+    if ($formatted_date < time()) {
+      form_set_error('ecard_scheduled_date', t('Please enter a date in the future to send the ecards on.'));
+    }
+    else {
+      // Default time to midnight.
+      $new_date = mktime(0, 0, 0, $date['month'], $date['day'], $date['year']);
+      form_set_value(array('#parents' => array('ecard_scheduled_timestamp')), $new_date, $form_state);
+    }
+  }
 }
 
 /**
@@ -600,36 +626,62 @@ function ecard_form_create_ecard_submit($form, &$form_state) {
   $ecard['entity_type'] = $form_state['build_info']['args'][0]['entity_type'];
   $ecard['bundle'] = $form_state['build_info']['args'][0]['bundle'];
   $ecard['entity_id'] = $form_state['build_info']['args'][0]['entity_id'];
+  $ecard['field_name'] = $form_state['build_info']['args'][0]['field_name'];
   $ecard['uid'] = $GLOBALS['user']->uid;
 
   // Remove any HTML and other unwanted chars that might destroy the senders name.
-  $ecard['name_from'] = str_replace(array(',', '<', '>'), '', check_plain($form['name_from']['#value']));
-  $ecard['mail_from'] = $form['mail_from']['#value'];
+  $ecard['name_from'] = str_replace(array(',', '<', '>'), '', check_plain($form_state['values']['name_from']));
+  $ecard['mail_from'] = $form_state['values']['mail_from'];
 
-  $ecard['name_to'] = str_replace(array(',', '<', '>'), '', check_plain($form['name_to']['#value']));
-  $ecard['mail_to'] = $form['mail_to']['#value'];
+  $ecard['name_to'] = str_replace(array(',', '<', '>'), '', check_plain($form_state['values']['name_to']));
+  $ecard['mail_to'] = $form_state['values']['mail_to'];
 
-  $ecard['notify'] = isset($form['ecard_send_notice']['#value']) ? $form['ecard_send_notice']['#value'] : 0;
+  $ecard['notify'] = $form_state['values']['ecard_send_notice'];
 
   // Make sure nothing bad can happen.
   // @todo Implement input filter system.
-  $ecard['text'] = filter_xss_admin($form['text']['#value']);
-
-  // @todo toggle this later when delayed sending functionality is added.
-  $ecard['sent'] = 1;
+  $ecard['text'] = filter_xss_admin($form_state['values']['text']);
+
+  // Handle delayed / scheduled sending.
+  $send_now = TRUE;
+  $ecard['scheduled_time'] = 0;
+  if ($form_state['build_info']['args'][0]['settings']['ecard_enable_scheduling'] && !empty($form_state['values']['ecard_scheduled_timestamp'])) {
+    $ecard['scheduled_time'] = $form_state['values']['ecard_scheduled_timestamp'];
+    if ($ecard['scheduled_time'] > time()) {
+      $send_now = FALSE;
+    }
+  }
 
+  // Create the ecard and save to the database.
   $ecard = ecard_create($ecard);
 
-  $ecard->entity_path = $form_state['build_info']['args'][0]['entity_path'];
+  // Configure some useful variables used when sending the ecard and its copy.
   $ecard->mail = $form_state['build_info']['args'][0]['mail'];
+  $ecard->entity_path = $form_state['build_info']['args'][0]['entity_path'];
   $ecard->ecard_url = url($ecard->entity_path, array('query' => array('ecard' => $ecard->hash), 'absolute' => TRUE));
   $ecard->ecard_copy_url = url($ecard->entity_path, array('query' => array('ecard' => $ecard->hash, 'preview' => 1), 'absolute' => TRUE));
   $ecard->site_name = variable_get('site_name', 'Default site name');
 
-  ecard_mail_send($ecard);
+  // Send ecard if no delayed sending.
+  if ($send_now) {
+    ecard_mail_send_ecard($ecard, 'ecard_ecard');
+    drupal_set_message(t('Your ecard was sent.'));
+  }
+  else {
+    drupal_set_message(t('Your e-card has been scheduled for delivery on %date', array('%date' => format_date($ecard->scheduled_time, 'custom', 'jS F Y'))));
+  }
+
+  // Send the ecard copy immediately.
+  if ($ecard->mail['copy']['ecard_copy_enabled']) {
+    ecard_mail_send_ecard($ecard, 'ecard_copy');
+    drupal_set_message(t('A copy of your ecard was sent to you.'));
+  }
+
+  // Redirect the sender to the specified custom path.
   if (!empty($form_state['build_info']['args'][0]['custom_path'])) {
     drupal_goto($form_state['build_info']['args'][0]['custom_path']);
   }
+  // Otherwise redirect to ecard preview.
   else {
     drupal_goto($ecard->entity_path, array('query' => array('ecard' => $ecard->hash, 'preview' => 1)));
   }
diff --git ecard/includes/ecard.mail.inc ecard/includes/ecard.mail.inc
index 5d3c1fa..58695d4 100644
--- ecard/includes/ecard.mail.inc
+++ ecard/includes/ecard.mail.inc
@@ -4,31 +4,21 @@
  * @file E-Mail implementation for the ecard module.
  */
 
-/**
- * Helper function to send the ecard and its copy.
- */
-function ecard_mail_send($ecard) {
-  ecard_mail_send_ecard($ecard);
-
-  if ($ecard->mail['copy']['ecard_copy_enabled']) {
-    // Just to be sure the ecard url can't be used in the email copy template.
-    $ecard->ecard_url = $ecard->ecard_copy_url;
-    ecard_mail_send_ecard($ecard, 'ecard_copy');
-  }
-}
-
 function ecard_mail_send_ecard($ecard, $key = 'ecard_ecard') {
   $module = 'ecard';
 
-  // Specify 'to' and 'from' addresses.
+  // Specify 'to' and 'from' addresses, and update sent_time for ecard_ecard.
   switch ($key) {
     case 'ecard_ecard':
       $to = ecard_recipient($ecard->mail_to, $ecard->name_to);
-      $send_message = t('Your ecard was sent.');
+      $ecard->sent_time = time();
+      $ecard->sent = 1;
+      ecard_update($ecard);
       break;
     case 'ecard_copy':
       $to = ecard_recipient($ecard->mail_from, $ecard->name_from);
-      $send_message = t('A copy of your ecard was sent to you.');
+      // Just to be sure the ecard url can't be used in the email copy template.
+      $ecard->ecard_url = $ecard->ecard_copy_url;
       break;
     case 'ecard_notice':
       $to = ecard_recipient($ecard->mail_from, $ecard->name_from);
@@ -46,9 +36,7 @@ function ecard_mail_send_ecard($ecard, $key = 'ecard_ecard') {
 
   $message = drupal_mail($module, $key, $to, $language, $params, $from, $send);
 
-  if ($message['result'] && !empty($send_message)) {
-    drupal_set_message($send_message);
-  }
+  return $message['result'];
 }
 
 /**
diff --git ecard/views/ecard.views.inc ecard/views/ecard.views.inc
index 6593c10..d2ced20 100644
--- ecard/views/ecard.views.inc
+++ ecard/views/ecard.views.inc
@@ -107,7 +107,7 @@ function ecard_views_data() {
 
   $data['ecard']['pick_up'] = array(
     'title' => t('Pickup'),
-    'help' => t('Flag if the ecard alredy picked up.'),
+    'help' => t('Flag if the ecard has been picked up.'),
     'field' => array(
       'handler' => 'views_handler_field_boolean',
       'click sortable' => TRUE,
@@ -124,9 +124,77 @@ function ecard_views_data() {
     ),
   );
 
-  $data['ecard']['timestamp'] = array(
-    'title' => t('Timestamp'),
-    'help' => t('The timestamp of the ecard.'),
+  $data['ecard']['sent'] = array(
+    'title' => t('Sent'),
+    'help' => t('Flag if the ecard has been sent.'),
+    'field' => array(
+      'handler' => 'views_handler_field_boolean',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_boolean_operator',
+      'label' => t('Ecard sent'),
+      'type' => 'yes-no',
+      // use boolean_field = 1 instead of boolean_field <> 0 in WHERE statment
+      'use equal' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
+  $data['ecard']['notify'] = array(
+    'title' => t('Notfiy'),
+    'help' => t('Flag if the sender should be notified when the ecard is picked up.'),
+    'field' => array(
+      'handler' => 'views_handler_field_boolean',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_boolean_operator',
+      'label' => t('Ecard notify'),
+      'type' => 'yes-no',
+      // use boolean_field = 1 instead of boolean_field <> 0 in WHERE statment
+      'use equal' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
+  $data['ecard']['created'] = array(
+    'title' => t('Created'),
+    'help' => t('When the ecard was created.'),
+    'field' => array(
+      'handler' => 'views_handler_field_date',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort_date',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_date',
+    ),
+  );
+
+  $data['ecard']['sent_time'] = array(
+    'title' => t('Sent time'),
+    'help' => t('When the ecard was sent.'),
+    'field' => array(
+      'handler' => 'views_handler_field_date',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort_date',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_date',
+    ),
+  );
+
+  $data['ecard']['scheduled_time'] = array(
+    'title' => t('Scheduled time'),
+    'help' => t('When the ecard is/was scheduled to be sent.'),
     'field' => array(
       'handler' => 'views_handler_field_date',
       'click sortable' => TRUE,
