001package edu.pdx.cs410J.grader.gradebook.ui;
002
003import edu.pdx.cs410J.grader.gradebook.GradeBook;
004import edu.pdx.cs410J.grader.gradebook.LetterGrade;
005import edu.pdx.cs410J.grader.gradebook.Student;
006
007import javax.swing.*;
008import java.awt.*;
009import java.util.HashMap;
010import java.util.Map;
011
012import static edu.pdx.cs410J.grader.gradebook.GradeBook.LetterGradeRanges.LetterGradeRange;
013
014public class LetterGradeRangesPanel extends JPanel {
015
016  private final Map<LetterGrade, MinMaxValueFields> minMaxValueFields = new HashMap<>();
017  private GradeBook.LetterGradeRanges letterGradeRanges;
018
019  LetterGradeRangesPanel(Student.Section undergraduate) {
020    addLetterGradeRanges();
021  }
022
023  private void addLetterGradeRanges() {
024    this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
025
026    this.add(createRangesPanel());
027
028    this.add(Box.createVerticalGlue());
029
030    JButton update = new JButton("Update");
031    update.addActionListener(e -> updateLetterGradeRanges());
032    this.add(update);
033
034  }
035
036  private JPanel createRangesPanel() {
037    JPanel rangesPanel = new JPanel(new GridBagLayout());
038    int row = 0;
039
040    for (LetterGrade letter : LetterGrade.values()) {
041      if (letter.hasNumericRange()) {
042
043        addLetterLabel(letter, rangesPanel, row);
044
045        MinMaxValueFields fields = createMinMaxValueFieldsFor(letter);
046
047        addMaxValueField(fields, rangesPanel, row);
048        addToLabel(rangesPanel, row);
049        addMinValueField(fields, rangesPanel, row);
050
051        row++;
052      }
053    }
054
055    return rangesPanel;
056  }
057
058  private void addMinValueField(MinMaxValueFields fields, JPanel rangesPanel, int row) {
059    addComponentToRow(fields.getMinValueField(), rangesPanel, row, 3);
060  }
061
062  private void addToLabel(JPanel rangesPanel, int row) {
063    addComponentToRow(new JLabel("to"), rangesPanel, row, 2);
064  }
065
066  private void addMaxValueField(MinMaxValueFields fields, JPanel rangesPanel, int row) {
067    addComponentToRow(fields.getMaxValueField(), rangesPanel, row, 1);
068  }
069
070  private void addLetterLabel(LetterGrade letter, JPanel rangesPanel, int row) {
071    JLabel letterLabel = new JLabel(letter.asString());
072    addComponentToRow(letterLabel, rangesPanel, row, 0);
073  }
074
075  private void addComponentToRow(JComponent component, JPanel rangesPanel, int row, int gridx) {
076    GridBagConstraints constraints = new GridBagConstraints();
077    constraints.fill = GridBagConstraints.HORIZONTAL;
078    constraints.gridx = gridx;
079    constraints.gridy = row;
080    rangesPanel.add(component, constraints);
081  }
082
083  private void updateLetterGradeRanges() {
084    this.minMaxValueFields.forEach((LetterGrade grade, MinMaxValueFields fields) -> {
085      int minValue = getIntValue(fields.getMinValueField());
086      int maxValue = getIntValue(fields.getMaxValueField());
087
088      LetterGradeRange range = this.letterGradeRanges.getRange(grade);
089      range.setRange(minValue, maxValue);
090    });
091
092    this.letterGradeRanges.validate();
093  }
094
095  private int getIntValue(JTextField field) {
096    return Integer.parseInt(field.getText());
097  }
098
099  private MinMaxValueFields createMinMaxValueFieldsFor(LetterGrade letter) {
100    MinMaxValueFields fields = new MinMaxValueFields(new JTextField(3), new JTextField(3));
101    this.minMaxValueFields.put(letter, fields);
102    return fields;
103  }
104
105  public void displayLetterGradeRanges(GradeBook.LetterGradeRanges letterGradeRanges) {
106    clearAllMinMaxValueFields();
107
108    this.letterGradeRanges = letterGradeRanges;
109    letterGradeRanges.forEach(this::displayLetterGradeRange);
110  }
111
112  private void clearAllMinMaxValueFields() {
113    this.minMaxValueFields.values().forEach(MinMaxValueFields::clearFields);
114  }
115
116  private void displayLetterGradeRange(LetterGradeRange range) {
117    setTextFieldValue(getMinValueField(range.letterGrade()), range.minimum());
118    setTextFieldValue(getMaxValueField(range.letterGrade()), range.maximum());
119  }
120
121  private void setTextFieldValue(JTextField field, int value) {
122    field.setText(String.valueOf(value));
123  }
124
125  private JTextField getMinValueField(LetterGrade letterGrade) {
126    MinMaxValueFields fields = this.minMaxValueFields.get(letterGrade);
127    return fields.getMinValueField();
128  }
129
130  private JTextField getMaxValueField(LetterGrade letterGrade) {
131    MinMaxValueFields fields = this.minMaxValueFields.get(letterGrade);
132    return fields.getMaxValueField();
133  }
134
135  private class MinMaxValueFields {
136    private final JTextField minValueField;
137    private final JTextField maxValueField;
138
139    private MinMaxValueFields(JTextField minValueField, JTextField maxValueField) {
140      this.minValueField = minValueField;
141      this.maxValueField = maxValueField;
142    }
143
144    public JTextField getMinValueField() {
145      return minValueField;
146    }
147
148    public JTextField getMaxValueField() {
149      return maxValueField;
150    }
151
152    public void clearFields() {
153      this.maxValueField.setText("");
154      this.minValueField.setText("");
155    }
156  }
157}