<?php defined('SYSPATH') or die('No direct access allowed.');

/**
 * Import photo to the database
 *
 * @package    Photo
 * @category   Tasks
 * @author     Deon George
 * @copyright  (c) 2014 Deon George
 * @license    http://dev.leenooks.net/license.html
 */
class Task_Photo_Import extends Minion_Task {
	private $_log = '/tmp/photo_import.txt';

	private $_accepted = array(
		'jpg',
	);

	protected $_options = array(
		'dir'=>NULL,		// Directory of Photos to Import
		'file'=>NULL,		// Photo File to Import
		'tags'=>NULL,
		'people'=>NULL,
		'ignoredupe'=>FALSE,	// Skip duplicate photos
		'deletedupe'=>FALSE,	// Skip duplicate photos
		'verbose'=>FALSE,	// Photo File to Import
	);

	private function _adddir(&$value,$key,$path='') {
		if ($path)
			$value = sprintf('%s/%s',$path,$value);
	}

	protected function _execute(array $params) {
		$tags = NULL;
		$t = $p = array();

		if (is_null($params['file']) AND is_null($params['dir']) OR ($params['file'] AND $params['dir']))
			throw new Kohana_Exception('Missing filename, please use --file= OR --dir=');

		if ($params['dir']) {
			$files = array_diff(scandir($params['dir']),array('.','..'));

			array_walk($files,'static::_adddir',$params['dir']);

		} else
			$files = array($params['file']);

		// Tags
		if ($params['tags']) {
			$tags = explode(',',$params['tags']);
			$t = ORM::factory('Tags')->where('tag','IN',$tags)->find_all();
		}

		// People
		if ($params['people']) {
			$tags = explode(',',$params['people']);
			$p = ORM::factory('People')->where('tag','IN',$tags)->find_all();
		}

		$c = 0;
		foreach ($files as $file) {
			if ($params['verbose'])
				printf("Processing file [%s]\n",$file);

			if (preg_match('/@__thumb/',$file) OR preg_match('/\/._/',$file)) {
				$this->writelog(sprintf("Ignoring file [%s]\n",$file));
				continue;
			}

			if (! in_array(strtolower(pathinfo($file,PATHINFO_EXTENSION)),$this->_accepted)) {
				$this->writelog(sprintf("Ignoring file [%s]\n",$file));
				continue;
			}

			$c++;

			$po = ORM::factory('Photo',array('filename'=>$file));

			if (! $po->loaded())
				$po->filename = realpath($file);

			$po->date_taken = $this->dbcol(strtotime($po->io('exif:DateTime')));
			$po->signature = $this->dbcol($po->io()->getImageSignature());
			$po->make = $this->dbcol($po->io('exif:Make'));
			$po->model = $this->dbcol($po->io('exif:Model'));
			$po->height = $this->dbcol($po->io()->getImageheight());
			$po->width = $this->dbcol($po->io()->getImageWidth());
			$po->orientation = $this->dbcol($po->io()->getImageOrientation());
			$po->subsectime = $this->dbcol($po->io('exif:SubSecTimeOriginal'));

			$po->gps_lat = $this->dbcol($po->gps(preg_split('/,\s?/',$po->io()->getImageProperty('exif:GPSLatitude')),$po->io()->getImageProperty('exif:GPSLatitudeRef')));
			$po->gps_lon = $this->dbcol($po->gps(preg_split('/,\s?/',$po->io()->getImageProperty('exif:GPSLongitude')),$po->io()->getImageProperty('exif:GPSLongitudeRef')));

			try {
				$po->thumbnail = $this->dbcol(exif_thumbnail($po->filename));
			} catch (Exception $e) {
			}

			switch ($params['verbose']) {
				case 1:
					print_r($po->what_changed());
					break;

				case 2:
					print_r($po->io()->getImageProperties());
					break;
			}

			$x = $po->list_duplicate()->find_all();
			if (count($x)) {
				$skip = FALSE;

				foreach ($x as $o) {
					# We'll only ignore based on the same signature.
					if ($params['ignoredupe'] AND ($po->signature == $o->signature)) {
						$skip = TRUE;
						$this->writelog(sprintf("Ignore file [%s], it's the same as [%s (%s)]\n",$po->filename,$o->id,$o->file_path()));
						break;

					} elseif ($params['deletedupe'] AND ($po->signature == $o->signature) AND ($po->filename != $o->filename)) {
						$skip = TRUE;
						$this->writelog(sprintf("Delete file [%s], it's the same as [%s (%s)] with signature [%s]\n",$po->filename,$o->id,$o->file_path(),$po->signature));
						unlink($file);
					}
				}

				unset($x);

				if ($skip)
					continue;
				else
					$po->duplicate = '1';
			}

			if (! $po->changed())
				$this->writelog(sprintf("Image [%s] already in DB: %s\n",$file,$po->id));

			$po->save();

			if ($po->saved())
				$this->writelog(sprintf("Image [%s] stored in DB: %s\n",$file,$po->id));

			// Record our tags
			foreach ($t as $o) {
				$x = ORM::factory('Photo_Tag')->where('tag_id','=',$o->id)->where('photo_id','=',$po->id)->find();
				$x->tag_id = $o->id;
				$x->photo_id = $po->id;
				$x->save();
			}

			// Record our people
			foreach ($p as $o) {
				$x = ORM::factory('Photo_People',array('people_id'=>$o->id,'photo_id'=>$po->id));
				$x->people_id = $o->id;
				$x->photo_id = $po->id;
				$x->save();
			}

			unset($po);
			unset($x);
			unset($o);
		}

		if ($c > 1)
			return sprintf("Images processed: %s\n",$c);
	}

	// Force the return of a string or NULL
	private function dbcol($val,$noval=NULL) {
		return $val ? (string)$val : $noval;
	}

	private function writelog($msg) {
		if (! $this->_log)
			return;

		static $fh = NULL;

		if (is_null($fh))
			$fh = fopen($this->_log,'a+');

		fwrite($fh,$msg);
	}
}
?>