/*
 * Copyright (C) 2011 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.
 */

package com.android.bidi;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class BiDiTestView extends View {

    private static final String TAG = "BiDiTestView";

    private static final int BORDER_PADDING = 4;
    private static final int TEXT_PADDING = 16;
    private static final int TEXT_SIZE = 16;
    private static final int ORIGIN = 80;

    private static final float DEFAULT_ITALIC_SKEW_X = -0.25f;

    private Paint paint = new Paint();
    private Rect rect = new Rect();

    private String NORMAL_TEXT;
    private String NORMAL_LONG_TEXT;
    private String NORMAL_LONG_TEXT_2;
    private String NORMAL_LONG_TEXT_3;
    private String ITALIC_TEXT;
    private String BOLD_TEXT;
    private String BOLD_ITALIC_TEXT;
    private String ARABIC_TEXT;
    private String CHINESE_TEXT;
    private String MIXED_TEXT_1;
    private String HEBREW_TEXT;

    private Typeface typeface;

    private int currentTextSize;

    public BiDiTestView(Context context) {
        super(context);
        init(context);
    }

    public BiDiTestView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public BiDiTestView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context context) {
        NORMAL_TEXT = context.getString(R.string.normal_text);
        NORMAL_LONG_TEXT = context.getString(R.string.normal_long_text);
        NORMAL_LONG_TEXT_2 = context.getString(R.string.normal_long_text_2);
        NORMAL_LONG_TEXT_3 = context.getString(R.string.normal_long_text_3);
        ITALIC_TEXT = context.getString(R.string.italic_text);
        BOLD_TEXT = context.getString(R.string.bold_text);
        BOLD_ITALIC_TEXT = context.getString(R.string.bold_italic_text);
        ARABIC_TEXT = context.getString(R.string.arabic_text);
        CHINESE_TEXT = context.getString(R.string.chinese_text);
        MIXED_TEXT_1 = context.getString(R.string.mixed_text_1);
        HEBREW_TEXT = context.getString(R.string.hebrew_text);

        typeface = paint.getTypeface();
        paint.setAntiAlias(true);
    }

    public void setCurrentTextSize(int size) {
        currentTextSize = size;
        invalidate();
    }

    @Override
    public void onDraw(Canvas canvas) {
        drawInsideRect(canvas, Color.BLACK);

        int deltaX = 0;

        deltaX  = testString(canvas, NORMAL_TEXT, ORIGIN, ORIGIN,
                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);

        deltaX += testString(canvas, ITALIC_TEXT, ORIGIN + deltaX, ORIGIN,
                paint, typeface, true, false,  Paint.DIRECTION_LTR, currentTextSize);

        deltaX += testString(canvas, BOLD_TEXT, ORIGIN + deltaX, ORIGIN,
                paint, typeface, false, true,  Paint.DIRECTION_LTR, currentTextSize);

        deltaX += testString(canvas, BOLD_ITALIC_TEXT, ORIGIN + deltaX, ORIGIN,
                paint, typeface, true, true,  Paint.DIRECTION_LTR, currentTextSize);

        // Test with a long string
        deltaX = testString(canvas, NORMAL_LONG_TEXT, ORIGIN, ORIGIN + 2 * currentTextSize,
                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);

        // Test with a long string
        deltaX = testString(canvas, NORMAL_LONG_TEXT_2, ORIGIN, ORIGIN + 4 * currentTextSize,
                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);

        // Test with a long string
        deltaX = testString(canvas, NORMAL_LONG_TEXT_3, ORIGIN, ORIGIN + 6 * currentTextSize,
                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);

        // Test Arabic ligature
        deltaX = testString(canvas, ARABIC_TEXT, ORIGIN, ORIGIN + 8 * currentTextSize,
                paint, typeface, false, false,  Paint.DIRECTION_RTL, currentTextSize);

        // Test Chinese
        deltaX = testString(canvas, CHINESE_TEXT, ORIGIN, ORIGIN + 10 * currentTextSize,
                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);

        // Test Mixed (English and Arabic)
        deltaX = testString(canvas, MIXED_TEXT_1, ORIGIN, ORIGIN + 12 * currentTextSize,
                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);

        // Test Hebrew
        deltaX = testString(canvas, HEBREW_TEXT, ORIGIN, ORIGIN + 14 * currentTextSize,
                paint, typeface, false, false,  Paint.DIRECTION_RTL, currentTextSize);
    }

    private int testString(Canvas canvas, String text, int x, int y, Paint paint, Typeface typeface,
            boolean isItalic, boolean isBold, int dir, int textSize) {
        paint.setTypeface(typeface);

        // Set paint properties
        boolean oldFakeBold = paint.isFakeBoldText();
        paint.setFakeBoldText(isBold);

        float oldTextSkewX = paint.getTextSkewX();
        if (isItalic) {
            paint.setTextSkewX(DEFAULT_ITALIC_SKEW_X);
        }

        Log.v(TAG, "START -- drawTextWithCanvasDrawText");
        drawTextWithCanvasDrawText(text, canvas, x, y, textSize, Color.WHITE, dir);
        Log.v(TAG, "END   -- drawTextWithCanvasDrawText");

        int length = text.length();
        float[] advances = new float[length];
        float textWidthHB = paint.getTextRunAdvances(text, 0, length, 0, length, dir, advances, 0);
        setPaintDir(paint, dir);
        float textWidthICU = paint.getTextRunAdvances(text, 0, length, 0, length, dir, advances, 0,
                1 /* use ICU */);

        logAdvances(text, textWidthHB, textWidthICU, advances);
        drawMetricsAroundText(canvas, x, y, textWidthHB, textWidthICU, textSize, Color.RED, Color.GREEN);

        paint.setColor(Color.WHITE);
//        char[] glyphs = new char[2*length];
//        int count = getGlyphs(text, glyphs, dir);
//
//        logGlypths(glyphs, count);
//        drawTextWithDrawGlyph(canvas, glyphs, count, x, y + currentTextSize);

        Log.v(TAG, "START -- drawTextWithGlyphs");
        drawTextWithGlyphs(canvas, text, x, y + currentTextSize, dir);
        Log.v(TAG, "END   -- drawTextWithGlyphs");

        // Restore old paint properties
        paint.setFakeBoldText(oldFakeBold);
        paint.setTextSkewX(oldTextSkewX);

        return (int) Math.ceil(textWidthHB) + TEXT_PADDING;
    }

    private void setPaintDir(Paint paint, int dir) {
        Log.v(TAG, "Setting Paint dir=" + dir);
        paint.setBidiFlags(dir);
    }

    private void drawTextWithDrawGlyph(Canvas canvas, char[] glyphs, int count, int x, int y) {
        canvas.drawGlyphs(glyphs, 0, count, x, y, paint);
    }

    private void drawTextWithGlyphs(Canvas canvas, String text, int x, int y, int dir) {
        setPaintDir(paint, dir);
        canvas.drawTextWithGlyphs(text, x, y, paint);
    }

    private void logGlypths(char[] glyphs, int count) {
        Log.v(TAG, "GlyphIds - count=" + count);
        for (int n = 0; n < count; n++) {
            Log.v(TAG, "GlyphIds - Id[" + n + "]="+ (int)glyphs[n]);
        }
    }

    private int getGlyphs(String text, char[] glyphs, int dir) {
        return paint.getTextGlypths(text, 0, text.length(), 0, text.length(), dir, glyphs);
    }

    private void drawInsideRect(Canvas canvas, int color) {
        paint.setColor(color);
        int width = getWidth();
        int height = getHeight();
        rect.set(BORDER_PADDING, BORDER_PADDING, width - BORDER_PADDING, height - BORDER_PADDING);
        canvas.drawRect(rect, paint);
    }

    private void drawTextWithCanvasDrawText(String text, Canvas canvas,
            float x, float y, float textSize, int color, int dir) {
        setPaintDir(paint, dir);
        paint.setColor(color);
        paint.setTextSize(textSize);
        canvas.drawText(text, x, y, paint);
    }

    private void drawMetricsAroundText(Canvas canvas, int x, int y, float textWidthHB,
            float textWidthICU, int textSize, int color, int colorICU) {
        paint.setColor(color);
        canvas.drawLine(x, y - textSize, x, y + 8, paint);
        canvas.drawLine(x, y + 8, x + textWidthHB, y + 8, paint);
        canvas.drawLine(x + textWidthHB, y - textSize, x + textWidthHB, y + 8, paint);
        paint.setColor(colorICU);
        canvas.drawLine(x + textWidthICU, y - textSize, x + textWidthICU, y + 8, paint);
    }

    private void logAdvances(String text, float textWidth, float textWidthICU, float[] advances) {
        Log.v(TAG, "Advances for text: " + text + " total= " + textWidth + " - totalICU= " + textWidthICU);
//        int length = advances.length;
//        for(int n=0; n<length; n++){
//            Log.v(TAG, "adv[" + n + "]=" + advances[n]);
//        }
    }
}
