/*
 * Copyright 2011 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.cellview.client;

import com.google.gwt.cell.client.Cell.Context;
import com.google.gwt.cell.client.HasCell;
import com.google.gwt.dom.builder.shared.ElementBuilderBase;
import com.google.gwt.dom.builder.shared.HtmlBuilderFactory;
import com.google.gwt.dom.builder.shared.HtmlTableSectionBuilder;
import com.google.gwt.dom.builder.shared.TableRowBuilder;
import com.google.gwt.dom.builder.shared.TableSectionBuilder;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * Builder used to construct a CellTable.
 * 
 * @param <T> the row data type
 */
public abstract class AbstractCellTableBuilder<T> implements CellTableBuilder<T> {
  
  /**
   * The attribute used to indicate that an element contains a cell.
   */
  private static final String CELL_ATTRIBUTE = "__gwt_cell";
  
  /**
   * The attribute used to specify the logical row index.
   */
  private static final String ROW_ATTRIBUTE = "__gwt_row";

  /**
   * The attribute used to specify the subrow within a logical row value.
   */
  private static final String SUBROW_ATTRIBUTE = "__gwt_subrow";
  
  protected final AbstractCellTable<T> cellTable;
  
  /**
   * A mapping of unique cell IDs to the cell.
   */
  private final Map<String, HasCell<T, ?>> idToCellMap = new HashMap<String, HasCell<T, ?>>();
  private final Map<HasCell<T, ?>, String> cellToIdMap = new HashMap<HasCell<T, ?>, String>();

  private HtmlTableSectionBuilder tbody;  
  private int rowIndex;
  private int subrowIndex;
  private Object rowValueKey;

  /**
   * Construct a new table builder.
   * 
   * @param cellTable the table this builder will build rows for
   */
  public AbstractCellTableBuilder(AbstractCellTable<T> cellTable) {
    this.cellTable = cellTable;
  }
  
  /**
   * Build zero or more table rows for the specified row value.
   *
   * @param rowValue the value for the row to render
   * @param absRowIndex the absolute row index
   */
  @Override
  public final void buildRow(T rowValue, int absRowIndex) {
    setRowInfo(absRowIndex, rowValue);
    buildRowImpl(rowValue, absRowIndex);
  }
  
  /**
   * Create the context for a column based on the current table building state.
   * 
   * @param column the column id
   * @return the context that contains the column index, row/subrow indexes, and the row value key
   */
  public final Context createContext(int column) {
    return new Context(rowIndex, column, rowValueKey, subrowIndex);
  }
  
  /**
   * Finish the building and get the {@link TableSectionBuilder} containing the children.
   */
  @Override
  public final TableSectionBuilder finish() {
    // End dangling elements.
    while (tbody.getDepth() > 0) {
      tbody.endTBody();
    }
    return tbody;
  }
  
  /**
   * Return the column containing an element.
   *
   * @param context the context for the element
   * @param rowValue the value for the row corresponding to the element
   * @param elem the element that the column contains
   * @return the immediate column containing the element
   */
  @Override
  public final HasCell<T, ?> getColumn(Context context, T rowValue, Element elem) {
    return getColumn(elem);
  }

  /**
   * Return all the columns that this table builder has renderred.
   */
  @Override
  public final Collection<HasCell<T, ?>> getColumns() {
    return idToCellMap.values();
  }
  
  /**
   * Get the index of the row value from the associated {@link TableRowElement}.
   * 
   * @param row the row element
   * @return the row value index
   */
  @Override
  public final int getRowValueIndex(TableRowElement row) {
    try {
      return Integer.parseInt(row.getAttribute(ROW_ATTRIBUTE));
    } catch (NumberFormatException e) {
      // The attribute doesn't exist. Maybe the user is overriding
      // renderRowValues().
      return row.getSectionRowIndex() + cellTable.getPageStart();
    }
  }
  
  /**
   * Get the index of the subrow value from the associated
   * {@link TableRowElement}. The sub row value starts at 0 for the first row
   * that represents a row value.
   * 
   * @param row the row element
   * @return the subrow value index, or 0 if not found
   */
  @Override
  public final int getSubrowValueIndex(TableRowElement row) {
    try {
      return Integer.parseInt(row.getAttribute(SUBROW_ATTRIBUTE));
    } catch (NumberFormatException e) {
      // The attribute doesn't exist. Maybe the user is overriding
      // renderRowValues() in {@link AbstractCellTable}.
      return 0;
    }
  }
  
  /**
   * Return if an element contains a cell. This may be faster to execute than {@link getColumn}.
   *
   * @param elem the element of interest
   */
  @Override
  public final boolean isColumn(Element elem) {
    return getCellId(elem) != null;
  }
  
  /**
   * Render the cell into an {@link ElementBuilderBase}.
   * 
   * @param builder the {@link ElementBuilderBase} that cell contents append to
   * @param context the context for the element
   * @param column the column containing the cell
   * @param rowValue the value for the row corresponding to the element
   */
  public final <C> void renderCell(ElementBuilderBase<?> builder, Context context,
      HasCell<T, C> column, T rowValue) {
    // Generate a unique ID for the cell.
    String cellId = cellToIdMap.get(column);
    if (cellId == null) {
      cellId = "cell-" + Document.get().createUniqueId();
      idToCellMap.put(cellId, column);
      cellToIdMap.put(column, cellId);
    }
    builder.attribute(CELL_ATTRIBUTE, cellId);

    // Render the cell into the builder.
    SafeHtmlBuilder cellBuilder = new SafeHtmlBuilder();
    if (column instanceof Column) {
      /*
       * If the HasCell is a Column, let it render the Cell itself. This is
       * here for legacy support.
       */
      Column<T, C> theColumn = (Column<T, C>) column;
      theColumn.render(context, rowValue, cellBuilder);
    } else {
      column.getCell().render(context, column.getValue(rowValue), cellBuilder);
    }
    builder.html(cellBuilder.toSafeHtml());
  }
  
  /**
   * 
   */
  /**
   * Start building rows. Reset the internal table section builder. If the table builder is going
   * to re-build all rows, the internal the maps associating the cells and ids will be cleared.
   *
   * @param isRebuildingAllRows is this start intended for rebuilding all rows
   */
  @Override
  public final void start(boolean isRebuildingAllRows) {
    /*
     * TODO(jlabanca): Test with DomBuilder.
     * 
     * DOM manipulation is sometimes faster than String concatenation and
     * innerHTML, but not when mixing the two. Cells render as HTML strings,
     * so its faster to render the entire table as a string.
     */
    tbody = HtmlBuilderFactory.get().createTBodyBuilder();
    if (isRebuildingAllRows) {
      cellToIdMap.clear();
      idToCellMap.clear();
    }
  }

  /**
   * Start a row and return the {@link TableRowBuilder} for this row.
   */
  public final TableRowBuilder startRow() {
    // End any dangling rows.
    while (tbody.getDepth() > 1) {
      tbody.end();
    }

    // Verify the depth.
    if (tbody.getDepth() < 1) {
      throw new IllegalStateException(
          "Cannot start a row.  Did you call TableRowBuilder.end() too many times?");
    }

    // Start the next row.
    TableRowBuilder row = tbody.startTR();
    row.attribute(ROW_ATTRIBUTE, rowIndex);
    row.attribute(SUBROW_ATTRIBUTE, subrowIndex);
    addRowAttributes(row);
    subrowIndex++;
    return row;
  }

  /**
   * Hook for subclasses to add their own attributes to each row in the table.
   * The default does nothing.
   *
   * @param row the row element
   */
  protected void addRowAttributes(TableRowBuilder row) {
  }

  /**
   * Build zero or more table rows for the specified row value.
   * 
   * @param rowValue the value for the row to render
   * @param absRowIndex the absolute row index
   */
  protected abstract void buildRowImpl(T rowValue, int absRowIndex);
  
  /**
   * Check if an element is the parent of a rendered cell.
   * 
   * @param elem the element to check
   * @return the cellId if a cell parent, null if not
   */
  private String getCellId(Element elem) {
    if (elem == null) {
      return null;
    }
    String cellId = elem.getAttribute(CELL_ATTRIBUTE);
    return (cellId == null) || (cellId.length() == 0) ? null : cellId;
  }

  /**
   * Return the column containing an element.
   *
   * @param elem the elm that the column contains
   * @return the column containing the element.
   */
  private HasCell<T, ?> getColumn(Element elem) {
    String cellId = getCellId(elem);
    return (cellId == null) ? null : idToCellMap.get(cellId);
  }

  /**
   * Set the information for the current row to build.
   *
   * @param rowIndex the index of the row
   * @param rowValue the value of this row
   */
  private void setRowInfo(int rowIndex, T rowValue) {
    this.rowIndex = rowIndex;
    this.rowValueKey = cellTable.getValueKey(rowValue);
    this.subrowIndex = 0; // Reset the subrow.
  }
}
