/*
 * 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 java.util.HashSet;
import java.util.Set;

/**
 * An {@link AbstractCell} used to render input elements that can receive focus.
 *
 * @param <C> the type that this Cell represents
 * @param <V> the data type of the view data state
 */
public abstract class AbstractInputCell<C, V> extends
    AbstractEditableCell<C, V> {

  /**
   * Get the events consumed by the input cell.
   *
   * @param userEvents the events consumed by the subclass
   * @return the events
   */
  private static Set<String> getConsumedEventsImpl(Set<String> userEvents) {
    Set<String> events = new HashSet<String>();
    events.add("focus");
    events.add("blur");
    events.add("keydown");
    if (userEvents != null && userEvents.size() > 0) {
      events.addAll(userEvents);
    }
    return events;
  }

  /**
   * Get the events consumed by the input cell.
   *
   * @param userEvents the events consumed by the subclass
   * @return the events
   */
  private static Set<String> getConsumedEventsImpl(String... consumedEvents) {
    Set<String> userEvents = new HashSet<String>();
    if (consumedEvents != null) {
      for (String event : consumedEvents) {
        userEvents.add(event);
      }
    }
    return getConsumedEventsImpl(userEvents);
  }

  /**
   * The currently focused value key. Only one key can be focused at any time.
   */
  private Object focusedKey;

  /**
   * Construct a new {@link AbstractInputCell} with the specified consumed
   * events.
   *
   * @param consumedEvents the events that this cell consumes
   */
  public AbstractInputCell(String... consumedEvents) {
    super(getConsumedEventsImpl(consumedEvents));
  }

  /**
   * Construct a new {@link AbstractInputCell} with the specified consumed
   * events.
   *
   * @param consumedEvents the events that this cell consumes
   */
  public AbstractInputCell(Set<String> consumedEvents) {
    super(getConsumedEventsImpl(consumedEvents));
  }

  @Override
  public boolean isEditing(Element parent, C value, Object key) {
    return focusedKey != null && focusedKey.equals(key);
  }

  @Override
  public void onBrowserEvent(Element parent, C value, Object key,
      NativeEvent event, ValueUpdater<C> valueUpdater) {
    super.onBrowserEvent(parent, value, key, event, valueUpdater);

    // Ignore events that don't target the input.
    Element target = event.getEventTarget().cast();
    if (!getInputElement(parent).isOrHasChild(target)) {
      return;
    }

    String eventType = event.getType();
    if ("focus".equals(eventType)) {
      focusedKey = key;
    } else if ("blur".equals(eventType)) {
      focusedKey = null;
    }
  }

  @Override
  public boolean resetFocus(Element parent, C value, Object key) {
    if (isEditing(parent, value, key)) {
      getInputElement(parent).focus();
      return true;
    }
    return false;
  }

  /**
   * Call this method when editing is complete.
   *
   * @param parent the parent Element
   * @param value the value associated with the cell
   * @param key the unique key associated with the row object
   * @param valueUpdater the value update to fire
   */
  protected void finishEditing(Element parent, C value, Object key,
      ValueUpdater<C> valueUpdater) {
    focusedKey = null;
    getInputElement(parent).blur();
  }

  /**
   * Get the input element.
   *
   * @param parent the cell parent element
   * @return the input element
   */
  protected Element getInputElement(Element parent) {
    return parent.getFirstChildElement();
  }

  @Override
  protected void onEnterKeyDown(Element parent, C value, Object key,
      NativeEvent event, ValueUpdater<C> valueUpdater) {
    Element input = getInputElement(parent);
    Element target = event.getEventTarget().cast();
    if (getInputElement(parent).isOrHasChild(target)) {
      finishEditing(parent, value, key, valueUpdater);
    } else {
      focusedKey = key;
      input.focus();
    }
  }
}
