<?php

/**
 * @file
 * Adds new styles based on sprites.
 *
 * This plugin implements the rendering based on CSS sprites,
 * generating automatically the needed files and providing
 * two extra styles.
 *
 * @author Fabio Mucciante (TheCrow)
 */

define('SLS_GD_WIDTH', 0);
define('SLS_GD_HEIGHT', 1);
define('SLS_GD_MIME', 'mime');

define('SLS_FILENAME', 'sl_sprites');

/**
 * Implements hook_init().
 */
function service_links_sprites_init() {
  if (variable_get('service_links_use_internal_sprites', 0)) {
    drupal_add_css(variable_get('file_public_path', conf_path() . '/files') . '/' . SLS_FILENAME . '.css');
  }
}

/**
 * Build the CSS file and images.
 */
function sls_build_sprites($files = array()) {
  $sprite_filename = variable_get('file_public_path', conf_path() . '/files') . '/' . SLS_FILENAME;
  $tot_height = array();
  $images = array();
  $sizes = array();
  //potrebbe essere configurabile
  $css_str = ".service-links ul.links li{display:inline-block;}\n.sprites.service-links span{display:block;}\n.service-links span.hide{display:none;}\n.sprites.service-links {background-repeat: no-repeat; float:left;}\n";

  foreach ($files as $service_id => $file) {
    if (is_file($file)) {
      $img_details = getimagesize($file);

      if (!isset($images[$img_details[SLS_GD_WIDTH]])) {
        $images[$img_details[SLS_GD_WIDTH]] = array();
      }

      $images[$img_details[SLS_GD_WIDTH]][$service_id] = array(
        'height' => $img_details[SLS_GD_HEIGHT],
        'file' => $file,
        'mime' => $img_details[SLS_GD_MIME],
      );

      if (!isset($tot_height[$img_details[SLS_GD_WIDTH]])) {
        $tot_height[$img_details[SLS_GD_WIDTH]] = 0;
      }

      $tot_height[$img_details[SLS_GD_WIDTH]] += (int)$img_details[SLS_GD_HEIGHT];
    }
  } 

  foreach ($images as $width => $image) {
    $img_dest = @imagecreatetruecolor($width, $tot_height[$width]);
    $background = @imagecolorallocatealpha($img_dest, 255, 255, 255, 127);
    @imagefill($img_dest, 0, 0, $background);
    @imagealphablending($img_dest, FALSE);
    @imagesavealpha($img_dest, TRUE);

    $y = 0;
    $padding = $width + 2;
    $css_str .= ".sprites.service-links.w$width {padding-left: {$padding}px; background-image:url(\"" . SLS_FILENAME . "$width.png\");}\n";

    foreach ((array)$image as $service_id => $img_details) {
      switch ($img_details['mime']) {
      case 'image/png':
        $img_src = @imagecreatefrompng($img_details['file']);
        break;
      case 'image/jpeg':
        $img_src = @imagecreatefromjpeg($img_details['file']);
        break;
      case 'image/gif':
        $img_src = @imagecreatefromgif($img_details['file']);
        break;
      default:
        continue;
      }

      $class = str_replace('_', '-', $service_id);
      $sign = ($y > 0) ? '-' : '';
      $css_str .= ".sprites.service-links-$class {background-position: 0 {$sign}{$y}px; height:{$img_details['height']}px}\n";
      @imagecopy($img_dest, $img_src, 0, $y, 0, 0, $width, $img_details['height']);
      @imagedestroy($img_src);
      $y += $img_details['height'];
      $sizes[$img_details['file']] = $width;
    }

    imagepng($img_dest, $sprite_filename . $width . '.png');
    imagedestroy($img_dest);
  }

  $css_fhandler = fopen($sprite_filename . '.css', 'w');
  if (($css_fhandler) && !empty($css_str)) {
    fwrite($css_fhandler, $css_str);
    fclose($css_fhandler);
  }

  variable_set('service_links_sprites_sizes', $sizes);
}

/**
 * Implements hook_form_alter().
 */
function service_links_sprites_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'service_links_admin_settings') {
    $form['buttons']['#weight'] = 100;
    $form['sprites'] = array(
      '#type' => 'fieldset',
      '#collapsible' => TRUE,
      '#collapsed' => FALSE,
      '#title' => t('Sprites'),
    );
    $form['sprites']['service_links_use_internal_sprites'] = array(
      '#type' => 'checkbox',
      '#title' => t('Load the CSS file generated by Service Links'),
      '#default_value' => variable_get('service_links_use_internal_sprites', 0),
      '#description' => t('Service Links will build the files needed everytime the modifies are saved in Services tab.'),
    );
  }

  if ($form_id == 'service_links_admin_services') {
    $form['#validate'][] = 'service_links_sprites_validate';
  }
}

function service_links_sprites_validate($form, &$form_state) {
  $services = array_keys(array_filter($form_state['values']['service_links_show']));
  $services = service_links_get_links($services);
  $paths = array();
  foreach ($services as $service_id => $service) {
    $icon = isset($service['icon']) ? $service['icon'] : $service_id . '.png';
    $paths[$service_id] = service_links_expand_path($icon);
  }

  sls_build_sprites($paths);
}

/**
 * Implements hook_sl_styles().
 */
function service_links_sprites_sl_styles($nodelink = FALSE) {
  return array(
    'sls_style_image' => t('Only Image (with Sprite)'),
    'sls_style_image_and_text' => t('Image and Text (with Sprite)'),
  );
}

/**
 * Implements hook_theme().
 */
function service_links_sprites_theme() {
  return array(
    'sls_style_image' => array(
      'variables' => array(
        'text' => NULL,
        'url' => array(),
        'image' => NULL,
        'nodelink' => NULL,
        'attributes' => array(),
      ),
    ),
    'sls_style_image_and_text' => array(
      'variables' => array(
        'text' => NULL,
        'url' => array(),
        'image' => NULL,
        'nodelink' => NULL,
        'attributes' => array(),
      ),
    ),
  );
}

function theme_sls_style_image($variables) {
  $text = $variables['text'];
  $url = $variables['url'];
  $image = $variables['image'];
  $nodelink = $variables['nodelink'];
  $attributes = $variables['attributes'];

  $width = sls_get_image_size(service_links_expand_path($image));
  $attributes['class'][] = "sprites service-links w$width";

  if ($nodelink) {
    $query = isset($url[1]) ? $url[1] : NULL;

    return array(
      'title' => '<span class="hide">' . $text . '</span>',
      'href' => $url[0],
      'query' => $query,
      'attributes' => $attributes,
      'html' => TRUE,
    );
  }
  else {
    $attributes = array_merge($attributes, array('html' => TRUE));
    if (isset($url[1])) {
      $attributes['query'] = $url[1];
    }

    return l('<span class="hide">' . $text . '</span>', $url[0], $attributes);
  }
}

function theme_sls_style_image_and_text($variables) {
  $text = $variables['text'];
  $url = $variables['url'];
  $image = $variables['image'];
  $nodelink = $variables['nodelink'];
  $attributes = $variables['attributes'];

  $width = sls_get_image_size(service_links_expand_path($image));
  $attributes['class'][] = "sprites service-links w$width";

  if ($nodelink) {
    $query = isset($url[1]) ? $url[1] : NULL;
    
    return array(
      'title' => $text,
      'href' => $url[0],
      'query' => $query,
      'attributes' => $attributes,
    );
  }
  else {
    if (isset($url[1])) {
      $attributes['query'] = $url[1];
    }
    return l($text, $url[0], $attributes);
  }
}

function sls_get_image_size($filepath = '') {
  static $sizes;

  if (!isset($sizes)) {
    $sizes = variable_get('service_links_sprites_sizes', array());
  }

  if (isset($sizes[$filepath])) {
    return $sizes[$filepath];
  }
  else {
    return 16;
  }
}
