<?php
/**
 * @file support_dashboard.module
 */

// Implement hook_menu().
function support_dashboard_menu() {
	$items = array();
  $items['support_dashboard'] = array(
    'title' => 'Support Dashboard',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('support_dashboard_form'),
    'access arguments' => array('access support dashboard'),
    'type' => MENU_NORMAL_ITEM,
  );
  $states = array(-3 => 'all', -2 => 'all open', -1 => 'my open') + _support_dashboard_states();
  foreach ($states as $sid => $state) {
		$items["support_dashboard/$state"] = array(
			'title' => "$state",
			'page callback' => 'drupal_get_form',
			'page arguments' => array('support_dashboard_form', $state),
			'access arguments' => array('access support dashboard'),
			'weight' => $sid,
      // -2 is 'all open'
			'type' => $sid == -2 ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
		);
  }
	return $items;
}

function support_dashboard_theme() {
  return array(
    'support_dashboard_form' => array(
      'render element' => 'form',
    ),
	);
}

// Implement hook_permission().
function support_dashboard_permission() {
 	return array(
    'access support dashboard' => array(
      'title' => t('Access Support Dashboard'),
			'restrict access' => TRUE,
      'description' => t('Grant access to support dashboard.'),
		),
	);
}

function support_dashboard_form($form, &$form_state, $state = NULL) {
  global $user;

  if (!$state) {
    $state = 'all open';
  }
	
  $state = _support_dashboard_get_state($state);

  $form['post-ticket'] = array(
    '#markup' => l(t('Post new support ticket'), 'node/add/support-ticket'),
  );
  // TODO: Use a tableselect element instead. (Requires rethinking "edit multiple tickets".)
  /*
	$checkboxes = array();
  if (user_access('edit multiple tickets') || user_access('administer support')) {
    $checkboxes = array(
      'data' => '',
      'class' => array('select-all'),
    );
    $form['#attached']['js']['misc/tableselect.js'] = array();
  }
	*/

  $sort = variable_get('support_default_sort_tickets', SUPPORT_SORT_UPDATE);
  if (variable_get('support_default_sort_order', SUPPORT_SORT_DESC) == SUPPORT_SORT_DESC) {
    $order = 'desc';
  }
  else {
    $order = 'asc';
  }
  foreach (array(
    SUPPORT_SORT_UPDATE => array('data' => t('Updated'), 'field' => 'last_updated'),
    SUPPORT_SORT_NID => array('data' => t('Id'), 'field' => 'n.nid'),
    SUPPORT_SORT_STATE => array('data' => t('State'), 'field' => 't.state'),
    SUPPORT_SORT_PRIORITY => array('data' => t('Priority'), 'field' => 't.priority')) as $key => $array) {
    if ($sort == $key) {
      $headers[$key] = $array + array('sort' => $order);
    }
    else {
      $headers[$key] = $array;
    }
  }
  $form['header'] = array(
    '#type' => 'value',
    '#value' => array(
      $headers[SUPPORT_SORT_NID],
      array('data' => t('Ticket'), 'field' => 'n.title'),
			array('data' => t('Client'), 'field' => 't.client'),
      $headers[SUPPORT_SORT_UPDATE],
      array('data' => t('Reported by'), 'field' => 'n.uid'),
      array('data' => t('Assigned to'), 'field' => 't.assigned'),
      $headers[SUPPORT_SORT_STATE],
      $headers[SUPPORT_SORT_PRIORITY],
      array('data' => t('Updates'), 'field' => 's.comment_count'),
    ),
  );

  $query = db_select('node', 'n')
    ->extend('PagerDefault')
    ->extend('TableSort')
    ->orderByHeader($form['header']['#value']);
  $query->leftjoin('support_ticket', 't', 't.nid = n.nid');
  $query->join('node_comment_statistics', 's', 's.nid = n.nid');
  $query->join('users', 'u', 'u.uid = n.uid');
  $query->condition('n.status', NODE_PUBLISHED)
        ->condition('n.type', 'support_ticket')
        ->addTag('support_dashboard_pager');

  if (!user_access('view other users tickets') && !user_access('administer support') && !user_access('edit any support_ticket content') && !user_access('delete any support_ticket content')) {
    $query->condition(db_or()
      ->condition('n.uid', $user->uid)
      ->condition('t.assigned', $user->uid));
  }

  if ($state == -2)
    $query->condition('t.assigned', $user->uid);

  if ($state < 0) {
    $states = _support_get_state(SUPPORT_STATE_CLOSED);
    $query->condition('t.state', $states, 'NOT IN');
  }
  else if ($state) {
    $query->condition('t.state', $state);
  }

  if (variable_get('support_secondary_sort_order', SUPPORT_SORT_DESC) == SUPPORT_SORT_DESC) {
    $order = 'desc';
  }
  else {
    $order = 'asc';
  }
  switch (variable_get('support_secondary_sort_tickets', SUPPORT_SORT_NONE)) {
    case SUPPORT_SORT_UPDATE:
      $query->orderBy('last_updated', $order);
      break;
    case SUPPORT_SORT_NID:
      $query->orderBy('n.nid', $order);
      break;
    case SUPPORT_SORT_STATE:
      $query->orderBy('t.state', $order);
      break;
    case SUPPORT_SORT_PRIORITY:
      $query->orderBy('t.priority', $order);
      break;
  }

  $query->fields('n', array('nid', 'title', 'type', 'changed', 'uid'))
      ->fields('u', array('name'))
      ->fields('s', array('comment_count'))
      ->fields('t', array('client', ' state', 'priority', 'assigned'))
      ->addExpression('GREATEST(n.changed, s.last_comment_timestamp)', 'last_updated');

  $query->limit(50);

  $result = $query->execute();

  $rows = array();
  $tickets = array();
  foreach ($result as $ticket) {
    drupal_alter('support_page_list_ticket', $ticket);
    $account = user_load($ticket->uid);
    $assigned = user_load($ticket->assigned);
    $comments = l($ticket->comment_count, "node/$ticket->nid", array('fragment' => 'comments'));
    if ($new = comment_num_new($ticket->nid)) {
      $node = node_load($ticket->nid);
      $comments .= '&nbsp;(' . l(format_plural($new, '1 new', '@count new'), "node/$ticket->nid", array('query' => comment_new_page_count($node->comment_count, $new, $node), 'fragment' => 'new')) . ')';
    }
    $tickets[$ticket->nid] = '';
    $form['id'][$ticket->nid] = array('#markup' => l($ticket->nid, "node/$ticket->nid", array('attributes' => array('class' => array('ticket-id')))));
    $form['title'][$ticket->nid] = array('#markup' => l(_support_dashboard_truncate($ticket->title), "node/$ticket->nid", array('attributes' => array('class' => array('ticket-title')))));
		$form['client'][$ticket->nid] = array('#markup' => _support_dashboard_client($ticket->client), '#attributes' => array('class' => array('ticket-client')));
    $form['updated'][$ticket->nid] = array('#markup' => format_date($ticket->last_updated, 'short', array('attributes' => array('class' => array('ticket-updated')))));
    $form['reported'][$ticket->nid] = array('#markup' => l(_support_truncate($account->name, 24), "user/$account->uid", array('attributes' => array('class' => array('ticket-reported')))));
   	$form['assigned']["assigned-$ticket->nid"] = array('#markup' => l(_support_truncate($assigned->name, 24), "user/$assigned->uid", array('attributes' => array('class' => array('ticket-assigned')))));
    $form['state']["state-$ticket->nid"] = array('#markup' => _support_dashboard_state($ticket->state), '#attributes' => array('class' => array('ticket-state')));
    $form['priority']["priority-$ticket->nid"] = array('#markup' => _support_dashboard_priorities($ticket->priority), '#attributes' => array('class' => array('ticket-priority')));
    $form['updates'][$ticket->nid] = array('#markup' => $comments, '#attributes' => array('class' => array("state-$ticket->state", "priority-$ticket->priority")));
    $form['class'][$ticket->nid] = array('#value' => array("state-$ticket->state", "priority-$ticket->priority"));
  }
  $form['pager'] = array('#markup' => theme('pager', array('tags' => NULL, 'element' => 0)));
  return $form;
}

/**
 * Theme function for ticket list
 */
function theme_support_dashboard_form($variables) {
  $form = $variables['form'];
  drupal_add_css(drupal_get_path('module', 'support_dashboard') . '/css/support-dashboard.css');
  $output = drupal_render($form['post-ticket']);
  if (isset($form['title']) && is_array($form['title'])) {
    foreach (element_children($form['title']) as $key) {
      $row = array();
      $row[] = drupal_render($form['id'][$key]);
      $row[] = drupal_render($form['title'][$key]);
			$row[] = drupal_render($form['client'][$key]);
      $row[] = drupal_render($form['updated'][$key]);
      $row[] = drupal_render($form['reported'][$key]);
      $row[] = drupal_render($form['assigned']["assigned-$key"]);
      $row[] = drupal_render($form['state']["state-$key"]);
      $row[] = drupal_render($form['priority']["priority-$key"]);
      $row[] = drupal_render($form['updates'][$key]);
      $rows[] = array(
        'data' => $row,
        'class' => $form['class'][$key]['#value'],
      );
      unset($form['class'][$key]);
    }
  }
  else {
    $rows[] = array(array(
        'data' => t('No tickets available.'),
        'colspan' => '9',
        ));
  }
  if ($form['pager']['#markup']) {
    $output .= drupal_render($form['pager']);
  }

  $output .= theme('table', array('header' => $form['header']['#value'], 'rows' => $rows, 'attributes' => array('class' => array('support-dashboard'))));

  $output .= drupal_render_children($form);

  return $output;
}

/**
 * Helper function to list available states.
 */
function _support_dashboard_states($all = TRUE, $sid = NULL, $account = NULL) {
  static $states = array();
  $admin = user_access('can administer state', $account);

  if (!isset($states["$admin-$all-$sid"])) {
    if ($admin || $all) {
      $result = db_query("SELECT sid, state FROM {support_states} ORDER BY weight");
    }
    else if (!$all && !$sid) {
      $result = db_query("SELECT sid, state FROM {support_states} WHERE phase1 = :phase1 ORDER BY weight", array(':phase1' => 1));
    }
    else if (!$all) {
      $result = db_query("SELECT sid, state FROM {support_states} WHERE phase2 = :phase2 ORDER BY weight", array(':phase2' => 1));
    }
    foreach ($result as $state) {
      $states["$admin-$all-$sid"][$state->sid] = $state->state;
    }
    // include the current state, even if user doesn't actually have access
    if ($sid && !in_array($sid, $states["$admin-$all-$sid"])) {
      $states["$admin-$all-$sid"][$sid] = db_query("SELECT state FROM {support_states} WHERE sid = :sid", array(':sid' => $sid))->fetchField();
    }
  }

  return $states["$admin-$all-$sid"];
}

/**
 * Return default sid.
 */
function _support_dashboard_state_default() {
  static $default = NULL;
  if (!$default) {
    $default = db_query_range('SELECT sid FROM {support_states} WHERE isdefault = :isdefault ORDER BY weight ASC', 0, 1, array(':isdefault' => 1))->fetchField();
  }
  return $default;
}

/**
 * Return secondary sid.
 */
function _support_dashboard_state_secondary() {
  static $secondary = NULL;
  if (!$secondary) {
    $secondary = db_query_range('SELECT sid FROM {support_states} WHERE phase2 = :phase2 ORDER BY weight ASC', 0, 1, array(':phase2' => 1))->fetchField();
  }
  return $secondary;
}

/**
 * Helper function to list available priorities.
 */
function _support_dashboard_priorities($pid = NULL) {
  static $priorities = array();

  if (empty($priorities)) {
    $result = db_query('SELECT pid, priority FROM {support_priority} ORDER BY weight');
    foreach ($result as $priority) {
      $priorities[$priority->pid] = $priority->priority;
    }
  }

  if ($pid && isset($priorities[$pid])) {
    return $priorities[$pid];
  }
  if ($pid === 0) {
    return '';
  }
  else {
    return $priorities;
  }
}

/**
 * Return default pid.
 */
function _support_dashboard_priority_default() {
  static $default = NULL;
  if (!$default) {
    $default = db_query_range('SELECT pid FROM {support_priority} WHERE isdefault = :isdefault', 0, 1, array(':isdefault' => 1))->fetchField();
  }
  return $default;
}

/**
 * Helper function to determine if a user has support tickets already.
 */
function _support_dashboard_ticket_exists($account) {
  $result = db_select('node', 'n')
    ->fields('n', array('nid', 'created'))
    ->condition('type', 'support_ticket')
    ->condition('status', 1)
    ->condition('uid', $account->uid)
    ->addTag('node_access')
    ->addTag('support_search') // Disable support query altering because we're doing our own filtering.
    ->execute()
    ->fetchField();
  return (bool) $result;
}

/**
 * Helper function, retrieve state name from database.
 */
function _support_dashboard_state($state) {
  static $state_name = array();

  if (!isset($state_name[$state])) {
    $state_name[$state] = db_query('SELECT state FROM {support_states} WHERE sid = :sid', array(':sid' => $state))->fetchField();
  }

  return $state_name[$state];
}

/**
 *
 */
function _support_dashboard_get_state($state) {
  if ($state == 'all') {
    return 0;
  }
  else if ($state == 'all open') {
    return -1;
  }
  else if ($state == 'my open') {
    return -2;
  }
  else if ($state == SUPPORT_STATE_CLOSED) {
    $result = db_query("SELECT sid FROM {support_states} WHERE isclosed = :isclosed", array(':isclosed' => 1));
    $states = array();
    foreach ($result as $state) {
      $states[$state->sid] = $state->sid;
    }
    return $states;
  }
  $sid = db_query("SELECT sid FROM {support_states} WHERE state = :state", array(':state' => $state))->fetchField();
  if (!$sid) {
    $sid = _support_dashboard_state_default();
  }
  return $sid;
}

/**
 * Helper function, retrieve client name from database.
 */
function _support_dashboard_client($client) {
  static $client_name = array();

  if (!isset($client_name[$client])) {
    $client_name[$client] = db_query('SELECT name FROM {support_client} WHERE clid = :clid', array(':clid' => $client))->fetchField();
  }

  return l(_support_truncate($client_name[$client]), "support/$client_name[$client]", array('attributes' => array('class' => array('ticket-client'))));
}

function _support_dashboard_truncate($text, $maxlen = 64) {
  return truncate_utf8($text, ($maxlen - 1), TRUE, TRUE);
}
