/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkDeviceLooper_DEFINED
#define SkDeviceLooper_DEFINED

#include "SkBitmap.h"
#include "SkMatrix.h"
#include "SkRasterClip.h"

/**
 *  Helper class to manage "tiling" a large coordinate space into managable
 *  chunks, where managable means areas that are <= some max critical coordinate
 *  size.
 *
 *  The constructor takes an antialiasing bool, which affects what this maximum
 *  allowable size is: If we're drawing BW, then we need coordinates to stay
 *  safely within fixed-point range (we use +- 16K, to give ourselves room to
 *  add/subtract two fixed values and still be in range. If we're drawing AA,
 *  then we reduce that size by the amount that the supersampler scan converter
 *  needs (at the moment, that is 4X, so the "safe" range is +- 4K).
 *
 *  For performance reasons, the class first checks to see if any help is needed
 *  at all, and if not (i.e. the specified bounds and base bitmap area already
 *  in the safe-zone, then the class does nothing (effectively).
 */
class SkDeviceLooper {
public:
    SkDeviceLooper(const SkPixmap& base, const SkRasterClip&, const SkIRect& bounds, bool aa);
    ~SkDeviceLooper();

    const SkPixmap& getPixmap() const {
        SkASSERT(kDone_State != fState);
        SkASSERT(fCurrDst);
        return *fCurrDst;
    }

    const SkRasterClip& getRC() const {
        SkASSERT(kDone_State != fState);
        SkASSERT(fCurrRC);
        return *fCurrRC;
    }

    void mapRect(SkRect* dst, const SkRect& src) const;
    void mapMatrix(SkMatrix* dst, const SkMatrix& src) const;

    /**
     *  Call next to setup the looper to return a valid coordinate chunk.
     *  Each time this returns true, it is safe to call mapRect() and
     *  mapMatrix(), to convert from "global" coordinate values to ones that
     *  are local to this chunk.
     *
     *  When next() returns false, the list of chunks is done, and mapRect()
     *  and mapMatrix() should no longer be called.
     */
    bool next();

private:
    const SkPixmap&     fBaseDst;
    const SkRasterClip& fBaseRC;

    enum State {
        kDone_State,    // iteration is complete, getters will assert
        kSimple_State,  // no translate/clip mods needed
        kComplex_State
    };

    // storage for our tiled versions. Perhaps could use SkTLazy
    SkPixmap            fSubsetDst;
    SkRasterClip        fSubsetRC;

    const SkPixmap*     fCurrDst;
    const SkRasterClip* fCurrRC;
    SkIRect             fClippedBounds;
    SkIPoint            fCurrOffset;
    int                 fDelta;
    State               fState;

    enum Delta {
        kBW_Delta = 1 << 14,        // 16K, gives room to spare for fixedpoint
        kAA_Delta = kBW_Delta >> 2  // supersample 4x
    };

    bool fitsInDelta(const SkIRect& r) const {
        return r.right() < fDelta && r.bottom() < fDelta;
    }

    bool computeCurrBitmapAndClip();
};

#endif
