package acquire.sdk.printer;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.RemoteException;
import android.view.Gravity;

import androidx.annotation.IntRange;
import androidx.annotation.NonNull;

import com.morefun.yapi.ServiceResult;
import com.morefun.yapi.device.printer.FontFamily;
import com.morefun.yapi.device.printer.MulPrintStrEntity;
import com.morefun.yapi.device.printer.MultipleAppPrinter;
import com.morefun.yapi.device.printer.OnPrintListener;
import com.morefun.yapi.device.printer.Printer;
import com.morefun.yapi.device.printer.PrinterConfig;

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

import acquire.sdk.DeviceHelper;

/**
 * Printer
 *
 * @author Janson
 * @date 2021/10/9 11:28
 */
public class BPrinter implements IPrinter {
    private MultipleAppPrinter multipleAppPrinter;
    private Printer mPrinter;

    private int grayLevel = 10;

    public BPrinter() {
        try {
            multipleAppPrinter = (MultipleAppPrinter) DeviceHelper.getMultipleAppPrinter();
            mPrinter = (Printer) DeviceHelper.getPrinter();
        } catch (Exception e) {
            multipleAppPrinter = null;
            mPrinter = null;
        }
    }


    /**
     * get the printer status
     *
     * @return OK = 0
     * ERR = -1
     * ERR_BUSY = 8
     * ERR_NOPAPER = 2
     * ERR_OVERHEAT = 4
     * ERR_VOLERR = 112
     * ERR_CUTERR = 512
     * ERR_PPSERR = 2048
     * ERR_IOCTL = -5
     * ERR_PARA = -6
     * ERR_PATH = -7
     * ERR_DECODE_IMAGE = -8
     * ERR_MACLLOC = -9
     * ERR_TIMEOUT = -10
     */
    public int getStatus() {
        try {
            int status = mPrinter.getStatus();
            return status;
        } catch (Exception e) {
            e.printStackTrace();
            return 0xff;
        }
    }

    public boolean outOfPaper(){
        try {
            int status = mPrinter.getStatus();
            return status == ServiceResult.Printer_PaperLack;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * get status description
     *
     * @param code printer status
     * @return status description
     */
    private String getResult(int code) {
        switch (code) {
            case ServiceResult.Success:
                return "Success";
            case ServiceResult.Printer_Print_Fail:
                return "Printer Fail";
            case ServiceResult.Printer_Busy:
                return "Busy";
            case ServiceResult.Printer_PaperLack:
                return "Paper Lack";
            default:
                return "Other Error";
        }
    }
    @Override
    public void print(@NonNull Bitmap receipt, final PrintCallback callback) {
        try {
            int fontSize = FontFamily.MIDDLE;
            List<MulPrintStrEntity> list = new ArrayList<>();
            Bundle config = new Bundle();
            config.putInt(PrinterConfig.COMMON_GRAYLEVEL, getGrayLevel());

            MulPrintStrEntity entity = new MulPrintStrEntity();
            entity.setFontsize(fontSize);
            entity.setBitmap(receipt);
            entity.setMarginX(50);
            entity.setGravity(Gravity.CENTER);
            entity.setUnderline(true);
            entity.setYspace(30);
            list.add(entity);

            DeviceHelper.getMultipleAppPrinter().printStr(list, new OnPrintListener.Stub() {
                @Override
                public void onPrintResult(int result) throws RemoteException {
                    if (result == ServiceResult.Success) {
                        callback.onFinish();
                    } else if (result == ServiceResult.Printer_PaperLack){
                        callback.onOutOfPaper();
                    } else {
                        callback.onError(getResult(result));
                    }
                }
            }, config);
        } catch (Exception e) {
            e.printStackTrace();
            if (callback != null) {
                callback.onError(e.getMessage());
            }
        }
    }

    @Override
    public void cutPaper(){
        try {
            mPrinter.cutPaper();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void setGray(@IntRange(from = 1,to = 10) int gray){
        grayLevel = gray;
    }

    private int getGrayLevel() {
        if (grayLevel > 6) {
            return PrinterConfig.PRINT_DENSITY_DENSE;
        } else if (grayLevel > 3) {
            return PrinterConfig.PRINT_DENSITY_NORMAL;
        } else {
            return PrinterConfig.PRINT_DENSITY_LIGHT;
        }
    }


}
