/*
 * Copyright (C) 2011 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 LegacyTileGrid_h
#define LegacyTileGrid_h

#if PLATFORM(IOS_FAMILY)

#include "IntPoint.h"
#include "IntPointHash.h"
#include "IntRect.h"
#include "IntSize.h"
#include "LegacyTileCache.h"
#include <wtf/HashMap.h>
#include <wtf/RefPtr.h>
#include <wtf/RetainPtr.h>

#define LOG_TILING 0

@class CALayer;

namespace WebCore {

class LegacyTileGridTile;

class LegacyTileGrid {
    WTF_MAKE_FAST_ALLOCATED;
public:
    typedef IntPoint TileIndex;

    LegacyTileGrid(LegacyTileCache&, const IntSize&);
    ~LegacyTileGrid();

    LegacyTileCache& tileCache() const { return m_tileCache; }

    CALayer *tileHostLayer() const;
    IntRect bounds() const;
    unsigned tileCount() const;

    float scale() const { return m_scale; }
    void setScale(float scale) { m_scale = scale; }

    IntRect visibleRect() const;

    void createTiles(LegacyTileCache::SynchronousTileCreationMode);

    void dropAllTiles();
    void dropInvalidTiles();
    void dropTilesOutsideRect(const IntRect&);
    void dropTilesIntersectingRect(const IntRect&);
    // Drops tiles that intersect dropRect but do not intersect keepRect.
    void dropTilesBetweenRects(const IntRect& dropRect, const IntRect& keepRect);
    bool dropDistantTiles(unsigned tilesNeeded, double shortestDistance);

    void addTilesCoveringRect(const IntRect&);

    bool tilesCover(const IntRect&) const;
    void centerTileGridOrigin(const IntRect& visibleRect);
    void invalidateTiles(const IntRect& dirtyRect);

    void updateTileOpacity();
    void updateTileBorderVisibility();
    void updateHostLayerSize();
    bool checkDoSingleTileLayout();

    bool hasTiles() const { return !m_tiles.isEmpty(); }

    IntRect calculateCoverRect(const IntRect& visibleRect, bool& centerGrid);

    // Logging
    void dumpTiles();

private:
    double tileDistance2(const IntRect& visibleRect, const IntRect& tileRect) const;
    unsigned tileByteSize() const;

    void addTileForIndex(const TileIndex&);

    RefPtr<LegacyTileGridTile> tileForIndex(const TileIndex&) const;
    IntRect tileRectForIndex(const TileIndex&) const;
    RefPtr<LegacyTileGridTile> tileForPoint(const IntPoint&) const;
    TileIndex tileIndexForPoint(const IntPoint&) const;

    IntRect adjustCoverRectForPageBounds(const IntRect&) const;
    bool shouldUseMinimalTileCoverage() const;

private:        
    LegacyTileCache& m_tileCache;
    RetainPtr<CALayer> m_tileHostLayer;

    IntPoint m_origin;
    IntSize m_tileSize;

    float m_scale;

    typedef HashMap<TileIndex, RefPtr<LegacyTileGridTile>> TileMap;
    TileMap m_tiles;

    IntRect m_validBounds;
};

static inline IntPoint topLeft(const IntRect& rect)
{
    return rect.location();
}

static inline IntPoint bottomRight(const IntRect& rect)
{
    return IntPoint(rect.maxX() - 1, rect.maxY() - 1);
}

} // namespace WebCore

#endif // PLATFORM(IOS_FAMILY)
#endif // TileGrid_h
