/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkTextBox.h"
#include "SkUtils.h"

static inline int is_ws(int c)
{
    return !((c - 1) >> 5);
}

static size_t linebreak(const char text[], const char stop[],
                        const SkPaint& paint, SkScalar margin,
                        size_t* trailing = NULL)
{
    size_t lengthBreak = paint.breakText(text, stop - text, margin);

    //Check for white space or line breakers before the lengthBreak
    const char* start = text;
    const char* word_start = text;
    int prevWS = true;
    if (trailing) {
        *trailing = 0;
    }

    while (text < stop) {
        const char* prevText = text;
        SkUnichar uni = SkUTF8_NextUnichar(&text);
        int currWS = is_ws(uni);

        if (!currWS && prevWS) {
            word_start = prevText;
        }
        prevWS = currWS;

        if (text > start + lengthBreak) {
            if (currWS) {
                // eat the rest of the whitespace
                while (text < stop && is_ws(SkUTF8_ToUnichar(text))) {
                    text += SkUTF8_CountUTF8Bytes(text);
                }
                if (trailing) {
                    *trailing = text - prevText;
                }
            } else {
                // backup until a whitespace (or 1 char)
                if (word_start == start) {
                    if (prevText > start) {
                        text = prevText;
                    }
                } else {
                    text = word_start;
                }
            }
            break;
        }

        if ('\n' == uni) {
            size_t ret = text - start;
            size_t lineBreakSize = 1;
            if (text < stop) {
                uni = SkUTF8_NextUnichar(&text);
                if ('\r' == uni) {
                    ret = text - start;
                    ++lineBreakSize;
                }
            }
            if (trailing) {
                *trailing = lineBreakSize;
            }
            return ret;
        }

        if ('\r' == uni) {
            size_t ret = text - start;
            size_t lineBreakSize = 1;
            if (text < stop) {
                uni = SkUTF8_NextUnichar(&text);
                if ('\n' == uni) {
                    ret = text - start;
                    ++lineBreakSize;
                }
            }
            if (trailing) {
                *trailing = lineBreakSize;
            }
            return ret;
        }
    }

    return text - start;
}

int SkTextLineBreaker::CountLines(const char text[], size_t len, const SkPaint& paint, SkScalar width)
{
    const char* stop = text + len;
    int         count = 0;

    if (width > 0)
    {
        do {
            count += 1;
            text += linebreak(text, stop, paint, width);
        } while (text < stop);
    }
    return count;
}

//////////////////////////////////////////////////////////////////////////////

SkTextBox::SkTextBox()
{
    fBox.setEmpty();
    fSpacingMul = SK_Scalar1;
    fSpacingAdd = 0;
    fMode = kLineBreak_Mode;
    fSpacingAlign = kStart_SpacingAlign;
}

void SkTextBox::setMode(Mode mode)
{
    SkASSERT((unsigned)mode < kModeCount);
    fMode = SkToU8(mode);
}

void SkTextBox::setSpacingAlign(SpacingAlign align)
{
    SkASSERT((unsigned)align < kSpacingAlignCount);
    fSpacingAlign = SkToU8(align);
}

void SkTextBox::getBox(SkRect* box) const
{
    if (box)
        *box = fBox;
}

void SkTextBox::setBox(const SkRect& box)
{
    fBox = box;
}

void SkTextBox::setBox(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
{
    fBox.set(left, top, right, bottom);
}

void SkTextBox::getSpacing(SkScalar* mul, SkScalar* add) const
{
    if (mul)
        *mul = fSpacingMul;
    if (add)
        *add = fSpacingAdd;
}

void SkTextBox::setSpacing(SkScalar mul, SkScalar add)
{
    fSpacingMul = mul;
    fSpacingAdd = add;
}

/////////////////////////////////////////////////////////////////////////////////////////////

SkScalar SkTextBox::visit(Visitor& visitor, const char text[], size_t len,
                          const SkPaint& paint) const {
    SkScalar marginWidth = fBox.width();

    if (marginWidth <= 0 || len == 0) {
        return fBox.top();
    }

    const char* textStop = text + len;

    SkScalar                x, y, scaledSpacing, height, fontHeight;
    SkPaint::FontMetrics    metrics;

    switch (paint.getTextAlign()) {
    case SkPaint::kLeft_Align:
        x = 0;
        break;
    case SkPaint::kCenter_Align:
        x = SkScalarHalf(marginWidth);
        break;
    default:
        x = marginWidth;
        break;
    }
    x += fBox.fLeft;

    fontHeight = paint.getFontMetrics(&metrics);
    scaledSpacing = SkScalarMul(fontHeight, fSpacingMul) + fSpacingAdd;
    height = fBox.height();

    //  compute Y position for first line
    {
        SkScalar textHeight = fontHeight;

        if (fMode == kLineBreak_Mode && fSpacingAlign != kStart_SpacingAlign) {
            int count = SkTextLineBreaker::CountLines(text, textStop - text, paint, marginWidth);
            SkASSERT(count > 0);
            textHeight += scaledSpacing * (count - 1);
        }

        switch (fSpacingAlign) {
        case kStart_SpacingAlign:
            y = 0;
            break;
        case kCenter_SpacingAlign:
            y = SkScalarHalf(height - textHeight);
            break;
        default:
            SkASSERT(fSpacingAlign == kEnd_SpacingAlign);
            y = height - textHeight;
            break;
        }
        y += fBox.fTop - metrics.fAscent;
    }

    for (;;) {
        size_t trailing;
        len = linebreak(text, textStop, paint, marginWidth, &trailing);
        if (y + metrics.fDescent + metrics.fLeading > 0) {
            visitor(text, len - trailing, x, y, paint);
        }
        text += len;
        if (text >= textStop) {
            break;
        }
        y += scaledSpacing;
        if (y + metrics.fAscent >= fBox.fBottom) {
            break;
        }
    }
    return y + metrics.fDescent + metrics.fLeading;
}

///////////////////////////////////////////////////////////////////////////////

class CanvasVisitor : public SkTextBox::Visitor {
    SkCanvas* fCanvas;
public:
    CanvasVisitor(SkCanvas* canvas) : fCanvas(canvas) {}
    
    virtual void operator()(const char text[], size_t length, SkScalar x, SkScalar y,
                            const SkPaint& paint) override {
        fCanvas->drawText(text, length, x, y, paint);
    }
};

void SkTextBox::setText(const char text[], size_t len, const SkPaint& paint) {
    fText = text;
    fLen = len;
    fPaint = &paint;
}

void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPaint& paint) {
    CanvasVisitor sink(canvas);
    this->visit(sink, text, len, paint);
}

void SkTextBox::draw(SkCanvas* canvas) {
    this->draw(canvas, fText, fLen, *fPaint);
}

int SkTextBox::countLines() const {
    return SkTextLineBreaker::CountLines(fText, fLen, *fPaint, fBox.width());
}

SkScalar SkTextBox::getTextHeight() const {
    SkScalar spacing = SkScalarMul(fPaint->getTextSize(), fSpacingMul) + fSpacingAdd;
    return this->countLines() * spacing;
}

///////////////////////////////////////////////////////////////////////////////

#include "SkTextBlob.h"

class TextBlobVisitor : public SkTextBox::Visitor {
public:
    SkTextBlobBuilder fBuilder;
    
    virtual void operator()(const char text[], size_t length, SkScalar x, SkScalar y,
                            const SkPaint& paint) override {
        SkPaint p(paint);
        p.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
        const int count = paint.countText(text, length);
        paint.textToGlyphs(text, length, fBuilder.allocRun(p, count, x, y).glyphs);
    }
};

SkTextBlob* SkTextBox::snapshotTextBlob(SkScalar* computedBottom) const {
    TextBlobVisitor visitor;
    SkScalar newB = this->visit(visitor, fText, fLen, *fPaint);
    if (computedBottom) {
        *computedBottom = newB;
    }
    return (SkTextBlob*)visitor.fBuilder.build();
}

