<?php if (!defined('HTTP_SERVER')) die('You can not access this file directly!');
/**
  @licence GPL 2005-2011  The osCSS developers - osCSS Open Source E-commerce
  @portion code Copyright (c) 2002 osCommerce
  @package osCSS-2 <www http://www.oscss.org>
  @version 2.1.0
  @date  27/03/11, 22:35
  @author oscim <mail aurelien@oscim.fr> <www http://www.oscim.fr> -Ayatus
  @encode UTF-8
  @class image_ratio
*/
class image_ratio {
  /**
    @var
  */
  protected static $key;
  /**
    @var
  */
  protected static $keydim;
  /**
    @var array cache image
  */
  protected static $CacheImage=array();
  /**
    @var current instance
  */
  protected static $_instance;
  /**
    @var support type images
  */
  private static $types = array (1 => "gif", "jpeg", "png");
  /**
    @var object param environnement exec
  */
  private static $env;
  /**
    PHP 5 Constructor
  */
  private function __construct() {

    self::$env = new stdClass();

    self::$env->cachedir = DIR_WS_IMAGES . 'imagecache/';

    umask(0);
    if (defined('DIR_WS_ADMIN')){
      self::$env->inadmin=true;
      !is_dir (DIR_FS_ADMIN.self::$env->cachedir) ? mkdir (DIR_FS_ADMIN.self::$env->cachedir, 0777) : @chmod (DIR_FS_ADMIN.self::$env->cachedir, 0777);
    }
    else{
      self::$env->inadmin=false;
    }
    !is_dir (DIR_FS_CATALOG.self::$env->cachedir) ? mkdir (DIR_FS_CATALOG.self::$env->cachedir, 0777) : @chmod (DIR_FS_CATALOG.self::$env->cachedir, 0777);

    self::$env->jpegquality = (defined('JPEG_QUALITY') ? JPEG_QUALITY :  95);

    self::$env->safemode=(!ini_get('safe_mode')? true : false );

    self::$env->Imagick=(class_exists('Imagick')? true : false);

    self::$env->img_required=(bool)_cst_bool('IMAGE_REQUIRED');

    self::$env->img_create=(bool)function_exists('imagecreatetruecolor');
  }

  public static function getInstance() {
    if(self::$_instance == null)  self::$_instance = new self();
    return self::$_instance;
  }

  public static function resetInstance() {
    self::$_instance = null;
    return self::getInstance();
  }


//   public static function debug(){
//     print_r(self::$CacheImage);
//   }

  /**
    @fn tep_image($src, $alt = '', $width = '', $height = '', $parameters = '',$mode=false)
    @brief The HTML image wrapper function
    @param  $src string
    @param  $alt string
    @param  $width numeric
    @param  $height numeric
    @param  $parameters string
    @param  $mode bool/string (true=url, false=normal, simple= sans width et height)
  */
  public static function tep_image($src, $alt = '', $width = '', $height = '', $parameters = '',$mode=false) {
    self::getInstance();

    self::initCurrent($src,$width,$height);

    if(!isset(self::$CacheImage[self::$key]['conf']['original'])) return self::$CacheImage[self::$key]['conf']['error'];
    else $src=self::$CacheImage[self::$key]['conf']['original'];

    $theImg=self::constructImg($src, $alt , $width , $height );

    $src = $theImg['src'];
    $alt = $theImg['alt'];
    $width = $theImg['width'];
    $height = $theImg['height'];

    if(is_bool($mode) && $mode){
      if (self::$env->inadmin)return tep_output_string($src);
      return tep_output_string(tep_get_httpdir().$src);
    }
    else {
      /// if cache return
      if( isset(self::$CacheImage[self::$key][self::$keydim]['img']) ) return self::$CacheImage[self::$key][self::$keydim]['img'];
      else {
        $image = '<img src="' . (!self::$env->inadmin ? tep_output_string(tep_get_httpdir().$src) : tep_output_string($src)) . '" alt="' . tep_output_string($alt) . '" ';
        if($mode !='simple') $image .= 'width="' . $theImg['width'] . '" height="' . $theImg['height'] . '"';
        if (tep_not_null($theImg['alt']))  $image .= ' title="' . tep_output_string($theImg['alt']) . '"';
        if (tep_not_null($parameters)) $image .= ' ' . $parameters;
        $image .= ' />';

        return self::$CacheImage[self::$key][self::$keydim]['img']= $image;
      }
    }
  }


  /**
    @brief Recup des info d'une image
    @param  $src string
    @param  $alt string
    @param  $width numeric
    @param  $height numeric
  */
  public static function get_image($src, $alt = '', $width = '', $height = '') {
    self::getInstance();
    self::initCurrent($src,$width,$height);

    if(!isset(self::$CacheImage[self::$key]['conf']['original'])) return self::$CacheImage[self::$key]['conf']['error'];
    else $src=self::$CacheImage[self::$key]['conf']['original'];

    return self::constructImg($src, $alt , $width , $height );
  }

  private static function initCurrent($src,$width,$height){
    self::$key = md5($src);
    self::$keydim=md5($width . $height);

    self::checkImg($src);
  }

  /**
    @brief constructor thumbail
    @param  $src string
    @param  $key string cache key for img
    @param  $alt string
    @param  $width/$height numeric
    @param  $parameters string
    @param  $mode bool/string (true=url, false=normal, simple= sans width et height)
  */
  private static function constructImg($src, $alt = '', $width = '', $height = ''){

    if(isset(self::$CacheImage[self::$key][self::$keydim]) ) return self::$CacheImage[self::$key][self::$keydim];

    $imgd = self::$CacheImage[self::$key]['conf']['getimagesize'];

    $image_size = self::aspectratio($imgd[0], $imgd[1], $width, $height);

    $width = $image_size["width"];
    $height = $image_size["height"];

    if (self::$env->img_create && $width !=$imgd[0] && $height != $imgd[1]) {
      $src=self::thumbfile($src, $width, $height, $imgd[0], $imgd[1], $imgd[2]);
      self::$CacheImage[self::$key][self::$keydim]['thumbfile']='true';
    }
    else{
      $src=self::CleanPathReturn($src);
      self::$CacheImage[self::$key][self::$keydim]['thumbfile']='false';
    }


    self::$CacheImage[self::$key][self::$keydim]['src']=$src;
    self::$CacheImage[self::$key][self::$keydim]['alt']=$alt;
    self::$CacheImage[self::$key][self::$keydim]['width']=$width;
    self::$CacheImage[self::$key][self::$keydim]['height']=$height;
    self::$CacheImage[self::$key][self::$keydim]['mime']=$imgd['mime'];


    return self::$CacheImage[self::$key][self::$keydim];
  }


  /**
    @fn checkImg($src)
    @brief check if image exists and format image is ok
    @param  $src string
    @param  $key string cache key for img
    @return boolean/string true if ok / false or string error
  */
  private static function checkImg($src){

    if(isset(self::$CacheImage[self::$key]['conf']['original'])) return ;

    $sortie=true;

    if(strpos($src, DIR_FS_CATALOG) === false ) $src;
    else $src= substr ($src, strlen(DIR_FS_CATALOG));

    if(strpos($src, DIR_WS_LANGUAGES) >0 ) self::$CacheImage[self::$key]['conf']['dest']='lang';
    else self::$CacheImage[self::$key]['conf']['dest']='image';

    if (self::$env->inadmin){
      self::$CacheImage[self::$key]['conf']['mode']='BO';
      if(strpos($src, DIR_WS_ADMIN)===false && strpos($src, DIR_WS_CATALOG)===false && file_exists(DIR_FS_ADMIN.$src)) $src_dir =  $src;
      elseif (strpos($src, DIR_WS_ADMIN) >0 || ( strpos($src, DIR_WS_IMAGES) ==0  && file_exists(DIR_FS_ADMIN.$src) ) ) $src_dir = DIR_FS_ADMIN . $src;
      elseif(strpos($src, DIR_WS_CATALOG)===false )  $src_dir = DIR_FS_CATALOG . $src;
      else $src_dir = DIR_FS_CATALOG . substr ($src, (strrpos (DIR_WS_CATALOG , '/'))+1);
    }
    else {
      self::$CacheImage[self::$key]['conf']['mode']='FO';
      $src_dir=$src;
    }

    if (!@is_file($src_dir) || empty($src_dir)){
      if (self::$env->img_required) $sortie= '<span class="errorText">'.__('Le fichier n\'a pas pu être trouvé sur le serveur !').'</span>';
      $sortie = false;
    }
    elseif ( ($imaged = getimagesize($src_dir)) && is_array($imaged) ) {

      if ( !$imaged[2] || $imaged[2] > 3) {
        if (empty($alt)) $sortie= '<span class="errorText">'.__('Ce format d\'image n\'est pas autorisé !').'</span>';
        else $sortie ='<span class="errorText" title="'.$src_dir.'">' . tep_output_string($alt) . '!</span>';
      }
      else self::$CacheImage[self::$key]['conf']['getimagesize']=$imaged;
    }


    if($sortie !=true) self::$CacheImage[self::$key]['conf']['error'] =$sortie;
    else  self::$CacheImage[self::$key]['conf']['original'] = $src_dir;
  }

  /**
    @fn self::aspectratio ($width_src , $height_src , $max_width = '', $max_height = '')
    @brief Redimensionnement des images en conservant leurs proportions
    @author Ayatus
    @param $width_src string path.src img
    @param $height_src float/empty max width en px
    @param $max_width float/empty max height en px
    @param $max_height float/empty max height en px
    @return array (width,height)
  */
  private static function aspectratio ($width_src , $height_src , $max_width = '', $max_height = ''){
//     error_reporting(E_ALL);

    !empty ($max_width) && preg_match ('/^[0-9]{1,}$/', $max_width, $regs) && $max_width <= $width_src
    ? true
    : $max_width = $width_src;
    !empty ($max_height) && preg_match ('/^[0-9]{1,}$/', $max_height, $regs) && $max_height <= $height_src
    ? true
    : $max_height = $height_src;
    $width=$max_width;
    $height=$max_height;
    $width_a=$max_height * $width_src / $height_src;
    $height_a=$max_width * $height_src / $width_src;

    if ($max_width == $max_height){
      if ($width_src < $height_src){
        $width=ceil($max_width * $width_src / $height_src);
        $height=$max_width;
      }
      elseif ($width_src > $height_src) $height=ceil($height_a);
      elseif ($width_src == $height_src) $height=$max_width;
    }
    elseif (($height_a) > $max_height) $width=ceil($width_a);
    elseif (($width_a) > $max_width) $height=ceil($height_a);
    elseif ($width_src == $height_src){
      if ($max_width > $max_height) $width=$max_height;
      elseif ($max_width < $max_height) $height=$max_width;
    }

    return array("width"=>$width,"height"=>$height);
  }

  private static function thumbfile ($image, $width, $height, $width_src, $height_scr, $format){

    $thumb = $width.'x'.$height.'_'.basename($image).'_'.md5($image).'.'.((self::$types[$format]=="jpeg") ? "jpg" : self::$types[$format]);

    $thumbfile = substr($image,0, strpos($image, DIR_WS_IMAGES) ) . self::$env->cachedir . $thumb;

    if(isset(self::$CacheImage[self::$key][self::$keydim]['thumbfile_cache'])) $iscached = (bool) self::$CacheImage[self::$key][self::$keydim]['thumbfile_cache'];
    else {
      if (file_exists ($thumbfile)) {
        $thumbdata = getimagesize ($thumbfile);
        $iscached =( $thumbdata[0] == $width && $thumbdata[1] == $height )?  true :  false;
        if (@filemtime($thumbfile) < @filemtime($image)) $iscached = false;
      }
      else  $iscached = false;
      self::$CacheImage[self::$key][self::$keydim]['thumbfile_cache'] = $iscached;
    }

    if (!$iscached)  $makethumb = ($width_src > $width || $height_scr > $height) ?  true : false;
    else $makethumb = false;

    if ($makethumb) $image=self::thumbgd($image, $width, $height, $width_src, $height_scr, self::$types[$format], $thumbfile);
    else{
      $img=($iscached) ? $thumbfile : $image;
      $image = self::CleanPathReturn($img);
    }

    return $image;
  }



  /**
    @brief Clean pathname prev return
    @param string pathname
  */
  private static function CleanPathReturn($img){

    $ws_=(strpos($img, DIR_WS_CATALOG)===false)?false:true;
    $ws_admin=(self::$env->inadmin && strpos($img, DIR_WS_ADMIN)===false )?false:true;
    $ws_lg=(strpos($img, DIR_WS_LANGUAGES)===false)?false:true;
    $ws_img=(strpos($img, DIR_WS_IMAGES)===false)?false:true;

    $image='';
    $mask='';
    if(!$ws_admin && $ws_){
      $image.=DIR_WS_CATALOG;
      $mask .='(.*'.DIR_WS_CATALOG.'){0,1}';
    }
    if(self::$env->inadmin && $ws_admin) $image.=DIR_WS_ADMIN;
    if($ws_lg){
      $image.=DIR_WS_LANGUAGES;
      $mask .='(.*'.DIR_WS_LANGUAGES.'){0,1}';
    }
    elseif($ws_img){
      $image.=DIR_WS_IMAGES;
      $mask .='(.*'.DIR_WS_IMAGES.'){0,1}';
    }

    $image.=preg_replace('#'.$mask.'#i','',$img);

    return $image;
  }

  /**
    @author by Christian Lamine, FlashDreams OHG   http://www.flashdreams.de/
      Modified by http://www.team-noehring.de
      Modified by http://www.tse.at
      Modified by lars@iwer.de
      Traduction Fr : cynic- pour OsCss
      Modified by oscim for oscss debug + php script
      Modified by Ayatus
    @version Thumbnail-Script v1.3
    Generating thumbnails 'on-the-fly' with PHP
    @note
      This script may be freely used, distribute
      and modified without any charge as long as
      this copyright information is included
      Any commercial selling of this script is forbidden.
  */
  private static function thumbgd ($image, $width, $height, $width_src, $height_scr, $format, $thumbfile){
//     error_reporting(E_ALL);
    $image = call_user_func("imagecreatefrom".$format, $image);
    $thumb = imagecreatetruecolor ($width, $height);
    imagealphablending($thumb, false);
    imagesavealpha($thumb, true);
    imagefill($thumb, 0, 0, imagecolorallocatealpha($thumb, 0, 0, 0, 127));
    imagecopyresampled ($thumb, $image, 0, 0, 0, 0, $width, $height, $width_src, $height_scr);

    if ($format == "jpeg")  call_user_func("image".$format, $thumb, $thumbfile, self::$env->jpegquality);
    else call_user_func("image".$format, $thumb, $thumbfile);
    imagedestroy ($image);
    imagedestroy ($thumb);

    return $thumbfile;
  }


  private static function thumbimagick ($image, $width, $height, $format, $thumbfile){
//     error_reporting(E_ALL);
    if (self::$env->Imagick && self::$env->safemod ) {
      $thumb = new Imagick($image);
        foreach ($thumb as $frame) {
          $frame->thumbnailImage($width, $height);
          $frame->setImagePage($width, $height, 0, 0);
        }
      if ($format == "jpeg") {
        $thumb->setImageCompression(imagick::COMPRESSION_JPEG);
        $thumb->setImageCompressionQuality(self::$env->jpegquality);
      }
      $thumb->writeImages($thumbfile, true);
    }

    return $thumbfile;
  }

}
?>