<?php
/**
 * @name		Page Builder CK
 * @package		com_pagebuilderck
 * @copyright	Copyright (C) 2015. All rights reserved.
 * @license		GNU General Public License version 2 or later; see LICENSE.txt
 * @author		Cedric Keiflin - https://www.template-creator.com - https://www.joomlack.fr
 */

// No direct access
defined('_JEXEC') or die;

use Pagebuilderck\CKFolder;
use Pagebuilderck\CKFile;

/**
 * Loader Class.
 */
class PagebuilderckLoaderFolder {

	private static $params;

	private static $folderLabels = array();

	private static $imagesOrderByLabels = array();

	public static function getItems(&$params) {
		self::$params = $params;

		$authorisedExt = array('png', 'jpg', 'JPG', 'JPEG', 'jpeg', 'bmp', 'tiff', 'gif', 'webp', 'WEBP');
		$folder = trim($params->get('autoloadfoldername'), '/');
		if (file_exists($folder . '/labels.txt') && $params->get('autoloadfolderorderby', 'default') == 'default') {
			$items = self::loadImagesFromFolder($folder);
		} else {
			$items = CKFolder::files(JPATH_ROOT . '/' . $folder, '\.(?:png|jpe?g|bmp|tiff|PNG|JPE?G|BMP|TIFF|webp|WEBP?)$', false, false);

			if ($params->get('autoloadfolderorderby', 'default') == 'exif') {
				foreach ($items as $i => $name) {
					$filename = JPATH_ROOT . '/' . $folder . '/' . $name;
					$exif = exif_read_data($filename, 'IFD0');
					if ($exif) {
						$items[strtotime($exif['DateTime'])] = $name;
					} else {
						$t = filemtime($filename) + $i;
						$items[$t] = $name;
					}
						unset($items[$i]);
				}
				if ($params->get('autoloadfolderorderdir', 'asc') == 'desc') {
					krsort($items);
				} else {
					ksort($items);
				}
			}

			foreach ($items as $i => $name) {
				$item = self::initItem();
				$item->image = trim(str_replace('\\','/',$name), '/');
				$item->image = JUri::root(true) . '/' . $folder . '/' . trim($item->image, '\\');

				if (!in_array(strToLower(CKFile::getExt($item->image)), $authorisedExt))
					continue;

				// load the image data from txt
				$item = self::getImageDataFromfolderLegacy($item, $params);
				$items[$i] = $item;

				// route the url
				$item->link = (string)$item->link;
				if (strcasecmp(substr($item->link, 0, 4), 'http') && (strpos($item->link, 'index.php?') !== false)) {
					$item->link = JRoute::_($item->link, true, false);
				} else {
					$item->link = JRoute::_($item->link);
				}
			}
		}
		
		return $items;
	}

	/**
	 * Old method that looks for a txt file that has the same name as the image
	 * @param type $item
	 * @param type $params
	 * @return type
	 */
	static function getImageDataFromfolderLegacy(&$item, $params) {
		// load the image data from txt
		$datafile = JPATH_ROOT . '/' . str_replace(JFile::getExt($item->image), 'txt', $item->image);
		$data = file_exists($datafile) ? file_get_contents($datafile) : '';
		$imgdatatmp = explode("\n", $data);

		$parmsnumb = count($imgdatatmp);
		for ($i = 0; $i < $parmsnumb; $i++) {
			$imgdatatmp[$i] = trim($imgdatatmp[$i]);
			$item->text = stristr($imgdatatmp[$i], "caption=") ? str_replace('caption=', '', $imgdatatmp[$i]) : $item->text;
			$item->articleid = stristr($imgdatatmp[$i], "articleid=") ? str_replace('articleid=', '', $imgdatatmp[$i]) : $item->articleid;
			$item->video = stristr($imgdatatmp[$i], "video=") ? str_replace('video=', '', $imgdatatmp[$i]) : $item->video;
			$item->link = stristr($imgdatatmp[$i], "link=") ? str_replace('link=', '', $imgdatatmp[$i]) : $item->link;
			$item->time = stristr($imgdatatmp[$i], "time=") ? str_replace('time=', '', $imgdatatmp[$i]) : $item->time;
			$item->target = stristr($imgdatatmp[$i], "target=") ? str_replace('target=', '', $imgdatatmp[$i]) : $item->target;
		}

		if ($item->video)
			$item->slideselect = 'video';
		
		// manage the title and description
		$item->text = (string)$item->text;
		if (stristr($item->text, "||")) {
			$splitcaption = explode("||", $item->text);
			$item->text = '<div class="pagebuilderck_title">' . $splitcaption[0] . '</div><div class="pagebuilderck_description">' . $splitcaption[1] . '</div>';
		}

		if (isset($item->articleid) && $item->articleid) {
			$item = PagebuilderckHelper::getArticle($item, $params);
		}

		return $item;
	}

	private static function getImageLabelsFromFolder($directory) {
		$dirindex = PagebuilderckHelper::cleanName($directory);
		if (! empty(self::$folderLabels[$dirindex])) return;

		$items = array();
		$item = new stdClass();

		// get the language
		$lang = JFactory::getLanguage();
		$langtag = $lang->getTag(); // returns fr-FR or en-GB

		// load the image data from txt
		if (file_exists(JPATH_ROOT . '/' . $directory . '/labels.' . $langtag . '.txt')) {
			$data = file_get_contents(JPATH_ROOT . '/' . $directory . '/labels.' . $langtag . '.txt');
		} else if (file_exists(JPATH_ROOT . '/' . $directory . '/labels.txt')) {
			$data = file_get_contents(JPATH_ROOT . '/' . $directory . '/labels.txt');
		} else {
			return null;
		}

		$doUTF8encode = true;
		// remove UTF-8 BOM and normalize line endings
		if (!strcmp("\xEF\xBB\xBF", substr($data,0,3))) {  // file starts with UTF-8 BOM
			$data = substr($data, 3);  // remove UTF-8 BOM
			$doUTF8encode = false;
		}
		$data = str_replace("\r", "\n", $data);  // normalize line endings

		// if no data found, exit
		if(! $data) return null;

		// explode the file into rows
		// $imgdatatmp = explode("\n", $data);
		$imgdatatmp = preg_split("/\r\n|\n|\r/", $data, -1, PREG_SPLIT_NO_EMPTY);

		$parmsnumb = count($imgdatatmp);
		for ($i = 0; $i < $parmsnumb; $i++) {
			$imgdatatmp[$i] = trim($imgdatatmp[$i]);
			$line = explode('|', $imgdatatmp[$i]);

			// store the order or files from the TXT file
			self::$imagesOrderByLabels[] = $line[0];

			$item = self::initItem();
			$item->index = PagebuilderckHelper::cleanName($line[0]);
			$item->title = (isset($line[1])) ? ( $doUTF8encode ? htmlspecialchars($line[1]) : htmlspecialchars($line[1]) ) : '';
			$item->text = (isset($line[2])) ? ( $doUTF8encode ? htmlspecialchars($line[2]) : htmlspecialchars($line[2]) ) : '';
			$item->link = (isset($line[3])) ? ( $doUTF8encode ? $line[3] : ($line[3]) ) : '';
			$item->video = (isset($line[4])) ? ( $doUTF8encode ? $line[4] : ($line[4]) ) : '';
			$item->articleid = (isset($line[5])) ? $line[5] : '';
			if ($item->articleid) $item = PagebuilderckHelper::getArticle($item);

			$items[$item->index] = $item;
		}

		self::$folderLabels[$dirindex] = $items;
	}

	/*
	 * Load the data for the image (title and description)
	 */
	private static function getImageDataFromfolder($file, $directory) {
		$filename = explode('/', $file);
		$filename = end($filename);
		$dirindex = PagebuilderckHelper::cleanName($directory);
		$fileindex = PagebuilderckHelper::cleanName($filename);

		if (! empty(self::$folderLabels[$dirindex]) && ! empty(self::$folderLabels[$dirindex][$fileindex])) {
			$item = self::$folderLabels[$dirindex][$fileindex];
		} else {
			$item = self::initItem();
		}

		return $item;
	}
	

	/*
	 * Load the image from the specified folder 
	 */
	public static function loadImagesFromFolder($directory) {

		// encode the folder path, needed if contains an accent
		try {
			$translatedDirectory = iconv("UTF-8", "ISO-8859-1//TRANSLIT", urldecode($directory));
			if ($translatedDirectory) $directory = $translatedDirectory;
		} catch (Exception $e) {
			echo 'CK Message : ',  $e->getMessage(), "\n";
		}

		// load the files from the folder
		$files = CKFolder::files(trim(trim($directory), '/'), '.', false, true);

		if (! $files) return 'CK message : No files found in the directory : ' . $directory;

		self::$imagesOrderByLabels = array();
		// load the labels from the folder
		self::getImageLabelsFromFolder($directory);

		$order = self::$params->get('displayorder');
		// set the images order
		if ($order == 'shuffle') {
			shuffle($files);
		} else {
			natsort($files);
			$files = array_map(array('PagebuilderckHelper', 'formatPath'), $files);
			$baseDir = PagebuilderckHelper::formatPath($directory);
			$labelsOrder = array_reverse(self::$imagesOrderByLabels);
			foreach ($labelsOrder as $name) {
				$imgFile = $baseDir . '/' . $name;
				array_unshift($files, $imgFile);
			}
			// now make it unique
			$files = array_unique($files);
		}

		$authorisedExt = array('png','jpg','jpeg','bmp','tiff','gif','webp');
		$items = array();
		$i = 0;
		foreach ($files as $file) {
			$fileExt = CKFile::getExt($file);
			if (!in_array(strToLower($fileExt),$authorisedExt)) continue;

			$item = self::initItem();

			// get the data for the image
			$filedata = self::getImageDataFromfolder($file, $directory);

			$file = str_replace("\\", "/", PagebuilderckHelper::utf8_encode($file));

			$item->image = JUri::base(true) . '/' . $file;
			$item->title = $filedata->title;
			$item->text = $filedata->text;
			$item->video = $filedata->video;
			$items[$i] = $item;
			if (isset($filedata->link) && $filedata->link) {
				$item->link = $filedata->link;
			} else {
				$videoFile = str_replace($fileExt, 'mp4', $file);
				$hasVideo = file_exists($videoFile);
				$item->link = $hasVideo ? $videoFile : $item->image;
			}
			$i++;
		}

		return $items;
	}

	/**
	 * Ajax method called from the module to list the images
	 */
	public static function loadLabelsFile() {
		$input	= \Pagebuilderck\CKFof::getInput();
		$path = $input->get('path', '', 'string');

		// outputs the heading
		echo '<div id="labelseditor">';
		echo '<div class="ckheader">'
					. '<div class="col ckmove">' . JText::_('CK_ORDERING') . '</div>'
					. '<div class="col ckimage">' . JText::_('CK_IMAGE') . '</div>'
					. '<div class="col">' . JText::_('CK_TEXT') . '</div>'
					. '<div class="col">' . JText::_('CK_LINK') . '</div>'
				. '</div>';

		$params = new JRegistry();
		$params->set('autoloadfoldername', $path);
		$items = self::getItems($params);
		$images = Array();
		foreach ($items as $item) {
			$filename = explode('/', $item->image);
			$filename = end($filename);
			$images[] = $filename;
		}

		$i = 0;
		$labels = Array();
		if (file_exists(JPATH_SITE . '/' . $path . '/labels.txt')) {
			$labels = file_get_contents(JPATH_SITE . '/' . $path . '/labels.txt');
			$lines = explode("\n", $labels);
			foreach ($lines as $line) {
				$line = trim($line);
				if (!$line) continue;
				$t = explode('|', $line);
				$image = isset($t[0]) ? $t[0] : '';
				if (! $image) continue;
				$title = isset($t[1]) ? htmlspecialchars($t[1]) : '';
				$desc = isset($t[2]) ? htmlspecialchars($t[2]) : '';
				$link = isset($t[3]) ? htmlspecialchars($t[3]) : '';
				if (in_array($image, $images)) {
					$key = array_search($image, $images);
					unset($images[$key]);
					self::renderLabelEdition($path, $image, $i, $title, $desc, $link);
					$i++;
				}

				
			}
		}

		
		foreach ($images as $image) {
			self::renderLabelEdition($path, $image, $i, $title = '', $desc = '', $link = '');
			$i++;
		}
		echo '</div>';
	}

	/*
	 * Output the html code for the label edition
	 */
	private static function renderLabelEdition($path, $image, $i, $title, $desc, $link) {
		echo '<div class="ckrow">'
				. '<div class="col ckmove">&nbsp;</div>'
				. '<div class="col ckfile cktip" data-image="' . PagebuilderckHelper::utf8_encode($image) . '" title="' . PagebuilderckHelper::utf8_encode($image) . '" style="background-image: url(\'' . JUri::root(true) . '/' . $path . '/' . $image . '\');" ></div>'
				. '<div class="col">'
					.'<div><label style="display: inline-block;padding: 5px;min-width: 100px">' . JText::_('CK_TITLE') . '</label><input class="labeltitle" type="text" value="' . $title . '" /></div>'
					. '<div><label style="display: inline-block;padding: 5px;min-width: 100px">' . JText::_('CK_DESCRIPTION') . '</label><input class="labeldesc" type="text" value="' . $desc . '" /></div>'
				. '</div>'
				. '<div class="col input-append"><input id="labellink'.$i.'" class="labellink" type="text" value="' . $link . '" /><button class="btn" onclick="CKBox.open({url: \''.JUri::root(true).'/administrator/index.php?option=com_pagebuilderck&view=menus&tmpl=component&fieldid=labellink'.$i.'\', id:\'ckmenusmodal\', style: {padding: \'10px\'} })">' . JText::_('CK_SELECT') . '</button></div>'
			. '</div>';
	}

	/*
	 * Write the labels.txt file in the folder
	 */
	public static function writeLabelsFile() {
		$input	= \Pagebuilderck\CKFof::getInput();
		$path = $input->get('path', '', 'string');
		$labels = $input->get('labels', '', 'html');
//		$labels = utf8_decode($input->get('labels', '', 'html'));
		$labelsFile = JPATH_SITE . '/' . $path . '/labels.txt';

		echo (bool)file_put_contents($labelsFile, $labels);
		exit();
	}

	public static function importFromFolder() {
		$input	= \Pagebuilderck\CKFof::getInput();
		$folder = $input->get('folder', '', 'string');
		$imgdir = JPATH_ROOT . '/' . trim(trim($folder, "/"), "\\");
		$imgs = CKFolder::files($imgdir, '\.(?:png|jpe?g|bmp|tiff|webp?)$', false, true);
		$imgs = str_replace(JPATH_ROOT, "", $imgs);
		$imgs = str_replace("\\", "/", $imgs);
		foreach ($imgs as &$img) {
			$img = trim($img, "/");
		}
		$imgs = json_encode($imgs);

		echo $imgs;
		exit;
	}

	/*
	 * Make empty slide object
	 */
	private static function initItem() {
		$item = new stdClass();
		$item->image = null;
		$item->link = null;
		$item->title = null;
		$item->text = null;
		$item->more = array();
		$item->alignment = null;
		$item->time = null;
		$item->target = 'default';
		$item->video = null;
		$item->texttype = null;
		$item->articleid = null;

		return $item;
	}
}