<?php

/**
 * @file
 * Provide an example module for using the educa.ch Curricula UI component.
 */

/**
 * Implements hook_init().
 */
function archibald_curricula_example_init() {
  // This is a hack for adding our custom fields to the
  // archibald_lomch_description content type. We cannot do this on install, as
  // our custom field type doesn't exist at that time yet. We put it in here,
  // meaning we actually add the fields on the first page load. We set a system
  // variable when done, so we only do this once.
  if (!variable_get('archibald_curricula_example_entities_added_fields', 0)) {
    //return;
    module_load_include('inc', 'archibald', 'includes/archibald.entities');
    $entity = 'node';
    $bundle = 'archibald_lomch_description';

    // Add a classification field first.
    archibald_add_field_to_entity($entity, $bundle, 'archibald_curricula_example_1', array(
      'label' => "Example classification",
      'cardinality' => 1,
      'type' => 'archibald_curricula_example',
      'widget' => array(
        'type' => 'archibald_curricula_example',
      ),
    ));

    // Add our field to the Classification group, both on the form and in the
    // default display.
    foreach (array('form', 'default') as $display) {
      $group = field_group_load_field_group('group_classification', $entity, $bundle, $display);
      $group->children[] = 'archibald_curricula_example_1';
      $group->children = array_unique($group->children);
      field_group_group_save($group);
    }

    // Add another field as an example for curricula.
    archibald_add_field_to_entity($entity, $bundle, 'archibald_curricula_example_2', array(
      'label' => "Example curricula",
      'cardinality' => 1,
      'type' => 'archibald_curricula_example',
      'widget' => array(
        'type' => 'archibald_curricula_example',
      ),
    ));

    // Add our field to the Curricula group, both on the form and in the
    // default display.
    foreach (array('form', 'default') as $display) {
      $group = field_group_load_field_group('group_curricula', $entity, $bundle, $display);
      $group->children[] = 'archibald_curricula_example_2';
      $group->children = array_unique($group->children);
      field_group_group_save($group);
    }

    variable_set('archibald_curricula_example_entities_added_fields', 1);
  }
}

/**
 * Implements hook_field_info().
 */
function archibald_curricula_example_field_info() {
  return array(
    'archibald_curricula_example' => array(
      'label' => t("Example curricula"),
      'description' => t("Example curricula field, using the Curricula UI JS component."),
      'default_widget' => 'archibald_curricula_example',
      'default_formatter' => 'archibald_curricula_example',
    ),
  );
}

/**
 * Implements hook_field_is_empty().
 */
function archibald_curricula_example_field_is_empty($item, $field) {
  return empty($item['item_ids']);
}

/**
 * Implements hook_field_widget_info().
 */
function archibald_curricula_example_field_widget_info() {
  return array(
    'archibald_curricula_example' => array(
      'label' => t("Example curricula"),
      'field types' => array('archibald_curricula_example'),
    ),
  );
}

/**
 * Implements hook_field_widget_form().
 */
function archibald_curricula_example_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $item = isset($items[$delta]) ? $items[$delta] : NULL;

  // We use the example JSON provided with the Curricula UI library as our data
  // source. In order to get the path, we need to call libraries_load().
  // Unfortunately, if we only load curricula-ui, Libraries API will put the
  // script tags *before* Underscore and Backbone, resulting in JS errors.
  // Although the Archibald Curricula module would load these libraries anyway,
  // we load them here as well, in order. This will prevent the JS errors, and
  // the libraries won't get loaded twice anyway.
  if (!archibald_curricula_load_libraries()) {
    // The libraries are not installed... Go on with the construction of our
    // widget. Archibald Curricula will put up a warning message, so we won't
    // have to.
    $library = array('library path' => '');
  }
  else {
    // Load the curricula-ui library. That's the one we want.
    $library = libraries_load('curricula-ui');
  }

  $element = array(
    '#type' => 'archibald_curricula',
    '#curricula_data_src' => url($library['library path'] . '/example/json/full.json'),
    '#curricula_settings' => array(),
    '#default_value' => isset($item['item_ids']) ? $item['item_ids'] : NULL,
  ) + $element;

  return $element;
}

/**
 * Implements hook_field_formatter_info().
 */
function archibald_curricula_example_field_formatter_info() {
  return array(
    'archibald_curricula_example' => array(
      'label' => t("Example curricula display"),
      'field types' => array('archibald_curricula_example'),
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function archibald_curricula_example_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  if (!archibald_curricula_load_libraries()) {
    return array();
  }

  $library = libraries_load('curricula-ui');
  $data = json_decode(file_get_contents($library['library path'] . '/example/json/full.json'), true);

  $elements = array();
  foreach ($items as $delta => $item) {
    // Activate all items that were selected.
    if (!empty($item['item_ids'])) {
      $item_ids = array_map('trim', explode(',', $item['item_ids']));

      // Here we actually alter the data. But, because for each field item, we
      // pass through the *whole* data tree, we will reset the "active" key
      // correctly. So, there is no risk we mix up items.
      foreach ($data as $group => &$models) {
        foreach ($models as &$model) {
          $model = (array) $model;
          $model['active'] = in_array($model['id'], $item_ids);
        }
      }

      $elements[$delta] = array(
        '#markup' => theme('archibald_curricula_summary', array(
          'items' => $data,
        )),
      );
    }
    else {
      $elements[$delta] = '';
    }
  }

  return $elements;
}

/**
 * Implements hook_archibald_json_export_alter().
 */
function archibald_curricula_example_archibald_json_export_alter(&$json_data, $node) {
  if (!archibald_curricula_load_libraries()) {
    return;
  }
  $library = libraries_load('curricula-ui');

  // Load the item database.
  $data = json_decode(file_get_contents($library['library path'] . '/example/json/full.json'), true);

  foreach ($node->archibald_curricula_example_1 as $langcode => $items) {
    foreach ($items as $item) {
      // Activate all items that were selected.
      if (!empty($item['item_ids'])) {
        $item_ids = array_map('trim', explode(',', $item['item_ids']));

        // Here we actually alter the data. But, because for each field item, we
        // pass through the *whole* data tree, we will reset the "active" key
        // correctly. So, there is no risk we mix up items.
        foreach ($data as $group => &$models) {
          foreach ($models as &$model) {
            $model = (array) $model;
            $model['active'] = in_array($model['id'], $item_ids);
          }
        }

        $json_data->classification[] = array(
          // We only handle discipline trees, the most common.
          'purpose' => array(
            'source' => 'LOMv1.0',
            'value' => 'discipline',
          ),
          // Convert the multiple paths returned by
          // theme_archibald_curricula_json_classification() to something
          // LOM-CHv1.1 can understand.
          'taxonPath' => array_map(function($path) {
            return array(
              'source' => array(
                'en' => 'archibald_curricula_example',
              ),
              'taxon' => $path,
            );
          }, theme('archibald_curricula_json_classification', array(
            'items' => $data,
          ))),
        );
      }
    }
  }

  // Add purpose vocabulary data to the models.
  foreach ($data as $group => &$models) {
    foreach ($models as &$model) {
      $model = (array) $model;
      if (!isset($model['data'])) {
        $model['data'] = array();
      }

      switch ($model['type']) {
        case 'subject_area':
        case 'subject':
          $model['data']['purpose'] = array(
            'source' => 'LOM-CHv1.2',
            'value' => 'discipline',
          );
          break;

        case 'area_of_competence':
        case 'theme':
          $model['data']['purpose'] = array(
            'source' => 'LOM-CHv1.2',
            'value' => 'component',
          );
          break;

        case 'competence':
          $model['data']['purpose'] = array(
            'source' => 'LOM-CHv1.2',
            'value' => 'competence',
          );
          break;

        case 'competence_element':
          $model['data']['purpose'] = array(
            'source' => 'LOM-CHv1.2',
            'value' => 'objective',
          );
          break;

        default:
          $model['data']['purpose'] = array(
            'source' => 'LOM-CHv1.2',
            'value' => 'note',
          );
          break;
      }
    }
  }

  $taxon_trees = array();
  foreach ($node->archibald_curricula_example_2 as $langcode => $items) {
    foreach ($items as $item) {
      // Activate all items that were selected.
      if (!empty($item['item_ids'])) {
        $item_ids = array_map('trim', explode(',', $item['item_ids']));

        // Here we actually alter the data. But, because for each field item, we
        // pass through the *whole* data tree, we will reset the "active" key
        // correctly. So, there is no risk we mix up items.
        foreach ($data as $group => &$models) {
          foreach ($models as &$model) {
            $model = (array) $model;
            $model['active'] = in_array($model['id'], $item_ids);
          }
        }

        $taxon_trees = array_merge(
          $taxon_trees,
          theme('archibald_curricula_json_curricula', array(
            'items' => $data,
          ))
        );
      }
    }
  }

  $json_data->curriculum[] = array(
    'source' => array(
      'name' => 'archibald_curricula_example',
      'hierarchy' => array(
        array(
          'type' => 'subject_area',
          'childTypes' => array('subject'),
          'entry' => array(
            'en' => "Subject area",
          ),
          'identifier' => array(array(
            'catalog' => 'URL',
            'entry' => 'http://www.example.com',
          )),
          'description' => array(
            'en' => "Subject area description comes here.",
          ),
        ),
        array(
          'type' => 'subject',
          'childTypes' => array('area_of_competence'),
          'entry' => array(
            'en' => "Subject",
          ),
          'identifier' => array(array(
            'catalog' => 'URL',
            'entry' => 'http://www.example.com',
          )),
          'description' => array(
            'en' => "Subject description comes here.",
          ),
        ),
        array(
          'type' => 'area_of_competence',
          'childTypes' => array('theme'),
          'entry' => array(
            'en' => "Area of competence",
          ),
          'identifier' => array(array(
            'catalog' => 'URL',
            'entry' => 'http://www.example.com',
          )),
          'description' => array(
            'en' => "Area of competence description comes here.",
          ),
        ),
        array(
          'type' => 'theme',
          'childTypes' => array('competence'),
          'entry' => array(
            'en' => "Theme",
          ),
          'identifier' => array(array(
            'catalog' => 'URL',
            'entry' => 'http://www.example.com',
          )),
          'description' => array(
            'en' => "Theme description comes here.",
          ),
        ),
        array(
          'type' => 'competence',
          'childTypes' => array('competence_element'),
          'entry' => array(
            'en' => "Competence",
          ),
          'identifier' => array(array(
            'catalog' => 'URL',
            'entry' => 'http://www.example.com',
          )),
          'description' => array(
            'en' => "Competence description comes here.",
          ),
        ),
        array(
          'type' => 'competence_element',
          'childTypes' => array(),
          'entry' => array(
            'en' => "Competence element",
          ),
          'identifier' => array(array(
            'catalog' => 'URL',
            'entry' => 'http://www.example.com',
          )),
          'description' => array(
            'en' => "Competence element description comes here.",
          ),
        ),
      ),
    ),
    'taxonTree' => $taxon_trees,
  );
}
