<?php
/*
 * $RCSfile: GalleryDerivativeHelper_medium.class,v $
 *
 * Gallery - a web based photo album viewer and editor
 * Copyright (C) 2000-2005 Bharat Mediratta
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
 */
/**
 * @version $Revision: 1.11 $ $Date: 2005/08/23 03:49:04 $
 * @package GalleryCore
 * @author Bharat Mediratta <bharat@menalto.com>
 */

/**
 * A helper class for GalleryDerivatives
 *
 * Utility functions useful in managing GalleryDerivatives
 *
 * @package GalleryCore
 * @subpackage Helpers
 */
class GalleryDerivativeHelper_medium {

    /**
     * Convenience function to fetch the thumbnail for an item id
     *
     * @param array GalleryItem ids
     * @return array object GalleryStatus a status code
     *               array(GalleryItem id => GalleryDerivativeImage, ...)
     * @static
     */
    function fetchThumbnailsByItemIds($ids) {
	if (!is_array($ids)) {
	    return array(GalleryStatus::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__), null);
	}

	if (empty($ids)) {
	    return array(GalleryStatus::success(), array());
	}

	list ($ret, $results) = GalleryDerivativeHelper_medium::_loadDerivatives(
	    $ids, null, DERIVATIVE_TYPE_IMAGE_THUMBNAIL);
	if ($ret->isError()) {
	    return array($ret->wrap(__FILE__, __LINE__), null);
	}

	/* Only one thumb per item, so simplify the results */
	foreach ($results as $id => $value) {
	    $results[$id] = $value[0];
	}

	return array(GalleryStatus::success(), $results);
    }

    /**
     * Convenience function to fetch the resizes for an item id
     *
     * @param array GalleryItem ids
     * @return array object GalleryStatus a status code
     *               array(GalleryItem id => array(GalleryDerivativeImage, ...)
     *                     ...)
     * @static
     */
    function fetchResizesByItemIds($ids) {
	if (!is_array($ids)) {
	    return array(GalleryStatus::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__), null);
	}

	if (empty($ids)) {
	    return array(GalleryStatus::success(), array());
	}

	list ($ret, $results) = GalleryDerivativeHelper_medium::_loadDerivatives(
	    $ids, null, DERIVATIVE_TYPE_IMAGE_RESIZE);
	if ($ret->isError()) {
	    return array($ret->wrap(__FILE__, __LINE__), null);
	}
	return array(GalleryStatus::success(), $results);
    }

    /**
     * Convenience function to fetch the preferred for an item id
     *
     * @param array GalleryItem ids
     * @return array object GalleryStatus a status code
     *               array(GalleryItem id => GalleryDerivativeImage, ...)
     * @static
     */
    function fetchPreferredsByItemIds($ids) {
	if (!is_array($ids)) {
	    return array(GalleryStatus::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__), null);
	}

	if (empty($ids)) {
	    return array(GalleryStatus::success(), array());
	}
	
	list ($ret, $results) = GalleryDerivativeHelper_medium::_loadDerivatives(
	    $ids, null, DERIVATIVE_TYPE_IMAGE_PREFERRED);
	if ($ret->isError()) {
	    return array($ret->wrap(__FILE__, __LINE__), null);
	}

	/* Only one preferred per item, so simplify the results */
	foreach ($results as $id => $value) {
	    $results[$id] = $value[0];
	}

	return array(GalleryStatus::success(), $results);
    }

    /**
     * Load the derivative images for the ids/types specified
     *
     * @param array GalleryItem ids
     * @param array GalleryDataItem or GalleryDerivative source ids
     * @param array derivative types (eg, 'DERIVATIVE_TYPE_IMAGE_THUMBNAIL')
     * @return array object GalleryStatus a status code
     *               array(GalleryItem id => GalleryDerivativeImage, ...)
     * @access private
     * @static
     */
    function _loadDerivatives($itemIds, $sourceIds, $types=array()) {
	global $gallery;

	if (empty($itemIds) && empty($sourceIds) ||
	    empty($itemIds) && !is_array($sourceIds) ||
	    empty($sourceIds) && !is_array($itemIds)) {
	    return array(GalleryStatus::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__),
			 null);
	}

	if (!is_array($types)) {
	    $types = array($types);
	}

	if (!empty($itemIds)) {
	    $idMarkers = GalleryUtilities::makeMarkers(sizeof($itemIds));
	    $data = $itemIds;
	    $query = '
            SELECT
              [GalleryDerivative::id], [GalleryChildEntity::parentId]
            FROM
              [GalleryDerivative], [GalleryChildEntity]
            WHERE
              [GalleryDerivative::id] = [GalleryChildEntity::id]
              AND
              [GalleryChildEntity::parentId] IN (' . $idMarkers . ')
            ';
	} else {
	    $idMarkers = GalleryUtilities::makeMarkers(sizeof($sourceIds));
	    $data = $sourceIds;
	    $query = '
            SELECT
              [GalleryDerivative::id], [GalleryDerivative::derivativeSourceId]
            FROM
              [GalleryDerivative]
            WHERE
              [GalleryDerivative::derivativeSourceId] IN (' . $idMarkers . ')
            ';
	}

	if (!empty($types)) {
	    $typeMarkers = GalleryUtilities::makeMarkers(sizeof($types));
	    $query .= '
              AND
              [GalleryDerivative::derivativeType] IN (' . $typeMarkers . ')
            ';
	    $data = array_merge($data, $types);
	}

	list ($ret, $searchResults) = $gallery->search($query, $data);
	if ($ret->isError()) {
	    return array($ret->wrap(__FILE__, __LINE__), null);
	}

	$derivativeTable = array();
	if ($searchResults->resultCount() > 0) {
	    $derivativeIds = array();
	    while ($result = $searchResults->nextResult()) {
		$derivativeIds[] = $result[0];
	    }

	    /*
	     * Sorting this in the database triggers a fielsort in MySQL which
	     * is slow.  We expect this to be a fairly small set of derivatives
	     * so we'll do it in memory in PHP instead and lighten the load on
	     * the DB.
	     *
	     * TODO: Consider caching this result since it's the kind of thing
	     * that will be called often on data that won't change frequently.
	     */
	    sort($derivativeIds, SORT_NUMERIC);

	    /* Load all the derivative images */
	    list ($ret, $derivativeEntities) = GalleryCoreApi::loadEntitiesById($derivativeIds);
	    if ($ret->isError()) {
		return array($ret->wrap(__FILE__, __LINE__), null);
	    }

	    /* Create a table of child id -> image data */
	    foreach ($derivativeEntities as $derivative) {
		$derivativeTable[$derivative->getParentId()][] = $derivative;
	    }
	}

	return array(GalleryStatus::success(), $derivativeTable);
    }

}
?>
