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

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

#include "TextRenderer.h"

#include <assert.h>

namespace android {
#include "FontBitmap.h"
};

using namespace android;

const char TextRenderer::kWhitespace[] = " \t\n\r";

bool TextRenderer::mInitialized = false;
uint32_t TextRenderer::mXOffset[FontBitmap::numGlyphs];

void TextRenderer::initOnce() {
    if (!mInitialized) {
        initXOffset();
        mInitialized = true;
    }
}

void TextRenderer::initXOffset() {
    // Generate a table of X offsets.  They start at zero and reset whenever
    // we move down a line (i.e. the Y offset changes).  The offset increases
    // by one pixel more than the width because the generator left a gap to
    // avoid reading pixels from adjacent glyphs in the texture filter.
    uint16_t offset = 0;
    uint16_t prevYOffset = (int16_t) -1;
    for (unsigned int i = 0; i < FontBitmap::numGlyphs; i++) {
        if (prevYOffset != FontBitmap::yoffset[i]) {
            prevYOffset = FontBitmap::yoffset[i];
            offset = 0;
        }
        mXOffset[i] = offset;
        offset += FontBitmap::glyphWidth[i] + 1;
    }
}

static bool isPowerOfTwo(uint32_t val) {
    // a/k/a "is exactly one bit set"; note returns true for 0
    return (val & (val -1)) == 0;
}

static uint32_t powerOfTwoCeil(uint32_t val) {
    // drop it, smear the bits across, pop it
    val--;
    val |= val >> 1;
    val |= val >> 2;
    val |= val >> 4;
    val |= val >> 8;
    val |= val >> 16;
    val++;

    return val;
}

float TextRenderer::getGlyphHeight() const {
    return FontBitmap::maxGlyphHeight;
}

status_t TextRenderer::loadIntoTexture() {
    ALOGV("Font::loadIntoTexture");

    glGenTextures(1, &mTextureName);
    if (mTextureName == 0) {
        ALOGE("glGenTextures failed: %#x", glGetError());
        return UNKNOWN_ERROR;
    }
    glBindTexture(GL_TEXTURE_2D, mTextureName);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // The pixel data is stored as combined color+alpha, 8 bits per pixel.
    // It's guaranteed to be a power-of-two wide, but we cut off the height
    // where the data ends.  We want to expand it to a power-of-two bitmap
    // with ARGB data and hand that to glTexImage2D.

    if (!isPowerOfTwo(FontBitmap::width)) {
        ALOGE("npot glyph bitmap width %u", FontBitmap::width);
        return UNKNOWN_ERROR;
    }

    uint32_t potHeight = powerOfTwoCeil(FontBitmap::height);
    uint8_t* rgbaPixels = new uint8_t[FontBitmap::width * potHeight * 4];
    memset(rgbaPixels, 0, FontBitmap::width * potHeight * 4);
    uint8_t* pix = rgbaPixels;

    for (unsigned int i = 0; i < FontBitmap::width * FontBitmap::height; i++) {
        uint8_t alpha, color;
        if ((FontBitmap::pixels[i] & 1) == 0) {
            // black pixel with varying alpha
            color = 0x00;
            alpha = FontBitmap::pixels[i] & ~1;
        } else {
            // opaque grey pixel
            color = FontBitmap::pixels[i] & ~1;
            alpha = 0xff;
        }
        *pix++ = color;
        *pix++ = color;
        *pix++ = color;
        *pix++ = alpha;
    }

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FontBitmap::width, potHeight, 0,
            GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
    delete[] rgbaPixels;
    GLint glErr = glGetError();
    if (glErr != 0) {
        ALOGE("glTexImage2D failed: %#x", glErr);
        return UNKNOWN_ERROR;
    }
    return NO_ERROR;
}

void TextRenderer::setProportionalScale(float linesPerScreen) {
    if (mScreenWidth == 0 || mScreenHeight == 0) {
        ALOGW("setFontScale: can't set scale for width=%d height=%d",
                mScreenWidth, mScreenHeight);
        return;
    }
    float tallest = mScreenWidth > mScreenHeight ? mScreenWidth : mScreenHeight;
    setScale(tallest / (linesPerScreen * getGlyphHeight()));
}

float TextRenderer::computeScaledStringWidth(const String8& str8) const {
    // String8.length() isn't documented, but I'm assuming it will return
    // the number of characters rather than the number of bytes.  Since
    // we can only display ASCII we want to ignore anything else, so we
    // just convert to char* -- but String8 doesn't document what it does
    // with values outside 0-255.  So just convert to char* and use strlen()
    // to see what we get.
    const char* str = str8.string();
    return computeScaledStringWidth(str, strlen(str));
}

size_t TextRenderer::glyphIndex(char ch) const {
    size_t chi = ch - FontBitmap::firstGlyphChar;
    if (chi >= FontBitmap::numGlyphs) {
        chi = '?' - FontBitmap::firstGlyphChar;
    }
    assert(chi < FontBitmap::numGlyphs);
    return chi;
}

float TextRenderer::computeScaledStringWidth(const char* str,
        size_t len) const {
    float width = 0.0f;
    for (size_t i = 0; i < len; i++) {
        size_t chi = glyphIndex(str[i]);
        float glyphWidth = FontBitmap::glyphWidth[chi];
        width += (glyphWidth - 1 - FontBitmap::outlineWidth) * mScale;
    }

    return width;
}

void TextRenderer::drawString(const Program& program, const float* texMatrix,
        float x, float y, const String8& str8) const {
    ALOGV("drawString %.3f,%.3f '%s' (scale=%.3f)", x, y, str8.string(),mScale);
    initOnce();

    // We want to draw the entire string with a single GLES call.  We
    // generate two arrays, one with screen coordinates, one with texture
    // coordinates.  Need two triangles per character.
    const char* str = str8.string();
    size_t len = strlen(str);       // again, unsure about String8 handling

    const size_t quadCoords =
            2 /*triangles*/ * 3 /*vertex/tri*/ * 2 /*coord/vertex*/;
    float vertices[len * quadCoords];
    float texes[len * quadCoords];

    float fullTexWidth = FontBitmap::width;
    float fullTexHeight = powerOfTwoCeil(FontBitmap::height);
    for (size_t i = 0; i < len; i++) {
        size_t chi = glyphIndex(str[i]);
        float glyphWidth = FontBitmap::glyphWidth[chi];
        float glyphHeight = FontBitmap::maxGlyphHeight;

        float vertLeft = x;
        float vertRight = x + glyphWidth * mScale;
        float vertTop = y;
        float vertBottom = y + glyphHeight * mScale;

        // Lowest-numbered glyph is in top-left of bitmap, which puts it at
        // the bottom-left in texture coordinates.
        float texLeft = mXOffset[chi] / fullTexWidth;
        float texRight = (mXOffset[chi] + glyphWidth) / fullTexWidth;
        float texTop = FontBitmap::yoffset[chi] / fullTexHeight;
        float texBottom = (FontBitmap::yoffset[chi] + glyphHeight) /
                fullTexHeight;

        size_t off = i * quadCoords;
        vertices[off +  0] = vertLeft;
        vertices[off +  1] = vertBottom;
        vertices[off +  2] = vertRight;
        vertices[off +  3] = vertBottom;
        vertices[off +  4] = vertLeft;
        vertices[off +  5] = vertTop;
        vertices[off +  6] = vertLeft;
        vertices[off +  7] = vertTop;
        vertices[off +  8] = vertRight;
        vertices[off +  9] = vertBottom;
        vertices[off + 10] = vertRight;
        vertices[off + 11] = vertTop;
        texes[off +  0] = texLeft;
        texes[off +  1] = texBottom;
        texes[off +  2] = texRight;
        texes[off +  3] = texBottom;
        texes[off +  4] = texLeft;
        texes[off +  5] = texTop;
        texes[off +  6] = texLeft;
        texes[off +  7] = texTop;
        texes[off +  8] = texRight;
        texes[off +  9] = texBottom;
        texes[off + 10] = texRight;
        texes[off + 11] = texTop;

        // We added 1-pixel padding in the texture, so we want to advance by
        // one less.  Also, each glyph is surrounded by a black outline, which
        // we want to merge.
        x += (glyphWidth - 1 - FontBitmap::outlineWidth) * mScale;
    }

    program.drawTriangles(mTextureName, texMatrix, vertices, texes,
            len * quadCoords / 2);
}

float TextRenderer::drawWrappedString(const Program& texRender,
        float xpos, float ypos, const String8& str) {
    ALOGV("drawWrappedString %.3f,%.3f '%s'", xpos, ypos, str.string());
    initOnce();

    if (mScreenWidth == 0 || mScreenHeight == 0) {
        ALOGW("drawWrappedString: can't wrap with width=%d height=%d",
                mScreenWidth, mScreenHeight);
        return ypos;
    }

    const float indentWidth = mIndentMult * getScale();
    if (xpos < mBorderWidth) {
        xpos = mBorderWidth;
    }
    if (ypos < mBorderWidth) {
        ypos = mBorderWidth;
    }

    const size_t maxWidth = (mScreenWidth - mBorderWidth) - xpos;
    if (maxWidth < 1) {
        ALOGE("Unable to render text: xpos=%.3f border=%.3f width=%u",
                xpos, mBorderWidth, mScreenWidth);
        return ypos;
    }
    float stringWidth = computeScaledStringWidth(str);
    if (stringWidth <= maxWidth) {
        // Trivial case.
        drawString(texRender, Program::kIdentity, xpos, ypos, str);
        ypos += getScaledGlyphHeight();
    } else {
        // We need to break the string into pieces, ideally at whitespace
        // boundaries.
        char* mangle = strdup(str.string());
        char* start = mangle;
        while (start != NULL) {
            float xposAdj = (start == mangle) ? xpos : xpos + indentWidth;
            char* brk = breakString(start,
                    (float) (mScreenWidth - mBorderWidth - xposAdj));
            if (brk == NULL) {
                // draw full string
                drawString(texRender, Program::kIdentity, xposAdj, ypos,
                        String8(start));
                start = NULL;
            } else {
                // draw partial string
                char ch = *brk;
                *brk = '\0';
                drawString(texRender, Program::kIdentity, xposAdj, ypos,
                        String8(start));
                *brk = ch;
                start = brk;
                if (strchr(kWhitespace, ch) != NULL) {
                    // if we broke on whitespace, skip past it
                    start++;
                }
            }
            ypos += getScaledGlyphHeight();
        }
        free(mangle);
    }

    return ypos;
}

char* TextRenderer::breakString(const char* str, float maxWidth) const {
    // Ideally we'd do clever things like binary search.  Not bothering.
    ALOGV("breakString '%s' %.3f", str, maxWidth);

    size_t len = strlen(str);
    if (len == 0) {
        // Caller should detect this and not advance ypos.
        return NULL;
    }

    float stringWidth = computeScaledStringWidth(str, len);
    if (stringWidth <= maxWidth) {
        return NULL;        // trivial -- use full string
    }

    // Find the longest string that will fit.
    size_t goodPos = 0;
    for (size_t i = 0; i < len; i++) {
        stringWidth = computeScaledStringWidth(str, i);
        if (stringWidth < maxWidth) {
            goodPos = i;
        } else {
            break;  // too big
        }
    }
    if (goodPos == 0) {
        // space is too small to hold any glyph; output a single char
        ALOGW("Couldn't find a nonzero prefix that fit from '%s'", str);
        goodPos = 1;
    }

    // Scan back for whitespace.  If we can't find any we'll just have
    // an ugly mid-word break.
    for (size_t i = goodPos; i > 0; i--) {
        if (strchr(kWhitespace, str[i]) != NULL) {
            goodPos = i;
            break;
        }
    }

    ALOGV("goodPos=%zu for str='%s'", goodPos, str);
    return const_cast<char*>(str + goodPos);
}
