/*
 * Copyright (C) 2015-2023 Emanuel Moecklin
 *
 * 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.
 */

package com.onegravity.rteditor.spans;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Layout;
import android.text.Spanned;
import android.text.style.LeadingMarginSpan;

/**
 * Paragraph numbering.
 * <p>
 * Android seems to add the leading margin for an empty paragraph to the previous paragraph
 * (]0, 4][4, 4] --> the leading margin of the second span is added to the ]0, 4] paragraph regardless of the Spanned.flags)
 * --> therefore we ignore the leading margin for the last, empty paragraph unless it's the only one
 */
public class NumberSpan extends BaseListItemSpan implements LeadingMarginSpan, RTSpan<Boolean>, RTParagraphSpan<Boolean> {

    private final int mNr;
    private final int mGapWidth;
    private final boolean mIgnoreSpan;

    private float mWidth;

    public NumberSpan(int nr, int gapWidth, boolean isEmpty, boolean isFirst, boolean isLast) {
        mNr = nr;
        mGapWidth = gapWidth;
        mIgnoreSpan = isEmpty && isLast && !isFirst;
    }

    private NumberSpan(int nr, int gapWidth, boolean ignoreSpan) {
        mNr = nr;
        mGapWidth = gapWidth;
        mIgnoreSpan = ignoreSpan;
    }

    @Override
    public int getLeadingMargin(boolean first) {
        return mIgnoreSpan ? 0 : Math.max(Math.round(mWidth + 2), mGapWidth);
    }

    @Override
    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom,
                                  CharSequence text, int start, int end, boolean first, Layout l) {

        Spanned spanned = (Spanned) text;
        if (!mIgnoreSpan && spanned.getSpanStart(this) == start) {
            // set paint
            Paint.Style oldStyle = p.getStyle();
            float oldTextSize = p.getTextSize();
            p.setStyle(Paint.Style.FILL);
            float textSize = determineTextSize(spanned, start, end, oldTextSize);
            p.setTextSize(textSize);
            mWidth = p.measureText(mNr + ".");

            // draw the number
            c.drawText(mNr + ".", x, baseline, p);

            // restore paint
            p.setStyle(oldStyle);
            p.setTextSize(oldTextSize);
        }
    }

    @Override
    public Boolean getValue() {
        return Boolean.TRUE;
    }

    @Override
    public NumberSpan createClone() {
        return new NumberSpan(mNr, mGapWidth, mIgnoreSpan);
    }

}
