/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HWUI_UV_MAPPER_H
#define ANDROID_HWUI_UV_MAPPER_H

#include "Rect.h"

namespace android {
namespace uirenderer {

/**
 * This class can be used to map UV coordinates from the [0..1]
 * range to other arbitrary ranges. All the methods below assume
 * that the input values lie in the [0..1] range already.
 */
class UvMapper {
public:
    /**
     * Using this constructor is equivalent to not using any mapping at all.
     * UV coordinates in the [0..1] range remain in the [0..1] range.
     */
    UvMapper(): mIdentity(true), mMinU(0.0f), mMaxU(1.0f), mMinV(0.0f), mMaxV(1.0f) {
    }

    /**
     * Creates a new mapper with the specified ranges for U and V coordinates.
     * The parameter minU must be < maxU and minV must be < maxV.
     */
    UvMapper(float minU, float maxU, float minV, float maxV):
        mMinU(minU), mMaxU(maxU), mMinV(minV), mMaxV(maxV) {
        checkIdentity();
    }

    /**
     * Returns true if calling the map*() methods has no effect (that is,
     * texture coordinates remain in the 0..1 range.)
     */
    bool isIdentity() const {
        return mIdentity;
    }

    /**
     * Changes the U and V mapping ranges.
     * The parameter minU must be < maxU and minV must be < maxV.
     */
    void setMapping(float minU, float maxU, float minV, float maxV) {
        mMinU = minU;
        mMaxU = maxU;
        mMinV = minV;
        mMaxV = maxV;
        checkIdentity();
    }

    /**
     * Maps a single value in the U range.
     */
    void mapU(float& u) const {
        if (!mIdentity) u = lerp(mMinU, mMaxU, u);
    }

    /**
     * Maps a single value in the V range.
     */
    void mapV(float& v) const {
        if (!mIdentity) v = lerp(mMinV, mMaxV, v);
    }

    /**
     * Maps the specified rectangle in place. This method assumes:
     * - left = min. U
     * - top = min. V
     * - right = max. U
     * - bottom = max. V
     */
    void map(Rect& texCoords) const {
        if (!mIdentity) {
            texCoords.left = lerp(mMinU, mMaxU, texCoords.left);
            texCoords.right = lerp(mMinU, mMaxU, texCoords.right);
            texCoords.top = lerp(mMinV, mMaxV, texCoords.top);
            texCoords.bottom = lerp(mMinV, mMaxV, texCoords.bottom);
        }
    }

    /**
     * Maps the specified UV coordinates in place.
     */
    void map(float& u1, float& v1, float& u2, float& v2) const {
        if (!mIdentity) {
            u1 = lerp(mMinU, mMaxU, u1);
            u2 = lerp(mMinU, mMaxU, u2);
            v1 = lerp(mMinV, mMaxV, v1);
            v2 = lerp(mMinV, mMaxV, v2);
        }
    }

    void dump() const {
        ALOGD("mapper[minU=%.2f maxU=%.2f minV=%.2f maxV=%.2f]", mMinU, mMaxU, mMinV, mMaxV);
    }

private:
    static float lerp(float start, float stop, float amount) {
        return start + (stop - start) * amount;
    }

    void checkIdentity() {
        mIdentity = mMinU == 0.0f && mMaxU == 1.0f && mMinV == 0.0f && mMaxV == 1.0f;
    }

    bool mIdentity;
    float mMinU;
    float mMaxU;
    float mMinV;
    float mMaxV;
};

}; // namespace uirenderer
}; // namespace android

#endif // ANDROID_HWUI_UV_MAPPER_H
