/*
 * Copyright (C) 2020 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.
 */

#define LOG_TAG "TouchSpotController"

// Log debug messages about pointer updates
#define DEBUG_SPOT_UPDATES 0

#include "TouchSpotController.h"

#include <android-base/stringprintf.h>
#include <input/PrintTools.h>
#include <log/log.h>

#include <mutex>

#define INDENT "  "
#define INDENT2 "    "

namespace {
// Time to spend fading out the spot completely.
const nsecs_t SPOT_FADE_DURATION = 200 * 1000000LL; // 200 ms
} // namespace

namespace android {

// --- Spot ---

void TouchSpotController::Spot::updateSprite(const SpriteIcon* icon, float newX, float newY,
                                             ui::LogicalDisplayId displayId, bool skipScreenshot) {
    sprite->setLayer(Sprite::BASE_LAYER_SPOT + id);
    sprite->setAlpha(alpha);
    sprite->setTransformationMatrix(SpriteTransformationMatrix(scale, 0.0f, 0.0f, scale));
    sprite->setPosition(newX, newY);
    sprite->setDisplayId(displayId);
    sprite->setSkipScreenshot(skipScreenshot);
    x = newX;
    y = newY;

    if (icon != mLastIcon) {
        mLastIcon = icon;
        if (icon) {
            sprite->setIcon(*icon);
            sprite->setVisible(true);
        } else {
            sprite->setVisible(false);
        }
    }
}

void TouchSpotController::Spot::dump(std::string& out, const char* prefix) const {
    out += prefix;
    base::StringAppendF(&out, "Spot{id=%" PRIx32 ", alpha=%f, scale=%f, pos=[%f, %f]}\n", id, alpha,
                        scale, x, y);
}

// --- TouchSpotController ---

TouchSpotController::TouchSpotController(ui::LogicalDisplayId displayId,
                                         PointerControllerContext& context)
      : mDisplayId(displayId), mContext(context) {
    mContext.getPolicy()->loadPointerResources(&mResources, mDisplayId);
}

TouchSpotController::~TouchSpotController() {
    std::scoped_lock lock(mLock);

    size_t numSpots = mLocked.displaySpots.size();
    for (size_t i = 0; i < numSpots; i++) {
        delete mLocked.displaySpots[i];
    }
    mLocked.displaySpots.clear();
}

void TouchSpotController::setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
                                   BitSet32 spotIdBits, bool skipScreenshot) {
#if DEBUG_SPOT_UPDATES
    ALOGD("setSpots: idBits=%08x", spotIdBits.value);
    for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) {
        uint32_t id = idBits.firstMarkedBit();
        idBits.clearBit(id);
        const PointerCoords& c = spotCoords[spotIdToIndex[id]];
        ALOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f, displayId=%" PRId32 ".", id,
              c.getAxisValue(AMOTION_EVENT_AXIS_X), c.getAxisValue(AMOTION_EVENT_AXIS_Y),
              c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), mDisplayId.id);
    }
#endif

    std::scoped_lock lock(mLock);
    auto& spriteController = mContext.getSpriteController();
    spriteController.openTransaction();

    // Add or move spots for fingers that are down.
    for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) {
        uint32_t id = idBits.clearFirstMarkedBit();
        const PointerCoords& c = spotCoords[spotIdToIndex[id]];
        const SpriteIcon& icon = c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE) > 0
                ? mResources.spotTouch
                : mResources.spotHover;
        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X);
        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y);

        Spot* spot = getSpot(id, mLocked.displaySpots);
        if (!spot) {
            spot = createAndAddSpotLocked(id, mLocked.displaySpots);
        }

        spot->updateSprite(&icon, x, y, mDisplayId, skipScreenshot);
    }

    for (Spot* spot : mLocked.displaySpots) {
        if (spot->id != Spot::INVALID_ID && !spotIdBits.hasBit(spot->id)) {
            fadeOutAndReleaseSpotLocked(spot);
        }
    }

    spriteController.closeTransaction();
}

void TouchSpotController::clearSpots() {
#if DEBUG_SPOT_UPDATES
    ALOGD("clearSpots");
#endif

    std::scoped_lock lock(mLock);
    fadeOutAndReleaseAllSpotsLocked();
}

TouchSpotController::Spot* TouchSpotController::getSpot(uint32_t id,
                                                        const std::vector<Spot*>& spots) {
    for (size_t i = 0; i < spots.size(); i++) {
        Spot* spot = spots[i];
        if (spot->id == id) {
            return spot;
        }
    }
    return nullptr;
}

TouchSpotController::Spot* TouchSpotController::createAndAddSpotLocked(uint32_t id,
                                                                       std::vector<Spot*>& spots)
        REQUIRES(mLock) {
    // Remove spots until we have fewer than MAX_SPOTS remaining.
    while (spots.size() >= MAX_SPOTS) {
        Spot* spot = removeFirstFadingSpotLocked(spots);
        if (!spot) {
            spot = spots[0];
            spots.erase(spots.begin());
        }
        releaseSpotLocked(spot);
    }

    // Obtain a sprite from the recycled pool.
    sp<Sprite> sprite;
    if (!mLocked.recycledSprites.empty()) {
        sprite = mLocked.recycledSprites.back();
        mLocked.recycledSprites.pop_back();
    } else {
        sprite = mContext.getSpriteController().createSprite();
    }

    // Return the new spot.
    Spot* spot = new Spot(id, sprite);
    spots.push_back(spot);
    return spot;
}

TouchSpotController::Spot* TouchSpotController::removeFirstFadingSpotLocked(
        std::vector<Spot*>& spots) REQUIRES(mLock) {
    for (size_t i = 0; i < spots.size(); i++) {
        Spot* spot = spots[i];
        if (spot->id == Spot::INVALID_ID) {
            spots.erase(spots.begin() + i);
            return spot;
        }
    }
    return NULL;
}

void TouchSpotController::releaseSpotLocked(Spot* spot) REQUIRES(mLock) {
    spot->sprite->clearIcon();

    if (mLocked.recycledSprites.size() < MAX_RECYCLED_SPRITES) {
        mLocked.recycledSprites.push_back(spot->sprite);
    }
    delete spot;
}

void TouchSpotController::fadeOutAndReleaseSpotLocked(Spot* spot) REQUIRES(mLock) {
    if (spot->id != Spot::INVALID_ID) {
        spot->id = Spot::INVALID_ID;
        startAnimationLocked();
    }
}

void TouchSpotController::fadeOutAndReleaseAllSpotsLocked() REQUIRES(mLock) {
    size_t numSpots = mLocked.displaySpots.size();
    for (size_t i = 0; i < numSpots; i++) {
        Spot* spot = mLocked.displaySpots[i];
        fadeOutAndReleaseSpotLocked(spot);
    }
}

void TouchSpotController::reloadSpotResources() {
    mContext.getPolicy()->loadPointerResources(&mResources, mDisplayId);
}

bool TouchSpotController::doAnimations(nsecs_t timestamp) {
    std::scoped_lock lock(mLock);
    bool keepAnimating = doFadingAnimationLocked(timestamp);
    if (!keepAnimating) {
        /*
         * We know that this callback will be removed before another
         * is added. mLock in PointerAnimator will not be released
         * until after this is removed, and adding another callback
         * requires that lock. Thus it's safe to set mLocked.animating
         * here.
         */
        mLocked.animating = false;
    }
    return keepAnimating;
}

bool TouchSpotController::doFadingAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) {
    bool keepAnimating = false;
    nsecs_t animationTime = mContext.getAnimationTime();
    nsecs_t frameDelay = timestamp - animationTime;
    size_t numSpots = mLocked.displaySpots.size();
    for (size_t i = 0; i < numSpots;) {
        Spot* spot = mLocked.displaySpots[i];
        if (spot->id == Spot::INVALID_ID) {
            spot->alpha -= float(frameDelay) / SPOT_FADE_DURATION;
            if (spot->alpha <= 0) {
                mLocked.displaySpots.erase(mLocked.displaySpots.begin() + i);
                releaseSpotLocked(spot);
                numSpots--;
                continue;
            } else {
                spot->sprite->setAlpha(spot->alpha);
                keepAnimating = true;
            }
        }
        ++i;
    }
    return keepAnimating;
}

void TouchSpotController::startAnimationLocked() REQUIRES(mLock) {
    using namespace std::placeholders;

    if (mLocked.animating) {
        return;
    }
    mLocked.animating = true;

    std::function<bool(nsecs_t)> func = std::bind(&TouchSpotController::doAnimations, this, _1);
    mContext.addAnimationCallback(mDisplayId, func);
}

void TouchSpotController::dump(std::string& out, const char* prefix) const {
    using base::StringAppendF;
    out += prefix;
    out += "SpotController:\n";
    out += prefix;
    StringAppendF(&out, INDENT "DisplayId: %s\n", mDisplayId.toString().c_str());
    std::scoped_lock lock(mLock);
    out += prefix;
    StringAppendF(&out, INDENT "Animating: %s\n", toString(mLocked.animating));
    out += prefix;
    out += INDENT "Spots:\n";
    std::string spotPrefix = prefix;
    spotPrefix += INDENT2;
    for (const auto& spot : mLocked.displaySpots) {
        spot->dump(out, spotPrefix.c_str());
    }
}

} // namespace android
