<?php
// $Id$

/**
 * @file
 * Main module file for Stalker module.
 */

/**
 * Implementation of hook_perm().
 *
 * This function takes 0 arguments, and returns an array of permissions
 * defined by our module. Our permissions are automatically made available
 * under admin/user/permissions.
 */
 function stalker_perm() {
   return array('view stalkers');
 }

/**
 * Implemention of hook_user()
 */
function stalker_user($op, &$edit, &$account, $category = NULL) {
  // Drupal (as part of the bootstrap process) makes a global $user object
  // available for the currently logged in user.
  global $user;

  switch ($op) {
    case 'view':
      if (($user->uid != $account->uid) || variable_get('stalker_narcissism', FALSE)) {
        // Update the counter for how many times we've viewed this page
        $view_count = stalker_get_count($user->uid, $account->uid);
        $view_count++;
        
        // Update the counter for how many times we've viewed this page
        stalker_set_count($view_count, $user->uid, $account->uid);
      }
      
      if (user_access('view stalkers')) {
        $content = theme('stalker_user', $account);

        // Here is our first peek at a "renderable array".
        $account->content['stalker'] = array(
          '#type' => 'user_profile_item',
          '#title' => t('Profile hits'),
          '#value' => $content,
          '#weight' => 10,          
        );
      }
      break;
  }
}

/**
 * Example implementation of hook_theme().
 *
 * hook_theme is required to register our themeable (overrideable) output
 * with drupal's theme system.
 */
function stalker_theme() {
  return array (
    'stalker_user' => array (
      'arguments' => array('account' => NULL),
    )
  );
}

/**
 * Default theme output for "stalker_user".
 *
 * Any time we create themeable output, we must provide the default
 * implementation (that can be later overridden by themers).
 */
function theme_stalker_user($account) {
  global $user;
  return t('You have viewed this profile %num times', array('%num' => stalker_get_count($user->uid, $account->uid)));
}

/**
 * Implementation of hook_menu().
 *
 * Hook menu registers page callbacks with Drupal's central menu system.
 */
function stalker_menu() {
  $items = array();
  
  $items['admin/settings/stalker'] = array(
    'title' => 'Stalker settings',
    'description' => 'Configuration options for the stalker module',
    'page callback' => 'stalker_admin_settings',
    'access callback' => 'user_access', // TRUE will give access to everyone
    'access arguments' => array('administer site configuration'),
  );
  
  $items['user/%user/stalkers'] = array(
    'title' => 'Top Stalkers',
    'page callback' => 'stalker_user_page',
    'page arguments' => array(1),
    'access callback' => 'stalker_user_access',
    'access arguments' => array(1),
    'file' => 'stalker.pages.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => -10,
  );
  
  return $items;
}

/**
 * Access callback function for user/%user/stalkers menu path
 */
function stalker_user_access($account) {
  global $user;
  
  if ($user->uid == $account->uid || user_access('view stalkers')) {
    return TRUE;
  }
  
  return FALSE;
}

/**
 * Page callback function for admin/settings/stalker.
 */
function stalker_admin_settings() {
  return drupal_get_form('stalker_settings_form');
}

/**
 * Form builder function for stalker_settings_form.
 */
function stalker_settings_form() {
  $form = array();
  
  $form['stalker_threshold'] = array(
    '#type' => 'textfield',
    '#title' => t('Stalker threshold'),
    '#description' => t('Users who view the profile fewer times than this number will not be listed as stalkers.'),
    '#default_value' => variable_get('stalker_threshold', 1),
    '#required' => TRUE,
  );

  $form['modes'] = array(
    '#type' => 'fieldset',
    '#title' => t('Modes of operation'),
  );
  
  $form['modes']['stalker_identity'] = array(
    '#type' => 'checkbox',
    '#title' => t('Secret admirer mode'),
    '#description' => t('Show the number of times users have visited, but hide their identities.'),
    '#default_value' => variable_get('stalker_identity', FALSE),
  );

  $form['modes']['stalker_narcissism'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow narcissism'),
    '#description' => t('Show how many times a user views their own profile.'),
    '#default_value' => variable_get('stalker_narcissism', FALSE),
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save settings'),
  );
  
  return $form;
}

/**
 * Validation function for stalker_admin_settings.
 */
function stalker_settings_form_validate(&$form, &$form_state) {
  // form_set_error() allows us to stop the form from being submitted, and display an error
  // to the user on the page.
  if (!is_numeric($form_state['values']['stalker_threshold'])) {
    form_set_error('stalker_threshold', t('You must enter a number for the threshold.'));
  } elseif ($form_state['values']['stalker_threshold'] < 1) {
    form_set_error('stalker_threshold', t('The stalker threshold must be greater than zero.'));
  }
}

/**
 * Submission function for stalker_admin_settings.
 */
function stalker_settings_form_submit(&$form, &$form_state) {
  // Validation has already been handled -- we just need to save the results.
  variable_set('stalker_threshold', $form_state['values']['stalker_threshold']);
  variable_set('stalker_identity', $form_state['values']['stalker_identity']);
  variable_set('stalker_narcissism', $form_state['values']['stalker_narcissism']);  
}

/**
 * Implementation for hook_form_alter().
 */
function stalker_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == "user_admin_settings") {
    $form['stalker_threshold'] = array(
      '#type' => 'textfield',
      '#title' => t('Stalker threshold'),
      '#description' => t('Users who view the profile fewer times than this number will not be listed as stalkers.'),
      '#default_value' => variable_get('stalker_threshold', 1),
      '#required' => TRUE,
      '#weight' => -10,
    );
    $form['#validate'][] = 'stalker_settings_form_validate';
  }
}

/**
 * Get the profile hit count for a user.
 */
function stalker_get_count($stalker_uid, $profile_uid) {
  $result = db_query("SELECT view_count FROM {stalker} WHERE stalker_uid = %d AND profile_uid = %d", $stalker_uid, $profile_uid);
  
  return (int) db_result($result);
}

/**
 * Set a view count for a profile
 */
function stalker_set_count($view_count, $stalker_uid, $profile_uid) {
  $result = db_query("UPDATE {stalker} SET view_count = %d, last_stalked = %d WHERE stalker_uid = %d AND profile_uid = %d", $view_count, time(), $stalker_uid, $profile_uid);
  
  // If no rows were updated, a row doesn't exist yet for this user.
  if (db_affected_rows() == 0) {
    db_query("INSERT INTO {stalker} (stalker_uid, profile_uid, view_count, last_stalked) VALUES (%d, %d, %d, %d)", $stalker_uid, $profile_uid, $view_count, time());
  }
}













