package in.ashish29agre.passcode;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.text.InputFilter;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;

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

/**
 * Created by Ashish on 25/12/15.
 */
public class PasscodeView extends LinearLayout implements
        KeyCallback {

    private String TAG = PasscodeView.class.getSimpleName();

    private Drawable activeDrawable;
    private Drawable inActiveDrawable;
    private int textColor;
    private int drawableSize;
    private int passcodeItemMargin;

    private int passCodeCount;
    private List<View> passCodeViewsList;
    private int currentViewPos = 0;
    private StringBuilder passcodeItems;

    private PasscodeCallback passcodeCallback;

    public PasscodeView(Context context) {
        super(context);
        initDefaultConfig();
    }

    public PasscodeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initDefaultConfig();
    }

    public PasscodeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initDefaultConfig();
    }

    public PasscodeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initDefaultConfig();
    }

    private void initDefaultConfig() {
        setOrientation(HORIZONTAL);
        setGravity(Gravity.CENTER);
        passCodeViewsList = new ArrayList<>();
        activeDrawable = ContextCompat.getDrawable(getContext(), R.drawable.bg_active);
        inActiveDrawable = ContextCompat.getDrawable(getContext(), R.drawable.bg_in_active);
        textColor = android.R.color.transparent;
        drawableSize = 72;
        passcodeItemMargin = 8;
        passcodeItems = new StringBuilder();
    }


    public void setPassCodeCount(int passCodeCount) {
        this.passCodeCount = passCodeCount;
        invalidate();
    }

    public int getPassCodeCount() {
        return passCodeCount;
    }


    private void addPasscodeViews() {
        removeAllViews();
        removeAllViewsInLayout();
        if (passCodeCount < 0) {
            throw new IllegalStateException("Invalid PassCodeCount > 0 required");
        }
        for (int i = 0; i < this.passCodeCount; i++) {
            PasscodeEditText view = new PasscodeEditText(getContext());
            view.setGravity(Gravity.CENTER);
            view.setKeyCallback(this);
            view.setCursorVisible(false);
            view.setRawInputType(InputType.TYPE_CLASS_NUMBER);
            view.setInputType(InputType.TYPE_CLASS_NUMBER);
            view.setFilters(new InputFilter[]{new InputFilter.LengthFilter(1)});
            view.setTextColor(ContextCompat.getColor(getContext(), textColor));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                view.setBackground(inActiveDrawable);
            } else {
                view.setBackgroundDrawable(inActiveDrawable);
            }
            view.setLayoutParams(getPassCodeLayoutParams());
            addView(view, i);
            passCodeViewsList.add(view);
        }

    }

    private LayoutParams getPassCodeLayoutParams() {
        LayoutParams layoutParams = new LayoutParams(drawableSize, drawableSize);
        layoutParams.setMargins(passcodeItemMargin, passcodeItemMargin, passcodeItemMargin, passcodeItemMargin);
        return layoutParams;
    }


    public void setActiveDrawable(Drawable defaultActiveDrawable) {
        this.activeDrawable = defaultActiveDrawable;
        invalidate();
    }

    public Drawable getActiveDrawable() {
        return activeDrawable;
    }

    public void seInActiveDrawable(Drawable defaultInActiveDrawable) {
        this.inActiveDrawable = defaultInActiveDrawable;
        invalidate();
    }

    public Drawable getInActiveDrawable() {
        return inActiveDrawable;
    }


    public void setPasscodeItemMargin(int passcodeItemMargin) {
        this.passcodeItemMargin = passcodeItemMargin;
        invalidate();
    }


    public void setDrawableSize(int drawableSize) {
        this.drawableSize = drawableSize;
    }

    public int getDrawableSize() {
        return drawableSize;
    }

    public void setPasscodeCallback(PasscodeCallback passcodeCallback) {
        this.passcodeCallback = passcodeCallback;
    }

    public PasscodeCallback getPasscodeCallback() {
        return passcodeCallback;
    }

    @Override
    public void onPrevious() {
        if (currentViewPos == 0) {
            return;
        }
        passcodeItems.deleteCharAt(passcodeItems.length() - 1);
        --currentViewPos;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            passCodeViewsList.get(currentViewPos).setBackground(inActiveDrawable);
        } else {
            passCodeViewsList.get(currentViewPos).setBackgroundDrawable(inActiveDrawable);
        }

        if (currentViewPos >= 0) {
            passCodeViewsList.get(currentViewPos).requestFocus();
        }
    }

    @Override
    public void onNext(char value) {
        if (currentViewPos == this.passCodeCount) {
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            passCodeViewsList.get(currentViewPos).setBackground(activeDrawable);
        } else {
            passCodeViewsList.get(currentViewPos).setBackgroundDrawable(inActiveDrawable);
        }
        if (currentViewPos < this.passCodeCount) {
            passCodeViewsList.get(currentViewPos).requestFocus();
            passcodeItems.append(value);
            ++currentViewPos;
        }
        if (passcodeItems.length() == this.passCodeCount) {
            if (passcodeCallback != null) {
                passcodeCallback.onComplete(passcodeItems.toString());
            }
        }
    }

    @Override
    public void onDone() {
    }

    @Override
    public void onDelete() {
        onPrevious();
    }


    @Override
    protected void onDetachedFromWindow() {
        passCodeViewsList = null;
        activeDrawable = null;
        inActiveDrawable = null;
        super.onDetachedFromWindow();

    }

    public void hideSoftKeyboard() {
        InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getWindowToken(), 0);
    }
    public void clearAndShow() {
        addPasscodeViews();
    }

}