/**
  * Given an experiment, we see for each condition if a new growth medium is associated to the cell
  * line, and if new media are found, these are added to the medium binding list.
  *
  * @param experiment
  */
 public void addNewMedia(Experiment experiment) {
   for (PlateCondition plateCondition : experiment.getPlateConditionList()) {
     CellLine cellLine = plateCondition.getCellLine();
     String medium = cellLine.getGrowthMedium();
     if (!mediumBindingList.contains(medium)) {
       mediumBindingList.add(medium);
     }
   }
 }
 /**
  * Given an experiment, we see for each condition if a new serum is associated to the cell line,
  * and if new sera are found, these are added to the serum binding list.
  *
  * @param experiment
  */
 public void addNewSera(Experiment experiment) {
   for (PlateCondition plateCondition : experiment.getPlateConditionList()) {
     CellLine cellLine = plateCondition.getCellLine();
     String serum = cellLine.getSerum();
     if (!serumBindingList.contains(serum)) {
       serumBindingList.add(serum);
     }
   }
 }
  /** Initialize ConditionsPanel components */
  private void initConditionsPanel() {
    // set selected matrix dimension to "2D"
    setupConditionsPanel.getEcmDimensionComboBox().setSelectedIndex(0);
    setupConditionsPanel.getjTabbedPane1().setEnabled(false);
    // set current and previous conditions indexes
    conditionIndex = 0;
    previousConditionIndex = -1;

    conditionsPanel.getAddButton().setEnabled(false);
    // init conditionJList (create new empty list) (conditions are NOT retrieved from DB)
    plateConditionBindingList =
        ObservableCollections.observableList(new ArrayList<PlateCondition>());

    // autobind cell line
    // autobind seeding density
    Binding binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.cellLine.seedingDensity"),
            setupConditionsPanel.getSeedingDensityTextField(),
            BeanProperty.create("text"),
            "seedingdensitybinding");
    bindingGroup.addBinding(binding);
    // autobind seeding time
    binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.cellLine.seedingTime"),
            setupConditionsPanel.getSeedingTimeTextField(),
            BeanProperty.create("text"),
            "seedingtimebinding");
    bindingGroup.addBinding(binding);
    // autobind growth medium
    binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.cellLine.growthMedium"),
            setupConditionsPanel.getGrowthMediumComboBox(),
            BeanProperty.create("selectedItem"),
            "growthmediumbinding");
    bindingGroup.addBinding(binding);
    // autobind serum
    binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.cellLine.serum"),
            setupConditionsPanel.getSerumComboBox(),
            BeanProperty.create("selectedItem"),
            "celllineserumbinding");
    bindingGroup.addBinding(binding);
    // autobind serum concentration
    binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.cellLine.serumConcentration"),
            setupConditionsPanel.getSerumConcentrationTextField(),
            BeanProperty.create("text"),
            "celllineserumconcentrationbinding");
    bindingGroup.addBinding(binding);
    // autobind cell line type
    binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.cellLine.cellLineType"),
            setupConditionsPanel.getCellLineComboBox(),
            BeanProperty.create("selectedItem"),
            "celllinetypebinding");
    bindingGroup.addBinding(binding);

    // autobind assay medium
    // autobind medium
    binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.assayMedium.medium"),
            treatmentsController.getTreatmentsPanel().getAssayMediumComboBox(),
            BeanProperty.create("selectedItem"),
            "assaymediumbinding");
    bindingGroup.addBinding(binding);
    // autobind serum
    binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.assayMedium.serum"),
            treatmentsController.getTreatmentsPanel().getSerumComboBox(),
            BeanProperty.create("selectedItem"),
            "assayserumbinding");
    bindingGroup.addBinding(binding);
    // autobind serum concentration
    binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.assayMedium.serumConcentration"),
            treatmentsController.getTreatmentsPanel().getSerumConcentrationTextField(),
            BeanProperty.create("text"),
            "assayserumconcentrationbinding");
    bindingGroup.addBinding(binding);
    // autobind volume
    binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.assayMedium.volume"),
            treatmentsController.getTreatmentsPanel().getMediumVolumeTextField(),
            BeanProperty.create("text"),
            "assayvolumebinding");
    bindingGroup.addBinding(binding);

    // autobind matrix dimension
    binding =
        Bindings.createAutoBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            conditionsPanel.getConditionsJList(),
            BeanProperty.create("selectedElement.matrixDimension"),
            setupConditionsPanel.getEcmDimensionComboBox(),
            BeanProperty.create("selectedItem"),
            "matrixdimensionbinding");
    bindingGroup.addBinding(binding);
    bindingGroup.bind();

    // init conditionListBinding
    JListBinding conditionListBinding =
        SwingBindings.createJListBinding(
            AutoBinding.UpdateStrategy.READ_WRITE,
            plateConditionBindingList,
            conditionsPanel.getConditionsJList());
    bindingGroup.addBinding(conditionListBinding);
    bindingGroup.bind();

    // create and init the first condition (Condition 1)
    PlateCondition firstCondition = createFirstCondition();
    // add Condition 1 to the list
    plateConditionBindingList.add(firstCondition);

    // set cell renderer for conditionJList
    conditionsPanel.getConditionsJList().setCellRenderer(new ConditionsSetupListRenderer());

    /** add mouse listeners */
    // if Condition validation is OK, update previous condition and user input fields
    conditionsPanel
        .getConditionsJList()
        .getSelectionModel()
        .addListSelectionListener(
            new ListSelectionListener() {
              @Override
              public void valueChanged(ListSelectionEvent e) {
                if (!e.getValueIsAdjusting()) {
                  conditionsPanel.getAddButton().setEnabled(true);
                  int selectedIndex = conditionsPanel.getConditionsJList().getSelectedIndex();
                  if (selectedIndex != -1) {
                    // add mouse listener and enable tabbed pane on the right (only once, for
                    // Condition 1)
                    if (selectedIndex == 0) {
                      setupExperimentController.addMouseListener();
                      setupConditionsPanel.getjTabbedPane1().setEnabled(true);
                    }
                    if (previousConditionIndex < plateConditionBindingList.size()
                        && previousConditionIndex != -1) {
                      // check if validation of condition is OK
                      if (setupExperimentController.validateCondition(
                          plateConditionBindingList.get(previousConditionIndex))) {
                        // update fields of previous condition
                        updateCondition(previousConditionIndex);
                        // update and reset fields for the assay-ecm panel
                        assayEcmController.updateAssayEcmInputFields(
                            plateConditionBindingList.get(selectedIndex));
                        // assayEcmPanelController.resetAssayEcmInputFields(plateConditionBindingList.get(locationToIndex));
                        // keep source and destination lists sync: show actual treatment collection
                        treatmentsController.updateLists(
                            plateConditionBindingList.get(selectedIndex));
                      }
                    }
                    previousConditionIndex = selectedIndex;
                  }
                }
              }
            });

    // add an empty list of rectangles for Condition 1
    setupExperimentController.onNewConditionAdded(firstCondition);
    // disable the Remove Button
    conditionsPanel.getRemoveButton().setEnabled(false);

    /** add action listeners */
    // add a new Condition to the List
    // each new Condition is init through values selected from the previously created one!
    conditionsPanel
        .getAddButton()
        .addActionListener(
            new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                // create and init a new Condition
                PlateCondition newCondition = new PlateCondition();
                initNewCondition(newCondition);
                // add the new Condition to the list
                plateConditionBindingList.add(newCondition);
                // add a new empty list of rectangles for the just added Condition
                setupExperimentController.onNewConditionAdded(newCondition);
                // after a new condition is added enable the remove button
                if (!conditionsPanel.getRemoveButton().isEnabled()) {
                  conditionsPanel.getRemoveButton().setEnabled(true);
                }
              }
            });

    // remove a Condition from the list
    conditionsPanel
        .getRemoveButton()
        .addActionListener(
            new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                if (conditionsPanel.getConditionsJList().getSelectedValue() != null) {
                  // empty the list of rectangles for this Condition and reset to null the Condition
                  // of the associated wells
                  setupExperimentController.onConditionToRemove(
                      (PlateCondition) (conditionsPanel.getConditionsJList().getSelectedValue()));
                  // remove the Condition from the list
                  int selectedIndex = conditionsPanel.getConditionsJList().getSelectedIndex();
                  PlateCondition conditionToRemove = plateConditionBindingList.get(selectedIndex);
                  // if the condition to remove is the last one, decrease previous condition index
                  if (plateConditionBindingList.indexOf(conditionToRemove)
                      == plateConditionBindingList.size() - 1) {
                    previousConditionIndex = plateConditionBindingList.size() - 2;
                  }
                  // remove condition from the list
                  plateConditionBindingList.remove(conditionToRemove);
                  // select first condition after removing
                  conditionsPanel.getConditionsJList().setSelectedIndex(0);
                  // if there's only one condition left, disable again the remove button
                  if (plateConditionBindingList.size() == 1) {
                    conditionsPanel.getRemoveButton().setEnabled(false);
                  }
                }
              }
            });
  }