<?php
// $Id: file_text.module,v 1.21 2009/03/26 23:30:54 miglius Exp $

/**
 * @file
 * Supports text file formats.
 */

//////////////////////////////////////////////////////////////////////////////

define('FILE_TEXT_PREVIEW_LINES',  variable_get('file_text_preview_lines', '0'));
define('FILE_TEXT_PREVIEW_STRING', variable_get('file_text_preview_string', '<----- End of Preview ----->'));
define('FILE_TEXT_CODE',           variable_get('file_text_code', 0));

//////////////////////////////////////////////////////////////////////////////
// Core API hooks

/**
 * Implementation of hook_theme().
 */
function file_text_theme() {
  return array(
    'file_text_text_render' => array(
      'arguments' => array('options' => NULL),
      'file' => 'file_text.theme.inc'
    ),
    'file_text_code_render' => array(
      'arguments' => array('options' => NULL),
      'file' => 'file_text.theme.inc'
    ),
  );
}

/**
 * Implementation of hook_menu().
 */
function file_text_menu() {
  return array(
    'admin/settings/file/format/text' => array(
      'title' => 'Texts',
      'description' => 'Manage the text files.',
      'page callback' => 'drupal_get_form',
      'page arguments' => array('file_text_admin_settings'),
      'access arguments' => array('administer site configuration'),
      'file' => 'file_text.admin.inc',
    ),
  );
}

//////////////////////////////////////////////////////////////////////////////
// File API hooks

/**
 * Implementation of hook_mime_handlers().
 */
function file_text_mime_handlers() {
  return array(
    'file_text_text' => array(
      'name' => t('Text'),
      'dimensions' => '580x350',
      'weight' => 1,
    ),
    'file_text_code' => array(
      'name' => t('Code'),
      'dimensions' => '590x360',
      'parent' => 'file_text_text',
      'weight' => 2,
    ),
  );
}

/**
 * Implementation of hook_mime_types().
 */
function file_text_mime_types() {
  return array(
    'text/plain' => array(
      'name' => t('Plain text document'),
      'handlers' => array('file_text_text'),
      'extensions' => array('txt'), // to use as a first extension instead of asc as defined in mime.type
    ),
    'text/html' => array(
      'name' => t('HTML document'),
      'handlers' => array('file_text_txt'),
    ),
    'text/css' => array(
      'name' => t('CSS stylesheet'),
      'handlers' => array('file_text_text'),
    ),
    'text/sgml' => array(
      'name' => t('SGML document'),
      'handlers' => array('file_text_text'),
      'extensions' => array('sgml'),
    ),
    'application/xml' => array(
      'name' => t('XML document'),
      'handlers' => array('file_text_text'),
      'icon' => 'xml.gif',
    ),
    'application/xslt+xml' => array(
      'name' => t('XSLT document'),
      'handlers' => array('file_text_txt'),
    ),
    'application/xhtml+xml' => array(
      'name' => t('XHTML document'),
      'handlers' => array('file_text_txt'),
    ),
    'text/csv' => array(
      'name' => t('CSV text document'),
      'handlers' => array('file_text_text'),
    ),
    'text/x-c++hdr' => array(
      'name' => t('C++ document'),
      'handlers' => array('file_text_text'),
    ),
    'text/x-c++src' => array(
      'name' => t('C++ document'),
      'handlers' => array('file_text_text'),
    ),
  );
}

/**
 * Implementation of hook_mime_converters().
 */
function file_text_mime_converters() {
  return array(
    'text/html' => array(
      'text/plain' => array(
        'pipeline' => '[out_content] = {strip_tags}([in_content])||[out_content] = {html_entity_decode}([in_content])',
        'handlers' => array('file_text_text'),
      ),
    ),
  );
}

/**
 * Implementation of hook_metadata_info().
 */
function file_text_metadata_info() {
  $info = array(
    'wordnet:characters' => array('name' => t('Characters')),
    'wordnet:words' => array('name' => t('Words')),
    'wordnet:lines' => array('name' => t('Lines')),
  );
  return $info;
}

/**
 * Implementation of hook_metadata_parse().
 */
function file_text_metadata_parse($filename, $mimetype) {
  if (!array_key_exists($mimetype, file_text_mime_types()))
    return NULL;

  $text = file_get_contents($filename);
  return array(
    'wordnet:characters' => array((int)(drupal_strlen($text) - substr_count($text, ' ') - substr_count($text, "\n"))),
    'wordnet:words'      => array((int)str_word_count($text)),
    'wordnet:lines'      => array((int)substr_count($text, "\n")),
  );
}

//////////////////////////////////////////////////////////////////////////////
// MIME handlers

/**
 * Generates a text preview.
 */
function file_text_text_generate($file, $tier = NULL) {
  if (isset($tier) && !in_array($file->handlers[$tier], isset($file->previews[$file->mimes[$tier]]) ? $file->previews[$file->mimes[$tier]] : array())) {
    if (!file_get_converted($file, $tier))
      return FALSE;
    if (!file_data_save($file, $tier))
      return FALSE;
    watchdog('file_text', 'The %mime preview was generated for the file %name, uri=%uri.', array('%mime' => $file->mimes[$tier], '%name' => $file->filename, '%uri' => $file->uri), WATCHDOG_NOTICE, isset($file->nid) ? l(t('view'), 'node/'. $file->nid) : NULL);
  }

  if (!isset($tier) && FILE_TEXT_CODE) {
    $tier = 0;
    $file->converters[$tier] = array('pipeline' => '{code2html} --fallback ruby "[in_file]" "[out_file]"');
    $file->handlers[$tier] = 'file_text_code';
    $file->mimes[$tier] = 'text/html';
    if (!in_array($file->handlers[$tier], isset($file->previews[$file->mimes[$tier]]) ? $file->previews[$file->mimes[$tier]] : array())) {
      if (!file_get_converted($file, $tier))
        return FALSE;
      if (!file_data_save($file, $tier))
        return FALSE;
      watchdog('file_text', 'The %mime preview was generated for the file %name, uri=%uri.', array('%mime' => $file->mimes[$tier], '%name' => $file->filename, '%uri' => $file->uri), WATCHDOG_NOTICE, isset($file->nid) ? l(t('view'), 'node/'. $file->nid) : NULL);
      file_delete($file->converted[$tier]->filepath);
      unset($file->converted[$tier]);
    }
  }
  return TRUE;
}

/**
 * Implements a plain text handler.
 */
function file_text_text_render($uri, $options = array()) {
  $options = array_merge($options, _file_text_render_options($uri, $options));
  return theme('file_text_text_render', $options);
}

/**
 * Implements a code text handler.
 */
function file_text_code_render($uri, $options = array()) {
  $options = array_merge($options, _file_text_render_options($uri, $options));
  return theme('file_text_code_render', $options);
}

//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions

/**
 * Renders options for the text display.
 */
function _file_text_render_options($uri, $options = array()) {
  $text = bitcache_get_contents(file_get_hash($uri));
  if (FILE_TEXT_PREVIEW_LINES > 0) {
    $text = explode("\n", $text);
    $lines = count($text);
    if ($lines > FILE_TEXT_PREVIEW_LINES) {
      for ($i = FILE_TEXT_PREVIEW_LINES; $i < $lines; $i++) {
        unset($text[$i]);
      }
      $append = "\n". FILE_TEXT_PREVIEW_STRING;
    }
    $text = implode("\n", $text);

  }

  return array_merge($options, compact('uri', 'text', 'append'));
}

