package com.rn_bxl;

import com.bixolon.BixolonConst;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableNativeArray;

import com.bixolon.mpos.MPosControllerPrinter;
import com.bixolon.mpos.print.FontAttribute;

import java.io.File;
import java.nio.charset.StandardCharsets;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;

import android.util.Log;




public class MPosControllerPrinterProxy extends ReactContextBaseJavaModule {

    private String TAG = MPosControllerPrinterProxy.class.getSimpleName();
    private MPosControllerPrinter mPosControllerPrinter;

    public MPosControllerPrinterProxy(ReactApplicationContext reactContext) {
        super(reactContext);
        mPosControllerPrinter = new MPosControllerPrinter();
    }

    @Override
    public String getName() {
        return "MPosControllerPrinterProxy";
    }

    @ReactMethod
    protected void selectInterface(int interfaceType, String address, Promise promise){
        long ret = -1;
        try{
            ret = mPosControllerPrinter.selectInterface(interfaceType,address);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void selectCommandMode(int commandMode, Promise promise){
        long ret = -1;
        try{
            ret = mPosControllerPrinter.selectCommandMode(commandMode);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void openService(int deviceID, int timeout, Promise promise){
        long ret = -1;
        try{
            ret = mPosControllerPrinter.openService(deviceID, timeout, getReactApplicationContext());
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void closeService(int timeout, Promise promise){
        long ret = -1;
        try{
            ret = mPosControllerPrinter.closeService(timeout);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void isOpen(Promise promise){
        try{
            boolean ret = mPosControllerPrinter.isOpen();
            if(ret == true){
                promise.resolve(1);
            }else{
                promise.resolve(0);
            }
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }


    @ReactMethod
    protected void getDeviceId(Promise promise){
        try{
            long ret = mPosControllerPrinter.getDeviceId();
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void directIO(ReadableArray data, Promise promise) {
        try{
            byte[] bytes = new byte[data.size()];

            for (int i = 0; i < data.size(); i ++) {
                bytes[i] = (byte) data.getInt(i);
            }
            
            long ret = mPosControllerPrinter.directIO(bytes);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void setTransaction(int mode,Promise promise){
        try{
            //0 == success
            long ret = mPosControllerPrinter.setTransaction(mode);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void setReadMode(int control,Promise promise){
        try{
            //0 == success
            long ret = mPosControllerPrinter.setReadMode(control);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void setKeepNetworkConnection(int enable,Promise promise){
        try{
            //currently, there's no matched method existed.
            promise.resolve(-1);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }
    

    @ReactMethod
    protected void setCharacterset(int codePage,Promise promise){
        try{
            //0 == success
            long ret = mPosControllerPrinter.setCharacterset(codePage);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod 
    protected void setInternationalCharacterSet(int internationalCharset,Promise promise){
        try{
            //0 == success
            long ret = mPosControllerPrinter.setInternationalCharacterset(internationalCharset);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void cutPaper(int cutType,Promise promise){
        try{
            //0 == success
            long ret = mPosControllerPrinter.cutPaper(cutType);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void setPagemode(int mode,Promise promise){
        try{
            //0 == success
            long ret = mPosControllerPrinter.setPageMode(mode);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void setPagemodePrintArea(int x,int y,int width,int height,Promise promise){
        try{
            //0 == success
            long ret = mPosControllerPrinter.setPagemodePrintArea(x,y,width,height);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void setPagemodeDirection(int direction,Promise promise){
        try{
            //0 == success
            long ret = mPosControllerPrinter.setPagemodeDirection(direction);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }


    @ReactMethod
    protected void setPagemodePosition(int x,int y,Promise promise){
        try{
            //0 == success
            long ret = mPosControllerPrinter.setPagemodePosition(x,y);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }



    @ReactMethod
    protected void printText(String data, int fontType, int fontWidth, int fontHeight, int bold, int underline, int reverse, int alignment,Promise promise){
        try{
            FontAttribute attribute = new FontAttribute();
            attribute.setFontType(fontType);
            if(bold == 1){
                attribute.setBold(true);
            }
            attribute.setUnderline(underline);
            if(reverse == 1){
                attribute.setReverse(true);
            }
            attribute.setAlignment(alignment);
            String size = "0x" + Integer.toString(fontHeight) + Integer.toString(fontWidth);
            attribute.setFontSize(Integer.decode(size));
            long ret = mPosControllerPrinter.printText(data,attribute);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }
    
    @ReactMethod
    protected void printImageFile(String filename, int width,int alignment, int threshold,int ditheringType, int compressType,Promise promise){
        try{
            BitmapDrawable drawable = (BitmapDrawable) getReactApplicationContext().getResources().getDrawable(getReactApplicationContext().getResources().getIdentifier(filename,"drawable", getReactApplicationContext().getPackageName()));
            Bitmap bitmap = drawable.getBitmap();
            long ret=-1;
            if(ditheringType == 1 && compressType == 1){
                ret = mPosControllerPrinter.printBitmap(bitmap,width,alignment,threshold,true,true);
            }else if(ditheringType == 1 && compressType == 0){
                ret = mPosControllerPrinter.printBitmap(bitmap,width,alignment,threshold,true,false);
            }else if(ditheringType == 0 && compressType == 1){
                ret = mPosControllerPrinter.printBitmap(bitmap,width,alignment,threshold,false,true);
            }else if(ditheringType == 0 && compressType == 0){
                ret = mPosControllerPrinter.printBitmap(bitmap,width,alignment,threshold,false,false);
            }
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void printBase64Image(String base64String, int width,int alignment, int threshold,int ditheringType, int compressType,Promise promise){
        try{
            long ret = mPosControllerPrinter.printBase64Image(base64String,width,alignment,threshold,ditheringType,compressType,true);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void printPDFFile(Uri uri, int width,int alignment,int startPage,int endPage,int threshold,int ditheringType, int compressType,Promise promise){
        try{
            long ret = mPosControllerPrinter.printPDFFile(uri,width,alignment,startPage,endPage,threshold,ditheringType,compressType);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }
    
    @ReactMethod
    protected void print1DBarcode(String data, int symbology,int barWidth,int height,int alignment,int textPosition,Promise promise){
        try{
            long ret = mPosControllerPrinter.print1dBarcode(data,symbology,barWidth,height,alignment,textPosition);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }
 
    @ReactMethod
    protected void printQRCode(String data, int model,int alignment,int moduleSize,int eccLevel,Promise promise){
        try{
            long ret = mPosControllerPrinter.printQrCode(data,model,alignment,moduleSize,eccLevel);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }
    
    @ReactMethod
    protected void printPDF417(String data, int model,int alignment,int columnNumber,int rowNumber,int moduleWidth,int moduleHeight,int eccLevel,Promise promise){
        try{
            switch(eccLevel){
                case 0:
                    eccLevel = 0x30;
                    break;
                case 1:
                    eccLevel = 0x31;
                    break;
                case 2:
                    eccLevel = 0x32;
                    break;
                case 3:
                    eccLevel = 0x33;
                    break;
                case 4:
                    eccLevel = 0x34;
                    break;
                case 5:
                    eccLevel = 0x35;
                    break;
                case 6:
                    eccLevel = 0x36;
                    break;
                case 7:
                    eccLevel = 0x37;
                    break;
                case 8:
                    eccLevel = 0x38;
                    break;
            }
            long ret = mPosControllerPrinter.printPDF417(data,model,alignment,columnNumber,rowNumber,moduleWidth,moduleHeight,eccLevel);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void printDataMatrix(String data, int alignment,int moduleSize,Promise promise){
        try{
            long ret = mPosControllerPrinter.printDataMatrix(data,alignment,moduleSize);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void printLine(int x1, int y1, int x2, int y2, int thickness,Promise promise){
        try{
            long ret = mPosControllerPrinter.printLine(x1,y1,x2,y2,thickness);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void printBox(int left, int top, int right, int bottom, int thickness,Promise promise){
        try{
            long ret = mPosControllerPrinter.printBox(left,top,right,bottom,thickness);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }
    
    @ReactMethod
    protected void checkPrinterStatus(Promise promise){
        try{
            long ret = mPosControllerPrinter.checkPrinterStatus();
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void checkBattStatus(Promise promise){
        try{
            long ret = mPosControllerPrinter.checkBattStatus();
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void asbEnable(int enable,Promise promise){
        try{
            long ret;
            if(enable == 0){
                ret = mPosControllerPrinter.asbEnable(true);
            }else{
                ret = mPosControllerPrinter.asbEnable(false);
            }
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void openDrawer(int pinNumber,int onTimePulse,int offTimePulse,Promise promise){
        try{
            long ret =mPosControllerPrinter.openDrawer(pinNumber);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void getModelName(Promise promise){
        try{
            String ret = mPosControllerPrinter.getModelName();
            promise.resolve(ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    protected void getFirmwareVersion(Promise promise){
        try{
            String ret = mPosControllerPrinter.getFirmwareVersion();
            promise.resolve(ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

        @ReactMethod
    protected void getOccuredData(Promise promise){
        try{
            byte[] data = mPosControllerPrinter.getOccuredData();
            WritableArray rnRet = new WritableNativeArray();
            for(int i=0; i<data.length; i++){
                rnRet.pushInt((int)data[i]);
            }
            promise.resolve(rnRet);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }
}

