// Dependencies:
//  jQuery
//  Prototype

// Array implementation that contains DOM Image elements:
//
function ImageArray() {
  this.oa_images = new Array();
  }
ImageArray.prototype.getArray = function() {
  return this.oa_images;
  };
ImageArray.prototype.push = function(po_image) {
  this.oa_images.push(po_image);
  };
ImageArray.prototype.maxWidth = function() {
  var ret = 0;
  $.each(this.oa_images, function(idx, value) {
    ret = Math.max(ret, value.width);
    });
  return ret;
  };
ImageArray.prototype.maxHeight = function() {
  var ret = 0;
  $.each(this.oa_images, function(idx, value) {
    ret = Math.max(ret, value.height);
    });
  return ret;
  };


// Class to pre-load image URLs and store the created DOM Image
// elements in an array.
//
// N.B. Calls a call-back function, if specified, whenever the
// images have finished loading.  Therefore, if you want to use
// this call-back facility, do not call 'ImagePreloader::preload()'
// more than once, but create a new object, or else the call-back
// functionality may not work correctly.
//
ImagePreloader = Class.create({
  initialize: function(pf_callback) {
    this.oa_images = new ImageArray();
    this.on_images = 0;
    this.on_loadedimages = 0;
    this.on_processedimages = 0;
    this.of_callback = pf_callback; // optional call-back function
    },

  onComplete: function() {
    ++this.on_processedimages;
    if (this.on_processedimages == this.on_images && this.of_callback) {
      this.of_callback(this.oa_images, this.on_loadedimages);
      }
    },

  onLoad: function() {
    ++this.on_loadedimages;
    this.onComplete();
    },

  onError: function() {
    this.onComplete();
    },

  onAbort: function() {
    this.onComplete();
    },

  preloadImage: function(ps_imageurl) {
    var ho_img = new Image();

    ho_img.onload = this.onLoad.bind(this);
    ho_img.onerror = this.onError.bind(this);
    ho_img.onabort = this.onAbort.bind(this);

    ho_img.src = ps_imageurl;

    this.oa_images.push(ho_img);

    return ho_img;
    },


  // }}}
  // {{{ preload()

  /**
   * Returns option data for specified HTML form/select elements
   *
   * N.B. this function is a private recursive function which should be called
   * by SearchFormManager::getOptionData()
   *
   * @param array    pa_images   array of images
   * @param function pf_callback function to call when all images have been
   *                              loaded (only used when pa_images is an array)
   *
   * @return mixed   one of:
   *                   1. array of options
   *                   2. object: [ display text => value ]
   * @access private
   */
  preload: function(pa_images, pf_callback) {
    //
    // Optional call-back function only used if array of images passed,
    // otherwise ignored (although the call-back will still fire if
    // specified in the constructor).
    //
    // Returns 'ImageArray' of image elements corresponding to image URLs
    // passed (not the complete array of stored elements, which is accessible
    // from the object itself).

    var ret = new ImageArray();
    if (arguments.length == 0) {
      if (this.of_callback) {
        this.of_callback(this.oa_images, this.on_loadedimages);
        }
      return ret;
      }

    if (typeof arguments[0] == 'object') {
      // Array of image URLs:
      //
      this.on_images += pa_images.length;
      if (pf_callback) {
        this.of_callback = pf_callback;
        }

      var ho_this = this;
      $.each(arguments[0], function(idx, value) {
        ret.push(ho_this.preloadImage(value));
        });
      }
    else {
      // Arguments are a list of image URLs:
      //
      this.on_images += arguments.length;
      for (var i = 0; i < arguments.length; ++i) {
        ret.push(this.preloadImage(arguments[i]));
        }
      }

    return ret;
    }

  });

var go_imagepreloader = new ImagePreloader(); // no call-back
