<?php

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_page() {
  $pools = vote_pools();

  foreach ($pools as $pool) {
    $operations = array(
      'pool_edit' => array('title' => t('edit'), 'href' => vote_pool_admin_path($pool->pool)),
      'pool_delete' => array('title' => t('delete'), 'href' => vote_pool_admin_path($pool->pool, 'delete')),
    );
    
    foreach ($pool->functions as $function) {
      if ($function['status']) {
        $operations['pool_results'] = array('title' => t('results'), 'href' => vote_pool_admin_path($pool->pool, 'results'));
        break;
      }
    }

    $rows[] = array(
      theme('vote_pool', array('pool' => $pool)), 
      theme('vote_type', array('type' => $pool->type)), 
      theme('vote_functions', array('functions' => $pool->functions)),
      theme('links', array('links' => $operations, 'attributes' => array('class' => array('links', 'inline'))))
    );
  }
  
  if (empty($pools)) {
    $rows[] = array(
      array('data' => t('No pools are currently defined.'), 'colspan' => 6),
    );
  }

  $header = array(t('Pool'), t('Type'), t('Enabled functions'), t('Operations'));

  return theme('table', array('header' => $header, 'rows' => $rows));
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_settings_form($form, &$form_state) {
  $form['settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Vote settings'),
  );
  
  $sessionapi = module_exists('session_api'); 
  $data = vote_data_exists();
  $storage = vote_storage_options();
  
  $form['settings']['vote_allow_anonymous'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow anonymous voting') . (!$sessionapi ? ' - <span class="marker">' . t('Requires Session API') . '</span>' : ''),
    '#description' => t('Activating this will allow anonymous users to vote by using the Session API to handle identification.'),
    '#default_value' => variable_get('vote_allow_anonymous', FALSE),
    '#disabled' => !$sessionapi,
  );  
  
  $form['settings']['vote_calculation_schedule'] = array(
    '#type' => 'radios',
    '#title' => t('Calculation schedule'),
    '#description' => t('Do you want votes to be calculated and cached in real-time or by cron?'),
    '#options' => array(
      'exit' => t('Calculate in real-time'),
      'cron' => t('Schedule for cron'),
    ),
    '#default_value' => variable_get('vote_calculation_schedule', 'exit'),
  );
  
  $form['settings']['vote_storage_method'] = array(
    '#type' => 'radios',
    '#title' => t('Storage method'),
    '#description' => $data ? '<span class="marker">' . t('You cannot change this option because there are already votes in the database.') . '</span>' : t('How and where do you want to store your votes?'),
    '#options' => $storage,
    '#default_value' => vote_storage(),
    '#disabled' => $data,
  ); 
  
  $form['settings']['actions'] = array(
    '#type' => 'actions',
  );
  
  $form['settings']['actions']['vote_flush'] = array(
    '#type' => 'submit',
    '#value' => t('Flush all results'),
    '#submit' => array('vote_admin_flush_submit'),
  );
  
  $form['settings']['actions']['vote_schedule'] = array(
    '#type' => 'submit',
    '#value' => t('Schedule all votes for recalculation'),
    '#submit' => array('vote_admin_schedule_submit'),
  );
  
  return system_settings_form($form);
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_flush_function_submit($form, &$form_state) {
  $function = $form_state['triggering_element']['#function'];
  $pool = $form_state['pool'];
  
  vote_pool_flush($pool->pool, $function);
  
  $function = vote_fetch_function_definition($function);
  
  drupal_set_message(t('All %function resulte for %pool have been flushed.', array('%function' => $function['title'], '%pool' => $pool->name)));
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_flush_submit($form, &$form_state) {
  vote_flush();
  
  drupal_set_message(t('All vote results have been flushed.'));
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_schedule_submit($form, &$form_state) {
  vote_schedule_all();
  
  drupal_set_message(t('All votes have been scheduled for recalculation.'));
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_add_form($form, &$form_state) {
  $pool = !empty($form_state['pool']) ? $form_state['pool'] : NULL;
  $options = vote_definitions_options();

  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Pool name'),
    '#description' => t('A descriptive name for this pool. Spaces are allowed.'),
    '#default_value' => isset($pool) ? $pool->name : '',
    '#required' => TRUE,
    '#size' => 32,
    '#maxlength' => 255,
  );

  $form['pool'] = array(
    '#type' => 'machine_name',
      '#default_value' => isset($pool) ? $pool->pool : '',
    '#maxlength' => 32,
    '#machine_name' => array(
      'exists' => 'vote_pool_get',
      'source' => array('name'),
      'replace_pattern' => '[^a-z0-9-]+',
      'replace' => '-',  
    ),
    '#description' => t('A unique machine-readable name. Can only contain lowercase letters, numbers, and hyphens.'), 
  );

  $form['description'] = array(
    '#type' => 'textfield',
    '#title' => t('Pool description'),
    '#description' => t('This description will appear on the administrative UI to tell you what the pool is about.'),
    '#default_value' => isset($pool) ? $pool->description : '',
    '#maxlength' => 255,
  );
  
  $form['type'] = array(
    '#type' => 'radios',
    '#title' => t('Value type'),
    '#options' => $options,
    '#default_value' => isset($pool) ? $pool->type : key($options),
    '#required' => TRUE,
  );  
  
   $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Proceed'),
    '#submit' => array('vote_admin_pool_add_form_submit'),
  );
   
  return $form;
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_add_form_submit($form, &$form_state) {
  $values = $form_state['values'];  
  
  $pool = !empty($form_state['pool']) ? $form_state['pool'] : vote_pool::construct($values['type']);

  $pool->pool = $values['pool'];
  $pool->name = $values['name'];
  $pool->description = $values['description'];

   vote_pool_cache_set($pool);
  
   $form_state['redirect'] ='admin/structure/vote/manage/' . $pool->pool;
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_form($form, &$form_state, $pool) {
  $definition = vote_fetch_type_definition($pool->type);
  $type = $pool->broken() ? t('Handler broken') : $definition['title'];
  $pool->locked = ctools_object_cache_test('vote_pool', $pool->pool);

  if (!empty($pool->pid)) {    
    drupal_set_title(t('Edit pool @name (@type)', array('@name' => $pool->name, '@type' => $type)));
  } 
  else {
    drupal_set_title(t('Create pool (@type)', array('@type' => $type)));
  }

  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Pool name'),
    '#description' => t('A descriptive name for this pool. Spaces are allowed.'),
    '#default_value' => $pool->name,
    '#required' => TRUE,
    '#size' => 32,
    '#maxlength' => 255,
  );

  $form['pool'] = array(
    '#type' => 'machine_name',
    '#maxlength' => 32,
    '#default_value' => $pool->pool,
    '#machine_name' => array(
      'exists' => 'vote_pool_get',
      'source' => array('name'),
      'replace_pattern' => '[^a-z0-9-]+',
      'replace' => '-',  
    ),
    '#description' => t('A unique machine-readable name. Can only contain lowercase letters, numbers, and hyphens.'), 
  );

  $form['description'] = array(
    '#type' => 'textfield',
    '#title' => t('Pool description'),
    '#description' => t('This description will appear on the administrative UI to tell you what the pool is about.'),
    '#default_value' => $pool->description,
    '#maxlength' => 255,
  );
  
  $pool->options_form(&$form, &$form_state);
  
  $form['actions'] = array('#type' => 'actions');
  
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
    '#submit' => array('vote_admin_pool_form_submit'),
    '#disabled' => $pool->locked || $pool->broken(),
  ); 

  $form['actions']['cancel'] = array(
    '#type' => 'submit',
    '#value' => t('Cancel'),
    '#submit' => array('vote_admin_pool_form_cancel'),
    '#limit_validation_errors' => array(),
  ); 

  if (isset($pool->pid)) {
    $form['actions']['delete'] = array(
      '#type' => 'submit',
      '#value' => t('Delete'),
      '#submit' => array('vote_admin_pool_form_delete'),
      '#disabled' => $pool->locked,
    );
    
    $form['actions']['flush'] = array(
      '#type' => 'submit',
      '#value' => t('Flush all @pool results', array('@pool' => $pool->name)),
      '#submit' => array('vote_admin_pool_form_flush_submit'),
      '#disabled' => $pool->locked,
    );
    
    $form['actions']['schedule'] = array(
      '#type' => 'submit',
      '#value' => t('Schedule all votes on @pool for recalculation', array('@pool' => $pool->name)),
      '#submit' => array('vote_admin_pool_form_schedule_submit'),
      '#disabled' => $pool->locked,
    );    
  }
  
  $form_state['pool'] = $pool;
  
  return $form;
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_form_validate($form, &$form_state) {
  $pool = $form_state['pool'];
  
  if ($pool->locked) {
    form_set_error('', t('Changes cannot be made to a locked pool.'));
  } 
  elseif ($pool->broken()) {
    form_set_error('', t('Changes cannot be made because the handler for this pool is broken or missing.'));
  } 
  else {
    $pool->options_form_validate(&$form, &$form_state);
  }
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_form_submit($form, &$form_state) {
  $values = $form_state['values'];
  $pool = $form_state['pool'];
  
  ctools_object_cache_clear('vote_pool', $pool->pool);
  
  $pool->name = $values['name'];
  $pool->description = $values['description'];
  $pool->pool = $values['pool'];
  $pool->options_form_submit(&$form, &$form_state);
  
  vote_pool_save($pool);
  
  entity_info_cache_clear();
  
  $form_state['redirect'] = 'admin/structure/vote';
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_form_cancel($form, &$form_state) {
  $pool = $form_state['pool'];
  
  ctools_object_cache_clear('vote_pool', $pool->pool);
  
  $form_state['redirect'] = 'admin/structure/vote';
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_form_flush_submit($form, &$form_state) {
  $pool = $form_state['pool'];
  
  vote_pool_flush($pool->pool);
  
  drupal_set_message(t('All vote results of %pool have been flushed.', array('%pool' => $pool->name)));
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_form_schedule_submit($form, &$form_state) {
  $pool = $form_state['pool'];
  
  vote_schedule_pool($pool->pool);
  
  drupal_set_message(t('The entire pool %pool has been scheduled for recalculation.', array('%pool' => $pool->name)));
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_form_delete($form, &$form_state) {
  unset($_REQUEST['destination']);
  
  $pool = $form_state['pool'];  
  $query = drupal_get_destination() + array('cancel' => vote_pool_admin_path($pool->pool));

  $form_state['redirect'] = array(vote_pool_admin_path($pool->pool, 'delete'), array('query' => $query));
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_delete_confirm($form, &$form_state, $pool) {
  if (!isset($pool->pid)) {
    drupal_not_found();
    exit;
  }
  
  $form_state['pool'] = $pool;
  $query = !empty($_GET['cancel']) ? drupal_parse_url($_GET['cancel']) : NULL;

  return confirm_form($form,
    t('Are you sure you want to delete this pool?'),
    !empty($query['path']) ? $query['path'] : 'admin/structure/vote',
    t('This action cannot be undone. All attached votes and results will be deleted.'),
    t('Delete'),
    t('Cancel')
  );
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_delete_confirm_submit($form, &$form_state) {
  if ($form_state['values']['confirm']) {
    $pool = $form_state['pool'];
    
    vote_pool_delete($pool->pool);
    
    watchdog('content', 'Pool %name deleted.', array('%name' => $pool->name));
    drupal_set_message(t('The pool %name has been deleted.', array('%name' => $pool->name)));
    
    module_invoke_all('vote_admin_pool_delete', $pool);
  }

   $form_state['redirect'] = 'admin/structure/vote';
}

/**
 * TODO.
 *
 * @param 
 *   TODO
 * @return
 *   TODO.
 */
function vote_admin_pool_allowed_values_validate($element, &$form_state) {  
  $values = vote_explode_allowed_values($element['#value']);

  foreach ($values as $key => $value) {
    if (!is_numeric($key)) {
      form_error($element, t('Allowed values list: each key must be a valid integer or decimal.'));
      
      break;
    }
  }
  
  form_set_value($element, $values, $form_state);
}