1 package com.jetbrains.edu.learning.courseFormat;
3 import com.google.gson.annotations.Expose;
4 import com.google.gson.annotations.SerializedName;
5 import com.intellij.util.containers.ContainerUtil;
6 import com.intellij.util.containers.hash.HashMap;
7 import com.intellij.util.xmlb.annotations.Transient;
8 import org.jetbrains.annotations.NotNull;
10 import java.util.Collections;
11 import java.util.List;
15 * Implementation of windows which user should type in
18 public class AnswerPlaceholder {
20 @SerializedName("offset")
21 @Expose private int myOffset = -1;
23 @Expose private int length = -1;
25 private int myIndex = -1;
26 private MyInitialState myInitialState;
27 private StudyStatus myStatus = StudyStatus.Unchecked;
28 private boolean mySelected = false;
29 private boolean myUseLength = true;
31 @Transient private TaskFile myTaskFile;
33 @Expose private Map<Integer, AnswerPlaceholderSubtaskInfo> mySubtaskInfos = new HashMap<>();
34 public AnswerPlaceholder() {
37 public void initAnswerPlaceholder(final TaskFile file, boolean isRestarted) {
39 setInitialState(new MyInitialState(myOffset, length));
40 myStatus = file.getTask().getStatus();
46 public int getIndex() {
50 public void setIndex(int index) {
55 * in actions {@link AnswerPlaceholder#getRealLength()} should be used
57 public int getLength() {
61 public void setLength(int length) {
66 public String getPossibleAnswer() {
67 return getActiveSubtaskInfo().getPossibleAnswer();
71 public void setPossibleAnswer(String possibleAnswer) {
72 getActiveSubtaskInfo().setPossibleAnswer(possibleAnswer);
75 public MyInitialState getInitialState() {
76 return myInitialState;
79 public void setInitialState(MyInitialState initialState) {
80 myInitialState = initialState;
84 public String getTaskText() {
85 return getActiveSubtaskInfo().getPlaceholderText();
89 public void setTaskText(String taskText) {
90 getActiveSubtaskInfo().setPlaceholderText(taskText);
94 public TaskFile getTaskFile() {
99 public void setTaskFile(TaskFile taskFile) {
100 myTaskFile = taskFile;
103 public int getPossibleAnswerLength() {
104 return getPossibleAnswer().length();
108 * Returns window to its initial state
110 public void reset() {
111 myOffset = myInitialState.getOffset();
112 length = myInitialState.getLength();
115 public StudyStatus getStatus() {
119 public void setStatus(StudyStatus status) {
123 public boolean getSelected() {
127 public void setSelected(boolean selected) {
128 mySelected = selected;
132 setInitialState(new MyInitialState(myOffset, getTaskText().length()));
135 public boolean getUseLength() {
140 * @return length or possible answer length
142 public int getRealLength() {
143 return myUseLength ? getLength() : getVisibleLength(getActiveSubtaskIndex());
146 public void setUseLength(boolean useLength) {
147 myUseLength = useLength;
150 public int getOffset() {
154 public void setOffset(int offset) {
159 public List<String> getHints() {
160 return getActiveSubtaskInfo().getHints();
164 public void setHints(@NotNull final List<String> hints) {
165 getActiveSubtaskInfo().setHints(hints);
168 public void addHint(@NotNull final String text) {
169 getActiveSubtaskInfo().addHint(text);
172 public void removeHint(int i) {
173 getActiveSubtaskInfo().removeHint(i);
176 public Map<Integer, AnswerPlaceholderSubtaskInfo> getSubtaskInfos() {
177 return mySubtaskInfos;
180 public void setSubtaskInfos(Map<Integer, AnswerPlaceholderSubtaskInfo> subtaskInfos) {
181 mySubtaskInfos = subtaskInfos;
184 public boolean isActive() {
185 return getActiveSubtaskInfo() != null;
188 public static class MyInitialState {
189 private int length = -1;
190 private int offset = -1;
192 public MyInitialState() {
195 public MyInitialState(int initialOffset, int length) {
196 this.offset = initialOffset;
197 this.length = length;
200 public int getLength() {
204 public void setLength(int length) {
205 this.length = length;
208 public int getOffset() {
212 public void setOffset(int offset) {
213 this.offset = offset;
217 public AnswerPlaceholderSubtaskInfo getActiveSubtaskInfo() {
218 return mySubtaskInfos.get(getActiveSubtaskIndex());
221 public int getActiveSubtaskIndex() {
222 if (myTaskFile == null || myTaskFile.getTask() == null) {
225 return myTaskFile.getTask().getActiveSubtaskIndex();
228 public int getVisibleLength(int subtaskIndex) {
229 int minIndex = Collections.min(mySubtaskInfos.keySet());
230 AnswerPlaceholderSubtaskInfo minInfo = mySubtaskInfos.get(minIndex);
231 if (minIndex == subtaskIndex) {
232 return getUseLength() ? length : minInfo.getPossibleAnswer().length();
234 if (minIndex > subtaskIndex) {
235 return minInfo.isNeedInsertText() ? 0 : minInfo.getPlaceholderText().length();
237 int maxIndex = Collections.max(ContainerUtil.filter(mySubtaskInfos.keySet(), i -> i < subtaskIndex));
238 return getUseLength() ? length : mySubtaskInfos.get(maxIndex).getPossibleAnswer().length();