package com.example.mposonewrapper;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.common.pos.api.PosException;
import com.common.pos.api.printer.UsbThermalPrinter;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;

/**
 * This class echoes a string called from JavaScript.
 * https://cordova.apache.org/docs/en/latest/guide/platforms/android/plugin.html
 */
public class MpoSoneWrapper extends CordovaPlugin {

    private String printVersion;
    private final int PRINTER_STATUS_OK = 0;
    private final int PRINTER_STATUS_NO_PAPER = 0; //tbd
    private final int PRINTER_STATUS_OVER_HEAT = 0; //tbd
    private final int PRINTER_STATUS_OVER_FLOW = 0; //tbd
    private final int PRINTER_STATUS_UNKNOWN = 0; //tbd

    private String Result;
    public String printContent;
    public Context appContext;
    public CallbackContext publicCallbackContext;
    private Boolean noPaper = false;
    private Boolean lowBattery = false;
    UsbThermalPrinter mUsbThermalPrinter;

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        publicCallbackContext = callbackContext;
        if (action.equals("print")) {
            String message = args.getString(0);
            this.print(message, callbackContext);
            return true;
        }
        return false;
    }

    private void print(String message, CallbackContext callbackContext) {
        if (message != null && message.length() > 0) {
            printContent = message;
            // send to printer
            cordova.getThreadPool().execute(new Runnable() {
                public void run() {
                    try {
                        Result = null;
                        int printerStatus = mUsbThermalPrinter.checkStatus();
                        int wordGray = 3;
                        int wordFont = 2;
        
                        mUsbThermalPrinter.reset();
                        mUsbThermalPrinter.setAlgin(UsbThermalPrinter.ALGIN_LEFT);
                        //mUsbThermalPrinter.setLeftIndent(0);
                        mUsbThermalPrinter.setLineSpace(2);
                        mUsbThermalPrinter.setCharSpace(1);
                        mUsbThermalPrinter.setGray(wordGray); // 1-7
        
                        String lines[] = printContent.split("\\r?\\n");
        
                        for (String s: lines) { 
                            if (s.equals("FEED")) {
                                mUsbThermalPrinter.printString();
                                mUsbThermalPrinter.walkPaper(5);
                            } else if (s.equals("FEEDDOUBLE")) {
                                mUsbThermalPrinter.printString();
                                mUsbThermalPrinter.walkPaper(10);
                            } else if (s.equals("FEEDLITTLE")) {
                                mUsbThermalPrinter.printString();
                                mUsbThermalPrinter.walkPaper(3);
                            } else if (s.equals("LEFT")) {
                                mUsbThermalPrinter.setAlgin(UsbThermalPrinter.ALGIN_LEFT);
                            } else if (s.equals("MIDDLE")) {
                                mUsbThermalPrinter.setAlgin(UsbThermalPrinter.ALGIN_MIDDLE);
                            } else if (s.equals("RIGHT")) {
                                mUsbThermalPrinter.setAlgin(UsbThermalPrinter.ALGIN_RIGHT);
                            } else if (s.equals("BIG")) {
                                wordFont = 4;
                                mUsbThermalPrinter.setFontSize(2);
                                mUsbThermalPrinter.enlargeFontSize(2, 2);
                            } else if (s.equals("LARGE")) {
                                wordFont = 3;
                                mUsbThermalPrinter.setFontSize(1);
                                mUsbThermalPrinter.enlargeFontSize(2, 2);
                            } else if (s.equals("NORMAL")) {
                                wordFont = 2;
                                wordGray = 3;
                                //mUsbThermalPrinter.setGray(wordGray);
                                //mUsbThermalPrinter.setFontSize(2);
                                //mUsbThermalPrinter.enlargeFontSize(1, 1);

                                mUsbThermalPrinter.printString();
                                mUsbThermalPrinter.reset();
                                mUsbThermalPrinter.setLineSpace(2);
                                mUsbThermalPrinter.setCharSpace(1);
                                mUsbThermalPrinter.setGray(wordGray); // 1-7
                            } else if (s.equals("SMALL")) {
                                //back to NORMAL first
                                wordFont = 2;
                                wordGray = 3;
                                mUsbThermalPrinter.printString();
                                mUsbThermalPrinter.reset();
                                mUsbThermalPrinter.setLineSpace(2);
                                mUsbThermalPrinter.setCharSpace(1);
                                mUsbThermalPrinter.setGray(wordGray); // 1-7

                                // then SMALL
                                wordFont = 1;
                                mUsbThermalPrinter.setFontSize(1);
                                mUsbThermalPrinter.enlargeFontSize(1, 1);
                            } else if (s.equals("BOLD")) {
                                wordFont = 2;
                                wordGray = 7;
                                mUsbThermalPrinter.setGray(wordGray);
                                mUsbThermalPrinter.setFontSize(2);
                            } else if (s.equals("BOLDLARGE")) { // and LARGE
                                wordFont = 3;
                                wordGray = 7;
                                mUsbThermalPrinter.setGray(wordGray);
                                mUsbThermalPrinter.setFontSize(1);
                                mUsbThermalPrinter.enlargeFontSize(2, 2);
                            } else if (s.equals("LINE")) {
                                if (wordFont == 4) {
                                    s = "------------\n";
                                } else if (wordFont == 3) {
                                    s = "---------------------\n";
                                } else if (wordFont == 1) {
                                    s = "-------------------------------------\n";
                                } else {
                                    s = "-------------------------\n";
                                }
                                mUsbThermalPrinter.addString(s);
                            } else if (s.equals("HIGHLIGHTON")) {
                                mUsbThermalPrinter.setHighlight(true);
                            } else if (s.equals("HIGHLIGHTOFF")) {
                                mUsbThermalPrinter.setHighlight(false);
                            } else if (s.equals("LOGO")) {
                                //todo
                            } else {    
                                mUsbThermalPrinter.addString(s);        
                            }
                        }
        
                        mUsbThermalPrinter.printString();
                        mUsbThermalPrinter.walkPaper(10);
                        publicCallbackContext.success("{\"status\":\"success\",\"code\":\"OK\",\"description\":\"OK\"}");
                    } catch (Exception e) {
                        e.printStackTrace();
                        Result = e.toString();
                        if (Result.equals("com.common.pos.api.printer.NoPaperException")) {
                            noPaper = true;
                        } else if (Result.equals("com.common.pos.api.printer.DeviceNotOpenException")) {
                            publicCallbackContext.error("{\"status\":\"error\",\"code\":\"DEVICE_NOT_OPEN\",\"description\":\"Device not available. Reboot and try again.\"}");
                        } else if (Result.equals("com.common.pos.api.printer.DeviceOverFlowException")) {
                            publicCallbackContext.error("{\"status\":\"error\",\"code\":\"DEVICE_OVERFLOW\",\"description\":\"Too much data\"}");
                        } else if (Result.equals("com.common.pos.api.printer.OverHeatException'")) {
                            publicCallbackContext.error("{\"status\":\"error\",\"code\":\"DEVICE_OVERHEAT\",\"description\":\"Device overheating. Power off for a while.\"}");
                        } else {
                            publicCallbackContext.error("{\"status\":\"error\",\"code\":\"PRINT_ERR\",\"description\":\"Printer error: " + Result + "\"}");
                        }
                    } finally {
                        if (noPaper) {
                            noPaper = false;
                            publicCallbackContext.error("{\"status\":\"error\",\"code\":\"NO_PAPER\",\"description\":\"Printer out of paper. Load paper and try again.\"}");
                        }
                    }
                }
            });
        } else {
            callbackContext.error("{\"status\":\"error\",\"code\":\"NO_DATA\",\"description\":\"No data to print.\"}");
        }
    }

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        super.initialize(cordova, webView);

        appContext = this.cordova.getActivity().getApplicationContext();
        mUsbThermalPrinter = new UsbThermalPrinter(appContext);

        /*
        IntentFilter pIntentFilter = new IntentFilter();
        pIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
        pIntentFilter.addAction("android.intent.action.BATTERY_CAPACITY_EVENT");
        registerReceiver(printReceive, pIntentFilter);
        */
        
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Result = null;
                    mUsbThermalPrinter.start(0);
                    mUsbThermalPrinter.reset();
                    printVersion = mUsbThermalPrinter.getVersion();
                } catch (PosException e) {
                    e.printStackTrace();
                    Result = e.toString();
                }
            }
        }).start();
    }

    @Override
    public void onDestroy() {
        //unregisterReceiver(printReceive);
        mUsbThermalPrinter.stop();
        //cordova.getActivity().getApplicationContext().unbindService(this);
        super.onDestroy();
    }

    /*
    private final BroadcastReceiver printReceive = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_NOT_CHARGING);
                int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
                int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
                if (status != BatteryManager.BATTERY_STATUS_CHARGING) {
                    if (level * 5 <= scale) {
                        lowBattery = true;
                    } else {
                        lowBattery = false;
                    }
                } else {
                    lowBattery = false;
                }
            }
        }
    };
    */

}
