<?php

/**
 * @version $Id: Makethumbs.php 499 2006-01-03 22:35:52Z drewish $
 * @author  Andrew Morton <drewish@katherinehouse.com>
 * @license http://opensource.org/licenses/lgpl-license.php
 *          GNU Lesser General Public License, Version 2.1
 * @package Phlickr
 */

/**
 * This class implements the Phlickr_Framework_IUploadBatch interface.
 */
include_once ('Phlickr/Framework/IUploadBatch.php');

/**
 * Import a gallery generated by Rob Molenda's
 * {@link http://www.molenda.com/makethumbs/ makethumbs.sh script} for uploding
 * to Flickr
 *
 * The import process works as follows:
 * - All listed photos will be uploaded.
 * - The photos' caption will become the Flickr title.
 * - The photos' descriptions will become the Flickr description.
 * - No tags will be assigned.
 * - (Currently) the photo's taken dates will not be assigned.
 * - Finally, a photoset will be created using the album's 'short title' as a
 *   title and 'longer page description' as a description.
 *
 * <code>
 * <?php
 * require_once 'Phlickr/Import/Makethumbs.php';
 * require_once 'Phlickr/TextUi/UploadListener.php';
 * require_once 'Phlickr/Api.php';
 * require_once 'Phlickr/Uploader.php';
 *
 * // set up the api connection
 * $api = Phlickr_Api::createFrom(API_CONFIG_FILE);
 *
 * // create an uploader
 * $uploader = new Phlickr_Uploader($api);
 *
 * // create the importer using the album directory with the descriptions.txt file.
 * $batch = new Phlickr_Import_Makethumbs(IMPORT_DIRECTORY);
 *
 * // if you want, assign additional tags on all photos
 * $uploader->setTags(array('tags', 'for','all photos'));
 *
 * // create a listener to display the upload status
 * $listener =  new Phlickr_TextUi_UploaderListener();
 *
 * // hand the batch and listener the uploader and away it will go.
 * $uploader->uploadBatch($batch, $listener);
 * ?>
 * </code>
 *
 * @package     Phlickr
 * @subpackage  Import
 * @author      Andrew Morton <drewish@katherinehouse.com>
 * @since       0.2.5
 */
class Phlickr_Import_Makethumbs implements Phlickr_Framework_IUploadBatch
{
    /**
     * The name of the file that has the titles and descriptions
     */
    const FILE_DESCRIPTIONS = 'descriptions.txt';
    /**
     * Name of the (optional) file with dates.
     */
    const FILE_DATES = 'dates.txt';

    /**
     * Array of full filenames.
     * @var array
     */
    protected $_files = array();
    /**
     * Album name.
     * @var string
     */
    protected $_setName = '';
    /**
     * Album description.
     * @var string
     */
    protected $_setDesc = '';
    /**
     * Array of titles keyed on the complete filenames.
     * @var array
     */
    protected $_titles = array();
    /**
     * Array of descriptions keyed on the complete filenames.
     * @var array
     */
    protected $_descriptions = array();

    /**
     * Constructor. For the given directory open the description file and
     * load all the titles and descriptions.
     *
     * @param   string $dir
     * @todo    Finish the code to read in the dates.txt file.
     */
    public function __construct($dir) {
        $dir = realpath($dir) . DIRECTORY_SEPARATOR;
        $filename = $dir . self::FILE_DESCRIPTIONS;
        $fh = fopen($filename, 'r');
        if ($fh === false) {
            throw new Exception("The album could not be loaded ($filename).");
        }

        // skip down to the start
        self::readStringTo($fh, '/^\[short title\]/');

        // short title
        $this->_setName = self::readStringTo($fh, '/^\[longer page description\]/');

        // longer page description
        $this->_setDesc = self::readStringTo($fh, '/^\[captions\]/');

        // files and titles
        while ($s = fgets($fh)) {
            $s = trim($s);
            if (preg_match('/^\[descriptions\]/', $s)) break;

            if (preg_match('/^(\S*)\s(.*)/', $s, $matches)) {
                $file = $dir . $matches[1];
                $this->_files[] = $file;
                $this->_titles[$file] = $matches[2];
            }
        }

        // descriptions
        while ($s = fgets($fh)) {
            $s = trim($s);
            if (preg_match('/^(\S*)\s(.*)/', $s, $matches)) {
                $file = $dir . $matches[1];
                $this->_descriptions[$file] = $matches[2];
            }
        }
        fclose($fh);

        // check if dates are provided.
        $filename = $dir . self::FILE_DATES;
        if (file_exists($filename)) {
            $fh = fopen($filename, 'r');
            // import dates
            fclose($fh);
        }
    }

    /**
     * Read from a file until encountering a line matching a pattern. Return
     * everything found up to that point.
     *
     * @param   resource $fh file stream
     * @param   string $pattern
     * @return  string
     */
    static function readStringTo($fh, $pattern) {
        while ($s = fgets($fh)) {
            $s = trim($s);
            if (preg_match($pattern, $s)) break;
            $ret .= $s;
        }
        return $ret;
    }

    public function getFiles() {
        return $this->_files;
    }

    public function isSetWanted() {
        return true;
    }

    public function getSetTitle() {
        return $this->_setName;
    }

    public function getSetDescription() {
        return $this->_setDesc;
    }

    public function getSetPrimary() {
        // this doesn't support a primary photo
        return null;
    }

    public function getTitleForFile($filePath) {
        return (string) $this->_titles[$filePath];
    }

    public function getDescriptionForFile($filePath) {
        return (string) $this->_descriptions[$filePath];
    }

    public function getTagsForFile($filePath) {
        return array();
    }

    public function getTakenDateForFile($filePath) {
        return '';
    }
}
