<?php
/**
 * Created by PhpStorm.
 * User: sale
 * Date: 24.10.17.
 * Time: 11.44
 */

namespace Intellex\Generator\Text\HTML;

use Intellex\Generator\Text\WordGenerator;
class HTMLSentenceGenerator extends WordGenerator {

	/** @var int $min Minimum number of words. */
	private $min;

	/**@var int $max Maximum number of words. */
	private $max;

	/** @var bool $dot Sets dots at end of the sentence. */
	private $dot;

	/** @var bool $comma Sets commas on random places in sentence. */
	private $comma;

	/** @var float $link Sets links on random places in sentence. */
	private $link;

	/** @var float $decorate Determines whether the sentence should have decoration tags. */
	private $decorate;

	/** @var array $decorations Determines type of decoration tags. */
	private $decorations;

	/** @var string $htmlClass Specifies name of CSS class given to generated HTML tags. */
	protected $htmlClass;

	/**
	 * Constructor for SentenceGenerator.
	 * SentenceGenerator constructor.
	 *
	 * @param int    $min         Minimum number of words in sentence.
	 * @param int    $max         Maximum number of words in sentence
	 * @param bool   $dot         Determines should sentence have dot at the end.
	 * @param bool   $comma       Determines should sentence have commas in it.
	 * @param float  $link        Sets links on random places in sentence, in percentage of
	 *                            occurrence (0-1).
	 * @param float  $decorate    Determines how many words to decorate, in percentage of
	 *                            occurrence (0-1).
	 * @param array  $decorations Determines type of decoration tags.
	 * @param string $htmlClass   Specifies name of CSS class given to generated HTML tags.
	 * @param null   $words       Map of lorem ipsum words.
	 */
	public function __construct($min = 5, $max = 25, $dot = true, $comma = true, $link = 0.05, $decorate = 0.1, $decorations = [ 'b', 'strong', 'i', 'em', 'u', 'strike' ], $htmlClass = 'html-generator', $words = null) {
		parent::__construct($words);
		$this->dot = $dot;
		$this->comma = $comma;
		$this->min = $min;
		$this->max = $max;
		$this->link = $link;
		$this->decorate = $decorate;
		$this->decorations = $decorations;
		$this->htmlClass = $htmlClass;

	}

	/**
	 * Generates random html sentence. Called from HTMLSentenceGenerator.
	 */
	public function generateValue() {
		return $this->generateSentence();
	}

	/**
	 * Generates random html sentence.
	 *
	 * @param int   $min      Minimum word for sentence.
	 * @param int   $max      Maximum word for sentence.
	 * @param float $decorate Determines whether the sentence should have decoration tags in range
	 *                        of 0-1. Default = 0.1
	 * @param bool  $dot      Determines should sentence have dot at the end. Default = true
	 * @param float $link     Determines whether the sentence should have links in range of 0-1.
	 *                        Default = 0.05
	 *
	 * @return string
	 */
	public function generateSentence($min = 5, $max = 25, $decorate = 0.1, $dot = true, $link = 0.05) {
		$this->min = $min;
		$this->max = $max;
		$this->decorate = $decorate;
		$this->dot = $dot;
		$this->link = $link;
		$len = rand($this->min, $this->max);

		// Used to make sure we have only one comma per sentence.
		$hasComma = false;

		$sentence = '';
		for ($i = 0; $i < $len; $i++) {

			// Separate word
			$glue = '';
			if (strlen($sentence)) {

				// Optional comma
				$glue = ' ';
				if ($this->comma && !$hasComma && rand(6, 11) == $i) {
					$hasComma = true;
					$glue = ', ';
				}
			}

			// Get word
			$word = parent::generateValue();

			// Link
			if (static::should($this->link)) {
				$word = '<a class="' . $this->htmlClass . '" href="javascript:alert(\'Hello :)\')">' . $word . '</a>';
			}

			$sentence .= $glue . $word;
		}

		// Decorate
		if (static::should($this->decorate)) {
			$tag = $this->decorations[rand(0, sizeof($this->decorations) - 1)];
			$sentence = $this->tag($tag, $sentence);
		}

		return ucfirst($sentence) . ($this->dot ? '.' : null);
	}

	/**
	 * Create an HTML tag.
	 *
	 * @param string $tag     The tag to create.
	 * @param string $content The content inside the tag.
	 *
	 * @return string The content wrapped in the specified tag.
	 */
	public function tag($tag, $content) {

		// Class
		$class = null;
		if ($this->htmlClass) {
			$class = ' class="' . $this->htmlClass . '"';
		}

		return "<{$tag}{$class}>{$content}</{$tag}>";
	}

	/**
	 * Get true or false by supplied probability.
	 *
	 * @param float $value The probability of true, form 0 - 1.
	 *
	 * @return bool True to execute, false to skip/
	 */
	protected static function should($value) {
		$rand = mt_rand(0, 1000000) / 1000000;
		return $rand < $value;
	}

}