// Copyright 2016 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 "modules/accessibility/AXRadioInput.h"

#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/RadioInputType.h"
#include "core/layout/LayoutObject.h"
#include "modules/accessibility/AXObjectCacheImpl.h"

namespace blink {

using namespace HTMLNames;

AXRadioInput::AXRadioInput(LayoutObject* layoutObject,
                           AXObjectCacheImpl& axObjectCache)
    : AXLayoutObject(layoutObject, axObjectCache) {
  // Updates posInSet and setSize for the current object and the next objects.
  if (!calculatePosInSet())
    return;
  // When a new object is inserted, it needs to update setSize for the previous
  // objects.
  requestUpdateToNextNode(false);
}

AXRadioInput* AXRadioInput::create(LayoutObject* layoutObject,
                                   AXObjectCacheImpl& axObjectCache) {
  return new AXRadioInput(layoutObject, axObjectCache);
}

void AXRadioInput::updatePosAndSetSize(int position) {
  if (position)
    m_posInSet = position;
  m_setSize = sizeOfRadioGroup();
}

void AXRadioInput::requestUpdateToNextNode(bool forward) {
  HTMLInputElement* nextElement =
      RadioInputType::nextRadioButtonInGroup(element(), forward);
  AXObject* nextAXobject = axObjectCache().get(nextElement);
  if (!nextAXobject || !nextAXobject->isAXRadioInput())
    return;

  int position = 0;
  if (forward)
    position = posInSet() + 1;
  // If it is backward, it keeps position as positions are already assigned for
  // previous objects.  updatePosAndSetSize() is called with '0' and it doesn't
  // modify m_posInSet and updates m_setSize as size is increased.

  toAXRadioInput(nextAXobject)->updatePosAndSetSize(position);
  axObjectCache().postNotification(nextAXobject,
                                   AXObjectCacheImpl::AXAriaAttributeChanged);
  toAXRadioInput(nextAXobject)->requestUpdateToNextNode(forward);
}

HTMLInputElement* AXRadioInput::findFirstRadioButtonInGroup(
    HTMLInputElement* current) const {
  while (HTMLInputElement* prevElement =
             RadioInputType::nextRadioButtonInGroup(current, false))
    current = prevElement;
  return current;
}

int AXRadioInput::posInSet() const {
  if (hasAttribute(aria_posinsetAttr))
    return getAttribute(aria_posinsetAttr).toInt();
  return m_posInSet;
}

int AXRadioInput::setSize() const {
  if (hasAttribute(aria_setsizeAttr))
    return getAttribute(aria_setsizeAttr).toInt();
  return m_setSize;
}

bool AXRadioInput::calculatePosInSet() {
  // Calculate 'posInSet' attribute when AXRadioInputs need to be updated
  // as a new AXRadioInput Object is added or one of objects from RadioGroup is
  // removed.
  bool needToUpdatePrev = false;
  int position = 1;
  HTMLInputElement* prevElement =
      RadioInputType::nextRadioButtonInGroup(element(), false);
  if (prevElement) {
    AXObject* object = axObjectCache().get(prevElement);
    // If the previous element doesn't have AXObject yet, caculate position from
    // the first element.  Otherwise, get position from the previous AXObject.
    if (!object || !object->isAXRadioInput()) {
      position = countFromFirstElement();
    } else {
      position = object->posInSet() + 1;
      // It returns true if previous objects need to be updated.
      // When AX tree exists already and a new node is inserted,
      // as updating is started from the inserted node,
      // we need to update setSize for previous nodes.
      if (setSize() != object->setSize())
        needToUpdatePrev = true;
    }
  }
  updatePosAndSetSize(position);

  // If it is not the last element, request update to the next node.
  if (position != setSize())
    requestUpdateToNextNode(true);
  return needToUpdatePrev;
}

int AXRadioInput::countFromFirstElement() const {
  int count = 1;
  HTMLInputElement* current = element();
  while (HTMLInputElement* prevElement =
             RadioInputType::nextRadioButtonInGroup(current, false)) {
    current = prevElement;
    count++;
  }
  return count;
}

HTMLInputElement* AXRadioInput::element() const {
  return toHTMLInputElement(m_layoutObject->node());
}

int AXRadioInput::sizeOfRadioGroup() const {
  int size = element()->sizeOfRadioGroup();
  // If it has no size in Group, it means that there is only itself.
  if (!size)
    return 1;
  return size;
}

}  // namespace blink
