package com.app.wave.keyboard.kbhelper;


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.inputmethod.EditorInfo;

import androidx.core.graphics.drawable.DrawableCompat;

import com.app.wave.keyboard.App;
import com.app.wave.keyboard.R;
import com.app.wave.keyboard.sourcecode.KBCode;
import com.app.wave.keyboard.sourcecode.KBCodeView;
import com.app.wave.keyboard.utils.MyKeyName;
import com.app.wave.keyboard.utils.KBManager;

import java.util.ArrayList;
import java.util.List;


public class KBView extends KBCodeView {

    private Paint mPaint;
    private Context mContext;

    private float mRation = 0.5f;


    //0 小写 1 大写 2 大写锁定
    private int isLowerCase = 0;
    //0 默认键盘 1 字母键盘 2 符号键盘
    private int mMode = 0;

    private KBManager KBManager;
    private int curImeAction = EditorInfo.IME_ACTION_UNSPECIFIED;

    public KBView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        setAttribute(attrs, context);
    }

    public KBView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        setAttribute(attrs, context);
    }

    public KBView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mContext = context;
        setAttribute(attrs, context);
    }


    public void setMode(int mType) {
        this.mMode = mType;
    }

    public int getMode() {
        return mMode;
    }

    public int isLowerCase() {
        return isLowerCase;
    }

    public void setLowerCase(int lowerCase) {
        isLowerCase = lowerCase;
    }

    public void updateUi(int ime) {
        Log.d(App.TAG, "----------ime=" + ime);
        curImeAction = ime;
        KBManager.updateSkinConfig();
        invalidate();
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setTextAlign(Paint.Align.CENTER);

    }

    private void setAttribute(AttributeSet attrs, Context con) {
        KBManager = new KBManager(con);
        initPaint();
        TypedArray mTypedArray = con.obtainStyledAttributes(attrs, R.styleable.CustomInputView);

//        int color = mTypedArray.getColor(R.styleable.CustomInputView_text_color_done, 1);
//
//        Drawable drawable = mTypedArray.getDrawable(R.styleable.CustomInputView_drawable_cancel);
//
//        int textSize = mTypedArray.getInt(R.styleable.CustomInputView_text_size_key, 12);

        mTypedArray.recycle();
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);


        RespConfig config = KBManager.getConfig();
        List<KBModel> KBModels = new ArrayList<>();
        int i = 0;

        for (KBCode.Key curKey : getKeyboard().getKeys()) {
            int code = curKey.codes[0];
            if (config != null&& !config.getLayouts().isEmpty()) {
                if (code == 113 ||code == 81 || code == 49||code == 91) {
                    i = 0;
                    RespLayout respLayout = config.getLayouts().get(0);
                    KBModels = respLayout.getKeys();
                } else if (code == 97||code == 65 || code == 33||code == 126) {
                    i = 0;
                    RespLayout respLayout = config.getLayouts().get(1);
                    KBModels = respLayout.getKeys();
                }else if (code == -1 || code == -103||code==-101) {
                    i = 0;
                    RespLayout respLayout = config.getLayouts().get(2);
                    KBModels = respLayout.getKeys();
                }else if (code == -2 || code == -102) {
                    i = 0;
                    RespLayout respLayout = config.getLayouts().get(3);
                    KBModels = respLayout.getKeys();
                }
                String background = KBModels.get(i).getBackground()+".9.png";
                i++;
                Drawable configBg = KBManager.getConfigBg(background);
                realNewDraw(configBg, curKey, canvas, code);

            } else {
                realDraw(curKey, canvas, code);
            }

        }

    }


    private void realNewDraw(Drawable configBg, KBCode.Key curKey, Canvas canvas, int code) {
        switch (code) {
            case MyKeyName.KEY_CODE_SHIFT:
//                drawAllShift(curKey, canvas);
                onDrawCurKey(curKey, canvas, "Shift", configBg, null);
                break;
            case MyKeyName.KEY_CODE_NUMBER_SHIFT:
                onDrawCurKey(curKey, canvas, "More", configBg, null);
                break;
            case MyKeyName.KEY_CODE_DELETE:
                onDrawCurKey(curKey, canvas, "Delete", configBg, null);
                break;
            case MyKeyName.KEY_CODE_SYMBOL_SHIFT:
                onDrawCurKey(curKey, canvas, "123", configBg, null);
                break;
            case MyKeyName.KEY_CODE_CHANGE_NUMBER:
                onDrawCurKey(curKey, canvas, null, configBg, null);
                break;
            case MyKeyName.KEY_CODE_BACK:
                onDrawCurKey(curKey, canvas, "Back", configBg, null);
                break;
            case MyKeyName.KEY_CODE_SPACE:
                onDrawCurKey(curKey, canvas, null, configBg, null);
                break;
            case MyKeyName.KEY_CODE_COMPLETE, MyKeyName.KEY_CODE_CANCEL:
                Log.d(App.TAG, "-11111111111---------curImeAction=" + curImeAction);
                if (curImeAction == EditorInfo.IME_ACTION_SEARCH) {
                    onDrawCurKey(curKey, canvas, "Search", configBg, null);
                } else {
                    onDrawCurKey(curKey, canvas, "Done", configBg, null);
                }
                break;
            default:

                onDrawCurKey(curKey, canvas, null, configBg, null);
                break;


        }
    }

    private void realDraw(KBCode.Key curKey, Canvas canvas, int code) {
        switch (code) {
            case MyKeyName.KEY_CODE_SHIFT:
                drawAllShift(curKey, canvas);
                break;
            case MyKeyName.KEY_CODE_NUMBER_SHIFT:
                onDrawCurKey(curKey, canvas, "More", KBManager.getFunctionDraw(), null);
                break;
            case MyKeyName.KEY_CODE_DELETE:
                onDrawCurKey(curKey, canvas, "Delete", KBManager.getFunctionDraw(), null);
                break;
            case MyKeyName.KEY_CODE_SYMBOL_SHIFT:
                onDrawCurKey(curKey, canvas, "123", KBManager.getFunctionDraw(), null);
                break;
            case MyKeyName.KEY_CODE_CHANGE_NUMBER:
                onDrawCurKey(curKey, canvas, null, KBManager.getToDraw(), null);
                break;
            case MyKeyName.KEY_CODE_BACK:
                onDrawCurKey(curKey, canvas, "Back", KBManager.getToDraw(), null);
                break;
            case MyKeyName.KEY_CODE_SPACE:
                onDrawCurKey(curKey, canvas, null, KBManager.getSpaceDraw(), null);
                break;
            case MyKeyName.KEY_CODE_COMPLETE, MyKeyName.KEY_CODE_CANCEL:
                Log.d(App.TAG, "-11111111111---------curImeAction=" + curImeAction);
                if (curImeAction == EditorInfo.IME_ACTION_SEARCH) {
                    onDrawCurKey(curKey, canvas, "Search", KBManager.getFunctionDraw(), null);
                } else {
                    onDrawCurKey(curKey, canvas, "Done", KBManager.getFunctionDraw(), null);
                }
                break;
            default:

                onDrawCurKey(curKey, canvas, null, KBManager.getGeneralDraw(), null);
                break;


        }
    }

    private void drawAllShift(KBCode.Key curKey, Canvas canvas) {
        if (isLowerCase == 0) {
            onDrawCurKey(curKey, canvas, "Shift", KBManager.getFunctionDraw(), null);
        } else if (isLowerCase == 1) {
            onDrawCurKey(curKey, canvas, "Shift", KBManager.getFunctionDraw(), null);
        } else if (isLowerCase == 2) {
            onDrawCurKey(curKey, canvas, "Shift", KBManager.getFunctionDraw(), null);
        }
    }

    private void onDrawCurKey(KBCode.Key curKey, Canvas curCanvas, String label, Drawable bgDrawable, Drawable iconDraw) {

        if (bgDrawable != null) {
            onDrawKeyBackground(curKey, curCanvas, bgDrawable);
        }
        if (iconDraw != null) {
            onDrawKeyIcon(curKey, curCanvas, iconDraw);
        }
        onDrawKeyText(curKey, curCanvas, label);
    }

    private void onDrawKeyText(KBCode.Key curKey, Canvas curCanvas, String label) {
        mPaint.setColor(KBManager.getKeyTextColor());
        mPaint.setTextSize(mContext.getResources().getDimension(R.dimen.text_size));
        float v = curKey.width / 2f;
        float v1 = curKey.height / 2f;
        float v2 = (mPaint.getTextSize() - mPaint.descent()) / 2f;


        if (curKey.label != null) {
            curCanvas.drawText((String) curKey.label, curKey.x + getPaddingLeft() + v, curKey.y + getPaddingRight() + v1 + v2, mPaint);
        } else if (label != null) {
            curCanvas.drawText(label, curKey.x + getPaddingLeft() + v, curKey.y + getPaddingRight() + v1 + v2, mPaint);
        }


    }

    private void onDrawKeyBackground(KBCode.Key curKey, Canvas curCanvas, Drawable curDrawable) {
        if (curKey.codes[0] != 0) {
            curDrawable.setState(curKey.getCurrentDrawableState());
        }
        Rect rect = new Rect((curKey.x + this.getPaddingLeft()), (curKey.y + this.getPaddingTop()), (curKey.x + this.getPaddingLeft() + curKey.width), (curKey.y + this.getPaddingTop() + curKey.height));
        curDrawable.setBounds(rect);

        curDrawable.draw(curCanvas);


    }

    private void onDrawKeyIcon(KBCode.Key curKey, Canvas curCanvas, Drawable curDrawable) {

        Drawable wrap = DrawableCompat.wrap(curDrawable);

        curKey.icon = curDrawable;
        float iconW = (float) curKey.icon.getIntrinsicWidth();
        float iconH = (float) curKey.icon.getIntrinsicHeight();

        float wDivRation = iconW / curKey.width;
        float hDivRation = iconH / curKey.height;

        curKey.icon.draw(curCanvas);

        if (wDivRation > hDivRation) {
            float minRatio = 0;
            if (wDivRation <= mRation) {
                minRatio = wDivRation;
            } else {
                minRatio = mRation;
            }
            iconH = (iconH / wDivRation) * minRatio;
            iconW = (iconW / wDivRation) * minRatio;
        } else {
            float minRatio = 0;
            if (hDivRation <= mRation) {
                minRatio = hDivRation;
            } else {
                minRatio = mRation;
            }
            iconH = (iconH / hDivRation) * minRatio;
            iconW = (iconW / hDivRation) * minRatio;
        }
        float subW = (curKey.width - iconW) / 2f;
        float subH = (curKey.height - iconH) / 2f;
        int xLeft = (int) (curKey.x + getPaddingLeft() + subW);
        int yTop = (int) (curKey.y + getPaddingTop() + subH);
        int xRight = (int) (xLeft + iconW);
        int yBottom = (int) (yTop + iconH);
        curKey.icon.setBounds(xLeft, yTop, xRight, yBottom);
        curKey.icon.draw(curCanvas);


    }

}
