// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/views/controls/button/radio_button.h"

#include "base/logging.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/views/widget/widget.h"

namespace views {

// static
const char RadioButton::kViewClassName[] = "RadioButton";

RadioButton::RadioButton(const base::string16& label, int group_id)
    : Checkbox(label) {
  SetGroup(group_id);

  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();

  // Unchecked/Unfocused images.
  SetCustomImage(false, false, STATE_NORMAL,
                 *rb.GetImageSkiaNamed(IDR_RADIO));
  SetCustomImage(false, false, STATE_HOVERED,
                 *rb.GetImageSkiaNamed(IDR_RADIO_HOVER));
  SetCustomImage(false, false, STATE_PRESSED,
                 *rb.GetImageSkiaNamed(IDR_RADIO_PRESSED));
  SetCustomImage(false, false, STATE_DISABLED,
                 *rb.GetImageSkiaNamed(IDR_RADIO_DISABLED));

  // Checked/Unfocused images.
  SetCustomImage(true, false, STATE_NORMAL,
                 *rb.GetImageSkiaNamed(IDR_RADIO_CHECKED));
  SetCustomImage(true, false, STATE_HOVERED,
                 *rb.GetImageSkiaNamed(IDR_RADIO_CHECKED_HOVER));
  SetCustomImage(true, false, STATE_PRESSED,
                 *rb.GetImageSkiaNamed(IDR_RADIO_CHECKED_PRESSED));
  SetCustomImage(true, false, STATE_DISABLED,
                 *rb.GetImageSkiaNamed(IDR_RADIO_CHECKED_DISABLED));

  // Unchecked/Focused images.
  SetCustomImage(false, true, STATE_NORMAL,
                 *rb.GetImageSkiaNamed(IDR_RADIO_FOCUSED));
  SetCustomImage(false, true, STATE_HOVERED,
                 *rb.GetImageSkiaNamed(IDR_RADIO_FOCUSED_HOVER));
  SetCustomImage(false, true, STATE_PRESSED,
                 *rb.GetImageSkiaNamed(IDR_RADIO_FOCUSED_PRESSED));

  // Checked/Focused images.
  SetCustomImage(true, true, STATE_NORMAL,
                 *rb.GetImageSkiaNamed(IDR_RADIO_FOCUSED_CHECKED));
  SetCustomImage(true, true, STATE_HOVERED,
                 *rb.GetImageSkiaNamed(IDR_RADIO_FOCUSED_CHECKED_HOVER));
  SetCustomImage(true, true, STATE_PRESSED,
                 *rb.GetImageSkiaNamed(IDR_RADIO_FOCUSED_CHECKED_PRESSED));
}

RadioButton::~RadioButton() {
}

void RadioButton::SetChecked(bool checked) {
  if (checked == RadioButton::checked())
    return;
  if (checked) {
    // We can't just get the root view here because sometimes the radio
    // button isn't attached to a root view (e.g., if it's part of a tab page
    // that is currently not active).
    View* container = parent();
    while (container && container->parent())
      container = container->parent();
    if (container) {
      Views other;
      container->GetViewsInGroup(GetGroup(), &other);
      for (Views::iterator i(other.begin()); i != other.end(); ++i) {
        if (*i != this) {
          if (strcmp((*i)->GetClassName(), kViewClassName)) {
            NOTREACHED() << "radio-button-nt has same group as other non "
                            "radio-button-nt views.";
            continue;
          }
          RadioButton* peer = static_cast<RadioButton*>(*i);
          peer->SetChecked(false);
        }
      }
    }
  }
  Checkbox::SetChecked(checked);
}

const char* RadioButton::GetClassName() const {
  return kViewClassName;
}

void RadioButton::GetAccessibleState(ui::AXViewState* state) {
  Checkbox::GetAccessibleState(state);
  state->role = ui::AX_ROLE_RADIO_BUTTON;
}

View* RadioButton::GetSelectedViewForGroup(int group) {
  Views views;
  GetWidget()->GetRootView()->GetViewsInGroup(group, &views);
  if (views.empty())
    return NULL;

  for (Views::const_iterator i(views.begin()); i != views.end(); ++i) {
    // REVIEW: why don't we check the runtime type like is done above?
    RadioButton* radio_button = static_cast<RadioButton*>(*i);
    if (radio_button->checked())
      return radio_button;
  }
  return NULL;
}

bool RadioButton::IsGroupFocusTraversable() const {
  // When focusing a radio button with tab/shift+tab, only the selected button
  // from the group should be focused.
  return false;
}

void RadioButton::OnFocus() {
  Checkbox::OnFocus();
  SetChecked(true);
  ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), 0, 0);
  LabelButton::NotifyClick(event);
}

void RadioButton::NotifyClick(const ui::Event& event) {
  // Set the checked state to true only if we are unchecked, since we can't
  // be toggled on and off like a checkbox.
  if (!checked())
    SetChecked(true);
  RequestFocus();
  LabelButton::NotifyClick(event);
}

ui::NativeTheme::Part RadioButton::GetThemePart() const {
  return ui::NativeTheme::kRadio;
}

}  // namespace views
