/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "web/ValidationMessageClientImpl.h"

#include "core/dom/Element.h"
#include "core/frame/FrameView.h"
#include "platform/HostWindow.h"
#include "public/platform/WebRect.h"
#include "public/platform/WebString.h"
#include "public/web/WebTextDirection.h"
#include "public/web/WebViewClient.h"
#include "web/WebViewImpl.h"
#include "wtf/CurrentTime.h"

namespace blink {

ValidationMessageClientImpl::ValidationMessageClientImpl(WebViewImpl& webView)
    : m_webView(webView),
      m_currentAnchor(nullptr),
      m_lastPageScaleFactor(1),
      m_finishTime(0),
      m_timer(this, &ValidationMessageClientImpl::checkAnchorStatus) {}

ValidationMessageClientImpl* ValidationMessageClientImpl::create(
    WebViewImpl& webView) {
  return new ValidationMessageClientImpl(webView);
}

ValidationMessageClientImpl::~ValidationMessageClientImpl() {}

FrameView* ValidationMessageClientImpl::currentView() {
  return m_currentAnchor->document().view();
}

void ValidationMessageClientImpl::showValidationMessage(
    const Element& anchor,
    const String& message,
    TextDirection messageDir,
    const String& subMessage,
    TextDirection subMessageDir) {
  if (message.isEmpty()) {
    hideValidationMessage(anchor);
    return;
  }
  if (!anchor.layoutBox())
    return;
  if (m_currentAnchor)
    hideValidationMessage(*m_currentAnchor);
  m_currentAnchor = &anchor;
  IntRect anchorInViewport =
      currentView()->contentsToViewport(anchor.pixelSnappedBoundingBox());
  m_lastAnchorRectInScreen = currentView()->getHostWindow()->viewportToScreen(
      anchorInViewport, currentView());
  m_lastPageScaleFactor = m_webView.pageScaleFactor();
  m_message = message;
  const double minimumSecondToShowValidationMessage = 5.0;
  const double secondPerCharacter = 0.05;
  const double statusCheckInterval = 0.1;

  m_webView.client()->showValidationMessage(
      anchorInViewport, m_message, toWebTextDirection(messageDir), subMessage,
      toWebTextDirection(subMessageDir));

  m_finishTime =
      monotonicallyIncreasingTime() +
      std::max(minimumSecondToShowValidationMessage,
               (message.length() + subMessage.length()) * secondPerCharacter);
  // FIXME: We should invoke checkAnchorStatus actively when layout, scroll,
  // or page scale change happen.
  m_timer.startRepeating(statusCheckInterval, BLINK_FROM_HERE);
}

void ValidationMessageClientImpl::hideValidationMessage(const Element& anchor) {
  if (!m_currentAnchor || !isValidationMessageVisible(anchor))
    return;
  m_timer.stop();
  m_currentAnchor = nullptr;
  m_message = String();
  m_finishTime = 0;
  m_webView.client()->hideValidationMessage();
}

bool ValidationMessageClientImpl::isValidationMessageVisible(
    const Element& anchor) {
  return m_currentAnchor == &anchor;
}

void ValidationMessageClientImpl::documentDetached(const Document& document) {
  if (m_currentAnchor && m_currentAnchor->document() == document)
    hideValidationMessage(*m_currentAnchor);
}

void ValidationMessageClientImpl::checkAnchorStatus(TimerBase*) {
  DCHECK(m_currentAnchor);
  if (monotonicallyIncreasingTime() >= m_finishTime || !currentView()) {
    hideValidationMessage(*m_currentAnchor);
    return;
  }

  IntRect newAnchorRectInViewport =
      m_currentAnchor->visibleBoundsInVisualViewport();
  if (newAnchorRectInViewport.isEmpty()) {
    hideValidationMessage(*m_currentAnchor);
    return;
  }

  IntRect newAnchorRectInViewportInScreen =
      currentView()->getHostWindow()->viewportToScreen(newAnchorRectInViewport,
                                                       currentView());
  if (newAnchorRectInViewportInScreen == m_lastAnchorRectInScreen &&
      m_webView.pageScaleFactor() == m_lastPageScaleFactor)
    return;
  m_lastAnchorRectInScreen = newAnchorRectInViewportInScreen;
  m_lastPageScaleFactor = m_webView.pageScaleFactor();
  m_webView.client()->moveValidationMessage(newAnchorRectInViewport);
}

void ValidationMessageClientImpl::willBeDestroyed() {
  if (m_currentAnchor)
    hideValidationMessage(*m_currentAnchor);
}

DEFINE_TRACE(ValidationMessageClientImpl) {
  visitor->trace(m_currentAnchor);
  ValidationMessageClient::trace(visitor);
}

}  // namespace blink
