<?php
// $Id: smileys.module,v 1.48.2.18 2010/04/07 16:38:51 Gurpartap Exp $

/**
 * Implementation of hook_help().
 */
function smileys_help($path, $arg) {
  switch ($path) {
    case 'admin/settings/smileys':
    case 'admin/settings/smileys/list':
      return t('You can edit the Smileys that are recognized in your content.');
  }
}

/**
 * Implementation of hook_perm().
 */
function smileys_perm() {
  return array('administer smileys', 'use smiley select box');
}

/**
 * Implementation of hook_filter_tips().
 */
function smileys_filter_tips($delta, $format, $long = false) {
  if ($long) {
    return t('If you include a textual smiley in your post (see chart below), it will be replaced by a graphical smiley.') . '<br />' . smileys_table();
  }
  else {
    $GLOBALS['display_smileys_block'] = true;
    return t('<a href="!smileys_help">Textual smileys</a> will be replaced with graphical ones.', array('!smileys_help' => url('filter/tips/'. $format, array('fragment' => 'filter-smileys-'. $delta))));
  }
}

function _smileys_list($refresh = 0, $query_suffix = '') {
  static $list;
  if (!$list || $refresh) {
    $list = array();
    $result = db_query('SELECT * FROM {smileys} '. $query_suffix);
    while ($object = db_fetch_object($result)) {
      $list[] = $object;
    }
  }
  return $list;
}

/**
 * Implementation of hook_block().
 */
function smileys_block($op = 'list', $delta = 0) {
  if ($op == 'list') {
    $blocks[0]['info'] = t('Smileys on submission pages');
    return $blocks;
  }
  else if ($op == 'view') {
    switch ($delta) {
      case 0:
        $block['subject'] = t('Smileys');
        $block['content'] = $GLOBALS['display_smileys_block'] ? smileys_table() : '';
        return $block;
    }
  }
}

/**
 * Implementation of hook_form_alter().
 */
function smileys_form_alter(&$form, $form_state, $form_id) {
  if ($form_id != 'comment_form' && !isset($form['#node'])) {
    return;
  }

  if ($form_id == 'comment_form') {
    $node_type = db_result(db_query('SELECT type FROM {node} WHERE nid=%d', $form['nid']['#value']));
  }
  else if (!empty($form['type']['#value'])) {
    $node_type = $form['type']['#value'];
  }

  if (in_array($node_type, variable_get('smileys_node_types_content', array()), TRUE)) {
    if (user_access('use smiley select box') &&
      ((isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) &&
      variable_get('smileys_enable_for_nodes', 0) &&
      isset($form['body_field']) ||
      ('comment_form' == $form_id && variable_get('smileys_enable_for_comments', 0)))) {

      $output = '';
      if (array_key_exists('body_field', $form)) {
        $key = 'body_field';
      }
      elseif (array_key_exists('comment_filter', $form)) {
        $key = 'comment_filter';
      }
      else {
        $key = 'smileys_wrapper';
      }

      $collapsed = variable_get('smileys_select_box_expanded', TRUE) ? FALSE : TRUE;
      $form[$key]['smileys'] = array(
        '#type' => 'fieldset',
        '#title' => t('Smileys'),
        '#collapsible' => TRUE,
        '#collapsed' => $collapsed,
        '#weight' => 0,
        '#prefix' => '<div class="smileys-box">',
        '#suffix' => '</div>',
        );
      $form[$key]['smileys']['smileys_box'] = array(
        '#type' => 'markup',
        '#value' => theme('smileys_select_table', TRUE),
      );
      _smileys_add_files();
    }
  }

  return $form;
}

function _smileys_add_files() {
  static $files_added = FALSE;
  if (!$files_added) {
    // Add the JS and CSS
    $path = drupal_get_path('module', 'smileys');
    $dialog = variable_get('smileys_enable_dialog', TRUE);
    $draggable = variable_get('smileys_dialog_draggable', FALSE);
    $resizable = variable_get('smileys_dialog_resizable', FALSE);
    $width = variable_get('smileys_dialog_width', 400);
    $height = variable_get('smileys_dialog_height', 0);
    $jquery_ui = module_exists('jquery_ui');
    drupal_add_css($path . '/scripts/smileys.css');
    drupal_add_js(array(
      'smileys' => array(
        'enable_dialog' => $dialog,
        'draggable' => $draggable,
        'resizable' => $resizable,
        'dialog_width' => $width,
        'dialog_height' => $height,
      )
    ), 'setting');
    drupal_add_js($path . '/scripts/smileys.js');
    drupal_add_js($path . '/scripts/ui.core.dialog.js');
    if ($draggable) {
      $jquery_ui ? jquery_ui_add('ui.draggable') : drupal_add_js($path . '/scripts/ui.draggable.js');
    }
    if ($resizable) {
      $jquery_ui ? jquery_ui_add('ui.resizable') : drupal_add_js($path . '/scripts/ui.resizable.js');
    }
  }
}

function _smileys_select_table($promoted = false) {
  $content = '';
  $show_titles = variable_get('smileys_dialog_titles', TRUE) && !$promoted;
  if ($promoted == true) {
    $list = _smileys_list(1, " WHERE promote_to_box='1' ORDER BY weight");
  _smileys_list(1);
  }
  else {
    $list = _smileys_list(0 , " WHERE promote_to_box='0' ORDER by weight");
  }
  $first_package = NULL;
  if (!empty($show_titles)) {
    $first_package = $list[0]->package;
    $content .= '<fieldset><legend class="smileyPackageTitle">' . $first_package . '</legend>';
  }
  foreach ($list as $smiley) {
    $acronyms = explode(' ', $smiley->acronyms);
    $alt = check_plain(implode('  ', $acronyms));
    $desc = implode('&nbsp; ', $acronyms);
    if ($smiley->package != $first_package && !empty($show_titles)) {
      $content .= '</fieldset><fieldset><legend class="smileyPackageTitle">' . $smiley->package . '</legend>';
      $first_package = $smiley->package;
    }
    $content .= '<span>';
    $content .= theme_image(
      $smiley->image,
      $acronyms[0],
      $smiley->description . '  —  ' . $smiley->acronyms,
      array('class' => 'smiley-class')
    );
    $content .= '</span>';
  }
  $content .= !empty($show_titles) ? '</fieldset>' : '';
  return $content . (!$promoted ? '<br /><br />' : '');
}

/**
 * Implementation of hook_theme().
 */
function smileys_theme() {
  return array(
    'smileys_select_table' => array(
      'arguments' => array('promoted' => FALSE),
    ),
  );
}

function theme_smileys_select_table($promoted = false) {
  return '<div class="smileys">'. _smileys_select_table($promoted) .'</div>';
}

function smileys_table() {
  $form = array();
  $output = '';
  $header = array(t('Smiley'), t('Acronyms'));
  $rows = array();
  $list = _smileys_list(1, " ORDER BY weight");
  foreach ($list as $smiley) {
    $acronyms = explode(' ', $smiley->acronyms);
    $rows[] = array(
      '<img src="'. check_url($GLOBALS['base_url'] .'/'. $smiley->image) .'" alt="'. $acronyms[0] .'" title="'. check_plain($smiley->description) .'" class="smiley-class" />',
      check_plain($smiley->acronyms)
    );
  }
  $form['smileys'] = array(
    '#type' => 'fieldset',
    '#title' => t('Smileys'),
    '#collapsible' => TRUE,
  );
  $form['smileys']['smileys_box'] = array(
    '#type' => 'markup',
    '#value' => theme('table', $header, $rows),
  );
  $output .= drupal_render($form);
  return $output;
}

function smileys_list() {
  exit(_smileys_select_table());
}

/**
 * Implementation of hook_filter().
 */
function smileys_filter($op, $delta = 0, $format = -1, $text = "") {
  switch ($op) {
    case 'list':
      return array(0 => t('Smileys filter'));
    case 'description':
      return t('Replaces smileys inside posts with images.');
    case 'settings':
        $form['smileys_filter'] = array('#type' => 'fieldset', '#title' => t('Smileys filter'), '#value' => t('You can define a global list of smileys on the !page.', array('!page' => l(t('smileys settings page'), 'admin/settings/smileys'))));
      return $form;
    case "process":
      return smileys_filter_process($text);
    default:
      return $text;
  }
}

function smileys_filter_process($text) {
  $text = ' ' . $text . ' ';
  $list = _smileys_list(0, ' ORDER BY weight');

  // Don't process for <code> and <pre> elements.
  $chunks = preg_split('@(</?(?:code|pre)[^>]*>)@i', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
  $ignore = FALSE;
  $ignoretag = '';
  $output = '';
  foreach ($chunks as $i => $chunk) {
    if ($i % 2) {
      // Opening or closing tag?
      $open = ($chunk[1] != '/');
      list($tag) = split('[ >]', substr($chunk, 2 - $open), 2);
      if (!$ignore) {
        if ($open) {
          $ignore = TRUE;
          $ignoretag = $tag;
        }
      }
      // Only allow a matching tag to close it.
      else if (!$open && $ignoretag == $tag) {
        $ignore = FALSE;
        $ignoretag = '';
      }
    }
    else if (!$ignore) {
      foreach ($list as $smiley) {
        $acronyms = explode(" ", $smiley->acronyms);
        $alt = str_replace('\\', '\\\\', check_plain($smiley->description));
        foreach ($acronyms as $a) {
          if ($smiley->standalone)
            $chunk = eregi_replace("([ ,\.\?!:\(\)\r\n\<\>])". preg_quote($a) ."([ ,\.\?!:\(\)\r\n\<\>])", "\\1<img src=\"". check_url($GLOBALS['base_url'] .'/'. $smiley->image) ."\" title=\"". check_plain($alt) ."\" alt=\"". check_plain($alt) ."\" class=\"smiley-content\"/>\\2", $chunk);
          else
            $chunk = eregi_replace(preg_quote($a), '<img src="'. check_url($GLOBALS['base_url'] .'/'. $smiley->image) .'" title="'. check_plain($alt) .'" alt="'. check_plain($alt) .'" />', $chunk);
        }
      }
    }  
    $output .=  $chunk;
  }
  return $output;
}

/**
 * Implementation of hook_menu().
 */
function smileys_menu() {
  $items = array();

  $items['admin/settings/smileys'] = array(
    'title' => t('Smileys'),
    'description' => t('Manage Smileys and toggle select box behavior for nodes and comments.'),
    'page callback' => 'smileys_admin_list',
    'access arguments' => array('administer smileys'),
    'file' => 'smileys.admin.inc',
  );

  $items['admin/settings/smileys/list'] = array(
    'title' => t('List'),
    'page callback' => 'smileys_admin_list',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
    'file' => 'smileys.admin.inc',
  );

  $items['admin/settings/smileys/add'] = array(
    'title' => t('Add'),
    'page callback' => 'smileys_admin_add',
    'access arguments' => array('administer smileys'),
    'type' => MENU_LOCAL_TASK,
    'file' => 'smileys.admin.inc',
  );

  $items['admin/settings/smileys/configure'] = array(
    'title' => t('Settings'),
    'description' => t('Smileys configuration.'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array('smileys_admin_settings'),
    'access arguments' => array('administer smileys'),
    'weight' => 8,
    'type' => MENU_LOCAL_TASK,
    'file' => 'smileys.admin.inc',
  );

  $items['admin/settings/smileys/edit/%'] = array(
    'title' => t('Edit Smiley'),
    'page callback' => 'smileys_admin_add',
    'page arguments' => array(4),
    'access arguments' => array('administer smileys'),
    'type' => MENU_CALLBACK,
    'file' => 'smileys.admin.inc',
  );

  $items['admin/settings/smileys/delete/%'] = array(
    'title' => t('Delete Smiley'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array('smileys_admin_delete_confirm', 4),
    'access arguments' => array('administer smileys'),
    'type' => MENU_CALLBACK,
    'file' => 'smileys.admin.inc',
  );

  $items['admin/settings/smileys/category'] = array(
    'page callback' => 'smileys_category_handle',
    'access arguments' => array('administer smileys'),
    'type' => MENU_CALLBACK,
    'file' => 'smileys.admin.inc',
  );

  $items['admin/settings/smileys/promote'] = array(
    'page callback' => 'smileys_promote_handle',
    'access arguments' => array('administer smileys'),
    'type' => MENU_CALLBACK,
    'file' => 'smileys.admin.inc',
  );

  $items['admin/settings/smileys/weight'] = array(
    'page callback' => 'smileys_weight_handle',
    'access arguments' => array('administer smileys'),
    'type' => MENU_CALLBACK,
    'file' => 'smileys.admin.inc',
  );

  $items['smileys/fetch'] = array(
    'page callback' => 'smileys_list',
    'access arguments' => array('use smiley select box'),
    'type' => MENU_CALLBACK,
  );

  return $items;
}
