AbstractWriter   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 55
c 1
b 0
f 1
dl 0
loc 155
rs 10
wmc 28

11 Methods

Rating   Name   Duplication   Size   Complexity  
B writeToken() 0 32 9
B write() 0 35 7
A writeStandardAlgebraicNotation() 0 3 1
A writeNumericAnnotationGlyph() 0 3 1
A writeTagPair() 0 3 1
A writeRecursiveAnnotationVariation() 0 7 2
A writeComment() 0 3 1
A writeMoveNumber() 0 9 3
A __construct() 0 3 1
A writeNullMove() 0 3 1
A writeEndResult() 0 3 1
1
<?php declare(strict_types=1);
2
/**
3
 * portable-game-notation (https://github.com/chesszebra/portable-game-notation)
4
 *
5
 * @link https://github.com/chesszebra/portable-game-notation for the canonical source repository
6
 * @copyright Copyright (c) 2017 Chess Zebra (https://chesszebra.com)
7
 * @license https://github.com/chesszebra/portable-game-notation/blob/master/LICENSE.md MIT
8
 */
9
10
namespace ChessZebra\PortableGameNotation\Writer;
11
12
use ChessZebra\PortableGameNotation\Token\Comment;
13
use ChessZebra\PortableGameNotation\Token\EndResult;
14
use ChessZebra\PortableGameNotation\Token\MoveNumber;
15
use ChessZebra\PortableGameNotation\Token\NullMove;
16
use ChessZebra\PortableGameNotation\Token\NumericAnnotationGlyph;
17
use ChessZebra\PortableGameNotation\Token\RecursiveAnnotationVariation;
18
use ChessZebra\PortableGameNotation\Token\StandardAlgebraicNotation;
19
use ChessZebra\PortableGameNotation\Token\TagPair;
20
use ChessZebra\PortableGameNotation\Token\TokenInterface;
21
use ChessZebra\PortableGameNotation\Token\TokenIterator;
22
use InvalidArgumentException;
23
24
abstract class AbstractWriter implements WriterInterface
25
{
26
    /**
27
     * @var int
28
     */
29
    private $lastMoveNumber;
30
31
    /**
32
     * @var bool
33
     */
34
    private $showMoveNumberTwice;
35
36
    /**
37
     * Initializes a new instance of this class.
38
     *
39
     * @param bool $showMoveNumberTwice Whether or not to repeat the move number.
40
     */
41
    public function __construct(bool $showMoveNumberTwice = false)
42
    {
43
        $this->showMoveNumberTwice = $showMoveNumberTwice;
44
    }
45
46
    /**
47
     * Writes the token iterator.
48
     *
49
     * @param TokenIterator $tokenIterator The token iterator to write.
50
     * @return void
51
     */
52
    public function write(TokenIterator $tokenIterator): void
53
    {
54
        $tokens = [];
55
56
        /** @var TokenInterface $token */
57
        foreach ($tokenIterator as $token) {
58
            $value = $this->writeToken($token);
59
60
            if ($value) {
61
                $tokens[] = $value;
62
            }
63
        }
64
65
        $result = '';
66
        $line = '';
67
68
        /** @var string $token */
69
        foreach ($tokens as $token) {
70
            if ($token && $token[strlen($token) - 1] === "\n") {
71
                $result .= $token;
72
                $line = '';
73
                continue;
74
            }
75
76
            if (strlen($line) + strlen($token) > 79) {
77
                $result .= trim($line) . "\n";
78
                $line = '';
79
            }
80
81
            $line .= $token . ' ';
82
        }
83
84
        $result .= $line;
85
86
        $this->writeGame(trim($result, ' ') . "\n\n");
87
    }
88
89
    /**
90
     * Writes a single game.
91
     *
92
     * @param string $pgn The PGN data of a single game.
93
     * @return void
94
     */
95
    abstract protected function writeGame(string $pgn): void;
96
97
    private function writeToken(TokenInterface $token)
98
    {
99
        switch (true) {
100
            case $token instanceof Comment:
101
                return $this->writeComment($token);
102
103
            case $token instanceof EndResult:
104
                return $this->writeEndResult($token);
105
106
            case $token instanceof MoveNumber:
107
                return $this->writeMoveNumber($token);
108
109
            case $token instanceof NullMove:
110
                return $this->writeNullMove($token);
111
112
            case $token instanceof NumericAnnotationGlyph:
113
                return $this->writeNumericAnnotationGlyph($token);
114
115
            case $token instanceof RecursiveAnnotationVariation:
116
                return $this->writeRecursiveAnnotationVariation($token);
117
118
            case $token instanceof StandardAlgebraicNotation:
119
                return $this->writeStandardAlgebraicNotation($token);
120
121
            case $token instanceof TagPair:
122
                return $this->writeTagPair($token);
123
124
            default:
125
                break;
126
        }
127
128
        throw new InvalidArgumentException('Invalid node type: ' . get_class($token));
129
    }
130
131
    private function writeComment(Comment $node)
132
    {
133
        return '{' . $node->getComment() . '}';
134
    }
135
136
    private function writeEndResult(EndResult $node)
137
    {
138
        return $node->getResult();
139
    }
140
141
    private function writeMoveNumber(MoveNumber $node)
142
    {
143
        if ($node->getNumber() === $this->lastMoveNumber) {
144
            return $this->showMoveNumberTwice ? $node->getNumber() . '...' : '';
145
        }
146
147
        $this->lastMoveNumber = $node->getNumber();
148
149
        return $node->getNumber() . '.';
150
    }
151
152
    private function writeNullMove(/** @scrutinizer ignore-unused */ NullMove $node)
153
    {
154
        return '--';
155
    }
156
157
    private function writeNumericAnnotationGlyph(NumericAnnotationGlyph $node)
158
    {
159
        return '$' . $node->getValue();
160
    }
161
162
    private function writeRecursiveAnnotationVariation(RecursiveAnnotationVariation $node)
163
    {
164
        if ($node->isOpening()) {
165
            return '(';
166
        }
167
168
        return ')';
169
    }
170
171
    private function writeStandardAlgebraicNotation(StandardAlgebraicNotation $node)
172
    {
173
        return $node->getStandardAlgebraicNotation()->getValue();
174
    }
175
176
    private function writeTagPair(TagPair $node)
177
    {
178
        return sprintf('[%s "%s"]' . "\n", $node->getName(), $node->getValue());
179
    }
180
}
181