/*
 * 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 SkTracker_DEFINED
#define SkTracker_DEFINED

#include "SkBitmap.h"
#include "SkPoint.h"

// TODO(edisonn): draw plan from point! - list of draw ops of a point, like a tree!
// TODO(edisonn): Minimal PDF to draw some points - remove everything that it is not needed,
//                save pdf uncompressed

#define MAX_TRACKING_POINTS 100

/** \class SkTracker
 *
 *   A Tracker can be attached to a SkTrackDevice and it will store the track pixels.
 *   It can be used with SampleApp to investigate bugs (CL not checked in yet).
 *
 *   The Tracker tracks 2 sets of points
 *     A) one which is expected to issue breackpoints if the pixels are changes
 *     B) one which if changes will disable the breackpoint
 *   For point in A) there are two modes:
 *     A.1) a breackpoint require that any of the points is changed
 *     A.2) a breackpoint require that all of the points is changed
 *   Points in B are allways in "any mode" - chaning the value of any pixel, will disable
 *     the breackpoint
 *
 *   Point in A) are used to show what are the areas of interest, while poit in B are used to
 *     disable breackpoints which would be issued in background change.
 *
 */
class SkTracker {
public:
    SkTracker() : fEnabled(false)
                , fBreakOnAny(false)
                , fCntExpectedTouched(0)
                , fCntExpectedUntouched(0)
                , fHits(0) {}

    virtual ~SkTracker() {}

    // Clears all the points, but preserves the break mode.
    void clearPoints() {
        fCntExpectedTouched = 0;
        fCntExpectedUntouched = 0;
    }

    // Enable the breackpoints.
    void enableTracking(bool b) {
        fEnabled = b;
    }

    // Returns true if breackpoints are enabled.
    bool trackingEnabled() {
        return fEnabled;
    }

    // Puts the tracker in Any mode.
    void any() {
        fBreakOnAny = true;
    }

    // Puts the tracker in Any mode.
    void all() {
        fBreakOnAny = false;
    }

    // returns true in in All mode. False for Any mode.
    bool requireAllExpectedTouched() {
        return !fBreakOnAny;
    }

    // Returns the numbers of points in which if touched, would trigger a breackpoint.
    int cntExpectedTouched() {
        return fCntExpectedTouched;
    }

    // Returns the points which if touched, would trigger a breackpoint.
    // the Tracker owns the array
    const SkIPoint* expectedTouched() {
        return fExpectedTouched;
    }

    // Returns the numbers of points in which if touched, would disable a breackpoint.
    int cntExpectedUntouched() {
        return fCntExpectedUntouched;
    }

    // Returns the points which if touched, would disable a breackpoint.
    // the Tracker owns the array
    const SkIPoint* expectedUntouched() {
        return fExpectedUntouched;
    }

    // Adds a point which if changes in a drawFoo operation, would trigger a breakpoint.
    bool addExpectTouch(int x, int y) {
        if (fCntExpectedTouched >= MAX_TRACKING_POINTS) {
            return false;
        }
        if (found(x, y)) {
            return false;
        }
        fExpectedTouched[fCntExpectedTouched] = SkIPoint::Make(x, y);
        fCntExpectedTouched++;
        return true;
    }

    // Adds a point which if changes in a drawFoo operation, would disable a breakpoint.
    bool addExpectUntouch(int x, int y) {
        if (fCntExpectedUntouched >= MAX_TRACKING_POINTS) {
            return false;
        }
        if (found(x, y)) {
            return false;
        }
        fExpectedUntouched[fCntExpectedUntouched] = SkIPoint::Make(x, y);
        fCntExpectedUntouched++;
        return true;
    }

    // Starts a new rendering session - reset the number of hits.
    void newFrame() {
        fHits = 0;
    }

    // returns the number of breackpoints issues in this rendering session.
    int hits() {
        return fHits;
    }

    // Called before drawFoo to store the state of the pixels
    void before(const SkBitmap& bitmap) {
        if (fCntExpectedTouched == 0) {
            return;
        }

        for (int i = 0 ; i < fCntExpectedTouched; i++) {
            fBeforeTouched[i] = pickColor(bitmap, fExpectedTouched[i].x(), fExpectedTouched[i].y());
        }
        for (int i = 0 ; i < fCntExpectedUntouched; i++) {
            fBeforeUntouched[i] = pickColor(bitmap, fExpectedUntouched[i].x(),
                                            fExpectedUntouched[i].y());
        }
    }

    // Called after drawFoo to evaluate what pixels have changed, it could issue a breakpoint.
    // any/all of the expected touched has to be changed, and all expected untouched must be intact
    void after(const SkBitmap& bitmap) {
        if (fCntExpectedTouched == 0) {
            return;
        }

        bool doBreak;
        if (fBreakOnAny) {
            doBreak = false;
            for (int i = 0 ; i < fCntExpectedTouched; i++) {
                doBreak = doBreak || fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
                                                                    fExpectedTouched[i].y());
            }
        } else {
            doBreak = true;
            for (int i = 0 ; i < fCntExpectedTouched; i++) {
                doBreak = doBreak && fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
                                                                    fExpectedTouched[i].y());
            }
        }

        for (int i = 0 ; i < fCntExpectedUntouched; i++) {
            doBreak = doBreak && fBeforeUntouched[i] == pickColor(bitmap, fExpectedUntouched[i].x(),
                                                                  fExpectedUntouched[i].y());
        }

        if (doBreak) {
            fHits++;
            if (fEnabled) {
                breakExecution();
            }
        }
    }

private:
    inline SkColor pickColor(const SkBitmap& bitmap, int x, int y) {
        return bitmap.getColor(x, y);
    }

    void breakExecution() {
        printf("break;\n");
    }

    inline bool found(int x, int y) {
        for (int i = 0 ; i < fCntExpectedTouched; i++) {
            if (x == fExpectedTouched[i].x() && y == fExpectedTouched[i].y()) {
                return true;
            }
        }
        for (int i = 0 ; i < fCntExpectedUntouched; i++) {
            if (x == fExpectedUntouched[i].x() && y == fExpectedUntouched[i].y()) {
                return true;
            }
        }
        return false;
    }


    bool fEnabled;
    // break on any change on expected touched or all.
    bool fBreakOnAny;
    SkIPoint fExpectedTouched[MAX_TRACKING_POINTS];
    SkColor fBeforeTouched[MAX_TRACKING_POINTS];
    int fCntExpectedTouched;

    SkIPoint fExpectedUntouched[MAX_TRACKING_POINTS];
    SkColor fBeforeUntouched[MAX_TRACKING_POINTS];
    int fCntExpectedUntouched;

    int fHits;
};

#endif  // SkTracker_DEFINED
