/*
 * Copyright (C) 2010 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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 "config.h"
#include "RenderInputSpeech.h"

#if ENABLE(INPUT_SPEECH)

#include "GraphicsContext.h"
#include "HTMLNames.h"
#include "PaintInfo.h"
#include "RenderBox.h"
#include "TextControlInnerElements.h"

namespace WebCore {

static const float defaultControlFontPixelSize = 13;
static const float defaultSpeechButtonSize = 16;
static const float minSpeechButtonSize = 8;
static const float maxSpeechButtonSize = 40;

void RenderInputSpeech::adjustInputFieldSpeechButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*)
{
    // Scale the button size based on the font size.
    float fontScale = style->fontSize() / defaultControlFontPixelSize;
    int speechButtonSize = lroundf(std::min(std::max(minSpeechButtonSize, defaultSpeechButtonSize * fontScale), maxSpeechButtonSize));
    style->setWidth(Length(speechButtonSize, Fixed));
    style->setHeight(Length(speechButtonSize, Fixed));
}

bool RenderInputSpeech::paintInputFieldSpeechButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
{
    Element* element = object->node()->isElementNode() ? toElement(object->node()) : 0;
    if (!element || !element->isInputFieldSpeechButtonElement())
        return false;

    // Get the renderer of <input> element.
    Node* input = object->node()->shadowAncestorNode();
    if (!input->renderer()->isBox())
        return false;
    RenderBox* inputRenderBox = toRenderBox(input->renderer());
    IntRect inputContentBox = inputRenderBox->contentBoxRect();

    // Make sure the scaled button stays square and will fit in its parent's box.
    int buttonSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), rect.height()));
    // Calculate button's coordinates relative to the input element.
    // Center the button vertically.  Round up though, so if it has to be one pixel off-center, it will
    // be one pixel closer to the bottom of the field.  This tends to look better with the text.
    IntRect buttonRect(object->offsetFromAncestorContainer(inputRenderBox).width(),
                       inputContentBox.y() + (inputContentBox.height() - buttonSize + 1) / 2,
                       buttonSize, buttonSize);

    // Compute an offset between the part renderer and the input renderer.
    IntSize offsetFromInputRenderer = -(object->offsetFromAncestorContainer(inputRenderBox));
    // Move the rect into partRenderer's coords.
    buttonRect.move(offsetFromInputRenderer);
    // Account for the local drawing offset.
    buttonRect.move(rect.x(), rect.y());

    DEFINE_STATIC_LOCAL(RefPtr<Image>, imageStateNormal, (Image::loadPlatformResource("inputSpeech")));
    DEFINE_STATIC_LOCAL(RefPtr<Image>, imageStateRecording, (Image::loadPlatformResource("inputSpeechRecording")));
    DEFINE_STATIC_LOCAL(RefPtr<Image>, imageStateWaiting, (Image::loadPlatformResource("inputSpeechWaiting")));

    InputFieldSpeechButtonElement* speechButton = toInputFieldSpeechButtonElement(element);
    Image* image = imageStateNormal.get();
    if (speechButton->state() == InputFieldSpeechButtonElement::Recording)
        image = imageStateRecording.get();
    else if (speechButton->state() == InputFieldSpeechButtonElement::Recognizing)
        image = imageStateWaiting.get();
    paintInfo.context->drawImage(image, object->style()->colorSpace(), buttonRect);

    return false;
}

} // namespace WebCore

#endif // ENABLE(INPUT_SPEECH)
