<?php

/**
 * @file
 * Administrative functions for managing view modes for every entity.
 */

/**
 * Shows the list of view modes.
 */
function ds_view_modes_list() {
  $output = '';

  ctools_include('export');
  $view_modes = ctools_export_crud_load_all('ds_view_modes');
  if (!empty($view_modes)) {

    $rows = array();
    foreach ($view_modes as $view_mode_key => $view_mode_value) {

      $row = array();
      $row[] = check_plain($view_mode_value->label);
      $row[] = $view_mode_key;
      $row[] = ucwords(str_replace('_', ' ', implode(', ', $view_mode_value->entities)));
      $operations = l(t('Edit'), 'admin/structure/ds/view_modes/manage/' . $view_mode_key, array('alias' => TRUE));

      if ($view_mode_value->export_type == 3) {
        $operations .= ' - ' . l(t('Revert'), 'admin/structure/ds/view_modes/revert/' . $view_mode_key, array('alias' => TRUE));
      }
      elseif ($view_mode_value->export_type == 1) {
        $operations .= ' - ' . l(t('Delete'), 'admin/structure/ds/view_modes/delete/' . $view_mode_key, array('alias' => TRUE));
      }
      $row[] = $operations;
      $rows[] = $row;
    }

    $table = array(
      'header' => array(
        'Label',
        'Machine name',
        'Entities',
        'Operations',
      ),
      'rows' => $rows,
    );

    $output = theme('table', $table);
  }
  else {
    $output = t('No custom view modes have been defined.');
  }

  return $output;
}

/**
 * Manage a custom view mode.
 */
function ds_edit_view_mode_form($form, &$form_state, $view_mode = '') {

  ctools_include('export');
  $view_modes = ctools_export_crud_load_all('ds_view_modes');
  if (isset($view_modes[$view_mode])) {
    $view_mode = $view_modes[$view_mode];
  }
  else {
    $view_mode = new stdClass;
    $view_mode->label = '';
    $view_mode->view_mode = '';
    $view_mode->entities = array();
  }

  $form['name'] = array(
    '#title' => t('Label'),
    '#type' => 'textfield',
    '#default_value' => $view_mode->label,
    '#description' => t('The human-readable label of the view mode. This name must be unique.'),
    '#required' => TRUE,
    '#maxlength' => 32,
    '#size' => 30,
  );

  $form['view_mode'] = array(
    '#title' => t('Machine name'),
    '#type' => 'machine_name',
    '#default_value' => $view_mode->view_mode,
    '#maxlength' => 32,
    '#description' => t('The machine-readable name of this view mode. This name must contain only lowercase letters and underscores. This name must be unique.'),
    '#disabled' => !empty($view_mode->view_mode),
    '#machine_name' => array(
      'exists' => 'ds_view_mode_unique',
    ),
  );

  $entity_options = array();
  $entities = entity_get_info();
  foreach ($entities as $entity_type => $entity_info) {
    if (isset($entity_info['fieldable']) && $entity_info['fieldable']) {
      $entity_options[$entity_type] = drupal_ucfirst(str_replace('_', ' ', $entity_type));
    }
  }
  $form['entities'] = array(
    '#title' => t('Entities'),
    '#description' => t('Select the entities for which this view mode will be made available.'),
    '#type' => 'checkboxes',
    '#required' => TRUE,
    '#options' => $entity_options,
    '#default_value' => $view_mode->entities,
  );

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

  $form['existing'] = array('#type' => 'value', '#value' => !empty($view_mode->view_mode));

  return $form;
}

/**
 * Return whether a view mode machine name is unique.
 */
function ds_view_mode_unique($name) {
  ctools_include('export');
  $view_modes = ctools_export_crud_load_all('ds_view_modes');
  $value = strtr($name, array('-' => '_'));
  return isset($view_modes[$value]) ? TRUE : FALSE;
}

/**
 * Validates the view mode submission form generated by ds_edit_view_mode_form().
 */
function ds_edit_view_mode_form_validate($form, &$form_state) {

  $view_mode = new stdClass;
  $view_mode->view_mode = $form_state['values']['view_mode'];
  $view_mode->label = $form_state['values']['name'];

  $reserved = array();
  $entities = $form_state['values']['entities'];
  foreach ($entities as $key => $value) {
    if ($key !== $value) {
      unset($entities[$key]);
    }
    else {
      $reserved += ds_entity_view_modes($key);
    }
  }

  if (array_key_exists($view_mode->view_mode, $reserved) && !isset($form_state['values']['existing'])) {
    form_set_error('type', t('The machine-readable name %view_mode is reserved.', array('%view_mode' => $view_mode->view_mode)));
  }
  else {
    $view_mode->entities = $entities;
    $form_state['view_mode'] = $view_mode;
  }
}

/**
 * Saves the view mode.
 */
function ds_edit_view_mode_form_submit($form, &$form_state) {
  $view_mode = $form_state['view_mode'];

  // Delete previous view_mode configuration (if any)
  db_delete('ds_view_modes')
    ->condition('view_mode', $view_mode->view_mode)
    ->execute();

  // Save the new view mode.
  drupal_write_record('ds_view_modes', $view_mode);

  // Clear entity info cache and trigger menu build on next request.
  cache_clear_all('entity_info', 'cache', TRUE);
  variable_set('menu_rebuild_needed', TRUE);

  // Redirect.
  $form_state['redirect'] = 'admin/structure/ds/view_modes';
  drupal_set_message(t('The view mode %view_mode has been saved', array('%view_mode' => $view_mode->label)));
}

/**
 * Menu callback: Confirmation view mode delete form.
 */
function ds_delete_view_mode_confirm($form, &$form_state, $view_mode = '') {
  return ds_remove_view_mode_confirm($form, $form_state, $view_mode, 'delete');
}

/**
 * Menu callback: Confirmation view mode revert form.
 */
function ds_revert_view_mode_confirm($form, &$form_state, $view_mode = '') {
  return ds_remove_view_mode_confirm($form, $form_state, $view_mode, 'revert');
}

/**
 * Confirmation revert or remove form.
 */
function ds_remove_view_mode_confirm($form, &$form_state, $view_mode = '', $action = 'delete') {
  ctools_include('export');
  $view_modes = ctools_export_crud_load_all('ds_view_modes');
  if (isset($view_modes[$view_mode])) {
    $view_mode = $view_modes[$view_mode];
  }

  $confirm = FALSE;
  if (isset($view_mode->export_type)) {
    if ($action == 'delete' && $view_mode->export_type != 2) {
      $confirm = TRUE;
    }
    elseif ($action == 'revert' && $view_mode->export_type == 3) {
      $confirm = TRUE;
    }
  }

  if ($confirm) {
    $form['#view_mode'] = $view_mode;
    return confirm_form($form,
      t('Are you sure you want to ' . $action . ' %view_mode?', array('%view_mode' => $view_mode->label)),
      'admin/structure/ds/view_modes',
      t('This action cannot be undone.'),
      t(drupal_ucfirst($action)),
      t('Cancel')
    );
  }
  else {
    drupal_set_message(t('This operation is not possible.'));
    drupal_goto('admin/structure/ds/view_modes');
  }
}

/**
 * Confirmed view mode delete submit callback.
 */
function ds_delete_view_mode_confirm_submit($form, &$form_state) {
  ds_remove_view_mode($form, $form_state, 'deleted');
}

/**
 * Confirmed view mode revert submit callback.
 */
function ds_revert_view_mode_confirm_submit($form, &$form_state) {
  ds_remove_view_mode($form, $form_state, 'reverted');
}

/**
 * Remove a view mode from the database.
 *
 * @param $action
 *   Whether we delete or remove the view mode.
 */
function ds_remove_view_mode($form, &$form_state, $action = 'deleted') {

  $view_mode = $form['#view_mode'];

  // Remove view mode from database.
  db_delete('ds_view_modes')
    ->condition('view_mode', $view_mode->view_mode)
    ->execute();

  // Remove layout and field settings for this view mode.
  db_delete('ds_field_settings')
    ->condition('view_mode', $view_mode->view_mode)
    ->execute();
  db_delete('ds_layout_settings')
    ->condition('view_mode', $view_mode->view_mode)
    ->execute();

  // Clear entity info cache and trigger menu build on next request.
  cache_clear_all('entity_info', 'cache', TRUE);
  variable_set('menu_rebuild_needed', TRUE);

  // Redirect.
  $form_state['redirect'] = 'admin/structure/ds/view_modes';
  drupal_set_message(t('The view mode %view_mode has been ' . $action . '.', array('%view_mode' => $view_mode->label)));
}
