package com.key.vibekeyboard.inputmethod.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.util.AttributeSet;

import com.key.vibekeyboard.inputmethod.theme.KeyboardThemeManager;
import com.key.vibekeyboard.utils.DrawableUtils;

import java.util.List;

public class CustomKeyboardView extends KeyboardView {

    private final Paint mPaint;
    private final KeyboardThemeManager keyboardThemeManager;
    private ShiftState shiftState = ShiftState.NORMAL;

    private static final float TEXT_SIZE_NORMAL = 18f;
    private static final float TEXT_SIZE_LARGE = 20f;

    public CustomKeyboardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        keyboardThemeManager = new KeyboardThemeManager(context);
        mPaint = new Paint();
        mPaint.setTextSize(DrawableUtils.spToPx(TEXT_SIZE_LARGE, context));
        setPreviewEnabled(false);
    }

    @Override
    public void onDraw(Canvas canvas) {
        List<Keyboard.Key> keys = getKeyboard().getKeys();

        for (Keyboard.Key key : keys) {
            int keyCode = key.codes[0];
            setPaintColor(keyCode);

            Drawable keyBackground = getKeyBackgroundDrawable(keyCode);
            if (keyBackground != null) {
                drawKeyBackground(key, keyBackground, canvas);
            }

            switch (keyCode) {
                case Keyboard.KEYCODE_SHIFT:
                    DrawableUtils.drawKeyIcon(key, getShiftDrawable(), canvas, this);
                    break;

                case Keyboard.KEYCODE_DELETE:
                    DrawableUtils.drawKeyIcon(key, keyboardThemeManager.getDeleteIconDrawable(), canvas, this);
                    drawKeyLabel(key, canvas);
                    break;

                case Keyboard.KEYCODE_DONE:
                    DrawableUtils.drawKeyIcon(key, keyboardThemeManager.getReturnIconDrawable(), canvas, this);
                    break;

                default:
                    drawKeyLabel(key, canvas);
                    break;
            }
        }

    }

    private void setPaintColor(int keyCode) {
        if (isActionKey(keyCode)) {
            mPaint.setColor(keyboardThemeManager.getActionKeyColor());
        } else {
            mPaint.setColor(keyboardThemeManager.getNormalKeyColor());
        }
    }

    private boolean isActionKey(int keyCode) {
        return keyCode == Keyboard.KEYCODE_SHIFT || keyCode == Keyboard.KEYCODE_DELETE ||
                keyCode == Keyboard.KEYCODE_MODE_CHANGE || keyCode == Keyboard.KEYCODE_DONE
                || keyCode == -1000 || keyCode == 32;
    }

    private Drawable getKeyBackgroundDrawable(int keyCode) {
        if (isActionKey(keyCode)) {
            return keyboardThemeManager.getActionBackgroundDrawable();
        } else {
            return keyboardThemeManager.getNormalBackgroundDrawable();
        }
    }

    private Drawable getShiftDrawable() {
        if (shiftState == ShiftState.NORMAL) {
            return keyboardThemeManager.getShiftIconDrawable();
        } else if (shiftState == ShiftState.CAPS) {
            return keyboardThemeManager.getShiftLockIconDrawable();
        }
        return null;
    }

    private void drawKeyBackground(Keyboard.Key key, Drawable keyBackground, Canvas canvas) {
        if (keyBackground != null) {
            int left = key.x + getPaddingLeft();
            int top = key.y + getPaddingTop();
            int right = left + key.width;
            int bottom = top + key.height;

            keyBackground.setBounds(left, top, right, bottom);
            keyBackground.setState(key.getCurrentDrawableState());
            keyBackground.draw(canvas);
        }
    }

    private void drawKeyLabel(Keyboard.Key key, Canvas canvas) {
        if (key.label != null && !key.label.toString().isEmpty()) {
            float xPos = key.x + getPaddingLeft() + (key.width / 2f);
            float yPos = key.y + key.height / 2f - (mPaint.descent() + mPaint.ascent()) / 2f;
            xPos -= mPaint.measureText(key.label.toString()) / 2f;

            mPaint.setTextSize(DrawableUtils.spToPx(TEXT_SIZE_NORMAL, this.getContext()));
            canvas.drawText(key.label.toString(), xPos, yPos, mPaint);
        }
    }

    public void updateKeyboardView(Context context) {
        keyboardThemeManager.updateBackground(context);
        setBackground(keyboardThemeManager.getBackgroundDrawable());
        invalidateAllKeys();
    }

    public enum ShiftState {
        NORMAL, CAPS
    }

    public void setShiftState(ShiftState state) {
        this.shiftState = state;
    }
}

