GeezCalculator::updateSubTotal()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Geezify\Helper;
4
5
use Geezify\Converter\Converter;
6
use SplQueue as Queue;
7
8
/**
9
 * GeezCalculator calculate the ascii number from the parsed queue.
10
 *
11
 * @author Sam As End <4sam21{at}gmail.com>
12
 */
13
class GeezCalculator
14
{
15
    const ONE = 1;
16
17
    const HUNDRED = 100;
18
19
    const TEN_THOUSAND = 10000;
20
21
    /**
22
     * @var Queue
23
     */
24
    protected $queue;
25
26
    /**
27
     * @var int
28
     */
29
    protected $total;
30
31
    /**
32
     * @var int
33
     */
34
    protected $sub_total;
35
36
    /**
37
     * GeezCalculator constructor.
38
     *
39
     * @param Queue $queue
40
     */
41 91
    public function __construct(Queue $queue)
42
    {
43 91
        $this->queue = $queue;
44 91
        $this->total = 0;
45 91
    }
46
47
    /**
48
     * Do the magic.
49
     */
50 91
    public function calculate()
51
    {
52 91
        $this->resetSubTotalToZero();
53
54 91
        foreach ($this->queue as $token) {
55 91
            $this->processToken($token);
56
        }
57 91
    }
58
59
    /**
60
     * set the sub total attribute to zero.
61
     */
62 91
    protected function resetSubTotalToZero()
63
    {
64 91
        $this->sub_total = 0;
65 91
    }
66
67
    /**
68
     * Process a single token from the Queue.
69
     *
70
     * @param $token
71
     */
72 91
    protected function processToken($token)
73
    {
74 91
        list($block, $separator) = $this->fetchBlockAndSeparator($token);
75
76 91
        $this->processBySeparator($block, $separator);
77 91
    }
78
79
    /**
80
     * Fetch the block and separator from the token.
81
     *
82
     * @param $token
83
     *
84
     * @return array
85
     */
86 91
    protected function fetchBlockAndSeparator($token)
87
    {
88 91
        $block = $token['block'];
89 91
        $separator = $token['separator'];
90
91
        // This method looks dumb but it's for z sack of clarity
92
        return [
93 91
            $block,
94 91
            $separator,
95
        ];
96
    }
97
98
    /**
99
     * Process based on separator.
100
     *
101
     * @param $block
102
     * @param $separator
103
     */
104 91
    protected function processBySeparator($block, $separator)
105
    {
106 91
        if ($separator == self::ONE) {
107 91
            $this->addToTotal($block);
108 82
        } elseif ($separator == self::HUNDRED) {
109 65
            $this->updateSubTotal($block);
110 62
        } elseif ($separator == self::TEN_THOUSAND) {
111 62
            $this->updateTotal($block);
112
        }
113 91
    }
114
115
    /**
116
     * Add the sub total and the block to total
117
     * and reset sub total to zero.
118
     *
119
     * @param $block
120
     *
121
     * @return void
122
     */
123 91
    protected function addToTotal($block)
124
    {
125 91
        $this->total += ($this->sub_total + $block);
126 91
        $this->resetSubTotalToZero();
127 91
    }
128
129
    /**
130
     * Is the leading block?
131
     *
132
     * @param $block
133
     *
134
     * @return bool
135
     */
136 82
    protected function isLeading($block)
137
    {
138
        return
139 82
            $this->isBlockZero($block) &&
140 82
            $this->isSubtotalZero();
141
    }
142
143
    /**
144
     * Is the value of block zero?
145
     *
146
     * @param $block
147
     *
148
     * @return bool
149
     */
150 82
    protected function isBlockZero($block)
151
    {
152 82
        return $this->isZero($block);
153
    }
154
155
    /**
156
     * Is a number zero?
157
     *
158
     * @param $number
159
     *
160
     * @return bool
161
     */
162 82
    protected function isZero($number)
163
    {
164 82
        return Converter::isZero($number);
165
    }
166
167
    /**
168
     * Is sub total attribute zero?
169
     *
170
     * @return bool
171
     */
172 42
    protected function isSubtotalZero()
173
    {
174 42
        return $this->isZero($this->sub_total);
175
    }
176
177
    /**
178
     * Add number to sun total.
179
     *
180
     * @param $number integer
181
     */
182 65
    protected function addToSubTotal($number)
183
    {
184 65
        $this->sub_total += $number;
185 65
    }
186
187
    /**
188
     * Is the leading 10k?
189
     *
190
     * @param $block
191
     *
192
     * @return bool
193
     */
194 62
    protected function isLeadingTenThousand($block)
195
    {
196
        return
197 62
            $this->isTotalZero() &&
198 62
            $this->isLeading($block);
199
    }
200
201
    /**
202
     * Is the total attribute zero?
203
     *
204
     * @return bool
205
     */
206 62
    protected function isTotalZero()
207
    {
208 62
        return $this->isZero($this->total);
209
    }
210
211
    /**
212
     * Multiply the total attribute by ten thousand.
213
     */
214 62
    protected function multiplyTotalBy10k()
215
    {
216 62
        $this->total *= self::TEN_THOUSAND;
217 62
    }
218
219
    /**
220
     * Return the calculated ascii number.
221
     *
222
     * @return int
223
     */
224 91
    public function getCalculated()
225
    {
226 91
        return $this->total;
227
    }
228
229
    /**
230
     * Update the sub total attribute.
231
     *
232
     * @param $block
233
     */
234 65
    protected function updateSubTotal($block)
235
    {
236 65
        if ($this->isLeading($block)) {
237 24
            $block = self::ONE;
238
        }
239
240 65
        $block *= self::HUNDRED;
241
242 65
        $this->addToSubTotal($block);
243 65
    }
244
245
    /**
246
     * Update the sub total attribute.
247
     *
248
     * @param $block
249
     */
250 62
    protected function updateTotal($block)
251
    {
252 62
        if ($this->isLeadingTenThousand($block)) {
253 22
            $block = self::ONE;
254
        }
255
256 62
        $this->addToTotal($block);
257 62
        $this->multiplyTotalBy10k();
258 62
    }
259
}
260