<?php

/**
 * Implementation of hook_context_plugins().
 * This is a ctools plugins hook.
 */
function context_panels_layouts_context_plugins() {
  return array(
    'context_panels_layouts_reaction_block' => array(
      'handler' => array(
        'path' => drupal_get_path('module', 'context_panels_layouts') .'/plugins',
        'file' => 'context_panels_layouts_reaction_block.inc',
        'class' => 'context_panels_layouts_reaction_block',
        'parent' => 'context_layouts_reaction_block',
      ),
    ),
  );
}

/**
 * Implementation of hook_context_registry_alter().
 */
function context_panels_layouts_context_registry_alter(&$registry) {
  if (isset($registry['reactions']['block'])) {
    $registry['reactions']['block']['plugin'] = 'context_panels_layouts_reaction_block';
  }
}

/**
 * Fetch metadata for all layout plugins.
 *
 * @return
 *   An array of arrays with information about all available panel layouts.
 */
function context_panels_layouts_get_panels_layouts() {
  ctools_include('plugins');
  $layouts = ctools_get_plugins(module_exists('panels') ? 'panels' : 'context_panels_layouts', 'layouts');
  foreach ($layouts as $key => $layout) {
    if (!isset($layout['regions'])) {
      unset($layouts[$key]);
    }
  }
  return $layouts;
}

/**
 * Implementation of hook_theme().
 *
 * If Panels is not enabled, register Panels theme callbacks.
 * @see panels_theme().
 */
function context_panels_layouts_theme() {
  $theme = array();
  if (!module_exists('panels')) {
    // Register layout and style themes on behalf of all of these items.
    // No need to worry about files; the plugin has to already be loaded for us
    // to even know what the theme function is, so files will be auto included.
    ctools_include('plugins');
    $layouts = ctools_get_plugins('context_panels_layouts', 'layouts');
    foreach ($layouts as $name => $data) {
      foreach (array('theme', 'admin theme') as $callback) {
        if (!empty($data[$callback])) {
          $theme[$data[$callback]] = array(
            'variables' => array('css_id' => NULL, 'content' => NULL, 'settings' => NULL, 'display' => NULL, 'layout' => NULL, 'renderer' => NULL),
            'path' => $data['path'],
            'file' => $data['file'],
          );

          // if no theme function exists, assume template.
          if (!function_exists("theme_$data[theme]")) {
            $theme[$data[$callback]]['template'] = str_replace('_', '-', $data[$callback]);
            $theme[$data[$callback]]['file'] = $data['file']; // for preprocess.
          }
        }
      }
    }
  }
  return $theme;
}

/**
 * Retrieve layouts for the specified theme.
 */
function context_panels_layouts_get_layouts($theme = NULL, $reset = FALSE) {
  static $layouts = array();
  $layouts = $reset ? array() : $layouts;
  static $panels_layouts = array();
  $panels_layouts = empty($panels_layouts) || $reset ? _context_panels_layouts_get_panels_layout_data() : $panels_layouts;

  $theme = isset($theme) ? $theme : variable_get('theme_default', 'bartik');

  if (!isset($layouts[$theme])) {
    $info = $theme_info = system_get_info('theme', $theme);
    $themes = array();

    // Find all our ancestor themes that use layouts.
    if (isset($info['base theme'])) {
      while (!empty($info['base theme'])) {
        $base_theme = $info['base theme'];
        $info = system_get_info('theme', $base_theme);
        $themes[$base_theme] = $info;
      }
    }

    // Assemble in inheritance order and add the theme on.
    $themes = array_reverse($themes);
    $themes[$theme] = $theme_info;

    // Merge layout info into a single array.
    foreach ($themes as $key => $theme_info) {
      if (!empty($theme_info['layouts'])) {
        foreach ($theme_info['layouts'] as $layout => $layout_info) {
          if (!isset($layout_info['regions'])) {
            $layout_info['layout'] = str_replace('-', '_', $layout);
            $layout_info['theme'] = $key;
            $layouts[$theme][$layout] = $layout_info;
          }
        }
      }
    }
    if (!empty($panels_layouts)) {
      if (!isset($layouts[$theme])) {
        $layouts[$theme]['default'] = array(
          'name' => t('Default'),
          'description' => t('Use the default layout for !theme.', array('!theme' => $info['name'])),
          'regions' => array_keys($info['regions']),
        );
      }
      $layouts[$theme] = array_merge($layouts[$theme], $panels_layouts);
    }
  }
  return isset($layouts[$theme]) ? $layouts[$theme] : FALSE;
}

 /**
 * Return data for panels-style layouts.
 */
function _context_panels_layouts_get_panels_layout_data() {
  $layouts = array();
  $panels_layouts = context_panels_layouts_get_panels_layouts();
  foreach ($panels_layouts as $name => $layout) {
    if (!empty($layout['regions'])) {
      $layout_info = array(
        'key' => $name,
        'name' => $layout['title'],
        'type' => 'panels',
        // Usually empty.
        'description' => isset($layout['description']) ? $layout['description'] : NULL,
        'theme_hook' => $layout['theme'],
        'panels' => $layout['regions'],
        'regions' => array(),
        'path' => $layout['path'],
        'stylesheet' => isset($layout['css']) ? $layout['css'] : NULL,
      );
      if (isset($layout['content_region'])) {
        $layout_info['content_region'] = $layout['content_region'];
      }
      foreach ($layout['regions'] as $key => $title) {
        $layout_info['regions'][] = 'context_panels_layouts_' . $key;
      }
      $layouts[$name] = $layout_info;
    }
  }
  return $layouts;
}

/**
 * Implements hook_ctools_plugin_directory().
 *
 * Return data for panels plugins but not for context, since context
 * maintains its own registry.
 */
function context_panels_layouts_ctools_plugin_directory($module, $plugin) {
  if ($module == 'panels' && !module_exists('panels')) {
    return 'plugins/' . $plugin;
  }
}

/**
 * Implements hook_ctools_plugin_type().
 *
 * Register layout, style, cache, and display_renderer plugin types, declaring
 * relevant plugin type information as necessary.
 */
function context_panels_layouts_ctools_plugin_type() {
  $data = array();
  if (!module_exists('panels')) {
    $data['layouts'] = array(
      'load themes' => TRUE, // Can define layouts in themes
      'process' => 'context_panels_layouts_process',
      'child plugins' => TRUE,
      // Emulate panels so that other modules providing panels layouts will
      // be recognized.
      'module' => 'panels',
      'hook' => 'panels_layouts',
    );
  }
  return $data;
}

/**
 * Ensure a layout has a minimal set of data.
 */
function context_panels_layouts_process(&$plugin) {
  $plugin += array(
    'category' => t('Miscellaneous'),
    'description' => '',
  );
}

