Completed
Push — master ( 2f74f3...29426d )
by Samson
02:55
created

GeezCalculator::processBySeparator()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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