package com.fastaccess.provider.timeline.handler;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.SpannableStringBuilder;
import android.text.style.ReplacementSpan;

import net.nightwhistler.htmlspanner.handlers.PreHandler;

import org.htmlcleaner.ContentNode;
import org.htmlcleaner.TagNode;

import lombok.AllArgsConstructor;

import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;

/**
 * Created by Kosh on 22 Apr 2017, 1:07 PM
 */

@AllArgsConstructor public class PreTagHandler extends PreHandler {

    @ColorInt private final int color;
    private final boolean isPre;
    private boolean isDark;

    private void getPlainText(StringBuffer buffer, Object node) {
        if (node instanceof ContentNode) {
            ContentNode contentNode = (ContentNode) node;
            String text = contentNode.getContent().toString();
            buffer.append(text);
        } else if (node instanceof TagNode) {
            TagNode tagNode = (TagNode) node;
            for (Object child : tagNode.getChildren()) {
                this.getPlainText(buffer, child);
            }
        }
    }

    private String replace(String text) {
        return text.replaceAll("&nbsp;", "\u00A0")
                .replaceAll("&amp;", "&")
                .replaceAll("&quot;", "\"")
                .replaceAll("&cent;", "¢")
                .replaceAll("&lt;", "<")
                .replaceAll("&gt;", ">")
                .replaceAll("&sect;", "§")
                .replaceAll("&ldquo;", "“")
                .replaceAll("&rdquo;", "”")
                .replaceAll("&lsquo;", "‘")
                .replaceAll("&rsquo;", "’")
                .replaceAll("&ndash;", "\u2013")
                .replaceAll("&mdash;", "\u2014")
                .replaceAll("&horbar;", "\u2015");
    }

    @Override public void handleTagNode(TagNode node, SpannableStringBuilder builder, int start, int end) {
        if (isPre) {
            StringBuffer buffer = new StringBuffer();
            buffer.append("\n");//fake padding top + make sure, pre is always by itself
            getPlainText(buffer, node);
            buffer.append("\n");//fake padding bottom + make sure, pre is always by itself
            builder.append(replace(buffer.toString()));
            builder.append("\n");
            builder.setSpan(new CodeBackgroundRoundedSpan(color), start, builder.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
            builder.append("\n");
            this.appendNewLine(builder);
            this.appendNewLine(builder);
        } else {
            StringBuffer text = node.getText();
            builder.append("  ");
            builder.append(replace(text.toString()));
            builder.append("  ");
            builder.setSpan(new CodeBackground(color, isDark), start + 1, builder.length() - 1, SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }

    private static class CodeBackground extends ReplacementSpan {
        private int color;
        private boolean isDark;

        CodeBackground(int color, boolean isDark) {
            this.color = color;
            this.isDark = isDark;
        }

        @Override public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
            return (int) paint.measureText(text, start, end);
        }

        @Override public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end,
                                   float x, int top, int y, int bottom, @NonNull Paint paint) {
            int tempColor = paint.getColor();
            RectF rectF = new RectF(x, top, x + paint.measureText(text, start, end), bottom);
            paint.setColor(color);
            canvas.drawRoundRect(rectF, 5, 5, paint);
            paint.setColor(isDark ? tempColor : Color.RED);
            canvas.drawText(text, start, end, x, y, paint);
        }
    }
}
