<?php declare(strict_types=1);

namespace Aviat\Kilo;

class Syntax {
	// Tokens for PHP files
	public array $tokens = [];

	public static function new(
		string $name,
		array $keywords1 = [],
		array $keywords2 = [],
		array $operators = [],
		string $slcs = '//',
		string $mcs = '/*',
		string $mce = '*/',
		bool $highlightNumbers = true,
		bool $highlightStrings = true,
		bool $highlightComments = true,
		bool $hasCharType = false,
		bool $highlightCharacters = false,
	): self
	{
		return new self(
			$name,
			$keywords1,
			$keywords2,
			$operators,
			$slcs,
			$mcs,
			$mce,
			$highlightNumbers,
			$hasCharType,
			$highlightCharacters,
			$highlightStrings,
			$highlightComments,
		);
	}

	public static function default(): self
	{
		return self::new('No filetype', slcs: '', mcs: '', mce: '', highlightNumbers: false, highlightStrings: false);
	}

	private function __construct(
		/** The name of the programming language */
		public string $filetype,
		/** Primary set of language keywords */
		public array $keywords1,
		/** Secondary set of language keywords */
		public array $keywords2,
		/** Operators for the current language */
		public array $operators,
		/** Syntax to start a single line comment */
		public string $singleLineCommentStart,
		/** Syntax to start a multi-line comment */
		public string $multiLineCommentStart,
		/** Syntax to end a multi-line commment */
		public string $multiLineCommentEnd,
		/** Should we highlight numbers? */
		private bool $highlightNumbers,
		/** Does this language have a character type, separate from strings? */
		private bool $hasCharType,
		/** Should we highlight chars? */
		private bool $highlightCharacters,
		/** should we highlight Strings? */
		private bool $highlightStrings,
		/** should we highlight comments? */
		private bool $highlightComments,
	) {}

	public function numbers(): bool
	{
		return $this->highlightNumbers;
	}

	public function strings(): bool
	{
		return $this->highlightStrings;
	}

	public function hasChar(): bool
	{
		return $this->hasCharType;
	}

	public function characters(): bool
	{
		return $this->hasCharType && $this->highlightCharacters;
	}

	public function mlComments(): bool
	{
		return $this->highlightComments
			&& strlen($this->multiLineCommentStart) !== 0
			&& strlen($this->multiLineCommentStart) !== 0;
	}

	public function comments(): bool
	{
		return $this->highlightComments && strlen($this->singleLineCommentStart) !== 0;
	}
}