[LIB-9] Set of entities for PGN parsing and formatting
[chesshog.git] / chesshog-format / src / main / java / org / hedgecode / chess / pgn / token / MovesToken.java
1 /*
2  * Copyright (c) 2018-2020. Developed by Hedgecode.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.hedgecode.chess.pgn.token;
18
19 import java.util.regex.Matcher;
20 import java.util.regex.Pattern;
21
22 import org.hedgecode.chess.pgn.PGNUtils;
23 import org.hedgecode.chess.pgn.entity.Moves;
24 import org.hedgecode.chess.position.ParseException;
25
26 /**
27  * MovesToken
28  *
29  * @author Dmitry Samoshin aka gotty
30  */
31 public class MovesToken<Entity extends Moves> implements Token<Entity> {
32
33     enum Type {
34
35         MOVE      ( new MoveToken()      ),
36         COMMENT   ( new CommentToken()   ),
37         VARIATION ( new VariationToken() );
38
39         private Token<Moves> token;
40
41         public Token<Moves> token() {
42             return token;
43         }
44
45         Type(Token<Moves> token) {
46             this.token = token;
47         }
48     }
49
50     private static final String MOVES_REGEX = "^\\s*([^\\s])";
51     private static final Pattern MOVES_PATTERN = Pattern.compile(MOVES_REGEX);
52
53     private static final String COMMENT = "{";
54     private static final String VARIATION = "(";
55
56     @Override
57     public int token(Entity entity, String pgn) throws ParseException {
58         int pgnLength = pgn.length();
59         pgn = PGNUtils.stripCrlf(pgn);
60         Token<Moves> token = assignToken(pgn);
61         while (token != null) {
62             int index = token.token(entity, pgn);
63             pgn = pgn.substring(index);
64             token = assignToken(pgn);
65         }
66         return pgnLength;
67     }
68
69     private Token<Moves> assignToken(String pgn) {
70         Token<Moves> token = null;
71         Matcher moveMatcher = MOVES_PATTERN.matcher(pgn);
72         if (moveMatcher.find()) {
73             switch (moveMatcher.group(1)) {
74                 case COMMENT:
75                     token = Type.COMMENT.token();
76                     break;
77                 case VARIATION:
78                     token = Type.VARIATION.token();
79                     break;
80                 default:
81                     token = Type.MOVE.token();
82             }
83         }
84         return token;
85     }
86
87 }