<?php

include_once('panopoly_magic.features.inc');

/**
 * Implements hook_init()
 */
function panopoly_magic_init() {
  // Override the Chaos Tools Modal Default Settings
  $default_style = array(
    'CToolsModal' => array(
      'modalSize' => array(
        'type' => 'scale',
        'width' => '.9',
        'height' => '.9',
        'addWidth' => 0,
        'addHeight' => 0,
        'contentRight' => 25,
        'contentBottom' => 75,
      ),
      'modalOptions' => array(
        'opacity' => '.55',
        'background-color' => '#FFF',
      ),
      'animationSpeed' => 'fast',
      'modalTheme' => 'CToolsModalDialog',
      'throbberTheme' => 'CToolsModalThrobber',
    ),
  );
  $modal_style = variable_get('panopoly_magic_modal_style', $default_style);
  drupal_add_js($modal_style, 'setting');
}

/**
 * Implements hook_apps_app_info()
 */
function panopoly_magic_apps_app_info() {
  return array(
    'configure form' => 'panopoly_magic_configure_form',
  );
}

/**
 * Implements hook_theme().
 */
function panopoly_magic_theme($existing, $type, $theme, $path) {
  return array(
    'panopoly_magic_stylizer_preview_form' => array(
      'render element' => 'form',
    ),
  );
}

/**
 * Implements hook_menu_alter().
 */
function panopoly_magic_menu_alter(&$items) {
  // Include entity_field.inc from ctools to ensure that files can be properly removed 
  // from within the panelizer edit forms.
  $items['file/ajax']['file'] = 'entity_field.inc';
  $items['file/ajax']['file path'] = drupal_get_path('module', 'ctools') . '/plugins/content_types/entity_context';
}

/**
 * Configuration Form for Panopoly Magic
 */
function panopoly_magic_configure_form($form, &$form_state) {
  $form = array();

  $form['panopoly_magic_live_preview'] = array(
    '#title' => t('Live Preview'),
    '#type' => 'select',
    '#required' => TRUE,
    '#options' => array(
      '1' => 'Automatic',
      '2' => 'Manual',
      '0' => 'Disabled',
    ),
    '#default_value' => variable_get('panopoly_magic_live_preview', 1),
    '#description' => t('Do you want Panopoly to provide a live preview for modal content through the in place editor?'),
  );

  $form['panopoly_magic_pane_add_preview'] = array(
    '#title' => t('Enable previews when adding panes'),
    '#type' => 'select',
    '#required' => TRUE,
    '#options' => array(
      '1' => t('Enabled'),
      '0' => t('Disabled'),
    ),
    '#default_value' => variable_get('panopoly_magic_pane_add_preview', 1),
    '#description' => t('Do you want to automatically generate previews when adding existing panels panes through the IPE?'),
  );

  $form['panopoly_magic_show_panels_styles'] = array(
    '#title' => t('Show seldom used panels pane styles'),
    '#type' => 'select',
    '#required' => TRUE,
    '#options' => array(
      '1' => t('Yes'),
      '0' => t('No'),
    ),
    '#default_value' => variable_get('panopoly_magic_show_panels_styles', 0),
    '#description' => t('Do you want to show seldom used pane styles such as "no markup at all"?'),
  );

  $form['panopoly_magic_strip_js_from_preview'] = array(
    '#title' => t('Strip embedded .js from previews'),
    '#type' => 'select',
    '#required' => TRUE,
    '#options' => array(
      '1' => t('Enabled'),
      '0' => t('Disabled'),
    ),
    '#default_value' => variable_get('panopoly_magic_strip_js_from_preview', 0),
    '#description' => t('Some embedded javascript may cause issues with panopoly and the IPE, stripping the .js from your previews will fix this issue, but may alter the look of the preview.'),
  );

  return system_settings_form($form);
}

/**
 * Implements hook_module_implements_alter()
 */
function panopoly_magic_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'form_alter') {
    $group = $implementations['panopoly_magic'];
    unset($implementations['panopoly_magic']);
    $implementations['panopoly_magic'] = $group;
  }
}

/**
 * Implements hook_form_alter()
 */
function panopoly_magic_form_alter(&$form, &$form_state, $form_id) {
  /**
   * Add a custom preview to the content type edit form and style edit form. This is applied in all cases, except for cases where
   * we are customizing an entity (i.e. fieldable panels panes) because we cannot reliable regenerate a preview without saving.
   */
  $ids_to_alter = array(
    'panels_edit_style_settings_form',
    'panels_edit_style_type_form',
    'ctools_entity_field_content_type_formatter_options',
    'ctools_entity_field_content_type_formatter_styles',
  );
  if (variable_get('panopoly_magic_live_preview', 1) && (strpos($form_id, '_content_type_edit_form') || in_array($form_id, $ids_to_alter))) {

    // Start the magic
    $pane = $form_id == 'panels_edit_style_settings_form' ? $form_state['display']->content[$form_state['pid']] : $form_state['pane'];
    $display = $form_state['display'];
    ctools_include('plugins', 'panels');
    ctools_include('content');

    // Do some special processing for stylizer settings forms to ensure previews work correctly.
    if ($form_id == 'panels_edit_style_settings_form') {

      if (!empty($form_state['style']) && is_array($form_state['style'])) {
        $form_state['style'] = $form_state['style']['name'];
      }

      if (!empty($form_state['values']['settings'])) {
        $form_state['conf'] = $form_state['values']['settings'];
      }

      if (!empty($form_state['values']['settings'])) {
        $pane->style = array(
          'settings' => $form_state['values']['settings'],
          'style' => $form_state['style'],
        );
      }
    }

    // Determine the style
    if (strpos($form_id, '_content_type_edit_form') || $form_id == 'ctools_entity_field_content_type_formatter_options') {
      $style = (isset($pane->style['style'])) ? panels_get_style($pane->style['style']) : NULL;
    }
    elseif ($form_id == 'panels_edit_style_type_form') {
      $style = ($form_state['rebuild'] && $form_id == 'panels_edit_style_type_form') ? panels_get_style($form_state['values']['style']) : panels_get_style($form_state['style']);
    }
    elseif ($form_id == 'panels_edit_style_settings_form') {
      $style = panels_get_style($form_state['style']);
    }
    else {
      $style = NULL;
    }

    // EXPERIEMENTAL: Handling Saving a Fieldable Panel Pane To Create a Live Preview. The trick
    // here is to make sure we properly save a version to get a vid, but don't make it the real one.
    // NOTE - I doubt this will be very good for performance. Let's call it RC1.
    $clicked_button = empty($form_state['clicked_button']['#value']) ? '' : $form_state['clicked_button']['#value'];
    if ($form_id == 'fieldable_panels_panes_fieldable_panels_pane_content_type_edit_form' && ($clicked_button == 'Update Preview' || ($form_state['op'] == 'add' && empty($form_state['input']['form_build_id'])))) {

      // Do not run this through validation since it creates a wierd experience
      // TODO - extend this to other elements that might have validation hooks on them (i.e. link fields)
      $form['#validate'] = array();

      // Determine the current VID for the element
      if (!empty($form_state['entity']->fpid)) {
        $current_vid = db_query("SELECT vid FROM {fieldable_panels_panes} WHERE fpid = :fpid", array(':fpid' => $form_state['entity']->fpid))->fetchField();
      }

      // Run entity information through standard submission form if this is a new or updated object
      // Update the pane settngs with the VID afterwards
      if (!$form_state['entity']->reusable || $form_state['op'] != 'add' || $form_state['rebuild'] == TRUE) {
        // Process the entity to create a preview. Set the FPID to be the correct version. We need to 
        // generate a fake set of values to avoid notices from FPP as per http://drupal.org/node/1791734.
        $default_values = array(
          'language' => '',
          'title' => '',
          'link' => '',
          'path' => '',
          'reusable' => '',
          'category' => '',
          'admin_title' => '',
          'admin_description' => '',
          'revision' => '',
        );

        if (!empty($form_state['values'])) {
          $form_state['values'] = array_merge($default_values, $form_state['values']);
        }
        else {
          $form_state['values'] = $default_values;
        }


        fieldable_panels_panes_entity_edit_form_submit($form, $form_state);
        $preview_subtype = 'vid:' . $form_state['entity']->vid;
        $pane->subtype = 'fpid:' . $form_state['entity']->fpid;
      }

      // Properly adjust the VID if we are dealing with an existing object
      if (!empty($current_vid)) {
        db_query("UPDATE {fieldable_panels_panes} SET vid = :vid WHERE fpid = :fpid", array(':vid' => $current_vid, ':fpid' => $form_state['entity']->fpid));
      }
    }

    // Make some adjustments based on the way the data is being expected
    // TODO - this should not be necessary, so find out why!
    if (!empty($form_state['input']['sort_by'])) {
      $form_state['input']['exposed']['sort_by'] = $form_state['input']['sort_by'];
      $form_state['input']['exposed']['sort_order'] = $form_state['input']['sort_order'];
    }
    if (!empty($form_state['input']['exposed']['more_link'])) {
      $form_state['input']['more_link'] = $form_state['input']['exposed']['more_link'];
      $form_state['input']['path'] = $form_state['input']['exposed']['path'];
    }
    if (!empty($form_state['input']['exposed']['link_to_view'])) {
      $form_state['input']['link_to_view'] = $form_state['input']['exposed']['link_to_view'];
      $form_state['input']['path'] = $form_state['input']['exposed']['path'];
    }
    if (!empty($form_state['input']['exposed']['use_pager'])) {
      $form_state['input']['use_pager'] = $form_state['input']['exposed']['use_pager'];
      $form_state['input']['offset'] = $form_state['input']['exposed']['offset'];
    }

    // Set the configuration and determine the content for the pane
    $configuration_ids = array(
      'ctools_entity_field_content_type_formatter_options',
      'ctools_entity_field_content_type_formatter_styles',
      'panels_edit_style_settings_form',
    );
    $configuration = ($form_state['rebuild'] && (strpos($form_id, 'content_type_edit_form') || in_array($form_id, $configuration_ids))) ? array_merge($pane->configuration, $form_state['input']) : $pane->configuration;
   
    $keywords = array();
    $args = array();
    if (!empty($form_state['contexts'])) {
      $context = $form_state['contexts'];
    }
    elseif (!empty($form_state['display']->context)) {
      $context = $form_state['display']->context;
    }
    else {
      $context = array();
    }
   
    // Special case for panelizer fields being edited through the IPE. For some reason images are not being fully loaded
    if (!empty($pane->configuration['formatter']) && $pane->configuration['formatter'] == 'image') {
      list($entity_type, $field_name) = explode(':', $pane->subtype);
      if (!empty($form_state['entity']) && !empty($form_state['entity']->$field_name)) {
        $form_state['entity']->{$field_name}[LANGUAGE_NONE][0] = array_merge((array) file_load($form_state['entity']->{$field_name}[LANGUAGE_NONE][0]['fid']), $form_state['entity']->{$field_name}[LANGUAGE_NONE][0]);
      }

      if (!empty($configuration['image_style']) ) {
        $configuration['formatter_settings']['image_style'] = $configuration['image_style'];
        unset($configuration['image_style']);
      }

      if (!empty($configuration['image_link'])) {
        $configuration['formatter_settings']['image_link'] = $configuration['image_link'];
        unset($configuration['image_link']);
      }
    }
    $content = (empty($preview_subtype)) ? ctools_content_render($pane->type, $pane->subtype, $configuration, $keywords, $args, $context) : ctools_content_render($pane->type, $preview_subtype, $configuration, $keywords, $args, $context);

    // Create the preview fieldset
    if ($form_id == 'fieldable_panels_panes_fieldable_panels_pane_content_type_edit_form' || is_object($content)) {

      // Create the fieldset with appropriate content
      $form['widget_preview'] = array(
        '#type' => 'fieldset',
        '#title' => t('Preview'),
        '#attributes' => array('class' => array('widget-preview', 'widget-preview-single')),
        '#collapsible' => FALSE,
        '#weight' => -100,
      );
      $form['widget_preview']['preview'] = array(
        '#markup' => (!empty($style['render pane'])) ? theme($style['render pane'], array('content' => $content, 'pane' => $pane, 'display' => $display, 'style' => $style, 'settings' => $pane->style['settings'])) : theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $display)),
      );

      // Remove the clearfix for preview floating
      if (isset($form['aligner_start'])) {
        $form['aligner_start']['#markup'] = str_replace('clearfix', '', $form['aligner_start']['#markup']);
      }

      $preview_attributes = array(
        'class' => array(
          'widget-preview-button',
          'ctools-use-ajax',
        ),
      );

      // If live previewing, don't show button, and autoupdate.
      if (variable_get('panopoly_magic_live_preview', 1) == 1) {
        $preview_attributes['style'] = 'display: none';
        $preview_attributes['class'][] = 'ctools-auto-submit-click';
      }

      // Create the preview refresh button
      $form['buttons']['preview'] = array(
        '#type' => 'button',
        '#value' => t('Update Preview'),
        '#wizard type' => 'next',
        '#attributes' => $preview_attributes,
      );

      // Autosubmit the form
      ctools_add_js('auto-submit');
      $form['#attributes']['class'][] = 'ctools-auto-submit-full-form';
    }
  }
  
   /**
   * Globally improve the buttons for the Chaos Tools Content Type Settings Forms
   */
  if (strpos($form_id, 'content_type_edit_form') || $form_id == 'ctools_entity_field_content_type_formatter_options') {
    $form['buttons']['cancel']['#access'] = FALSE;
    if (!empty($form['buttons']['return'])) {
      $form['buttons']['return']['#value'] = t('Save');
    }
    $form['buttons']['#weight'] = (!empty($form['widget_preview']['#weight'])) ? ($form['widget_preview']['#weight'] +1 ): -99;
  }

  /**
   * Globally make sure that all options are inside a fieldset. Currently just supporting a known list
   * of forms, but persumably this can be applied to all items eventually.
   */
  $forms_to_improve = array(
    'panopoly_search_search_box_content_type_edit_form',
    'menu_block_menu_tree_content_type_edit_form',
    'ctools_node_content_content_type_edit_form',
    'ctools_entity_field_content_type_formatter_options',
    'panopoly_search_facet_content_type_edit_form',
    'ctools_entity_field_content_type_formatter_styles',
    'panels_edit_style_settings_form'
  );

  if (in_array($form_id, $forms_to_improve)) {
  
    // Grab child elements and create the fieldset.
    $children = element_children($form);
    if (count($children) > 1) {
      $form['general_settings'] = array(
        '#type' => 'fieldset',
        '#title' => t('General Settings'),
        '#weight' => -30,
      );

      // Move all elements which aren't fieldsets or the submit buttons into the general settings fieldset.
      foreach ($children as $child) {
        if ((!empty($form[$child]['#type']) || !empty($form[$child]['#tree'])) && $form[$child]['#type'] != 'fieldset' && $child != 'buttons' && $child != 'submit') {
          $form['general_settings'][$child] = $form[$child];
          unset($form[$child]);
        }
      }

      // Don't show the context when it is the only one
      if (!empty($form['general_settings']['context']) && count($form['general_settings']['context']['#options']) == 1) { 
        $form['general_settings']['context']['#type'] = 'value';
        $form['general_settings']['context']['#value'] = $form['general_settings']['context']['#default_value'];
      }

      // Don't show the override title text field unless we are overriding
      if (!empty($form['general_settings']['override_title_text'])) {
        $form['general_settings']['override_title_text']['#dependency_type'] = 'hide';
      }

      // Deal with cases where there is override title markup
      if (!empty($form['override_title_markup'])) {
        $form['override_title_markup']['#access'] = FALSE;
      }
    }
  }
}

/**
 * Recursively parse form elements to add special autosubmit handling on a per field-type basis.
 */
function panopoly_magic_autosubmit_configure(&$element) {
  if (!empty($element['#type'])) {
    switch ($element['#type']) {
      case 'textfield':
        // Special handling for autosubmit.
        if (!empty($element['#autocomplete_path'])) {
          $element['#attributes']['class'][] = 'ctools-auto-submit-exclude panopoly-autocomplete-autosubmit';
        }
        else {
          $element['#attributes']['class'][] = 'ctools-auto-submit-exclude panopoly-textfield-autosubmit';
        }
        break;
      case 'text_format':
        $element['#attributes']['class'][] = 'ctools-auto-submit-exclude panopoly-textarea-autosubmit';
        break;
      default:
        break;
    }
  }

  $children = element_children($element);
  
  if (!empty($children) && is_array($children)) {
    foreach ($children as $child) {
      panopoly_magic_autosubmit_configure($element[$child]);
    }
  }
}

/** 
 * Implementation of hook_form_FORM_ID_alter()
 */
function panopoly_magic_form_fieldable_panels_panes_fieldable_panels_pane_content_type_edit_form_alter(&$form, &$form_state, $form_id) {

  // Setup the live preview 
  if (variable_get('panopoly_magic_live_preview', 1)) {
    panopoly_magic_autosubmit_configure($form);

    // Special case exclusions for tablefield specific elements. 
    if ($form_state['entity']->bundle == 'table') {
      $form['field_basic_table_table'][LANGUAGE_NONE][0]['tablefield']['rebuild']['count_cols']['#attributes']['class'] = array('ctools-auto-submit-exclude');
      $form['field_basic_table_table'][LANGUAGE_NONE][0]['tablefield']['rebuild']['count_rows']['#attributes']['class'] = array('ctools-auto-submit-exclude');
    }
  }

  // Add custom validation function for the reusable title
  if (!empty($form_state['clicked_button']) && $form_state['clicked_button']['#value'] != 'Update Preview') {
    $form['reusable']['admin_title']['#element_validate'][] = 'panopoly_magic_reusable_entity_validate';
  }

  // Customize the view mode setting
  if (!empty($form['view_mode'])) {
    unset($form['view_mode']['#options']['token']);
    if (count($form['view_mode']['#options']) < 2) {
      $form['view_mode']['#type'] = 'value';
      $form['view_mode']['#value'] = reset($form['view_mode']['#options']);
    }
    $form['widget_settings']['view_mode'] = $form['view_mode'];
    unset($form['view_mode']);
  }

  // Improving the general title setting
  if (!empty($form['widget_settings']['title'])) {
    $form['widget_settings']['title']['#size'] = '';
  }
  
  // Improving the link Options
  if (!empty($form['widget_settings']['link'])) {
    $form['widget_settings']['link']['path']['#size'] = '';
    $form['widget_settings']['link']['path']['#field_prefix'] =  $form['widget_settings']['link']['path']['#title'];
    $form['widget_settings']['link']['path']['#title'] = '';
    $form['widget_settings']['link']['path']['#description'] = t('The URL or Drupal path from which to build the link.');
    $form['widget_settings']['link']['link']['#description'] = '';
  }
  
  // Move the reusable option to the general settings
  if (!empty($form['reusable'])) {
    $form['reusable']['#type'] = '';
    $form['reusable']['#title'] = '';
    $form['reusable']['reusable']['#title'] = t('Make this reusable');
    $form['reusable']['admin_title']['#field_prefix'] = t('Admin Title');
    $form['reusable']['admin_title']['#title'] = '';
    $form['reusable']['admin_title']['#size'] = '';
    $form['reusable']['admin_title']['#description'] = '';
    $form['widget_settings']['reusable'] = $form['reusable'];
    unset($form['reusable']);
  }
}

/** 
 * Implementation of hook_form_FORM_ID_alter()
 *
 * Provides customizations to the views content type settings form
 */
function panopoly_magic_form_views_content_views_panes_content_type_edit_form_alter(&$form, &$form_state, $form_id) {

  // Get the configuration
  $conf = $form_state['conf'];
  
  // Add a widget title setting if views allows this to be customized
  if (!empty($form['override_title'])) {
    $form['override_title_markup']['#access'] = FALSE;
    $form['override_title']['#access'] = FALSE;
    $form['override_title_text']['#access'] = FALSE;
    $form['exposed']['widget_title'] = array(
      '#field_prefix' => t('Title'),
      '#type' => 'textfield',
      '#size' => '',
      '#weight' => -100,
      '#states' => array(
        'visible' => array(
          ':input[name="override_title"]' => array('value' => '1'),
        ),
      ),
      '#default_value' => (isset($conf['widget_title'])) ? $conf['widget_title'] : $form_state['view']->display_handler->options['title'],
    );
  }

  // Add an option to make the widget title a link if views allows this to happen
  if (!empty($form['link_to_view']) && !empty($form['path'])) {
    $form['link_to_view']['#title'] = t('Make title a link');
    $form['link_to_view']['#description'] =  '';
    $form['link_to_view']['#id'] = 'edit-link';
    $form['exposed']['link_to_view'] = $form['link_to_view'];
    unset($form['link_to_view']);
  } 
  
  // Add an option to make the more link available if views allows this to happen
  if (!empty($form['more_link'])) {
    $form['more_link']['#id'] = 'more-link';
    $form['more_link']['#description'] = '';
    $form['exposed']['more_link'] = $form['more_link'];
    unset($form['more_link']);
  }
  
    
  // Update the field settings for pagers
  if (!empty($form['use_pager']) && !empty($form['pager_id'])) {
    $form['use_pager']['#prefix'] = '<div class="form-item container-inline">';
    $form['exposed']['use_pager'] = $form['use_pager'];
    $form['exposed']['pager_id'] = $form['pager_id'];
    unset($form['use_pager']);
    unset($form['pager_id']);
  }
  
  // Handle the path value that views gives us
  if (!empty($form['path'])) {
    $form['path']['#description'] = t('The URL path used for linking and paging purposes. Leave blank to use the current page.');
    $form['path']['#title'] = '';
    $form['path']['#dependency'] = array('edit-link' => array(1), 'more-link' => array(1), 'use-pager-checkbox' => array(1));
    $form['exposed']['path'] = $form['path'];
    unset($form['path']);
  }
  
  // Adjust the items per page and offset settings
  if (!empty($form['items_per_page']) && !empty($form['offset'])) {
    $form['items_per_page']['#field_prefix'] = t('Items to Show');
    $form['items_per_page']['#title'] = '';
    $form['items_per_page']['#description'] = t('Enter 0 to display all.');
    $form['display_settings']['items_per_page'] = $form['items_per_page'];
    unset($form['items_per_page']);
    $form['offset']['#field_prefix'] = t('Items to Skip');
    $form['offset']['#title'] = '';
    $form['offset']['#description'] = t('Enter 0 to skip none.');
    $form['offset']['#suffix'] = '<div class="clearfix"></div>';
    $form['display_settings']['offset'] = $form['offset'];
    unset($form['offset']);
  }
  elseif (!empty($form['items_per_page']) && empty($form['offset'])) {
    $form['items_per_page']['#field_prefix'] = t('Items to Show');
    $form['items_per_page']['#title'] = '';
    $form['items_per_page']['#description'] = t('Enter 0 to display all.');
    $form['items_per_page']['#suffix'] = '<div class="clearfix"></div>';
    $form['display_settings']['items_per_page'] = $form['items_per_page'];
    unset($form['items_per_page']);
  }
  elseif (empty($form['items_per_page']) && !empty($form['offset'])) {
    $form['offset']['#field_prefix'] = t('Items to Skip');
    $form['offset']['#title'] = '';
    $form['offset']['#description'] = t('Enter 0 to skip none.');
    $form['offset']['#suffix'] = '<div class="clearfix"></div>';
    $form['display_settings']['offset'] = $form['offset'];
    unset($form['offset']);
  }
  
  // Adjust the sort ordering and sort by options
  if (!empty($form['exposed']['sort_order']) && !empty($form['exposed']['sort_by'])) {
    $form['exposed']['sort_order']['#title'] = t('Sort order');
    $form['display_settings']['sort_order'] = $form['exposed']['sort_order'];
    unset($form['exposed']['sort_order']);
    $form['exposed']['sort_by']['#suffix'] = '<div class="clearfix"></div>';
    $form['display_settings']['sort_by'] = $form['exposed']['sort_by'];
    unset($form['exposed']['sort_by']);
  }
  elseif (!empty($form['exposed']['sort_order']) && empty($form['exposed']['sort_by'])) {
    $form['exposed']['sort_order']['#title'] = t('Sort order');
    $form['exposed']['']['#suffix'] = '<div class="clearfix"></div>';
    $form['display_settings']['sort_order'] = $form['exposed']['sort_order'];
    unset($form['exposed']['sort_order']);
  }
  elseif (empty($form['exposed']['sort_order']) && !empty($form['exposed']['sort_by'])) {
    $form['exposed']['sort_by']['#suffix'] = '<div class="clearfix"></div>';
    $form['display_settings']['sort_by'] = $form['exposed']['sort_by'];
    unset($form['exposed']['sort_by']);
  }

  // Adjust the field setting options
  if (isset($form['fields_override'])) {
    $form['fields_override']['#title'] = t('Field Settings');
    $form['fields_override']['#collapsible'] = FALSE;
    foreach ($form['fields_override'] as &$field) {
      if (is_array($field)) {
        $field['#title'] = t('Display') . ' ' . $field['#title'];
      }
    }
  }

  // Determine if this is a fielded view. If so, add magic display type changer
  $view_handler = $form_state['view']->display_handler;
  if ($view_handler->options['row_plugin'] == 'fields') {

    // Default to a field view
    if (empty($conf['view_settings'])) {
      $conf['view_settings'] = 'fields';
    }

    // Add information about the View Mode
    $form['display_settings']['view_settings'] = array(
      '#type' => 'radios',
      '#prefix' => '<div class="view-settings-wrapper"><span class="field-prefix">' . t('Display Type') . '</span>',
      '#suffix' => '</div>',
      '#default_value' => $conf['view_settings'],
      '#weight' => 10,
      '#options' => array(
        'fields' => t('Fields'),
        'nodes' => t('Content'),
        'table' => t('Table'),
      ),
    );

    // Add header column options for table views.
    $form['display_settings']['header_type'] = array(
      '#type' => 'select',
      '#title' => t('Column Header'),
      '#options' => array(
        'none' => t('None'),
        'titles' => t('Titles'),
      ),
      '#default_value' => !empty($conf['header_type']) ? $conf['header_type'] : 'none',
      '#states' => array(
        'visible' => array(
          ':input[name="view_settings"]' => array('value' => 'table'),
        ),
      ),
      '#weight' => 11,
    );

    // Update the field overrides to be dependent on the view settings selection.
    $form['fields_override']['#states'] = array(
      // The inverted logic here isn't optimal, and in the future may be better achieved via OR'd conditions.
      // @link http://drupal.org/node/735528 @endlink
      'invisible' => array(
        ':input[name="view_settings"]' => array('value' => 'nodes'), 
      ),
    );
  }

  // Add specific style options.
  $form['content_settings']['view_mode'] = array(
    '#type' => 'radios',
    '#options' => panopoly_magic_view_mode_options(),
    '#default_value' => $conf['view_mode'] ? $conf['view_mode'] : 'teaser',
    '#states' => array(
      'visible' => array(
        ':input[name="view_settings"]' => array('value' => 'nodes'),
      ),
    ),
  );
   
  // Define a general settings fieldset if we have exposed values
  if (!empty($form['exposed']) && count(element_children($form['exposed'])) > 0) {
    $form['exposed']['#type'] = 'fieldset';
    $form['exposed']['#title'] = t('General Settings');
    $form['exposed']['#weight'] = -30;
    $form['exposed']['#attributes'] = array('class' => array('general-settings-fieldset'));
  }

  // Define a context settings fieldset if we have exposed values
  if (!empty($form['context']) && count(element_children($form['context'])) > 0) {
    $form['context']['#type'] = 'fieldset';
    $form['context']['#title'] = t('Context Settings');
    $form['context']['#weight'] = -29;
  }

  // Define a content settings fieldset if we have exposed values
  if (!empty($form['content_settings']) && count(element_children($form['content_settings'])) > 0) {
    $form['content_settings']['#type'] = 'fieldset';
    $form['content_settings']['#title'] = t('Content Settings');
    $form['content_settings']['#weight'] = -27;
  }
  
  // Define a display settings fieldset if we have display options
  if (!empty($form['display_settings']) && count(element_children($form['display_settings'])) > 0) {
    $form['display_settings']['#type'] = 'fieldset';
    $form['display_settings']['#title'] = t('Display Settings');
    $form['display_settings']['#weight'] = -28;
  }

  // Add auto submit functionality
  if (variable_get('panopoly_magic_live_preview', 1)) {
    panopoly_magic_autosubmit_configure($form);
  }

  // Add a custom submit handler to our preview and submit option
  $form['#submit'][] = 'panopoly_magic_views_content_type_modal_submit';
  $form['buttons']['preview']['#submit'][] = 'panopoly_magic_views_content_type_modal_submit';
}

/**
 * Implementation of hook_form_FORM_ID_alter()
 *
 * Provides customization to entity formatter option form
 */
function panopoly_magic_form_ctools_entity_field_content_type_formatter_options_alter(&$form, &$form_state, $form_id) {

  // Get the configuration
  $conf = $form_state['conf'];

  // Move the title for the label and formatter to be the field prefix
  foreach (array('label', 'formatter') as $field) {
    if (!empty($form['general_settings'][$field])) {
      $form['general_settings'][$field]['#field_prefix'] = $form['general_settings'][$field]['#title'];
      $form['general_settings'][$field]['#title'] = '';
    }
  }

  // Add in the field edit fields with FAPE if we are not editing a default
  if (empty($form_state['entity']) && !empty($form_state['display']->context['panelizer']->data)) {
    // Determine what entity type and field name we are editing based on the form subtype and URL args.
    $arg_parts = explode(':', arg(4));
    list($entity_type, $field_name) = explode(':', $form_state['subtype_name']);
    $entity = reset(entity_load($entity_type, array($arg_parts[2])));

    // Unfortunately the above code is not as reliable as we'd like. There are cases where the field we're editing
    // doesn't have an corrosponding entity (say, comments). Let's make sure we have an entity before adding FAPE specific
    // data into the form.
    if (!empty($entity)) {
      $form_state['entity'] = $entity;
      $form_state['entity_type'] = $entity_type;
      $form_state['field_name'] = $field_name;
      $form_state['bundle'] = empty($entity->bundle) ? $entity->type : $entity->bundle;
      $form_state['field_instance'] = field_info_instance($entity_type, $field_name, $form_state['bundle']);
      $form_state['langcode'] = LANGUAGE_NONE;
      $form_state['subform_id'] = 'fape_field_edit_field_form';
    }
  }

  // Ensure form id, form token, and form build id are on the root of the form.
  // Image fields in particular have issues with this.
  $form['form_id'] = $form['general_settings']['form_id'];
  $form['form_token'] = $form['general_settings']['form_token'];
  $form['form_build_id'] = $form['general_settings']['form_build_id'];
  unset($form['general_settings']['form_id']);
  unset($form['general_settings']['form_token']);
  unset($form['general_settings']['form_build_id']);

  if (!empty($form_state['entity'])) {
    // Add the field edit form.
    fape_field_edit_field_form($form, $form_state);

    // Remove the default submitter in favor of our own custom submit callback.
    array_pop($form['#submit']);
    $form['#submit'][] = 'panopoly_magic_fape_submit';
  }
  // Pre-rende fields into a fieldset.
  $form['#pre_render'][] = 'panopoly_magic_panelizer_pre_render';

  // When moving backwards through form steps, ensure image widgets properly retain their value.
  if (!empty($form_state['field_instance']) && $form_state['clicked_button']['#value'] == 'Back') {
    $field_name = $form_state['field_instance']['field_name'];
    $field_type = $form_state['field_instance']['widget']['module'];
    $entity = $form_state['entity'];
 
    // Reset the #default_value to the (currently) unsaved entity value.
    if ($field_type == 'image' && !empty($form[$field_name])) {
      $field = $entity->$field_name;
      foreach ($field[LANGUAGE_NONE] as $delta => $value) {
        $form[$field_name][LANGUAGE_NONE][$delta]['#default_value'] = $value;
      } 
    }
  }

  // Enable auto submit functionality
  if (variable_get('panopoly_magic_live_preview', 1)) {
    panopoly_magic_autosubmit_configure($form);
  }

  // Add a custom submit handler to our preview and submit option
  $form['#submit'][] = 'panopoly_magic_views_content_type_modal_submit';
  $form['buttons']['preview']['#submit'][] = 'panopoly_magic_views_content_type_modal_submit';
}

/**
 * Implement the "Content Settings" fieldset in a pre-render. This fixes issues with image caused by initially
 * doing this in a form_alter.
 *
 * @see http://drupal.org/node/1567704
 */
function panopoly_magic_panelizer_pre_render($element) {
  $exclude_list = array(
    'form_id',
    'form_token',
    'form_build_id',
    'buttons',
  );

  // Add any remaining fields to the content settings fieldset.
  foreach (element_children($element) as $key) {
    $value = $element[$key];
    if (!in_array($key, $exclude_list) && !empty($value['#type']) && $value['#type'] != 'fieldset') {
      if (empty($element['content_settings'])) {
        // Add a content settings fieldset.
        $element['content_settings'] = array(
          '#type' => 'fieldset',
          '#title' => t('Content Settings'),
          '#weight' => 1,
        );
      }

      $element['content_settings'][$key] = $value;
      unset($element[$key]);
    }
  }

  return $element;
}

function panopoly_magic_form_ctools_entity_field_content_type_formatter_styles_alter(&$form, &$form_state, $form_id) {
  // Push the panopoly magic submitter onto the front of the submit array.
  // We need it at the beginning so the entity is saved before the IPE 
  // reloads pane content.
  if (!empty($form_state['entity'])) {
    $form['#submit'][] = 'panopoly_magic_fape_submit';
  }
}

/**
 * Custom submit callback for FAPE enabled stylizer forms.
 */
function panopoly_magic_fape_submit(&$form, &$form_state) {
  // If there isn't a next step save the entity.
  if ((empty($form_state['clicked_button']['#next']) || !empty($form_state['field']['body'])) && !empty($form_state['entity'])) {
    entity_save($form_state['entity_type'], $form_state['entity']);
    $form_state['display_cache']->display->context['panelizer']->data = $form_state['entity'];
  }
  // Otherwise we're on step 1, so just run the FAPE submitter.
  else {
    fape_field_edit_field_form_submit($form, $form_state);
  }
}

/** 
 * Implementation of hook_form_FORM_ID_alter().
 *
 * Provides customization to panel pane style form
 */
function panopoly_magic_form_panels_edit_style_type_form_alter(&$form, &$form_state, $form_id) {

  if (!variable_get('panopoly_magic_show_panels_styles', 0)) {
    // Unset options for which we have no need
    unset($form['style']['#options']['block']);
    unset($form['style']['#options']['rounded_corners']);
    unset($form['style']['#options']['naked']);
  }

  // Better explain that "No Style" means "Default Pane Style"
  // Move the default option to the top. Also I should have learned
  // how to manage arrays in PHP.
  if (!empty($form['style']['#options']['default'])) {
    $form['style']['#options']['default'] = t('Default Pane Style');
    $default = $form['style']['#options']['default'];
    unset($form['style']['#options']['default']);
    $form['style']['#options'] = array_reverse($form['style']['#options']);
    $form['style']['#options']['default'] = $default;
    $form['style']['#options'] = array_reverse($form['style']['#options']);
  }

  // Better title for the List Style region style plugin
  if (!empty($form['style']['#options']['list'])) {
    $form['style']['#options']['list'] = t('List Style');
  }

  // Improve the UI around region style selections
  if (!empty($form['style']['#options'][0])) {
    $form['style']['#options'][0] = t('Default Region Style');
    if (empty($form['style']['#default_value']) || $form['style']['#default_value'] == '-1') {
      $form['style']['#default_value'] = '0';
    }
    unset($form['style']['#options']['default']);
  }

  // Move custom style option to bottom of list.
  if (!empty($form['style']['style']['#options']['stylizer'])) {
    unset($form['style']['style']['#options']['stylizer']);
    $form['style']['style']['#options']['stylizer'] = t('Custom Style');
  }

  // Adding a fieldset around styling
  $form['style'] = array('style' => $form['style']);
  $form['style']['#type'] = 'fieldset';
  $form['style']['#title'] = t('Style Settings');
}

/**
 * Implementation of hook_form_FORM_ID_alter().
 *
 * Provide customizations for the ctools stylizer edit form.
 */
function panopoly_magic_form_ctools_stylizer_edit_style_form_default_alter(&$form, &$form_state, $form_id) {
  // If Auto-submit is enabled.
  if (variable_get('panopoly_magic_live_preview', 1)) {

    // Customize the settings preview button.
    $form['top box']['preview']['submit']['#attributes'] = array(
      'class' => array('widget-preview-button', 'ctools-use-ajax', 'ctools-auto-submit-click'),
    );

    // Autosubmit the form.
    ctools_add_js('auto-submit');
    $form['#attributes']['class'][] = 'ctools-auto-submit-full-form';
    $form['top box']['preview']['#theme'] = 'panopoly_magic_stylizer_preview_form';

  }

  // Change the Weight Around
  $form['top box']['preview']['#weight'] = -50;
}

/**
 * Theme the stylizer preview form.
 */
function theme_panopoly_magic_stylizer_preview_form($vars) {
  $form = &$vars['form'];
  $plugin = $form['#form_state']['base_style_plugin'];
  $settings = $form['#form_state']['settings'];

  if (!empty($form['#form_state']['settings']['old_settings'])) {
    ctools_stylizer_cleanup_style($plugin, $form['#form_state']['settings']['old_settings']);
  }
  $preview = '';
  if (!empty($plugin['preview'])) {
    $preview = $plugin['preview'];
  }
  else {
    $base_types = ctools_get_style_base_types();
 
    if (!empty($base_types[$plugin['module']][$plugin['type']]['preview'])) {
      $preview = $base_types[$plugin['module']][$plugin['type']]['preview'];
    }
  }

  if (!empty($preview) && function_exists($preview)) {
    $output = '<fieldset id="preview" class="widget-preview-single"><legend>' . t('Preview') . '</legend><div class="fieldset-wrapper">';
    $output .= $preview($plugin, $settings);
    $output .= drupal_render_children($form);
    $output .= '</div></fieldset>';
    return $output;
  }
}

/**
 * Implementation of hook_form_FORM_ID_alter().
 *
 * Provide customizations for the ctools stylizer edit choose form.
 */
function panopoly_magic_form_ctools_stylizer_edit_style_form_choose_alter(&$form, &$form_state, $form_id) {

  // Remove the rounded corners options
  if (!empty($form['style_base']['Basic-styles']['pane_rounded_shadow'])) {
    unset($form['style_base']['Basic-styles']['pane_rounded_shadow']);
  }
  if (!empty($form['style_base']['Basic-styles']['region_rounded_shadow'])) {
    unset($form['style_base']['Basic-styles']['region_rounded_shadow']);
  }
}

/**
 *  Validator to ensure that reusable entites have titles.
 */
function panopoly_magic_reusable_entity_validate($element, &$form_state, $form) {
  // If the reusable entity checkbox is selected.
  if (!empty($form_state['values']['reusable'])) {
    // Ensure a title is present.
    if (empty($element['#value'])) {
      form_error($element, t('If you would like this entity to be reusable, please add a title.'));
    }
  }
}

/**
 * Custom submit handler to save panels pane configuration for styling
 */
function panopoly_magic_views_content_type_modal_submit(&$form, &$form_state) {
  $form_state['conf']['view_mode'] = (isset($form_state['values']['view_mode'])) ? $form_state['values']['view_mode'] : NULL;

  // Set the $conf['widget_title'] value. We need to do this a
  // little funky since sometimes it comes inside of $form_state['values']
  // and sometimes it doesn't.
  if (isset($form_state['values']['exposed']['widget_title'])) {
    $form_state['conf']['widget_title'] = $form_state['values']['exposed']['widget_title'];
  }
  elseif (isset($form_state['values']['widget_title'])) {
    $form_state['conf']['widget_title'] = $form_state['values']['widget_title'];
  }
  else {
    $form_state['conf']['widget_title'] = NULL;
  }

  // Set the $conf['items_per_page'] value. We need to do this a
  // little funky since sometimes it comes inside of $form_state['values']
  // and sometimes it doesn't.
  if (isset($form_state['values']['exposed']['items_per_page'])) {
    $form_state['conf']['items_per_page'] = $form_state['values']['exposed']['items_per_page'];
  }
  elseif (isset($form_state['values']['items_per_page'])) {
    $form_state['conf']['items_per_page'] = $form_state['values']['items_per_page'];
  }
  else {
    $form_state['conf']['items_per_page'] = NULL;
  }

  // Set the $conf['sort_by'] value. We need to do this a
  // little funky since sometimes it comes inside of $form_state['values']
  // and sometimes it doesn't.
  if (isset($form_state['values']['display_settings']['sort_by'])) {
    $form_state['conf']['exposed']['sort_by'] = $form_state['values']['display_settings']['sort_by'];
  } 
  elseif (isset($form_state['values']['sort_by'])) {
    $form_state['conf']['exposed']['sort_by'] = $form_state['values']['sort_by'];
  }   
  else {
    $form_state['conf']['exposed']['sort_by'] = NULL;
  } 

  // Set the $conf['sort_order'] value. We need to do this a
  // little funky since sometimes it comes inside of $form_state['values']
  // and sometimes it doesn't.
  if (isset($form_state['values']['display_settings']['sort_order'])) {
    $form_state['conf']['exposed']['sort_order'] = $form_state['values']['display_settings']['sort_order'];
  } 
  elseif (isset($form_state['values']['sort_order'])) {
    $form_state['conf']['exposed']['sort_order'] = $form_state['values']['sort_order'];
  }   
  else {
    $form_state['conf']['exposed']['sort_order'] = NULL;
  } 

  // Set the $conf['use_pager'] value. We need to do this a
  // little funky since sometimes it comes inside of $form_state['values']
  // and sometimes it doesn't.
  if (isset($form_state['values']['display_settings']['use_pager'])) {
    $form_state['conf']['use_pager'] = $form_state['values']['display_settings']['use_pager'];
  } 
  elseif (isset($form_state['values']['use_pager'])) {
    $form_state['conf']['use_pager'] = $form_state['values']['use_pager'];
  }   
  else {
    $form_state['conf']['use_pager'] = NULL;
  } 
  
  // Set the $conf['pager_id'] value. We need to do this a
  // little funky since sometimes it comes inside of $form_state['values']
  // and sometimes it doesn't.
  if (isset($form_state['values']['display_settings']['pager_id'])) {
    $form_state['conf']['pager_id'] = $form_state['values']['display_settings']['pager_id'];
  } 
  elseif (isset($form_state['values']['pager_id'])) {
    $form_state['conf']['pager_id'] = $form_state['values']['pager_id'];
  }   
  else {
    $form_state['conf']['pager_id'] = NULL;
  } 

  // Set the $conf['offset'] value. We need to do this a
  // little funky since sometimes it comes inside of $form_state['values']
  // and sometimes it doesn't.
  if (isset($form_state['values']['display_settings']['offset'])) {
    $form_state['conf']['offset'] = $form_state['values']['display_settings']['offset'];
  } 
  elseif (isset($form_state['values']['offset'])) {
    $form_state['conf']['offset'] = $form_state['values']['offset'];
  }   
  else {
    $form_state['conf']['offset'] = NULL;
  } 

  // Set the $conf['link_to_view'] value. We need to do this a
  // little funky since sometimes it comes inside of $form_state['values']
  // and sometimes it doesn't.
  if (isset($form_state['values']['exposed']['link_to_view'])) {
    $form_state['conf']['link_to_view'] = $form_state['values']['exposed']['link_to_view'];
  } 
  elseif (isset($form_state['values']['link_to_view'])) {
    $form_state['conf']['link_to_view'] = $form_state['values']['link_to_view'];
  }   
  else {
    $form_state['conf']['link_to_view'] = NULL;
  } 
  
  // Set the $conf['more_link'] value. We need to do this a
  // little funky since sometimes it comes inside of $form_state['values']
  // and sometimes it doesn't.
  if (isset($form_state['values']['exposed']['more_link'])) {
    $form_state['conf']['more_link'] = $form_state['values']['exposed']['more_link'];
  } 
  elseif (isset($form_state['values']['more_link'])) {
    $form_state['conf']['more_link'] = $form_state['values']['more_link'];
  }   
  else {
    $form_state['conf']['more_link'] = NULL;
  } 

  // Set the $conf['path'] value. We need to do this a
  // little funky since sometimes it comes inside of $form_state['values']
  // and sometimes it doesn't.
  if (isset($form_state['values']['exposed']['path'])) {
    $form_state['conf']['path'] = $form_state['values']['exposed']['path'];
  } 
  elseif (isset($form_state['values']['link_to_view'])) {
    $form_state['conf']['path'] = $form_state['values']['path'];
  }   
  else {
    $form_state['conf']['path'] = NULL;
  } 
  
  // Save the view settings field is present in the data.
  if (isset($form_state['values']['view_settings'])) {
    $form_state['conf']['view_settings'] = $form_state['values']['view_settings'];
  }
  if (!empty($form_state['values']['header_type'])) {
    $form_state['conf']['header_type'] = $form_state['values']['header_type'];
  }
}

/**
 * Implements hook_views_pre_render()
 */
function panopoly_magic_views_pre_render(&$view) {
  if (isset($view->display_handler->options['pane_conf'])) {
    $conf = $view->display_handler->options['pane_conf'];
  
    // Set the view title depending on where it comes. We do this a little
    // funky since sometimes it comes inside of $form_state['values'] and 
    // sometimes it doesn't.
    if (isset($conf['widget_title']) || isset($conf['exposed']['widget_title'])) {
      $view->display_handler->options['title'] = (isset($conf['exposed']['widget_title'])) ? $conf['exposed']['widget_title'] : $conf['widget_title']; 
      $view->build_info['title'] = (isset($conf['exposed']['widget_title'])) ? $conf['exposed']['widget_title'] : $conf['widget_title']; 
    }

    // Determine that this was previously a field view, which has been overridden to a node view in the pane config.
    if (!empty($conf['view_settings']) && $conf['view_settings'] == 'nodes' && empty($view->style_plugin->row_plugin->nodes)) {

      // Reconstruct the nodes array which a node row style expects.
      if (!empty($view->result)) {
        $nids = array();
        foreach ($view->result as $result) {
          if (!empty($result->nid)) {
            $nids[] = $result->nid;
          }
        }
        $nodes = node_load_multiple($nids);
      }

      // Change the row plugin.
      if (!empty($nodes)) {
        $view->style_plugin->row_plugin = views_get_plugin('row', 'node');
        $view->style_plugin->row_plugin->view =& $view;
        $view->style_plugin->row_plugin->display =& $view->display_handler->display;
        $view->style_plugin->row_plugin->field_alias = 'nid';
        $view->style_plugin->row_plugin->nodes = $nodes;
      }
    }
    // Set the style plugin to a table style.
    elseif (!empty($conf['view_settings']) && $conf['view_settings'] == 'table') {
      $row_plugin = $view->style_plugin->row_plugin;
      $view->style_plugin = views_get_plugin('style', 'table');
      $view->style_plugin->row_plugin = $row_plugin;
      $view->style_plugin->view =& $view;
      $view->style_plugin->display =& $view->display_handler->display;
      
      // Set or remove header labels depending on user selection.
      $use_header_titles = !empty($conf['header_type']) && $conf['header_type'] == 'titles';
      foreach ($view->field as &$field) {
        if ($use_header_titles && !empty($field->options['ui_name']) && empty($field->options['label'])) {
          $field->options['label'] = $field->options['ui_name'];
        }
        elseif (!$use_header_titles) {
          $field->options['label'] = NULL;
        }
        // Hide empty columns.
        if (!empty($view->style_plugin->row_plugin->options['hide_empty'])) {
          $view->style_plugin->options['info'][$field->field]['empty_column'] = TRUE;
        }
      }
    }

    // Set the view mode
    if (!empty($conf['view_mode'])) {
      $view->style_plugin->row_plugin->options['view_mode'] = $conf['view_mode'];
    }
  }
}

/**
 * Preprocess the panels_ipe_toolbar to change text for IPE buttons
 */
function panopoly_magic_preprocess_panels_ipe_toolbar(&$vars) {
  foreach ($vars['buttons'] as $panel_context_id => $panel_context) {
    foreach ($panel_context as $button_name => $button) {
      switch ($button_name) {
        case 'panels-ipe-startedit':
          $vars['buttons'][$panel_context_id][$button_name]['#title'] = t('Customize this page');
          break;
        case 'panels-ipe-change-layout':
          $vars['buttons'][$panel_context_id][$button_name]['#title'] = t('Change this layout');
          break;
      }
    }
  }
}

/**
 * Preprocess the panels_add_content_modal() function to add the HTML for the preview
 */
function panopoly_magic_preprocess_panels_add_content_modal(&$vars) {
  // Generate the pane preview
  if (!empty($vars['categories'][$vars['category']]['content'])) {
    foreach ($vars['categories'][$vars['category']]['content'] as &$plugin) {
      $use_preview = variable_get('panopoly_magic_pane_add_preview', 1);
      $strip_js = variable_get('panopoly_magic_strip_js_from_preview', 0);
      $query = drupal_get_query_parameters();
      $preview_panes = (!empty($query['preview_panes'])) ? explode(',', $query['preview_panes']) : array();

      // Determine if we should show a preview for this pane.
      if (!empty($use_preview) || in_array($plugin['subtype_name'], $preview_panes)) {
        $pane = panels_new_pane($plugin['type_name'], $plugin['subtype_name'], TRUE);
        $display = $vars['renderer']->display;
        $context = $vars['renderer']->display->context;
        $args = $vars['renderer']->display->args;
        $incoming_content = $vars['renderer']->display->incoming_content;
        $keywords = (!empty($vars['renderer']->display->keywords)) ? $vars['renderer']->display->keywords : array();
        if ($content = ctools_content_render($pane->type, $pane->subtype, $pane->configuration, $keywords, $args, $context, $incoming_content)) {
          $plugin['preview'] = theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $display));
          if (!empty($strip_js) && !empty($plugin['preview'])) {
            $plugin['preview'] = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $plugin['preview']);
          }
        }
      }
      else {

        // If we can't preview then generate a preview link.
        $preview = empty($query['preview_panes']) ? $plugin['subtype_name'] : $query['preview_panes'] . ',' . $plugin['subtype_name'];
        $options = array(
          'query' => array('preview_panes' => $preview),
          'attributes' => array('class' => array('use-ajax button'))
        );
        $plugin['preview'] = '<div class="modal-content-preview-button">' . l(t('Preview'), current_path(), $options) . '</div>';
      }
    }
  }
}

/** 
 * Process the panels_add_content_modal() to adjust the markup to present the preview
 */
function panopoly_magic_process_panels_add_content_modal(&$vars) {
  $content = !empty($vars['categories'][$vars['category']]['content']) ? $vars['categories'][$vars['category']]['content'] : array();

  // If no category is selected or the category is empty or our special empty
  // category render a 'header' that will appear instead of the columns.
  if (empty($vars['category']) || empty($content) || $vars['category'] == 'root') {
    // Nothing to do since there is no preview
  }
  else {
    $titles = array_keys($content);
    natcasesort($titles);
    $col_size = count($titles) / $vars['column_count'];

    // Zero out the existing column data
    $count = 0;
    foreach ($titles as $title) {
      $which = floor($count++ / $col_size) + 1;
      $vars['columns'][$which] = '';
    }

    // Read the column data with our preview functionality
    $count = 0;
    foreach ($titles as $title) {
      $which = floor($count++ / $col_size) + 1;
      $content[$title]['title'] = 'Add';
      $vars['columns'][$which] .= '<fieldset class="widget-preview"><legend><div class="widget-preview-title">' . theme('panels_add_content_link', array('renderer' => $vars['renderer'], 'region' => $vars['region'], 'content_type' => $content[$title])) . '</div><span class="fieldset-legend">' . $title . '</span></legend><div class="fieldset-wrapper">' . (!empty($content[$title]['preview']) ? $content[$title]['preview'] : t('No Preview')) . '</div></fieldset>';
    }
  }
}

/**
 * Helper function to get view modes
 */
function panopoly_magic_view_mode_options() {
  $entity_info = entity_get_info('node');
  $options = array();
  if (!empty($entity_info['view modes'])) {
    foreach ($entity_info['view modes'] as $mode => $settings) {
      if (!in_array($mode, array('rss', 'search_index', 'search_result', 'token'))) {
        $options[$mode] = $settings['label'];
      }
    }
  }
  return $options;
}

