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

#ifndef LegacyTileCache_h
#define LegacyTileCache_h

#if PLATFORM(IOS_FAMILY)

#include "Color.h"
#include "FloatRect.h"
#include "IntRect.h"
#include "IntSize.h"
#include "Timer.h"
#include <wtf/Lock.h>
#include <wtf/Noncopyable.h>
#include <wtf/Optional.h>
#include <wtf/RetainPtr.h>
#include <wtf/Threading.h>
#include <wtf/Vector.h>

#ifdef __OBJC__
@class CALayer;
@class LegacyTileCacheTombstone;
@class LegacyTileLayer;
@class WAKWindow;
#else
class CALayer;
class LegacyTileCacheTombstone;
class LegacyTileLayer;
class WAKWindow;
#endif

namespace WebCore {

class LegacyTileGrid;

class LegacyTileCache {
    WTF_MAKE_NONCOPYABLE(LegacyTileCache);
public:
    LegacyTileCache(WAKWindow*);
    ~LegacyTileCache();

    CGFloat screenScale() const;

    void setNeedsDisplay();
    void setNeedsDisplayInRect(const IntRect&);
    
    void layoutTiles();
    void layoutTilesNow();
    void layoutTilesNowForRect(const IntRect&);
    void removeAllNonVisibleTiles();
    void removeAllTiles();
    void removeForegroundTiles();

    // If 'contentReplacementImage' is not NULL, drawLayer() draws
    // contentReplacementImage instead of the page content. We assume the
    // image is to be drawn at the origin and scaled to match device pixels.
    void setContentReplacementImage(RetainPtr<CGImageRef>);
    RetainPtr<CGImageRef> contentReplacementImage() const;

    void setTileBordersVisible(bool);
    bool tileBordersVisible() const { return m_tileBordersVisible; }

    void setTilePaintCountersVisible(bool);
    bool tilePaintCountersVisible() const { return m_tilePaintCountersVisible; }

    void setAcceleratedDrawingEnabled(bool enabled) { m_acceleratedDrawingEnabled = enabled; }
    bool acceleratedDrawingEnabled() const { return m_acceleratedDrawingEnabled; }

    void setKeepsZoomedOutTiles(bool);
    bool keepsZoomedOutTiles() const { return m_keepsZoomedOutTiles; }

    void setZoomedOutScale(float);
    float zoomedOutScale() const;
    
    void setCurrentScale(float);
    float currentScale() const;
    
    bool tilesOpaque() const;
    void setTilesOpaque(bool);
    
    enum TilingMode {
        Normal,
        Minimal,
        Panning,
        Zooming,
        Disabled,
        ScrollToTop
    };
    TilingMode tilingMode() const { return m_tilingMode; }
    void setTilingMode(TilingMode);

    typedef enum {
        TilingDirectionUp,
        TilingDirectionDown,
        TilingDirectionLeft,
        TilingDirectionRight,
    } TilingDirection;
    void setTilingDirection(TilingDirection);
    TilingDirection tilingDirection() const;

    bool hasPendingDraw() const;

    void hostLayerSizeChanged();

    WEBCORE_EXPORT static void setLayerPoolCapacity(unsigned);
    WEBCORE_EXPORT static void drainLayerPool();

    // Logging
    void dumpTiles();

    // Internal
    void doLayoutTiles();
    
    enum class DrawingFlags { None, Snapshotting };
    void drawLayer(LegacyTileLayer*, CGContextRef, DrawingFlags);
    void prepareToDraw();
    void finishedCreatingTiles(bool didCreateTiles, bool createMore);
    FloatRect visibleRectInLayer(CALayer *) const;
    CALayer* hostLayer() const;
    unsigned tileCapacityForGrid(LegacyTileGrid*);
    Color colorForGridTileBorder(LegacyTileGrid*) const;
    bool setOverrideVisibleRect(const FloatRect&);
    void clearOverrideVisibleRect() { m_overrideVisibleRect = WTF::nullopt; }

    void doPendingRepaints();

    bool isSpeculativeTileCreationEnabled() const { return m_isSpeculativeTileCreationEnabled; }
    void setSpeculativeTileCreationEnabled(bool);
    
    enum SynchronousTileCreationMode { CoverVisibleOnly, CoverSpeculative };

    bool tileControllerShouldUseLowScaleTiles() const { return m_tileControllerShouldUseLowScaleTiles; } 
    void setTileControllerShouldUseLowScaleTiles(bool flag) { m_tileControllerShouldUseLowScaleTiles = flag; } 

private:
    LegacyTileGrid* activeTileGrid() const;
    LegacyTileGrid* inactiveTileGrid() const;

    void updateTilingMode();
    bool isTileInvalidationSuspended() const;
    bool isTileCreationSuspended() const;
    void flushSavedDisplayRects();
    void invalidateTiles(const IntRect& dirtyRect);
    void setZoomedOutScaleInternal(float);
    void commitScaleChange();
    void bringActiveTileGridToFront();
    void adjustTileGridTransforms();
    void removeAllNonVisibleTilesInternal();
    void createTilesInActiveGrid(SynchronousTileCreationMode);
    void scheduleLayerFlushForPendingRepaint();

    void tileCreationTimerFired();

    void drawReplacementImage(LegacyTileLayer*, CGContextRef, CGImageRef);
    void drawWindowContent(LegacyTileLayer*, CGContextRef, CGRect dirtyRect, DrawingFlags);

    WAKWindow* m_window { nullptr };

    RetainPtr<CGImageRef> m_contentReplacementImage;

    // Ensure there are no async calls on a dead tile cache.
    RetainPtr<LegacyTileCacheTombstone> m_tombstone;

    Optional<FloatRect> m_overrideVisibleRect;

    IntSize m_tileSize { 512, 512 };
    
    TilingMode m_tilingMode { Normal };
    TilingDirection m_tilingDirection { TilingDirectionDown };
    
    bool m_keepsZoomedOutTiles { false };
    bool m_hasPendingLayoutTiles { false };
    bool m_hasPendingUpdateTilingMode { false };
    bool m_tilesOpaque { true };
    bool m_tileBordersVisible { false };
    bool m_tilePaintCountersVisible { false };
    bool m_acceleratedDrawingEnabled { false };
    bool m_isSpeculativeTileCreationEnabled { true };
    bool m_tileControllerShouldUseLowScaleTiles { false };
    bool m_didCallWillStartScrollingOrZooming { false };
    
    std::unique_ptr<LegacyTileGrid> m_zoomedOutTileGrid;
    std::unique_ptr<LegacyTileGrid> m_zoomedInTileGrid;

    Timer m_tileCreationTimer;

    Vector<IntRect> m_savedDisplayRects;

    float m_currentScale { 1 };

    float m_pendingScale { 0 };
    float m_pendingZoomedOutScale { 0 };

    mutable Lock m_tileMutex;
    mutable Lock m_savedDisplayRectMutex;
    mutable Lock m_contentReplacementImageMutex;
};

} // namespace WebCore

#endif // PLATFORM(IOS_FAMILY)

#endif // TileCache_h
