
package com.imin;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;
import org.apache.cordova.PluginResult.Status;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.util.Iterator;

import android.graphics.Typeface;

import android.os.Build;


import android.widget.Toast;

import java.util.concurrent.TimeUnit;
import java.lang.reflect.Method;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;


import com.imin.printerlib.IminPrintUtils;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;

import android.content.Intent;
import android.content.IntentFilter;

import android.os.SystemClock;


import android.Manifest;
import android.annotation.TargetApi;

import android.content.pm.PackageManager;
import android.content.res.Configuration;

import android.text.TextUtils;




import java.io.IOException;
import java.io.UnsupportedEncodingException;

import java.util.List;

import com.imin.Scan;
import com.imin.Scanner;
import com.imin.Print;
import com.imin.Read;
import com.imin.InitRead;

import android.support.annotation.Nullable;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;

public class IminPrinter extends CordovaPlugin {

    private static final String TAG = "Imin";

    CallbackContext callbackContext = null;
    Context context = null;
    private IminPrintUtils mIminPrintUtils;
    private BluetoothStateReceiver mBluetoothStateReceiver;
    private static Handler scanEventHandler;
    private static Handler nfcEventHandler;
    private Handler progressHandler = new Handler();

    private boolean openHead;

    public static final int SCAN_RESPONSE = 1;
    public static final int READ_RESPONSE = 1;

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

    public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
        this.callbackContext = callbackContext;
        Log.d(TAG,action);
        context = cordova.getActivity().getApplicationContext();

        initReceiver();
        mIminPrintUtils = IminPrintUtils.getInstance(context);
        if (action.equals("print")) {
             final  String text = args.getString(0);
          cordova.getThreadPool().execute(new Runnable() {
            @Override
            public void run() {
                  try{
                    context = cordova.getActivity().getApplicationContext();

                    startPrint(context,text);


                  }catch (Exception e) {
                      e.printStackTrace();
                      Log.d(TAG,e.toString());
                      callbackContext.error("Printer Error in catch");
                  }

                    }
                });

                return true;
        }


        if (action.equals("checkStatus")) {

          cordova.getThreadPool().execute(new Runnable() {
            @Override
            public void run() {
                  try{

                      List<BluetoothDevice> printerDevices = BluetoothUtil.getPairedDevices();

                  if (printerDevices.size()>0 )
                      callbackContext.success("0");
                  else {
                    callbackContext.success("-1");
                  }

                  }catch (Exception e) {
                      e.printStackTrace();
                      Log.d(TAG,e.toString());
                      callbackContext.error("Printer Error in catch");
                  }

                    }
                });

                return true;
        }
        else if (action.equals("initNfcCard")) {
          nfcEventHandler = new Handler(Looper.getMainLooper()) {

                @Override
                public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                                switch (msg.what) {

                                    case READ_RESPONSE: {
                                        Bundle bundle = msg.getData();
                                        String[] cardIds = bundle.getStringArray("cardId");
                                        Log.d("Imin code", "cardId "+cardIds[0]);
                                        callbackContext.success(cardIds[0]);

                                        break;
                                    }
                                }
                            }

                        };
                        cordova.getThreadPool().execute(new Runnable() {
                          @Override
                          public void run() {

                              context = cordova.getActivity().getApplicationContext();

                              initNfcCard(context);
                      }
                      });

                    }
        else if (action.equals("readNfc")) {
          nfcEventHandler = new Handler(Looper.getMainLooper()) {

                @Override
                public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                                switch (msg.what) {

                                    case READ_RESPONSE: {
                                        Bundle bundle = msg.getData();
                                        String[] cardIds = bundle.getStringArray("cardId");
                                        Log.d("Imin code", "cardId "+cardIds[0]);
                                        callbackContext.success(cardIds[0]);

                                        break;
                                    }
                                }
                            }

                        };
                        cordova.getThreadPool().execute(new Runnable() {
                          @Override
                          public void run() {

                              context = cordova.getActivity().getApplicationContext();

                              startNfc(context);
                      }
                      });

                    }
      else if (action.equals("scan")) {
        scanEventHandler = new Handler(Looper.getMainLooper()) {

              @Override
              public void handleMessage(Message msg) {
                      super.handleMessage(msg);
                              switch (msg.what) {

                                  case SCAN_RESPONSE: {
                                      Bundle bundle = msg.getData();
                                      String[] barcodes = bundle.getStringArray("barcodes");
                                      Log.d("Imin code", "barcode "+barcodes[0]);
                                      callbackContext.success(barcodes[0]);

                                      break;
                                  }
                              }
                          }

                      };
        cordova.getThreadPool().execute(new Runnable() {
                        @Override
                        public void run() {

                            context = cordova.getActivity().getApplicationContext();

                            startScan(context);
                    }
                    });


    }
            return true;

      }
      private void initNfcCard(Context context) {
             Intent intent = new Intent(context, InitRead.class);
             cordova.getActivity().startActivity(intent);
         }
      private void startNfc(Context context) {
             Intent intent = new Intent(context, Read.class);
             cordova.getActivity().startActivity(intent);
         }
      private void startScan(Context context) {
             // Intent intent = new Intent(context, Scan.class);

              if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
                 || ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
               ActivityCompat.requestPermissions(cordova.getActivity(),
                   new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE,
                       Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
             }
             else{
               Intent intent = new Intent(context, Scanner.class);
               cordova.getActivity().startActivity(intent);
             }

         }

  // @Override
   public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
     // super.onRequestPermissionsResult(requestCode, permissions, grantResults);
     Log.e("MainActivity","lsy====onRequestPermissionsResult=");
        /* MyPrintService myPrintService = new MyPrintService();
         myPrintService.callPermissionCall();*/
     if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
       Intent intent = new Intent(context, Scanner.class);
       cordova.getActivity().startActivity(intent);
     }
     // this.finish();
   }
     private void startPrint(Context context,String text) {
            Intent intent = new Intent(context, Print.class);
            intent.putExtra("text",text);
            cordova.getActivity().startActivity(intent);
        }
     public static Handler getScanEventHandler() {
               return scanEventHandler;
           }

     public static void setScanEventHandler(Handler scanEventHandler) {
        IminPrinter.scanEventHandler = scanEventHandler;
     }

     public static Handler getNfcEventHandler() {
               return nfcEventHandler;
           }

     public static void setNfcEventHandler(Handler nfcEventHandler) {
        IminPrinter.nfcEventHandler = nfcEventHandler;
     }


      private void initReceiver() {
          mBluetoothStateReceiver = new BluetoothStateReceiver();
          IntentFilter filter = new IntentFilter();
          filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
          cordova.getActivity().registerReceiver(mBluetoothStateReceiver, filter);
      }
      class BluetoothStateReceiver extends BroadcastReceiver {

          @Override
          public void onReceive(Context context, Intent intent) {
              int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
              switch (state) {
                  case BluetoothAdapter.STATE_TURNING_ON:
                      toast("Bluetooth ON");
                      break;

                  case BluetoothAdapter.STATE_TURNING_OFF:
                      toast("Bluetooth OFF");
                      break;
              }
          }
      }
      protected void toast(String message) {

      }
    }
