<?php
namespace Newland\NeosViewHelpers\ViewHelpers\Format;

/*
 * This file is part of the "neos-viewhelpers" package.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 */

use Neos\FluidAdaptor\Core\ViewHelper\AbstractViewHelper;

/**
 * Text Abbreviation View Helper.
 *
 * Takes a string input and returns a shortened version of it.
 * Does the same as <f:format.crop> but respects word boundaries
 * when cropping.
 */
class CropViewHelper extends AbstractViewHelper
{
    public function initializeArguments()
    {
        $this->registerArgument('input', 'string', 'The string to crop.');
        $this->registerArgument('maxCharacters', 'integer', 'Place where to truncate the string.', true);
        $this->registerArgument('append', 'string', 'What to append, if truncation happened.', false, '...');
        $this->registerArgument(
            'respectWordBoundaries',
            'boolean',
            'If TRUE and division is in the middle of a word, the remains of that word is removed. '
            . 'If the input is only a single word then this option is ignored.',
            false,
            '...'
        );
    }

    public function render(): string
    {
        $input = (string) ($this->arguments['input'] ?? $this->renderChildren());

        if (empty($input)) {
            return $input;
        }

        $input = strip_tags($input);

        if (strlen($input) <= $this->arguments['maxCharacters']) {
            return $input;
        }

        return $this->crop($input);
    }

    private function crop(string $input): string
    {
        $hasSpaces = strpos($input, ' ') !== false;
        if ($this->arguments['respectWordBoundaries'] === false || !$hasSpaces) {
            $output = substr($input, 0, $this->arguments['maxCharacters']);
            return rtrim($output) . $this->arguments['append'];
        }

        // If we are cutting off a word, we check if the next characters is a space.
        if ($input[$this->arguments['maxCharacters']] === ' ') {
            $output = substr($input, 0, $this->arguments['maxCharacters']);
            return rtrim($output) . $this->arguments['append'];
        }

        $output = substr($input, 0, $this->arguments['maxCharacters']);

        $lastSpace = (int) strrpos($output, ' ');
        $output = substr($input, 0, $lastSpace);

        return rtrim($output) . $this->arguments['append'];
    }
}
