/**
  * Creates the color related to the passed Well.
  *
  * @param data The well to handle.
  * @return See above.
  */
 private Color createColor(WellData data) {
   int red = data.getRed();
   int green = data.getGreen();
   int blue = data.getBlue();
   int alpha = data.getAlpha();
   if (red < 0 || green < 0 || blue < 0 || alpha < 0) return null;
   if (red > 255 || green > 255 || blue > 255 || alpha > 255) return null;
   return new Color(red, green, blue, alpha);
 }
 /**
  * Handles the selection of a cell
  *
  * @param cell The selected cell.
  * @param well The well to handle.
  * @param results The collection of objects to update.
  */
 private void handleCellSelection(CellDisplay cell, WellImageSet well, List<DataObject> results) {
   String description = cell.getDescription();
   Color c = cell.getHighlight();
   WellData data = (WellData) well.getHierarchyObject();
   data.setWellType(description);
   well.setDescription(description);
   results.add(data);
   if (c == null || !cell.isSpecified()) {
     data.setRed(null);
   } else {
     data.setRed(c.getRed());
     data.setGreen(c.getGreen());
     data.setBlue(c.getBlue());
     data.setAlpha(c.getAlpha());
   }
   well.setHighlight(c);
 }
  /**
   * Creates a new instance.
   *
   * @param ctx The security context.
   * @param parent The parent of the wells.
   * @param wells The collection to wells the model is for.
   * @param withThumbnails Pass <code>true</code> to load the thumbnails, <code>false</code>
   *     otherwise.
   */
  WellsModel(SecurityContext ctx, Object parent, Set<WellData> wells, boolean withThumbnails) {
    super(ctx);
    if (wells == null) throw new IllegalArgumentException("No wells.");
    this.withThumbnails = withThumbnails;
    selectedNodes = new ArrayList<WellImageSet>();
    wellDimension = null;
    this.parent = parent;
    wellNodes = sortByRow(DataBrowserTranslator.transformHierarchy(wells));

    PlateData plate = (PlateData) parent;
    columnSequenceIndex = plate.getColumnSequenceIndex();
    rowSequenceIndex = plate.getRowSequenceIndex();
    selectedField = plate.getDefaultSample();
    if (selectedField < 0) selectedField = 0;
    Set<ImageDisplay> samples = new HashSet<ImageDisplay>();
    cells = new HashSet<CellDisplay>();
    rows = -1;
    columns = -1;
    int row, column;
    Iterator<ImageDisplay> j = wellNodes.iterator();
    WellImageSet node;
    ImageNode selected;
    int f;
    String columnSequence;
    String rowSequence;
    Map<Integer, ColourObject> cMap = new HashMap<Integer, ColourObject>();
    Map<Integer, ColourObject> rMap = new HashMap<Integer, ColourObject>();
    WellData data;
    String type;
    ColourObject co;
    Color color;
    boolean b;
    validWells = new ArrayList<WellGridElement>();
    int minRow = -1;
    int minColumn = -1;
    while (j.hasNext()) {
      node = (WellImageSet) j.next();
      row = node.getRow();
      column = node.getColumn();
      data = (WellData) node.getHierarchyObject();
      type = data.getWellType();
      if (cMap.containsKey(column)) {
        co = cMap.get(column);
        color = createColor(data);
        if (!UIUtilities.isSameColors(co.getColor(), color, true)
            || !isSameDescription(co.getDescription(), type)) {
          co.setColor(null);
          co.setDescription(null);
          cMap.put(column, co);
        }
      } else {
        cMap.put(column, new ColourObject(createColor(data), type));
      }

      if (rMap.containsKey(row)) {
        co = rMap.get(row);
        color = createColor(data);
        if (!UIUtilities.isSameColors(co.getColor(), color, true)
            || !isSameDescription(co.getDescription(), type)) {
          co.setColor(null);
          co.setDescription(null);
          rMap.put(row, co);
        }
      } else {
        rMap.put(row, new ColourObject(createColor(data), type));
      }
      if (row > rows) rows = row;
      if (column > columns) columns = column;

      if (minRow < 0 || minRow > row) {
        minRow = row;
      }

      if (minColumn < 0 || minColumn > column) {
        minColumn = column;
      }
      columnSequence = "";
      if (columnSequenceIndex == PlateData.ASCENDING_LETTER)
        columnSequence = UIUtilities.LETTERS.get(column + 1);
      else if (columnSequenceIndex == PlateData.ASCENDING_NUMBER)
        columnSequence = "" + (column + 1);
      rowSequence = "";
      if (rowSequenceIndex == PlateData.ASCENDING_LETTER)
        rowSequence = UIUtilities.LETTERS.get(row + 1);
      else if (rowSequenceIndex == PlateData.ASCENDING_NUMBER) rowSequence = "" + (row + 1);
      node.setCellDisplay(columnSequence, rowSequence);
      f = node.getNumberOfSamples();
      if (fieldsNumber < f) fieldsNumber = f;
      node.setSelectedWellSample(selectedField);
      selected = node.getSelectedWellSample();
      // set the title to Row/Column
      node.formatWellSampleTitle();
      samples.add(selected);
      b = false;
      if (node.isSampleValid()) {
        wellDimension = selected.getThumbnail().getOriginalSize();
        b = true;
      }
      validWells.add(new WellGridElement(row, column, b));
    }
    //
    if (minRow >= 0 || minColumn >= 0) {
      j = wellNodes.iterator();
      while (j.hasNext()) {
        node = (WellImageSet) j.next();
        if (minRow > 0) node.setIndentRow(minRow);
        if (minColumn > 0) node.setIndentColumn(minColumn);
        if (node.getRow() == minRow || node.getColumn() == minColumn) node.formatWellSampleTitle();
      }
    }

    columns++;
    rows++;
    CellDisplay cell;
    for (int k = 1; k <= columns; k++) {
      columnSequence = "";
      if (columnSequenceIndex == PlateData.ASCENDING_LETTER)
        columnSequence = UIUtilities.LETTERS.get(k + 1);
      else if (columnSequenceIndex == PlateData.ASCENDING_NUMBER) columnSequence = "" + k;
      cell = new CellDisplay(k - 1, columnSequence);
      co = cMap.get(k - 1);
      if (co != null) {
        cell.setHighlight(co.getColor());
        cell.setDescription(co.getDescription());
      }
      // if (!isMac)
      // samples.add(cell);
      // cells.add(cell);
    }
    for (int k = 1; k <= rows; k++) {
      rowSequence = "";
      if (rowSequenceIndex == PlateData.ASCENDING_LETTER) rowSequence = UIUtilities.LETTERS.get(k);
      else if (rowSequenceIndex == PlateData.ASCENDING_NUMBER) rowSequence = "" + k;

      cell = new CellDisplay(k - 1, rowSequence, CellDisplay.TYPE_VERTICAL);
      co = rMap.get(k - 1);
      if (co != null) {
        cell.setHighlight(co.getColor());
        cell.setDescription(co.getDescription());
      }
      // if (!isMac)
      // samples.add(cell);
      // cells.add(cell);
    }
    browser = BrowserFactory.createBrowser(samples);
    browser.accept(new DecoratorVisitor(getCurrentUser().getId()));

    layoutBrowser(LayoutFactory.PLATE_LAYOUT);
    if (wellDimension == null)
      wellDimension =
          new Dimension(ThumbnailProvider.THUMB_MAX_WIDTH, ThumbnailProvider.THUMB_MAX_HEIGHT);
  }