<?php

/**
 * @file
 * Quantity module.
 */

use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Render\Element;
use Drupal\quantity\Entity\QuantityInterface;
use Drupal\quantity\Event\QuantityEvent;

/**
 * Define information about available quantity measures.
 *
 * @return array
 *   Returns an array of measure information.
 */
function quantity_measures() {
  return [
    'count' => [
      'label' => t('Count'),
    ],
    'length' => [
      'label' => t('Length/depth'),
    ],
    'weight' => [
      'label' => t('Weight'),
    ],
    'area' => [
      'label' => t('Area'),
    ],
    'volume' => [
      'label' => t('Volume'),
    ],
    'time' => [
      'label' => t('Time'),
    ],
    'temperature' => [
      'label' => t('Temperature'),
    ],
    'pressure' => [
      'label' => t('Pressure'),
    ],
    'water_content' => [
      'label' => t('Water content'),
    ],
    'value' => [
      'label' => t('Value'),
    ],
    'rate' => [
      'label' => t('Rate'),
    ],
    'rating' => [
      'label' => t('Rating'),
    ],
    'ratio' => [
      'label' => t('Ratio'),
    ],
    'probability' => [
      'label' => t('Probability'),
    ],
    'speed' => [
      'label' => t('Speed'),
    ],
  ];
}

/**
 * Quantity measure options helper.
 *
 * @return array
 *   Returns an array of quantity measures for use in form select options.
 */
function quantity_measure_options() {

  // Start an empty options array.
  $options = [];

  // Load information about measures.
  $measures = quantity_measures();

  // Iterate through the measures and build a list of options.
  foreach ($measures as $measure => $data) {
    $options[$measure] = $data['label'];
  }

  // Return the array of options.
  return $options;
}

/**
 * Allowed values callback function for the quantity measure field.
 *
 * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $definition
 *   The field definition.
 * @param \Drupal\Core\Entity\ContentEntityInterface|null $entity
 *   The entity being created if applicable.
 * @param bool $cacheable
 *   Boolean indicating if the allowed values can be cached. Defaults to TRUE.
 *
 * @return array
 *   Returns an array of allowed values for use in form select options.
 */
function quantity_measure_field_allowed_values(FieldStorageDefinitionInterface $definition, ContentEntityInterface $entity = NULL, bool &$cacheable = TRUE) {
  return quantity_measure_options();
}

/**
 * Implements hook_farm_api_meta_alter().
 */
function quantity_farm_api_meta_alter(&$data) {

  // Add the quantity system of measurement.
  $data['system_of_measurement'] = \Drupal::config('quantity.settings')->get('system_of_measurement');
}

/**
 * Implements hook_ENTITY_TYPE_presave().
 */
function quantity_quantity_presave(QuantityInterface $quantity) {

  // Dispatch an event on quantity presave.
  // @todo Replace this with core event via https://www.drupal.org/node/2551893.
  $event = new QuantityEvent($quantity);
  $event_dispatcher = \Drupal::service('event_dispatcher');
  $event_dispatcher->dispatch($event, QuantityEvent::PRESAVE);
}

/**
 * Implements hook_ENTITY_TYPE_delete().
 */
function quantity_quantity_delete(QuantityInterface $quantity) {

  // Dispatch an event on quantity delete.
  // @todo Replace this with core event via https://www.drupal.org/node/2551893.
  $event = new QuantityEvent($quantity);
  $event_dispatcher = \Drupal::service('event_dispatcher');
  $event_dispatcher->dispatch($event, QuantityEvent::DELETE);
}

/**
 * Implements hook_theme().
 */
function quantity_theme() {
  return [
    'quantity' => [
      'render element' => 'elements',
    ],
    'field__quantity__field' => [
      'template' => 'field--quantity--field',
      'base hook' => 'field',
    ],
  ];
}

/**
 * Implements hook_theme_suggestions_HOOK().
 */
function quantity_theme_suggestions_field(array $variables) {
  $suggestions = [];

  // Add a theme hook suggestion for theming all fields on quantity entities.
  // Note that the field__quantity theme hook is used for any entity with
  // a field called "quantity", such as the log.quantity entity reference.
  if ($variables['element']['#entity_type'] == 'quantity') {
    $suggestions[] = 'field__quantity__field';
  }
  return $suggestions;
}

/**
 * Implements hook_theme_suggestions_HOOK().
 */
function quantity_theme_suggestions_quantity(array $variables) {
  $suggestions = [];
  $quantity = $variables['elements']['#quantity'];
  $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');

  $suggestions[] = 'quantity__' . $sanitized_view_mode;
  $suggestions[] = 'quantity__' . $quantity->bundle();
  $suggestions[] = 'quantity__' . $quantity->bundle() . '__' . $sanitized_view_mode;
  $suggestions[] = 'quantity__' . $quantity->id();
  $suggestions[] = 'quantity__' . $quantity->id() . '__' . $sanitized_view_mode;

  return $suggestions;
}

/**
 * Prepares variables for quantity templates.
 *
 * Default template: quantity.html.twig.
 *
 * @param array $variables
 *   An associative array containing:
 *   - elements: An associative array containing the quantity information and
 *     any fields attached to the quantity. Properties used:
 *     - #quantity: A \Drupal\quantity\Entity\Quantity object. Quantity entity.
 *   - attributes: HTML attributes for the containing element.
 */
function template_preprocess_quantity(array &$variables) {
  $variables['quantity'] = $variables['elements']['#quantity'];
  // Helpful $content variable for templates.
  $variables['content'] = [];
  foreach (Element::children($variables['elements']) as $key) {
    if (!empty($variables['elements'][$key]['#items'])) {
      $variables['content'][$key] = $variables['elements'][$key];
    }
  }
}
