/*
 * Copyright 2010 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.cell.client;

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;

import java.util.Set;

/**
 * A light weight representation of a renderable object.
 * 
 * <p>
 * <h3>Example</h3>
 * {@example com.google.gwt.examples.cell.CellExample}
 * </p>
 * 
 * @param <C> the type that this Cell represents
 */
public interface Cell<C> {

  /**
   * Contains information about the context of the Cell.
   */
  public static class Context {

    private final int column;
    private final int index;
    private final Object key;

    /**
     * Create a new {@link Context}.
     * 
     * @param index the absolute index of the value
     * @param column the column index of the cell, or 0
     * @param key the unique key that represents the row value
     */
    public Context(int index, int column, Object key) {
      this.index = index;
      this.column = column;
      this.key = key;
    }

    /**
     * Get the column index of the cell. If the view only contains a single
     * column, this method returns 0.
     * 
     * @return the column index of the cell
     */
    public int getColumn() {
      return column;
    }

    /**
     * Get the absolute index of the value.
     * 
     * @return the index
     */
    public int getIndex() {
      return index;
    }

    /**
     * Get the key that uniquely identifies the row object.
     * 
     * @return the unique key
     */
    public Object getKey() {
      return key;
    }
  }

  /**
   * Check if this cell depends on the selection state.
   * 
   * @return true if dependent on selection, false if not
   */
  boolean dependsOnSelection();

  /**
   * Get the set of events that this cell consumes. The container that uses this
   * cell should only pass these events to
   * {@link #onBrowserEvent(Context, Element, Object, NativeEvent, ValueUpdater))}
   * when the event occurs.
   * 
   * <p>
   * The returned value should not be modified, and may be an unmodifiable set.
   * Changes to the return value may not be reflected in the cell.
   * </p>
   * 
   * @return the consumed events, or null if no events are consumed
   */
  Set<String> getConsumedEvents();

  /**
   * Check if this cell handles selection. If the cell handles selection, then
   * its container should not automatically handle selection.
   * 
   * @return true if the cell handles selection, false if not
   */
  boolean handlesSelection();

  /**
   * Returns true if the cell is currently editing the data identified by the
   * given element and key. While a cell is editing, widgets containing the cell
   * may choose to pass keystrokes directly to the cell rather than using them
   * for navigation purposes.
   * 
   * @param context the {@link Context} of the cell
   * @param parent the parent Element
   * @param value the value associated with the cell
   * @return true if the cell is in edit mode
   */
  boolean isEditing(Context context, Element parent, C value);

  /**
   * Handle a browser event that took place within the cell. The default
   * implementation returns null.
   * 
   * @param context the {@link Context} of the cell
   * @param parent the parent Element
   * @param value the value associated with the cell
   * @param event the native browser event
   * @param valueUpdater a {@link ValueUpdater}, or null if not specified
   */
  void onBrowserEvent(Context context, Element parent, C value,
      NativeEvent event, ValueUpdater<C> valueUpdater);

  /**
   * Render a cell as HTML into a {@link SafeHtmlBuilder}, suitable for passing
   * to {@link Element#setInnerHTML(String)} on a container element.
   * 
   * <p>
   * Note: If your cell contains natively focusable elements, such as buttons or
   * input elements, be sure to set the tabIndex to -1 so that they do not steal
   * focus away from the containing widget.
   * </p>
   * 
   * @param context the {@link Context} of the cell
   * @param value the cell value to be rendered
   * @param sb the {@link SafeHtmlBuilder} to be written to
   */
  void render(Context context, C value, SafeHtmlBuilder sb);

  /**
   * Reset focus on the Cell. This method is called if the cell has focus when
   * it is refreshed.
   * 
   * @param context the {@link Context} of the cell
   * @param parent the parent Element
   * @param value the value associated with the cell
   * @return true if focus is taken, false if not
   */
  boolean resetFocus(Context context, Element parent, C value);

  /**
   * This method may be used by cell containers to set the value on a single
   * cell directly, rather than using {@link Element#setInnerHTML(String)}. See
   * {@link AbstractCell#setValue(Context)} for a default implementation that
   * uses {@link #render(Context, SafeHtmlBuilder))}.
   * 
   * @param context the {@link Context} of the cell
   * @param parent the parent Element
   * @param value the value associated with the cell
   */
  void setValue(Context context, Element parent, C value);
}
