/*
 * Copyright 2007 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.client.ui;

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.i18n.client.HasDirection.Direction;
import com.google.gwt.i18n.shared.DirectionEstimator;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.annotations.IsSafeHtml;
import com.google.gwt.uibinder.client.UiConstructor;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;

/**
 * A mutually-exclusive selection radio button widget. Fires
 * {@link com.google.gwt.event.dom.client.ClickEvent ClickEvents} when the
 * radio button is clicked, and {@link ValueChangeEvent ValueChangeEvents}
 * when the button becomes checked.
 * Note, however, that browser limitations prevent ValueChangeEvents from
 * being sent when the radio button is cleared as a side effect of another in
 * the group being clicked.
 * 
 * <p>
 * <img class='gallery' src='doc-files/RadioButton.png'/>
 * </p>
 *
 * <p>
 * <h3>Built-in Bidi Text Support</h3>
 * This widget is capable of automatically adjusting its direction according to
 * its content. This feature is controlled by {@link #setDirectionEstimator} or
 * passing a DirectionEstimator parameter to the constructor, and is off by
 * default.
 * </p>
 *
 * <h3>CSS Style Rules</h3> 
 * <dl>
 * <dt>.gwt-RadioButton</dt> 
 * <dd>the outer element</dd>
 * </dl>
 * 
 * <p>
 * <h3>Example</h3> {@example com.google.gwt.examples.RadioButtonExample}
 * </p>
 */
public class RadioButton extends CheckBox {

  public static final DirectionEstimator DEFAULT_DIRECTION_ESTIMATOR =
    DirectionalTextHelper.DEFAULT_DIRECTION_ESTIMATOR;

  private Boolean oldValue;

  /**
   * Creates a new radio associated with a particular group name. All radio
   * buttons associated with the same group name belong to a mutually-exclusive
   * set.
   * 
   * Radio buttons are grouped by their name attribute, so changing their name
   * using the setName() method will also change their associated group.
   * 
   * @param name the group name with which to associate the radio button
   */
  @UiConstructor
  public RadioButton(String name) {
    super(DOM.createInputRadio(name));
    setStyleName("gwt-RadioButton");

    sinkEvents(Event.ONCLICK);
    sinkEvents(Event.ONMOUSEUP);
    sinkEvents(Event.ONBLUR);
    sinkEvents(Event.ONKEYDOWN);
  }

  /**
   * Creates a new radio associated with a particular group, and initialized
   * with the given HTML label. All radio buttons associated with the same group
   * name belong to a mutually-exclusive set.
   * 
   * Radio buttons are grouped by their name attribute, so changing their name
   * using the setName() method will also change their associated group.
   * 
   * @param name the group name with which to associate the radio button
   * @param label this radio button's html label
   */
  public RadioButton(String name, SafeHtml label) {
    this(name, label.asString(), true);
  }

  /**
   * @see #RadioButton(String, SafeHtml)
   * 
   * @param name the group name with which to associate the radio button
   * @param label this radio button's html label
   * @param dir the text's direction. Note that {@code DEFAULT} means direction
   *          should be inherited from the widget's parent element.
   */
  public RadioButton(String name, SafeHtml label, Direction dir) {
    this(name);
    setHTML(label, dir);
  }

  /**
   * @see #RadioButton(String, SafeHtml)
   * 
   * @param name the group name with which to associate the radio button
   * @param label this radio button's html label
   * @param directionEstimator A DirectionEstimator object used for automatic
   *          direction adjustment. For convenience,
   *          {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
   */
  public RadioButton(String name, SafeHtml label,
      DirectionEstimator directionEstimator) {
    this(name);
    setDirectionEstimator(directionEstimator);
    setHTML(label.asString());
  }

  /**
   * Creates a new radio associated with a particular group, and initialized
   * with the given HTML label. All radio buttons associated with the same group
   * name belong to a mutually-exclusive set.
   * 
   * Radio buttons are grouped by their name attribute, so changing their name
   * using the setName() method will also change their associated group.
   * 
   * @param name the group name with which to associate the radio button
   * @param label this radio button's label
   */
  public RadioButton(String name, String label) {
    this(name);
    setText(label);
  }

  /**
   * @see #RadioButton(String, SafeHtml)
   * 
   * @param name the group name with which to associate the radio button
   * @param label this radio button's label
   * @param dir the text's direction. Note that {@code DEFAULT} means direction
   *          should be inherited from the widget's parent element.
   */
  public RadioButton(String name, String label, Direction dir) {
    this(name);
    setText(label, dir);
  }

  /**
   * @see #RadioButton(String, SafeHtml)
   * 
   * @param name the group name with which to associate the radio button
   * @param label this radio button's label
   * @param directionEstimator A DirectionEstimator object used for automatic
   *          direction adjustment. For convenience,
   *          {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
   */
  public RadioButton(String name, String label,
      DirectionEstimator directionEstimator) {
    this(name);
    setDirectionEstimator(directionEstimator);
    setText(label);
  }

  /**
   * Creates a new radio button associated with a particular group, and
   * initialized with the given label (optionally treated as HTML). All radio
   * buttons associated with the same group name belong to a mutually-exclusive
   * set.
   *
   * Radio buttons are grouped by their name attribute, so changing their name
   * using the setName() method will also change their associated group.
   *
   * @param name name the group with which to associate the radio button
   * @param label this radio button's label
   * @param asHTML <code>true</code> to treat the specified label as HTML
   */
  public RadioButton(String name, @IsSafeHtml String label, boolean asHTML) {
    this(name);
    if (asHTML) {
      setHTML(label);
    } else {
      setText(label);
    }
  }

  /**
   * Overridden to send ValueChangeEvents only when appropriate.
   */
  @Override
  public void onBrowserEvent(Event event) {
    switch (DOM.eventGetType(event)) {
      case Event.ONMOUSEUP:
      case Event.ONBLUR:
      case Event.ONKEYDOWN:
        // Note the old value for onValueChange purposes (in ONCLICK case)
        oldValue = getValue();
        break;

      case Event.ONCLICK:
        EventTarget target = event.getEventTarget();
        if (Element.is(target) && labelElem.isOrHasChild(Element.as(target))) {

          // They clicked the label. Note our pre-click value, and
          // short circuit event routing so that other click handlers
          // don't hear about it
          oldValue = getValue();
          return;
        }

        // It's not the label. Let our handlers hear about the
        // click...
        super.onBrowserEvent(event);
        // ...and now maybe tell them about the change
        ValueChangeEvent.fireIfNotEqual(RadioButton.this, oldValue, getValue());
        return;
    }

    super.onBrowserEvent(event);
  }

  /**
   * Change the group name of this radio button.
   * 
   * Radio buttons are grouped by their name attribute, so changing their name
   * using the setName() method will also change their associated group.
   * 
   * If changing this group name results in a new radio group with multiple
   * radio buttons selected, this radio button will remain selected and the
   * other radio buttons will be unselected.
   * 
   * @param name name the group with which to associate the radio button
   */
  @Override
  public void setName(String name) {
    // Just changing the radio button name tends to break groupiness,
    // so we have to replace it. Note that replaceInputElement is careful
    // not to propagate name when it propagates everything else
    replaceInputElement(DOM.createInputRadio(name));
  }

  @Override
  public void sinkEvents(int eventBitsToAdd) {
    // Like CheckBox, we want to hear about inputElem. We
    // also want to know what's going on with the label, to
    // make sure onBrowserEvent is able to record value changes
    // initiated by label events
    if (isOrWasAttached()) {
      Event.sinkEvents(inputElem, eventBitsToAdd
          | Event.getEventsSunk(inputElem));
      Event.sinkEvents(labelElem, eventBitsToAdd
          | Event.getEventsSunk(labelElem));
    } else {
      super.sinkEvents(eventBitsToAdd);
    }
  }

  /**
   * No-op. CheckBox's click handler is no good for radio button, so don't use
   * it. Our event handling is all done in {@link #onBrowserEvent}
   */
  @Override
  protected void ensureDomEventHandlers() {
  }
}
