<?php
/**
 *  File containing class for building image elements.
 *  @package    codeigniter_project
 *  @subpackage default
 */

if (!defined('BASEPATH')) {
  exit('No direct script access allowed');
}

/**
 *  Class for building standards-compliant image elements: sets width, height, size, and mime_type
 *  with info from the image file; user may set other attributes.
 *  @author     Richard S. Mitchell
 *  @copyright  Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
 */
class Img_element
{
  private $_height, $_mime_type, $_size, $_src, $_width;

  /**
   *  Flag for including a "cache busting" GET var (default FALSE).
   *  @var boolean
   */
  private $_cache_bust;

  public $alt, $class, $dir, $id, $lang, $longdesc, $style, $title, $usemap, $xml_lang,
    $onclick, $ondblclick, $onmousedown, $onmousemove, $onmouseout, $onmouseover,
    $onmouseup, $onkeydown, $onkeypress, $onkeyup;

  /**
   *  Constructor.
   *  @return void
   */
  function __construct() {}

  function __toString()
  {
    return 'class Img_element';
  }

  /**
   *  Getter for height.
   *  @return int
   */
  function get_height()
  {
    return (int) $this->_height;
  }

  /**
   *  Getter for mime-type.
   *  @return string
   */
  function get_mime_type()
  {
    return $this->_mime_type;
  }

  /**
   *  Getter for image source.
   *  @return string
   */
  function get_src()
  {
    return $this->_src . (($this->_cache_bust) ? '?cb=' . time() : '');
  }

  /**
   *  Getter for width.
   *  @return int
   */
  function get_width()
  {
    return (int) $this->_width;
  }

  /**
   *  Initializes an image element: accepted image types are gif, jpeg, or png.
   *  @param  string $src   file path from web root
   *  @return void
   *  @throws invalid image type exception
   *  @throws file not an image exception
   *  @throws file not found exception
   */
  function initialize($src)
  {
    $this->_reset();

    // get the system path to the file
    $CI =& get_instance();
    $phpsrc = $CI->config->item('doc_root') . $src;

    if (!is_file($phpsrc)) {
      throw new Exception('ERROR: file not found: ' . $phpsrc);
    }

    if ($img_info = @getimagesize($phpsrc)) {
      switch ($img_info[2]) {
        case IMAGETYPE_GIF:
        case IMAGETYPE_JPEG:
        case IMAGETYPE_PNG:
          $this->_mime_type = image_type_to_mime_type($img_info[2]);
          break;

        default:
          $e_msg = 'ERROR: invalid image type: ' . image_type_to_mime_type($img_info[2]);
          $e_msg .= '. Must be image/gif, image/jpeg, or image/png.';

          throw new Exception($e_msg);
      }

      $this->_height = $img_info[1];
      $this->_size = $img_info[3];
      $this->_width = $img_info[0];
      $this->alt = $src;
      $this->_src = base_url() . $src;
      $this->_cache_bust = FALSE;
    }
    else {
      throw new Exception('ERROR: source file is not an image.');
    }
  }

  /**
   *  Makes the HTML for the image.
   *  @return string
   *  @throws no image initialized exception
   */
  function makeHtml()
  {
    if (!isset($this->_src)) {
      throw new Exception('ERROR: no image initialized.');
    }

    $img_html = sprintf('<img src="%s" alt="%s" %s',
      $this->_src . (($this->_cache_bust) ? '?cb=' . time() : ''),
      $this->alt,
      $this->_size);

    if (isset($this->class)) {
      $img_html .= sprintf(' class="%s"', $this->class);
    }

    if (isset($this->dir)) {
      $img_html .= sprintf(' dir="%s"', $this->dir);
    }

    if (isset($this->id)) {
      $img_html .= sprintf(' id="%s"', $this->id);
    }

    if (isset($this->lang)) {
      $img_html .= sprintf(' lang="%s"', $this->lang);
    }

    if (isset($this->longdesc)) {
      $img_html .= sprintf(' longdesc="%s"', $this->longdesc);
    }

    if (isset($this->style)) {
      $img_html .= sprintf(' style="%s"', $this->style);
    }

    if (isset($this->title)) {
      $img_html .= sprintf(' title="%s"', $this->title);
    }

    if (isset($this->usemap)) {
      $img_html .= sprintf(' usemap="%s"', $this->usemap);
    }

    if (isset($this->xml_lang)) {
      $img_html .= sprintf(' xml:lang="%s"', $this->xml_lang);
    }

    if (isset($this->onclick)) {
      $img_html .= sprintf(' onclick="%s"', $this->onclick);
    }

    if (isset($this->ondblclick)) {
      $img_html .= sprintf(' ondblclick="%s"', $this->ondblclick);
    }

    if (isset($this->onmousedown)) {
      $img_html .= sprintf(' onmousedown="%s"', $this->onmousedown);
    }

    if (isset($this->onmousemove)) {
      $img_html .= sprintf(' onmousemove="%s"', $this->onmousemove);
    }

    if (isset($this->onmouseout)) {
      $img_html .= sprintf(' onmouseout="%s"', $this->onmouseout);
    }

    if (isset($this->onmouseover)) {
      $img_html .= sprintf(' onmouseover="%s"', $this->onmouseover);
    }

    if (isset($this->onmouseup)) {
      $img_html .= sprintf(' onmouseup="%s"', $this->onmouseup);
    }

    if (isset($this->onkeydown)) {
      $img_html .= sprintf(' onkeydown="%s"', $this->onkeydown);
    }

    if (isset($this->onkeypress)) {
      $img_html .= sprintf(' onkeypress="%s"', $this->onkeypress);
    }

    if (isset($this->onkeyup)) {
      $img_html .= sprintf(' onkeyup="%s"', $this->onkeyup);
    }
    
    return $img_html . ' />';
  }

  /**
   *  Sets the image element attributes (escapes HTML special chars).
   *  @param  array $attrs  associative array of attributes (attr => value)
   *  @return void
   *  @throws unavailable attribute exception
   */
  function set_attrs($attrs)
  {
    foreach ($attrs as $attr => $value) {
      switch ($attr) {
        case 'alt':
        case 'class':
        case 'dir':
        case 'id':
        case 'lang':
        case 'longdesc':
        case 'onclick':
        case 'ondblclick':
        case 'onmousedown':
        case 'onmousemove':
        case 'onmouseout':
        case 'onmouseover':
        case 'onmouseup':
        case 'onkeydown':
        case 'onkeypress':
        case 'onkeyup':
        case 'style':
        case 'title':
        case 'usemap':
        case 'xml_lang':
          $this->$attr = htmlspecialchars($value);
          break;
  
        default:
          throw new Exception('ERROR: this image element attribute is not available: ' . $attr);
      }
    }
  }

  /**
   *  Sets the flag to turn "cache busting" on / off.
   *  @param  boolean $is_on
   *  @return void
   */
  function set_cache_bust($is_on = FALSE)
  {
    $this->_cache_bust = $is_on;
  }

  /**
   *  Resets the class by unsetting all members.
   *  @return void
   */
  private function _reset()
  {
    foreach ($this as $key => $value) {
      unset($this->$key);
    }
  }
}

// end of file