/*
 * Copyright (C) 2009 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.
 */

#ifndef SKY_ENGINE_WEB_WEBLOCALFRAMEIMPL_H_
#define SKY_ENGINE_WEB_WEBLOCALFRAMEIMPL_H_

#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/platform/fetcher/MojoFetcher.h"
#include "sky/engine/platform/geometry/FloatRect.h"
#include "sky/engine/public/web/WebLocalFrame.h"
#include "sky/engine/web/FrameLoaderClientImpl.h"
#include "sky/engine/wtf/Compiler.h"
#include "sky/engine/wtf/OwnPtr.h"
#include "sky/engine/wtf/RefCounted.h"
#include "sky/engine/wtf/text/WTFString.h"

namespace blink {

class GraphicsContext;
class IntSize;
class KURL;
class Node;
class Range;
class WebFrameClient;
class WebView;
class WebViewImpl;

template <typename T> class WebVector;

// Implementation of WebFrame, note that this is a reference counted object.
class WebLocalFrameImpl final
    : public WebLocalFrame
    , public MojoFetcher::Client
    , public RefCounted<WebLocalFrameImpl> {
public:
    // WebFrame methods:
    virtual bool isWebLocalFrame() const override;
    virtual WebLocalFrame* toWebLocalFrame() override;
    virtual void close() override;
    virtual WebSize contentsSize() const override;
    virtual bool hasVisibleContent() const override;
    virtual WebRect visibleContentRect() const override;
    virtual WebView* view() const override;
    virtual WebDocument document() const override;
    virtual void executeScript(const WebScriptSource&) override;
    virtual void addMessageToConsole(const WebConsoleMessage&) override;
    virtual void collectGarbage() override;
    virtual void load(const WebURL&);
    virtual void loadFromDataPipeWithURL(mojo::ScopedDataPipeConsumerHandle, const WebURL&);
    virtual void replaceSelection(const WebString&) override;
    virtual void insertText(const WebString&) override;
    virtual void setMarkedText(const WebString&, unsigned location, unsigned length) override;
    virtual void unmarkText() override;
    virtual bool hasMarkedText() const override;
    virtual bool executeCommand(const WebString&, const WebNode& = WebNode()) override;
    virtual bool executeCommand(const WebString&, const WebString& value, const WebNode& = WebNode()) override;
    virtual bool isCommandEnabled(const WebString&) const override;
    virtual void enableContinuousSpellChecking(bool) override;
    virtual bool isContinuousSpellCheckingEnabled() const override;
    virtual void requestTextChecking(const WebElement&) override;
    virtual void replaceMisspelledRange(const WebString&) override;
    virtual void removeSpellingMarkers() override;
    virtual bool hasSelection() const override;
    virtual WebRange selectionRange() const override;
    virtual WebString selectionAsText() const override;
    virtual bool selectWordAroundCaret() override;
    virtual void selectRange(const WebPoint& base, const WebPoint& extent) override;
    virtual void selectRange(const WebRange&) override;
    virtual void moveRangeSelection(const WebPoint& base, const WebPoint& extent) override;
    virtual void moveCaretSelection(const WebPoint&) override;
    virtual bool setEditableSelectionOffsets(int start, int end) override;
    virtual bool setCompositionFromExistingText(int compositionStart, int compositionEnd, const WebVector<WebCompositionUnderline>& underlines) override;
    virtual void extendSelectionAndDelete(int before, int after) override;
    virtual void setCaretVisible(bool) override;

    virtual WebString contentAsText(size_t maxChars) const override;
    virtual WebString renderTreeAsText(RenderAsTextControls toShow = RenderAsTextNormal) const override;

    virtual bool selectionStartHasSpellingMarkerFor(int from, int length) const override;

    static WebLocalFrameImpl* create(WebFrameClient*);
    virtual ~WebLocalFrameImpl();

    PassRefPtr<LocalFrame> initializeCoreFrame(FrameHost*);

    void createFrameView();

    static WebLocalFrameImpl* fromFrame(LocalFrame*);
    static WebLocalFrameImpl* fromFrame(LocalFrame&);

    WebViewImpl* viewImpl() const;

    FrameView* frameView() const { return frame() ? frame()->view() : 0; }

    void didFail(const ResourceError&);

    LocalFrame* frame() const { return m_frame.get(); }
    WebFrameClient* client() const { return m_client; }
    void setClient(WebFrameClient* client) { m_client = client; }

    void setInputEventsTransformForEmulation(const IntSize&, float);

    static void selectWordAroundPosition(LocalFrame*, VisiblePosition);

    // Returns a hit-tested VisiblePosition for the given point
    VisiblePosition visiblePositionForWindowPoint(const WebPoint&);

private:
    friend class FrameLoaderClientImpl;

    explicit WebLocalFrameImpl(WebFrameClient*);

    // Sets the local core frame and registers destruction observers.
    void setCoreFrame(PassRefPtr<LocalFrame>);

    // MojoFetcher::Client
    void OnReceivedResponse(mojo::URLResponsePtr) override;

    FrameLoaderClientImpl m_frameLoaderClientImpl;

    // The embedder retains a reference to the WebCore LocalFrame while it is active in the DOM. This
    // reference is released when the frame is removed from the DOM or the entire page is closed.
    // FIXME: These will need to change to WebFrame when we introduce WebFrameProxy.
    RefPtr<LocalFrame> m_frame;

    WebFrameClient* m_client;
    OwnPtr<MojoFetcher> m_fetcher;

    // Stores the additional input events offset and scale when device metrics emulation is enabled.
    IntSize m_inputEventsOffsetForEmulation;
    float m_inputEventsScaleFactorForEmulation;
};

DEFINE_TYPE_CASTS(WebLocalFrameImpl, WebFrame, frame, frame->isWebLocalFrame(), frame.isWebLocalFrame());

} // namespace blink

#endif  // SKY_ENGINE_WEB_WEBLOCALFRAMEIMPL_H_
