/*
 * Copyright 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.
 */

#include <assert.h>
#include <inttypes.h>
#include <stdlib.h>

#define LOG_TAG "ScreenRecord"
//#define LOG_NDEBUG 0
#include <utils/Log.h>

#include <gui/BufferQueue.h>
#include <gui/GraphicBufferAlloc.h>
#include <gui/Surface.h>
#include <cutils/properties.h>
#include <utils/misc.h>

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include "screenrecord.h"
#include "Overlay.h"
#include "TextRenderer.h"

using namespace android;

// System properties to look up and display on the info screen.
const char* Overlay::kPropertyNames[] = {
        "ro.build.description",
        // includes ro.build.id, ro.build.product, ro.build.tags, ro.build.type,
        // and ro.build.version.release
        "ro.product.manufacturer",
        "ro.product.model",
        "ro.board.platform",
        "ro.revision",
        "dalvik.vm.heapgrowthlimit",
        "dalvik.vm.heapsize",
        "persist.sys.dalvik.vm.lib.2",
        //"ro.product.cpu.abi",
        //"ro.bootloader",
        //"this-never-appears!",
};


status_t Overlay::start(const sp<IGraphicBufferProducer>& outputSurface,
        sp<IGraphicBufferProducer>* pBufferProducer) {
    ALOGV("Overlay::start");
    mOutputSurface = outputSurface;

    // Grab the current monotonic time and the current wall-clock time so we
    // can map one to the other.  This allows the overlay counter to advance
    // by the exact delay between frames, but if the wall clock gets adjusted
    // we won't track it, which means we'll gradually go out of sync with the
    // times in logcat.
    mStartMonotonicNsecs = systemTime(CLOCK_MONOTONIC);
    mStartRealtimeNsecs = systemTime(CLOCK_REALTIME);

    Mutex::Autolock _l(mMutex);

    // Start the thread.  Traffic begins immediately.
    run("overlay");

    mState = INIT;
    while (mState == INIT) {
        mStartCond.wait(mMutex);
    }

    if (mThreadResult != NO_ERROR) {
        ALOGE("Failed to start overlay thread: err=%d", mThreadResult);
        return mThreadResult;
    }
    assert(mState == RUNNING);

    ALOGV("Overlay::start successful");
    *pBufferProducer = mProducer;
    return NO_ERROR;
}

status_t Overlay::stop() {
    ALOGV("Overlay::stop");
    Mutex::Autolock _l(mMutex);
    mState = STOPPING;
    mEventCond.signal();
    return NO_ERROR;
}

bool Overlay::threadLoop() {
    Mutex::Autolock _l(mMutex);

    mThreadResult = setup_l();

    if (mThreadResult != NO_ERROR) {
        ALOGW("Aborting overlay thread");
        mState = STOPPED;
        release_l();
        mStartCond.broadcast();
        return false;
    }

    ALOGV("Overlay thread running");
    mState = RUNNING;
    mStartCond.broadcast();

    while (mState == RUNNING) {
        mEventCond.wait(mMutex);
        if (mFrameAvailable) {
            ALOGV("Awake, frame available");
            processFrame_l();
            mFrameAvailable = false;
        } else {
            ALOGV("Awake, frame not available");
        }
    }

    ALOGV("Overlay thread stopping");
    release_l();
    mState = STOPPED;
    return false;       // stop
}

status_t Overlay::setup_l() {
    status_t err;

    err = mEglWindow.createWindow(mOutputSurface);
    if (err != NO_ERROR) {
        return err;
    }
    mEglWindow.makeCurrent();

    int width = mEglWindow.getWidth();
    int height = mEglWindow.getHeight();

    glViewport(0, 0, width, height);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    // Shaders for rendering from different types of textures.
    err = mTexProgram.setup(Program::PROGRAM_TEXTURE_2D);
    if (err != NO_ERROR) {
        return err;
    }
    err = mExtTexProgram.setup(Program::PROGRAM_EXTERNAL_TEXTURE);
    if (err != NO_ERROR) {
        return err;
    }

    err = mTextRenderer.loadIntoTexture();
    if (err != NO_ERROR) {
        return err;
    }
    mTextRenderer.setScreenSize(width, height);

    // Input side (buffers from virtual display).
    glGenTextures(1, &mExtTextureName);
    if (mExtTextureName == 0) {
        ALOGE("glGenTextures failed: %#x", glGetError());
        return UNKNOWN_ERROR;
    }

    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&mProducer, &consumer);
    mGlConsumer = new GLConsumer(consumer, mExtTextureName,
                GL_TEXTURE_EXTERNAL_OES, true, false);
    mGlConsumer->setName(String8("virtual display"));
    mGlConsumer->setDefaultBufferSize(width, height);
    mGlConsumer->setDefaultMaxBufferCount(5);
    mGlConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_TEXTURE);

    mGlConsumer->setFrameAvailableListener(this);

    return NO_ERROR;
}


void Overlay::release_l() {
    ALOGV("Overlay::release_l");
    mOutputSurface.clear();
    mGlConsumer.clear();
    mProducer.clear();

    mTexProgram.release();
    mExtTexProgram.release();
    mEglWindow.release();
}

void Overlay::processFrame_l() {
    float texMatrix[16];

    mGlConsumer->updateTexImage();
    mGlConsumer->getTransformMatrix(texMatrix);
    nsecs_t monotonicNsec = mGlConsumer->getTimestamp();
    nsecs_t frameNumber = mGlConsumer->getFrameNumber();
    int64_t droppedFrames = 0;

    if (mLastFrameNumber > 0) {
        mTotalDroppedFrames += size_t(frameNumber - mLastFrameNumber) - 1;
    }
    mLastFrameNumber = frameNumber;

    mTextRenderer.setProportionalScale(35);

    if (false) {  // DEBUG - full blue background
        glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    }

    int width = mEglWindow.getWidth();
    int height = mEglWindow.getHeight();
    if (false) {  // DEBUG - draw inset
        mExtTexProgram.blit(mExtTextureName, texMatrix,
                100, 100, width-200, height-200);
    } else {
        mExtTexProgram.blit(mExtTextureName, texMatrix,
                0, 0, width, height);
    }

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    if (false) {  // DEBUG - show entire font bitmap
        mTexProgram.blit(mTextRenderer.getTextureName(), Program::kIdentity,
                100, 100, width-200, height-200);
    }

    char textBuf[64];
    getTimeString_l(monotonicNsec, textBuf, sizeof(textBuf));
    String8 timeStr(String8::format("%s f=%" PRId64 " (%zd)",
            textBuf, frameNumber, mTotalDroppedFrames));
    mTextRenderer.drawString(mTexProgram, Program::kIdentity, 0, 0, timeStr);

    glDisable(GL_BLEND);

    if (false) {  // DEBUG - add red rectangle in lower-left corner
        glEnable(GL_SCISSOR_TEST);
        glScissor(0, 0, 200, 200);
        glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glDisable(GL_SCISSOR_TEST);
    }

    mEglWindow.presentationTime(monotonicNsec);
    mEglWindow.swapBuffers();
}

void Overlay::getTimeString_l(nsecs_t monotonicNsec, char* buf, size_t bufLen) {
    //const char* format = "%m-%d %T";    // matches log output
    const char* format = "%T";
    struct tm tm;

    // localtime/strftime is not the fastest way to do this, but a trivial
    // benchmark suggests that the cost is negligible.
    int64_t realTime = mStartRealtimeNsecs +
            (monotonicNsec - mStartMonotonicNsecs);
    time_t secs = (time_t) (realTime / 1000000000);
    localtime_r(&secs, &tm);
    strftime(buf, bufLen, format, &tm);

    int32_t msec = (int32_t) ((realTime % 1000000000) / 1000000);
    char tmpBuf[5];
    snprintf(tmpBuf, sizeof(tmpBuf), ".%03d", msec);
    strlcat(buf, tmpBuf, bufLen);
}

// Callback; executes on arbitrary thread.
void Overlay::onFrameAvailable(const BufferItem& /* item */) {
    ALOGV("Overlay::onFrameAvailable");
    Mutex::Autolock _l(mMutex);
    mFrameAvailable = true;
    mEventCond.signal();
}


/*static*/ status_t Overlay::drawInfoPage(
        const sp<IGraphicBufferProducer>& outputSurface) {
    status_t err;

    EglWindow window;
    err = window.createWindow(outputSurface);
    if (err != NO_ERROR) {
        return err;
    }
    window.makeCurrent();

    int width = window.getWidth();
    int height = window.getHeight();
    glViewport(0, 0, width, height);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    // Shaders for rendering.
    Program texProgram;
    err = texProgram.setup(Program::PROGRAM_TEXTURE_2D);
    if (err != NO_ERROR) {
        return err;
    }
    TextRenderer textRenderer;
    err = textRenderer.loadIntoTexture();
    if (err != NO_ERROR) {
        return err;
    }
    textRenderer.setScreenSize(width, height);

    doDrawInfoPage(window, texProgram, textRenderer);

    // Destroy the surface.  This causes a disconnect.
    texProgram.release();
    window.release();

    return NO_ERROR;
}

/*static*/ void Overlay::doDrawInfoPage(const EglWindow& window,
        const Program& texProgram, TextRenderer& textRenderer) {
    const nsecs_t holdTime = 250000000LL;

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    int width = window.getWidth();
    int height = window.getHeight();

    // Draw a thin border around the screen.  Some players, e.g. browser
    // plugins, make it hard to see where the edges are when the device
    // is using a black background, so this gives the viewer a frame of
    // reference.
    //
    // This is a clumsy way to do it, but we're only doing it for one frame,
    // and it's easier than actually drawing lines.
    const int lineWidth = 4;
    glEnable(GL_SCISSOR_TEST);
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glScissor(0, 0, width, lineWidth);
    glClear(GL_COLOR_BUFFER_BIT);
    glScissor(0, height - lineWidth, width, lineWidth);
    glClear(GL_COLOR_BUFFER_BIT);
    glScissor(0, 0, lineWidth, height);
    glClear(GL_COLOR_BUFFER_BIT);
    glScissor(width - lineWidth, 0, lineWidth, height);
    glClear(GL_COLOR_BUFFER_BIT);
    glDisable(GL_SCISSOR_TEST);

    //glEnable(GL_BLEND);
    //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    textRenderer.setProportionalScale(30);

    float xpos = 0;
    float ypos = 0;
    ypos = textRenderer.drawWrappedString(texProgram, xpos, ypos,
            String8::format("Android screenrecord v%d.%d",
                    kVersionMajor, kVersionMinor));

    // Show date/time
    time_t now = time(0);
    struct tm tm;
    localtime_r(&now, &tm);
    char timeBuf[64];
    strftime(timeBuf, sizeof(timeBuf), "%a, %d %b %Y %T %z", &tm);
    String8 header("Started ");
    header += timeBuf;
    ypos = textRenderer.drawWrappedString(texProgram, xpos, ypos, header);
    ypos += 8 * textRenderer.getScale();    // slight padding

    // Show selected system property values
    for (int i = 0; i < NELEM(kPropertyNames); i++) {
        char valueBuf[PROPERTY_VALUE_MAX];

        property_get(kPropertyNames[i], valueBuf, "");
        if (valueBuf[0] == '\0') {
            continue;
        }
        String8 str(String8::format("%s: [%s]", kPropertyNames[i], valueBuf));
        ypos = textRenderer.drawWrappedString(texProgram, xpos, ypos, str);
    }
    ypos += 8 * textRenderer.getScale();    // slight padding

    // Show GL info
    String8 glStr("OpenGL: ");
    glStr += (char*) glGetString(GL_VENDOR);
    glStr += " / ";
    glStr += (char*) glGetString(GL_RENDERER);
    glStr += ", ";
    glStr += (char*) glGetString(GL_VERSION);
    ypos = textRenderer.drawWrappedString(texProgram, xpos, ypos, glStr);

    //glDisable(GL_BLEND);

    // Set a presentation time slightly in the past.  This will cause the
    // player to hold the frame on screen.
    window.presentationTime(systemTime(CLOCK_MONOTONIC) - holdTime);
    window.swapBuffers();
}
