<?php

/**
* Handles image loading and saving, parameters, manipulation, and rendering.
*
* This class contains methods for the loading and saving of image files.  Also
* contained in this class are functions for getting and setting image parameters,
* image modification, and rendering.
*
* @version 0.3
* @author  Matt McClanahan <cardinal@dodds.net>
* @package Imlib
* @access public
*/
class ImlibImage
{
   /**
   * The image resource id#
   *
   * @var integer $id
   * @see create(), get_id()
   * @access private
   */
   var $id;

   /**
   * ImlibImage constructor
   *
   * @access public
   */
   function ImlibImage() { $this->id = 0; }

   /**
   * Callback for functions which query the current instance's attributes
   *
   * @param string The name of the function to call
   * @return mixed String or int
   * @access private
   */
   function _get_cb($cb)
   {
      if (!is_resource($this->id))
         return false;

      $cbname = 'imlib_image_' . $cb;
      return $cbname($this->id);
   }

   /**
   * Callback for functions which flip or tile the current instance
   *
   * @param string The name of the function to call
   * @access private
   */
   function _no_param_cb($cb)
   {
      if (!is_resource($this->id))
         return false;

      $cbname = 'imlib_image_' . $cb;
      return $cbname($this->id);
   }

   /**
   * Blend a region of the current image onto the region of another ImlibImage
   *
   * @param int Resource id# of the destination image
   * @param bool Merge alpha
   * @param int Upper left source X coordinate
   * @param int Upper left source Y coordinate
   * @param int Source width
   * @param int Source height
   * @param int Upper left destination X coordinate
   * @param int Upper left destination Y coordinate
   * @param int Destination width
   * @param int Destination height
   * @param bool Dither
   * @param bool Blend
   * @param bool Alias
   * @access public
   */
   function blend_onto_image($dst,$alpha,$sx,$sy,$sw,$sh,$dx,$dy,$dw,$dh,
                             $dither,$blend,$alias)
   {
      if (!is_resource($this->id) || !is_resource($dst))
         return false;

      imlib_blend_image_onto_image($dst,$this->id,$alpha,$sx,$sy,$sw,$sh,
                                   $dx,$dy,$dw,$dh,$dither,$blend,$alias);
   }

   /**
   * Blur an image with a given blur radius
   *
   * @param int Blur radius
   * @access public
   */
   function blur($r)
   {
      imlib_image_blur($this->id,$r);
   }

   /**
   * Create a clone of the current instance, return a new ImlibImage
   *
   * @return object ImlibImage
   * @access public
   */
   function create_clone()
   {
      if (!is_resource($this->id))
         return false;

      $clone = new ImlibImage();
      $clone->id = imlib_clone_image($this->id);

      return $clone;
   }

   /**
   * Create a cropped ImlibImage from a region of the current instance, return a new ImlibImage
   *
   * @param int Upper left X coordinate to crop from
   * @param int Upper left Y coordinate to crop from
   * @param int Width to crop
   * @param int Height to crop
   * @return object ImlibImage
   * @access public
   */
   function create_cropped($sx,$sy,$sw,$sh)
   {
      if (!is_resource($this->id))
         return false;

      $crop = new ImlibImage();
      $crop->id = imlib_create_cropped_image($this->id,$sx,$sy,$sw,$sh);

      return $crop;
   }

   /**
   * Create a cropped, scaled ImlibImage from a region of the current instance, return a new ImlibImage
   *
   * @param int Upper left X coordinate to crop from
   * @param int Upper left Y coordinate to crop from
   * @param int Width to crop
   * @param int Height to crop
   * @param int Width to scale the cropped region to
   * @param int Height to scale the cropped region to
   * @return object ImlibImage
   * @access public
   */
   function create_cropped_scaled($sx,$sy,$sw,$sh,$dw,$dh)
   {
      if (!is_resource($this->id))
         return false;

      $thumb = new ImlibImage();
      $thumb->id = imlib_create_cropped_scaled_image($this->id,
                                             $sx,$sy,$sw,$sh, $dw,$dh);
      return $thumb;
   }

   /**
   * Create an image resource to use with this instance
   *
   * @param int Width of the image
   * @param int Height of the image
   * @return int Resource id# that was created
   * @access public
   * @see get_id(), $id
   */
   function create($width,$height)
   {
      if (is_resource($this->id))
         return false;

      return $this->id = imlib_create_image($width,$height);
   }

   /**
   * Create a rotated ImlibImage, return a new ImlibImage
   *
   * If radians is specified, degrees will be ignored.
   *
   * @param float Angle to rotate the image
   * @param float Radians to rotate the image
   * @return object ImlibImage
   * @access public
   */
   function create_rotated($degrees,$radians=0.0)
   {
      if (!is_resource($this->id))
         return false;

      if ($radians)
         $num = $radians;
      else
         $num = $degrees;

      $rotated = new ImlibImage();
      $rotated->id = imlib_create_rotated_image($this->id,$num);

      return $rotated;
   }

   /**
   * Create a scaled ImlibImage, return a new ImlibImage
   *
   * If $height is not specified, it will be calculated from the dimensions
   * of the current image, so that the aspect ratio is preserved.
   *
   * @param integer Width to scale the new image to
   * @param integer Height to scale the new image to (Optional)
   * @return object ImlibImage
   * @access public
   */
   function create_scaled($width,$height=0)
   {
      if (!is_resource($this->id))
         return false;

      $scaled = new ImlibImage();
      $scaled->id = imlib_create_scaled_image($this->id,$width,$height);

      return $scaled;
   }

   /**
   * Output the raw image data of the current instance to stdout
   *
   * @param integer Quality or compression level to use
   * @access public
   */
   function dump($quality=75)
   {
      if (!is_resource($this->id))
         return false;

      if (!imlib_dump_image($this->id,&$err,$quality))
         return false;
      else
         return true;
   }

   /**
   * Flip the current image diagonally
   *
   * @access public
   */
   function flip_diagonal() { return $this->_no_param_cb('flip_diagonal'); }

   /**
   * Flip the current image horizontally
   *
   * @access public
   */
   function flip_horizontal() { return $this->_no_param_cb('flip_horizontal'); }

   /**
   * Flip the current image vertically
   *
   * @access public
   */
   function flip_vertical() { return $this->_no_param_cb('flip_vertical'); }

   /**
   * Free the current instance and image resource
   *
   * @access public
   */
   function free()
   {
      if (!is_resource($this->id))
         return false;

      imlib_free_image($this->id);
      $this->id = 0;
   }

   /**
   * Get the current filename, if it's set
   *
   * @return mixed Filename string or false.
   * @access public
   */
   function get_filename() { return $this->_get_cb('get_filename'); }

   /**
   * Get the current image format.  The default is png.
   *
   * @return string Image format
   * @access public
   */
   function get_format() { return $this->_get_cb('format'); }
   
   /**
   * Get the current image's height
   *
   * @return integer Image height
   * @access public
   */
   function get_height() { return $this->_get_cb('get_height'); }

   /**
   * Get the current image's resource id#
   *
   * @return integer Current resource id#
   * @access public
   * @see $id, create()
   */
   function get_id() { return $this->id; }

   /**
   * Get the current image's width
   *
   * @return integer Image width
   * @access public
   */
   function get_width() { return $this->_get_cb('get_width'); }

   /**
   * Check if the image has an alpha channel
   *
   * @return boolean
   * @access public
   */
   function has_alpha()
   {
      if (!is_resource($this->id))
         return false;

      return imlib_image_has_alpha($this->id);
   }

   /**
   * Set the alpha channel of an image
   *
   * @param int The alpha level to set for the image
   * @access public
   */
   function modify_alpha($alpha)
   {
      if (!is_resource($this->id))
         return false;

      imlib_image_modify_alpha($this->id,$alpha);
   }

   /**
   * Load an image file into the current instance
   *
   * @param string Filename
   * @param integer Load error number.  0 for no error.
   * @return integer Resource id# or false if load failed
   * @access public
   */
   function load($infile,$err=0)
   {
      if (is_resource($this->id))
         return false;

      $this->id = imlib_load_image_with_error_return($infile,&$err);
      if (!is_resource($this->id) || $err)
         return false;
      else
         return true;
   }

   /**
   * Save the current instance to a file
   *
   * @param string Filename
   * @param integer Quality or compression level to use
   * @return bool False if the save failed
   * @access public
   */
   function save($outfile,$quality=75)
   {
      if (!is_resource($this->id))
         return false;

      if (!imlib_save_image($this->id,$outfile,&$err,$quality))
         return false;
      else
         return true;
   }

   /**
   * Set the image format for the current instance
   *
   * @param string File format
   * @access public
   */
   function set_format($format)
   {
      if (!is_resource($this->id))
         return false;

      return imlib_image_set_format($this->id,$format);
   }

   /**
   * Sharpen an image with a given sharpen radius
   *
   * @param int Sharpen radius
   * @access public
   */
   function sharpen($r)
   {
      imlib_image_sharpen($this->id,$r);
   }

   /**
   * Seamlessly tile the current image both horizontally and vertically
   *
   * @access public
   */
   function tile() { return $this->_no_param_cb('tile'); }

   /**
   * Seamlessly tile the current image horizontally
   *
   * @access public
   */
   function tile_horizontal() { return $this->_no_param_cb('tile_horizontal'); }

   /**
   * Seamlessly tile the current image vertically
   *
   * @access public
   */
   function tile_vertical() { return $this->_no_param_cb('tile_vertical'); }
};

?>
