1<?php
2
3declare(strict_types = 1);
4
5namespace LanguageDetection;
6
7/**
8 * Class LanguageResult
9 *
10 * @copyright Patrick Schur
11 * @license https://opensource.org/licenses/mit-license.html MIT
12 * @author Patrick Schur <patrick_schur@outlook.de>
13 * @package LanguageDetection
14 */
15class LanguageResult implements \JsonSerializable, \IteratorAggregate, \ArrayAccess
16{
17    const THRESHOLD = .025;
18
19    /**
20     * @var array
21     */
22    private $result = [];
23
24    /**
25     * LanguageResult constructor.
26     * @param array $result
27     */
28    public function __construct(array $result = [])
29    {
30        $this->result = $result;
31    }
32
33    /**
34     * @param mixed $offset
35     * @return bool
36     */
37    public function offsetExists($offset): bool
38    {
39        return isset($this->result[$offset]);
40    }
41
42    /**
43     * @param mixed $offset
44     * @return mixed|null
45     */
46    public function offsetGet($offset): ?float
47    {
48        return $this->result[$offset] ?? null;
49    }
50
51    /**
52     * @param mixed $offset
53     * @param mixed $value
54     * @return void
55     */
56    public function offsetSet($offset, $value): void
57    {
58        if (null === $offset) {
59            $this->result[] = $value;
60        } else {
61            $this->result[$offset] = $value;
62        }
63    }
64
65    /**
66     * @param mixed $offset
67     */
68    public function offsetUnset($offset): void
69    {
70        unset($this->result[$offset]);
71    }
72
73    /**
74     * @return array
75     */
76    public function jsonSerialize(): array
77    {
78        return $this->result;
79    }
80
81    /**
82     * @return string
83     */
84    public function __toString(): string
85    {
86        return (string) \key($this->result);
87    }
88
89    /**
90     * @param \string[] ...$whitelist
91     * @return LanguageResult
92     */
93    public function whitelist(string ...$whitelist): LanguageResult
94    {
95        return new LanguageResult(\array_intersect_key($this->result, \array_flip($whitelist)));
96    }
97
98    /**
99     * @param \string[] ...$blacklist
100     * @return LanguageResult
101     */
102    public function blacklist(string ...$blacklist): LanguageResult
103    {
104        return new LanguageResult(\array_diff_key($this->result, \array_flip($blacklist)));
105    }
106
107    /**
108     * @return array
109     */
110    public function close(): array
111    {
112        return $this->result;
113    }
114
115    /**
116     * @return LanguageResult
117     */
118    public function bestResults(): LanguageResult
119    {
120        if (!\count($this->result))
121        {
122            return new LanguageResult;
123        }
124
125        $first = \array_values($this->result)[0];
126
127        return new LanguageResult(\array_filter($this->result, function ($value) use ($first) {
128            return ($first - $value) <= self::THRESHOLD ? true : false;
129        }));
130    }
131
132    /**
133     * @return \ArrayIterator
134     */
135    public function getIterator(): \ArrayIterator
136    {
137        return new \ArrayIterator($this->result);
138    }
139
140    /**
141     * @param int $offset
142     * @param int|null $length
143     * @return LanguageResult
144     */
145    public function limit(int $offset, int $length = null): LanguageResult
146    {
147        return new LanguageResult(\array_slice($this->result, $offset, $length));
148    }
149}
150