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

#include "GrEffect.h"
#include "SkMatrix.h"
#include "GrTexture.h"
#include "GrTypes.h"

/**
 * Coordinates available to GrEffect subclasses for requesting transformations. Transformed
 * coordinates are made available in the the portion of fragment shader emitted by the effect.
 */
enum GrCoordSet {
    /**
     * The user-space coordinates that map to the fragment being rendered. These coords account for
     * any change of coordinate system done on the CPU by GrContext before rendering, and also are
     * correct for draws that take explicit local coords rather than inferring them from the
     * primitive's positions (e.g. drawVertices). These are usually the coords a GrEffect wants.
     */
    kLocal_GrCoordSet,

    /**
     * The actual vertex position. Note that GrContext may not draw using the original view matrix
     * specified by the caller, as it may have transformed vertices into another space. These are
     * usually not the coordinates a GrEffect wants.
     */
    kPosition_GrCoordSet
};

/**
 * A class representing a linear transformation from one of the built-in coordinate sets (local or
 * position). GrEffects just define these transformations, and the framework does the rest of the
 * work to make the transformed coordinates available in their fragment shader.
 */
class GrCoordTransform : SkNoncopyable {
public:
    GrCoordTransform() { SkDEBUGCODE(fInEffect = false); }

    /**
     * Create a transformation that maps [0, 1] to a texture's boundaries.
     */
    GrCoordTransform(GrCoordSet sourceCoords, const GrTexture* texture) {
        SkDEBUGCODE(fInEffect = false);
        this->reset(sourceCoords, texture);
    }

    /**
     * Create a transformation from a matrix. The optional texture parameter is used to infer if the
     * framework should internally do a y reversal to account for it being upside down by Skia's
     * coord convention.
     */
    GrCoordTransform(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) {
        SkDEBUGCODE(fInEffect = false);
        this->reset(sourceCoords, m, texture);
    }

    void reset(GrCoordSet sourceCoords, const GrTexture* texture) {
        SkASSERT(!fInEffect);
        SkASSERT(NULL != texture);
        this->reset(sourceCoords, GrEffect::MakeDivByTextureWHMatrix(texture), texture);
    }

    void reset(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) {
        SkASSERT(!fInEffect);
        fSourceCoords = sourceCoords;
        fMatrix = m;
        fReverseY = NULL != texture && kBottomLeft_GrSurfaceOrigin == texture->origin();
    }

    GrCoordTransform& operator= (const GrCoordTransform& other) {
        SkASSERT(!fInEffect);
        fSourceCoords = other.fSourceCoords;
        fMatrix = other.fMatrix;
        fReverseY = other.fReverseY;
        return *this;
    }

    /**
     * Access the matrix for editing. Note, this must be done before adding the transform to an
     * effect, since effects are immutable.
     */
    SkMatrix* accessMatrix() {
        SkASSERT(!fInEffect);
        return &fMatrix;
    }

    bool operator== (const GrCoordTransform& other) const {
        return fSourceCoords == other.fSourceCoords &&
               fMatrix.cheapEqualTo(other.fMatrix) &&
               fReverseY == other.fReverseY;
    }

    GrCoordSet sourceCoords() const { return fSourceCoords; }
    const SkMatrix& getMatrix() const { return fMatrix; }
    bool reverseY() const { return fReverseY; }

private:
    GrCoordSet fSourceCoords;
    SkMatrix   fMatrix;
    bool       fReverseY;

    typedef SkNoncopyable INHERITED;

#ifdef SK_DEBUG
public:
    void setInEffect() const { fInEffect = true; }
private:
    mutable bool fInEffect;
#endif
};

#endif
