/*
 * Copyright (C) 2006, 2008, 2011, 2014 Apple Inc. All rights reserved.
 * Copyright (C) 2012 Research In Motion Limited. 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. ``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
 * 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. 
 */

#pragma once

#include "FloatRect.h"
#include "FrameLoaderTypes.h"
#include "IntPoint.h"
#include "IntRect.h"
#include "LengthBox.h"
#include "SerializedScriptValue.h"
#include <memory>
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>

#if PLATFORM(IOS)
#include "ViewportArguments.h"
#endif

#if PLATFORM(COCOA)
#import <wtf/RetainPtr.h>
typedef struct objc_object* id;
#endif

namespace WebCore {

class CachedPage;
class Document;
class FormData;
class HistoryItem;
class Image;
class ResourceRequest;
class URL;
enum class PruningReason;

WEBCORE_EXPORT extern void (*notifyHistoryItemChanged)(HistoryItem*);

class HistoryItem : public RefCounted<HistoryItem> {
    friend class PageCache;

public: 
    static Ref<HistoryItem> create() { return adoptRef(*new HistoryItem); }
    static Ref<HistoryItem> create(const String& urlString, const String& title)
    {
        return adoptRef(*new HistoryItem(urlString, title));
    }
    static Ref<HistoryItem> create(const String& urlString, const String& title, const String& alternateTitle)
    {
        return adoptRef(*new HistoryItem(urlString, title, alternateTitle));
    }
    
    WEBCORE_EXPORT ~HistoryItem();

    WEBCORE_EXPORT Ref<HistoryItem> copy() const;

    // Resets the HistoryItem to its initial state, as returned by create().
    void reset();
    
    WEBCORE_EXPORT const String& originalURLString() const;
    WEBCORE_EXPORT const String& urlString() const;
    WEBCORE_EXPORT const String& title() const;
    
    bool isInPageCache() const { return m_cachedPage.get(); }
    WEBCORE_EXPORT bool hasCachedPageExpired() const;

    WEBCORE_EXPORT void setAlternateTitle(const String&);
    WEBCORE_EXPORT const String& alternateTitle() const;
    
    WEBCORE_EXPORT URL url() const;
    WEBCORE_EXPORT URL originalURL() const;
    WEBCORE_EXPORT const String& referrer() const;
    WEBCORE_EXPORT const String& target() const;
    WEBCORE_EXPORT bool isTargetItem() const;
    
    WEBCORE_EXPORT FormData* formData();
    WEBCORE_EXPORT String formContentType() const;
    
    bool lastVisitWasFailure() const { return m_lastVisitWasFailure; }

    WEBCORE_EXPORT const IntPoint& scrollPosition() const;
    WEBCORE_EXPORT void setScrollPosition(const IntPoint&);
    void clearScrollPosition();

    WEBCORE_EXPORT bool shouldRestoreScrollPosition() const;
    WEBCORE_EXPORT void setShouldRestoreScrollPosition(bool);
    
    WEBCORE_EXPORT float pageScaleFactor() const;
    WEBCORE_EXPORT void setPageScaleFactor(float);
    
    WEBCORE_EXPORT const Vector<String>& documentState() const;
    WEBCORE_EXPORT void setDocumentState(const Vector<String>&);
    void clearDocumentState();

    WEBCORE_EXPORT void setShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy);
    WEBCORE_EXPORT ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy() const;

    void setURL(const URL&);
    WEBCORE_EXPORT void setURLString(const String&);
    WEBCORE_EXPORT void setOriginalURLString(const String&);
    WEBCORE_EXPORT void setReferrer(const String&);
    WEBCORE_EXPORT void setTarget(const String&);
    WEBCORE_EXPORT void setTitle(const String&);
    WEBCORE_EXPORT void setIsTargetItem(bool);
    
    WEBCORE_EXPORT void setStateObject(RefPtr<SerializedScriptValue>&&);
    SerializedScriptValue* stateObject() const { return m_stateObject.get(); }

    void setItemSequenceNumber(long long number) { m_itemSequenceNumber = number; }
    long long itemSequenceNumber() const { return m_itemSequenceNumber; }

    void setDocumentSequenceNumber(long long number) { m_documentSequenceNumber = number; }
    long long documentSequenceNumber() const { return m_documentSequenceNumber; }

    void setFormInfoFromRequest(const ResourceRequest&);
    WEBCORE_EXPORT void setFormData(RefPtr<FormData>&&);
    WEBCORE_EXPORT void setFormContentType(const String&);

    void setLastVisitWasFailure(bool wasFailure) { m_lastVisitWasFailure = wasFailure; }

    WEBCORE_EXPORT void addChildItem(Ref<HistoryItem>&&);
    void setChildItem(Ref<HistoryItem>&&);
    WEBCORE_EXPORT HistoryItem* childItemWithTarget(const String&);
    HistoryItem* childItemWithDocumentSequenceNumber(long long number);
    WEBCORE_EXPORT const Vector<Ref<HistoryItem>>& children() const;
    WEBCORE_EXPORT bool hasChildren() const;
    void clearChildren();
    
    bool shouldDoSameDocumentNavigationTo(HistoryItem& otherItem) const;
    bool hasSameFrames(HistoryItem& otherItem) const;

    bool isCurrentDocument(Document&) const;
    
#if PLATFORM(COCOA)
    WEBCORE_EXPORT id viewState() const;
    WEBCORE_EXPORT void setViewState(id);
    
    // Transient properties may be of any ObjC type.  They are intended to be used to store state per back/forward list entry.
    // The properties will not be persisted; when the history item is removed, the properties will be lost.
    WEBCORE_EXPORT id getTransientProperty(const String&) const;
    WEBCORE_EXPORT void setTransientProperty(const String&, id);
#endif

#ifndef NDEBUG
    int showTree() const;
    int showTreeWithIndent(unsigned indentLevel) const;
#endif

#if PLATFORM(IOS)
    FloatRect exposedContentRect() const { return m_exposedContentRect; }
    void setExposedContentRect(FloatRect exposedContentRect) { m_exposedContentRect = exposedContentRect; }

    IntRect unobscuredContentRect() const { return m_unobscuredContentRect; }
    void setUnobscuredContentRect(IntRect unobscuredContentRect) { m_unobscuredContentRect = unobscuredContentRect; }

    const FloatBoxExtent& obscuredInsets() const { return m_obscuredInsets; }
    void setObscuredInsets(const FloatBoxExtent& insets) { m_obscuredInsets = insets; }

    FloatSize minimumLayoutSizeInScrollViewCoordinates() const { return m_minimumLayoutSizeInScrollViewCoordinates; }
    void setMinimumLayoutSizeInScrollViewCoordinates(FloatSize minimumLayoutSizeInScrollViewCoordinates) { m_minimumLayoutSizeInScrollViewCoordinates = minimumLayoutSizeInScrollViewCoordinates; }

    IntSize contentSize() const { return m_contentSize; }
    void setContentSize(IntSize contentSize) { m_contentSize = contentSize; }

    float scale() const { return m_scale; }
    bool scaleIsInitial() const { return m_scaleIsInitial; }
    void setScaleIsInitial(bool scaleIsInitial) { m_scaleIsInitial = scaleIsInitial; }
    void setScale(float newScale, bool isInitial)
    {
        m_scale = newScale;
        m_scaleIsInitial = isInitial;
    }

    const ViewportArguments& viewportArguments() const { return m_viewportArguments; }
    void setViewportArguments(const ViewportArguments& viewportArguments) { m_viewportArguments = viewportArguments; }
#endif

    void notifyChanged();

    void setWasRestoredFromSession(bool wasRestoredFromSession) { m_wasRestoredFromSession = wasRestoredFromSession; }
    bool wasRestoredFromSession() const { return m_wasRestoredFromSession; }

private:
    WEBCORE_EXPORT HistoryItem();
    WEBCORE_EXPORT HistoryItem(const String& urlString, const String& title);
    WEBCORE_EXPORT HistoryItem(const String& urlString, const String& title, const String& alternateTitle);

    HistoryItem(const HistoryItem&);

    bool hasSameDocumentTree(HistoryItem& otherItem) const;

    String m_urlString;
    String m_originalURLString;
    String m_referrer;
    String m_target;
    String m_title;
    String m_displayTitle;
    
    IntPoint m_scrollPosition;
    float m_pageScaleFactor { 0 }; // 0 indicates "unset".
    Vector<String> m_documentState;

    ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
    
    Vector<Ref<HistoryItem>> m_children;
    
    bool m_lastVisitWasFailure { false };
    bool m_isTargetItem { false };
    bool m_wasRestoredFromSession { false };
    bool m_shouldRestoreScrollPosition { true };

    // If two HistoryItems have the same item sequence number, then they are
    // clones of one another.  Traversing history from one such HistoryItem to
    // another is a no-op.  HistoryItem clones are created for parent and
    // sibling frames when only a subframe navigates.
    int64_t m_itemSequenceNumber;

    // If two HistoryItems have the same document sequence number, then they
    // refer to the same instance of a document.  Traversing history from one
    // such HistoryItem to another preserves the document.
    int64_t m_documentSequenceNumber;

    // Support for HTML5 History
    RefPtr<SerializedScriptValue> m_stateObject;
    
    // info used to repost form data
    RefPtr<FormData> m_formData;
    String m_formContentType;

    // PageCache controls these fields.
    std::unique_ptr<CachedPage> m_cachedPage;
    PruningReason m_pruningReason;

#if PLATFORM(IOS)
    FloatRect m_exposedContentRect;
    IntRect m_unobscuredContentRect;
    FloatSize m_minimumLayoutSizeInScrollViewCoordinates;
    IntSize m_contentSize;
    FloatBoxExtent m_obscuredInsets;
    float m_scale { 0 }; // Note that UIWebView looks for a non-zero value, so this has to start as 0.
    bool m_scaleIsInitial { false };
    ViewportArguments m_viewportArguments;
#endif

#if PLATFORM(COCOA)
    RetainPtr<id> m_viewState;
    std::unique_ptr<HashMap<String, RetainPtr<id>>> m_transientProperties;
#endif
};

} // namespace WebCore

#if ENABLE(TREE_DEBUGGING)
// Outside the WebCore namespace for ease of invocation from the debugger.
extern "C" int showTree(const WebCore::HistoryItem*);
#endif
