<?php
/**
 * @file
 * Code for the Commons Radioactivity feature.
 */

// Include files contain hook implementations for the corresponding modules.
include_once 'commons_radioactivity.features.inc';
include_once 'includes/incidents/commons_radioactivity.incidents_comment.inc';
include_once 'includes/incidents/commons_radioactivity.incidents_flag.inc';
include_once 'includes/incidents/commons_radioactivity.incidents_votingapi.inc';

// Define constants for Commons Radioactivity incidents.
// These could be changed to variables and made more configurable.
define('COMMONS_RADIOACTIVITY_COMMENT', 2);
define('COMMONS_RADIOACTIVITY_LIKE', 4);
define('COMMONS_RADIOACTIVITY_NODE_IN_GROUP', 4);
define('COMMONS_RADIOACTIVITY_FLAG_NODE', 6);

/**
 * Implements hook_system_info_alter().
 */
function commons_radioactivity_system_info_alter(&$info, $file, $type) {
  // Commons Radioactivity dynamically adds field_radioactivity to content types
  // which implement commons_radioactivity_field().
  // We must add a corresponding line for each field instance
  // to commons_radioactivity.info so that Features is aware of the instance
  // and can successfully revert the field_instance component back
  // to its default state.
  if ($file->name == 'commons_radioactivity') {
    $commons_radioactivity_entity_types = commons_radioactivity_get_radioactive_entity_types();

    if (!empty($commons_radioactivity_entity_types)) {
      foreach ($commons_radioactivity_entity_types as $entity_type => $bundles) {
        foreach(array_keys($bundles) as $bundle) {
          $info['features']['field_instance'][] = "$entity_type-$bundle-field_radioactivity";
        }
      }
    }
  }
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function commons_radioactivity_form_node_form_alter(&$form, &$form_state, $form_id) {
  // Move radioactivity settings into the sidebar and restrict access to it.
  if (isset($form['field_radioactivity'])) {
    $form['field_radioactivity']['#access'] = user_access('edit radioactivity');
    $form['field_radioactivity']['#type'] = 'fieldset';
    $form['field_radioactivity']['#title'] = t('Radioactivity energy');
    $form['field_radioactivity']['#collapsible'] = TRUE;
    $form['field_radioactivity']['#collapsed'] = TRUE;
    $form['field_radioactivity']['#group'] = 'additional_settings';
    $form['field_radioactivity']['#attributes'] = array(
      'class' => array('radioactivity-form-energy'),
    );
    $form['field_radioactivity']['#attached']['js'][] = drupal_get_path('module', 'commons_radioactivity') . '/commons_radioactivity.js';
  }
}

/**
 * Returns an array of entity types that are enabled via Commons Radioactivity.
 */
function commons_radioactivity_get_radioactive_entity_types() {
  // Find all Commons Entity integrations.
  $commons_entity_integrations = commons_entity_integration_info();

  if (empty($commons_entity_integrations)) {
    return array();
  }

  foreach ($commons_entity_integrations as $entity_type => $integration) {
    foreach ($integration as $bundle => $options) {
      if (isset($options['radioactivity_exclude']) && $options['radioactivity_exclude'] == TRUE) {
        unset($commons_entity_integrations[$entity_type][$bundle]);
      }
    }

    // If an entity type has no integrations, don't return it.
    if (empty($commons_entity_integrations[$entity_type])) {
      unset($commons_entity_integrations[$entity_type]);
    }
  }

  return $commons_entity_integrations;
}

/**
 * Helper function to create Radioactivity incidents for nodes.
 *
 * @param $node
 *   The node which will have its radioactivity modified.
 * @param $value
 *   The value by which to modify the node's radioactivity.
 */
function commons_radioactivity_incident_node($node, $value) {
  // Only operate on nodes that have the radioactivity field.
  if (!empty($node->field_radioactivity)) {
    // Find the node's ID and bundle.
    list($id, , $bundle) = entity_extract_ids('node', $node);

    // Prevent groups from going negative in energy.
    if ($bundle == 'group' && $node->field_radioactivity[LANGUAGE_NONE][0]['radioactivity_energy'] + $value >= 0) {
      // Get an instance of the incident storage for the radioactivity field.
      $profile = radioactivity_get_field_profile('node', $bundle, 'field_radioactivity');

      // Trigger a radioactivity incident.
      if ($profile && $profile->storageObject) {
        $profile->storageObject->addIncident(new RadioactivityIncident('node', $bundle, 'field_radioactivity', LANGUAGE_NONE, $id, $value, time()));
      }
    }
  }
}
