<?php
/**
 * webtrees: online genealogy
 * Copyright (C) 2016 webtrees development team
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */
namespace Fisharebest\Webtrees\Module\BatchUpdate;

use Fisharebest\Algorithm\MyersDiff;
use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Filter;
use Fisharebest\Webtrees\Functions\FunctionsEdit;
use Fisharebest\Webtrees\GedcomRecord;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Module\BatchUpdateModule;

/**
 * Class BatchUpdateBasePlugin
 *
 * Each plugin should extend this class, and implement these two functions:
 *
 * bool doesRecordNeedUpdate($xref, $gedrec)
 * string updateRecord($xref, $gedrec)
 */
class BatchUpdateBasePlugin {
	/** @var bool User option; update change record */
	public $chan = false;

	/**
	 * Default is to operate on INDI records
	 *
	 * @return string[]
	 */
	public function getRecordTypesToUpdate() {
		return array('INDI');
	}

	/**
	 * Default option is just the "don't update CHAN record"
	 */
	public function getOptions() {
		$this->chan = Filter::getBool('chan');
	}

	/**
	 * Default option is just the "don't update CHAN record"
	 *
	 * @return string
	 */
	public function getOptionsForm() {
		return
			'<div class="form-group">' .
			'<label class="control-label col-sm-3">' . I18N::translate('Keep the existing “last change” information') . '</label>' .
			'<div class="col-sm-9">' .
			FunctionsEdit::radioButtons('chan', array(0 => I18N::translate('no'), 1 => I18N::translate('yes')), ($this->chan ? 1 : 0), 'class="radio-inline" onchange="this.form.submit();"') .
			'</div></div>';
	}

	/**
	 * Default buttons are update and update_all
	 *
	 * @param string $xref
	 *
	 * @return string[]
	 */
	public function getActionButtons($xref) {
		if (Auth::user()->getPreference('auto_accept')) {
			return array(
				BatchUpdateModule::createSubmitButton(I18N::translate('Update'), $xref, 'update'),
				BatchUpdateModule::createSubmitButton(I18N::translate('Update all'), $xref, 'update_all'),
			);
		} else {
			return array(
				BatchUpdateModule::createSubmitButton(I18N::translate('Update'), $xref, 'update'),
			);
		}
	}

	/**
	 * Default previewer for plugins with no custom preview.
	 *
	 * @param GedcomRecord $record
	 *
	 * @return string
	 */
	public function getActionPreview(GedcomRecord $record) {
		$old_lines   = preg_split('/[\n]+/', $record->getGedcom());
		$new_lines   = preg_split('/[\n]+/', $this->updateRecord($record->getXref(), $record->getGedcom()));
		$algorithm   = new MyersDiff;
		$differences = $algorithm->calculate($old_lines, $new_lines);
		$diff_lines  = array();

		foreach ($differences as $difference) {
			switch ($difference[1]) {
			case MyersDiff::DELETE:
				$diff_lines[] = self::decorateDeletedText($difference[0]);
				break;
			case MyersDiff::INSERT:
				$diff_lines[] = self::decorateInsertedText($difference[0]);
				break;
			default:
				$diff_lines[] = $difference[0];
			}
		}

		return '<pre class="gedcom-data">' . self::createEditLinks(implode("\n", $diff_lines)) . '</pre>';
	}

	/**
	 * Decorate inserted text
	 *
	 * @param string $text
	 *
	 * @return string
	 */
	public static function decorateInsertedText($text) {
		return '<ins>' . $text . '</ins>';
	}

	/**
	 * Decorate deleted text
	 *
	 * @param string $text
	 *
	 * @return string
	 */
	public static function decorateDeletedText($text) {
		return '<del>' . $text . '</del>';
	}

	/**
	 * Converted gedcom links into editable links
	 *
	 * @param string $gedrec
	 *
	 * @return string
	 */
	public static function createEditLinks($gedrec) {
		return preg_replace(
			"/@([^#@\n]+)@/m",
			'<a href="#" onclick="return edit_raw(\'\\1\');">@\\1@</a>',
			$gedrec
		);
	}
}
