65ef81d5e6b53b8902692c8cf1d256d5dc2ecb6c
[idea/community.git] / python / educational-core / student / src / com / jetbrains / edu / learning / courseFormat / TaskFile.java
1 package com.jetbrains.edu.learning.courseFormat;
2
3 import com.google.gson.annotations.Expose;
4 import com.google.gson.annotations.SerializedName;
5 import com.intellij.openapi.editor.Document;
6 import com.intellij.openapi.editor.LogicalPosition;
7 import com.intellij.util.xmlb.annotations.Transient;
8 import org.jetbrains.annotations.NotNull;
9 import org.jetbrains.annotations.Nullable;
10
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
14
15 /**
16  * Implementation of task file which contains task windows for student to type in and
17  * which is visible to student in project view
18  */
19
20 public class TaskFile {
21   @Expose public String name;
22   @Expose public String text;
23   @Expose private int myIndex = -1;
24   @Expose private boolean myUserCreated = false;
25   @Expose private boolean myTrackChanges = true;
26   @Expose private boolean myHighlightErrors = false;
27   @Expose @SerializedName("placeholders") private List<AnswerPlaceholder> myAnswerPlaceholders = new ArrayList<AnswerPlaceholder>();
28   @Transient private Task myTask;
29
30   public void initTaskFile(final Task task, boolean isRestarted) {
31     setTask(task);
32     final List<AnswerPlaceholder> answerPlaceholders = getAnswerPlaceholders();
33     for (AnswerPlaceholder answerPlaceholder : answerPlaceholders) {
34       answerPlaceholder.initAnswerPlaceholder(this, isRestarted);
35     }
36     Collections.sort(answerPlaceholders, new AnswerPlaceholderComparator());
37     for (int i = 0; i < answerPlaceholders.size(); i++) {
38       answerPlaceholders.get(i).setIndex(i);
39     }
40   }
41
42   public List<AnswerPlaceholder> getAnswerPlaceholders() {
43     return myAnswerPlaceholders;
44   }
45
46   public void setAnswerPlaceholders(List<AnswerPlaceholder> answerPlaceholders) {
47     this.myAnswerPlaceholders = answerPlaceholders;
48   }
49
50   public void addAnswerPlaceholder(AnswerPlaceholder answerPlaceholder) {
51     myAnswerPlaceholders.add(answerPlaceholder);
52   }
53
54   public int getIndex() {
55     return myIndex;
56   }
57
58   public void setIndex(int index) {
59     myIndex = index;
60   }
61
62   @Transient
63   public Task getTask() {
64     return myTask;
65   }
66
67   @Transient
68   public void setTask(Task task) {
69     myTask = task;
70   }
71
72   /**
73    * @param pos position in editor
74    * @return task window located in specified position or null if there is no task window in this position
75    */
76   @Nullable
77   public AnswerPlaceholder getAnswerPlaceholder(@NotNull final Document document, @NotNull final LogicalPosition pos) {
78     return getAnswerPlaceholder(document, pos, false);
79   }
80
81   @Nullable
82   public AnswerPlaceholder getAnswerPlaceholder(@NotNull final Document document, @NotNull final LogicalPosition pos,
83                                                 boolean useAnswerLength) {
84     int line = pos.line;
85     if (line >= document.getLineCount()) {
86       return null;
87     }
88     int column = pos.column;
89     int offset = document.getLineStartOffset(line) + column;
90     for (AnswerPlaceholder placeholder : myAnswerPlaceholders) {
91       if (placeholder.getLine() <= line) {
92         int realStartOffset = placeholder.getRealStartOffset(document);
93         int placeholderLength = placeholder.getRealLength();
94         final int length = placeholderLength > 0 ? placeholderLength : 0;
95         int endOffset = realStartOffset + length;
96         if (realStartOffset <= offset && offset <= endOffset) {
97           return placeholder;
98         }
99       }
100     }
101     return null;
102   }
103
104
105   public static void copy(@NotNull final TaskFile source, @NotNull final TaskFile target) {
106     List<AnswerPlaceholder> sourceAnswerPlaceholders = source.getAnswerPlaceholders();
107     List<AnswerPlaceholder> answerPlaceholdersCopy = new ArrayList<AnswerPlaceholder>(sourceAnswerPlaceholders.size());
108     for (AnswerPlaceholder answerPlaceholder : sourceAnswerPlaceholders) {
109       AnswerPlaceholder answerPlaceholderCopy = new AnswerPlaceholder();
110       answerPlaceholderCopy.setLine(answerPlaceholder.getLine());
111       answerPlaceholderCopy.setStart(answerPlaceholder.getStart());
112       answerPlaceholderCopy.setTaskText(answerPlaceholder.getTaskText());
113       answerPlaceholderCopy.setLength(answerPlaceholder.getLength());
114       answerPlaceholderCopy.setPossibleAnswer(answerPlaceholder.getPossibleAnswer());
115       answerPlaceholderCopy.setIndex(answerPlaceholder.getIndex());
116       answerPlaceholderCopy.setHint(answerPlaceholder.getHint());
117       answerPlaceholdersCopy.add(answerPlaceholderCopy);
118     }
119     target.name = source.name;
120     target.setAnswerPlaceholders(answerPlaceholdersCopy);
121   }
122
123   public void setUserCreated(boolean userCreated) {
124     myUserCreated = userCreated;
125   }
126
127   public boolean isUserCreated() {
128     return myUserCreated;
129   }
130
131   public boolean isTrackChanges() {
132     return myTrackChanges;
133   }
134
135   public void setTrackChanges(boolean trackChanges) {
136     myTrackChanges = trackChanges;
137   }
138
139   public boolean isHighlightErrors() {
140     return myHighlightErrors;
141   }
142
143   public void setHighlightErrors(boolean highlightErrors) {
144     myHighlightErrors = highlightErrors;
145   }
146
147   public void sortAnswerPlaceholders() {
148     Collections.sort(myAnswerPlaceholders, new AnswerPlaceholderComparator());
149     for (int i = 0; i < myAnswerPlaceholders.size(); i++) {
150       myAnswerPlaceholders.get(i).setIndex(i + 1);
151     }
152   }
153
154
155   @Override
156   public boolean equals(Object o) {
157     if (this == o) return true;
158     if (o == null || getClass() != o.getClass()) return false;
159
160     TaskFile that = (TaskFile)o;
161
162     if (getIndex() != that.getIndex()) return false;
163     if (!name.equals(that.name)) return false;
164
165     final List<AnswerPlaceholder> answerPlaceholders = getAnswerPlaceholders();
166     final List<AnswerPlaceholder> thatAnswerPlaceholders = that.getAnswerPlaceholders();
167     if (answerPlaceholders.size() != thatAnswerPlaceholders.size()) return false;
168     for (int i = 0; i < answerPlaceholders.size(); i++) {
169       final AnswerPlaceholder placeholder = answerPlaceholders.get(i);
170       final AnswerPlaceholder thatPlaceholder = thatAnswerPlaceholders.get(i);
171       if (!placeholder.equals(thatPlaceholder)) return false;
172     }
173     return true;
174   }
175
176   @Override
177   public int hashCode() {
178     int result = getIndex();
179     result = 31 * result + name.hashCode();
180     for (AnswerPlaceholder placeholder : myAnswerPlaceholders) {
181       result = 31 * result + placeholder.hashCode();
182     }
183     return result;
184   }
185 }