package gen2wave.rp70biodemo.passport;

import android.app.Activity;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.hardware.usb.UsbManager;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.amarula.gen2wave.sdk.usbaccessory.AccessoryPower;

import net.sf.scuba.smartcards.CardService;
import net.sf.scuba.smartcards.CardServiceException;

import org.jmrtd.BACKeySpec;
import org.jmrtd.PassportService;
import org.jmrtd.lds.DataGroup;
import org.jmrtd.lds.LDSFile;
import org.jmrtd.lds.LDSFileUtil;
import org.jmrtd.lds.SODFile;
import org.jmrtd.lds.icao.COMFile;
import org.jmrtd.lds.icao.DG1File;
import org.jmrtd.lds.icao.DG2File;
import org.jmrtd.lds.icao.DG3File;
import org.jmrtd.lds.icao.MRZInfo;
import org.jmrtd.lds.iso19794.FaceImageInfo;
import org.jmrtd.lds.iso19794.FaceInfo;
import org.jmrtd.lds.iso19794.FingerImageInfo;
import org.jmrtd.lds.iso19794.FingerInfo;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;

import elyctis.com.elytraveldocumentforandroid.PassportView;
import elyctis.com.elytraveldocumentforandroid.Scanner;
import gen2wave.rp70biodemo.R;
import gen2wave.rp70biodemo.msrocr.BeepManager;

public class MRZPassportActivity extends Activity {

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

    private final int PROGRESS_ON = 0;
    private final int PROGRESS_OFF = 1;

    private BeepManager beepmanager = null;
    private BeepManager beepmanager_fail = null;

    private String passportNumber = null;
    private String expirationDate = null;
    private String birthDate = null;
    TextView tvOcrData = null;
    private View mainLayout;
    private View passportLayout;
    private View loadingLayout;
    boolean state = false;
    boolean isNewIntentcall = false;

    Animation anim = null;
    ImageView redBarImg = null;
    Spinner passportspinner = null;
    int npassportimagetype = 0;

    private Scanner scanner = null;
    private ProgressDialog mProgressDialog = null;

    private Tag mtag = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_mrz_passport);
        super.onCreate(savedInstanceState);
        this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS);

        set_mrz_powerEnabled(true);
        mainLayout = findViewById(R.id.layout_readdata_ocr);
        passportLayout = findViewById(R.id.layout_readdata_passport);
        loadingLayout = findViewById(R.id.loading_layout);

        redBarImg = (ImageView) findViewById(R.id.red_bar);
        anim = AnimationUtils.loadAnimation(this, R.anim.red_bar_anim);
        redBarImg.startAnimation(anim);
        tvOcrData = (TextView) findViewById(R.id.tv_ocr_data);

        beepmanager = new BeepManager(getApplicationContext(), 1);
        beepmanager_fail = new BeepManager(getApplicationContext(), 0);
        passportspinner = (Spinner)findViewById(R.id.passport_image_spinner);

        String[] str = getResources().getStringArray(R.array.passport_image);

        final ArrayAdapter<String> adapter= new ArrayAdapter<String>(getApplicationContext(),R.layout.spinner_item,str);

        adapter.setDropDownViewResource(R.layout.spinner_dropdown);

        passportspinner.setAdapter(adapter);

        passportspinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                npassportimagetype= position;
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        initIntent();
    }
    private void showProgressDialog() {
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mProgressDialog.setMessage("Initialize...");
        mProgressDialog.setCancelable(false);
        mProgressDialog.show();
    }

    private void hideProgressIndicator() {
        if (mProgressDialog != null) {
            mProgressDialog.dismiss();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        Log.d(TAG, "onResume()");

        //NFC
        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
        if (adapter == null) {
            Toast.makeText(getApplicationContext(),
                    "NFC is not supported.", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        Intent intent = new Intent(getApplicationContext(), this.getClass());
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);
        String[][] filter = new String[][]{new String[]{"android.nfc.tech.IsoDep"}};
        adapter.enableForegroundDispatch(this, pendingIntent, null, filter);

        if (isNewIntentcall) {
            isNewIntentcall = false;
        } else {
            if (scanner != null)
                scanner.finalize(1);
            mHandler.sendEmptyMessageDelayed(PROGRESS_ON, 100);
        }
    }

    public static int READER_FLAGS =
            NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_NFC_B | NfcAdapter.FLAG_READER_NFC_BARCODE | NfcAdapter.FLAG_READER_NFC_F| NfcAdapter.FLAG_READER_NFC_V | NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK;

    @Override
    protected void onDestroy() {
        super.onDestroy();

        Log.d(TAG, "onDestroy()");

        String thisModel = getProperty("ro.product.model").toLowerCase();

        if (thisModel.contains("rp70a")) {
            unregisterReceiver(mMRZResultReceiver);
            scanner.finalize(1);
        }
        set_mrz_powerEnabled(false);

        if(beepmanager!=null) {
            beepmanager = null;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();

        Log.d(TAG, "onPause()");

        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
        if (adapter == null) return;
        adapter.disableForegroundDispatch(this);


    }

    public void initIntent() {

        String thisModel = getProperty("ro.product.model").toLowerCase();

        if (thisModel.contains("rp70a")) {
            IntentFilter mrzfilter = new IntentFilter();
            mrzfilter.addAction(Scanner.EXTRA_MRZ_DATA_ACTION);
            mrzfilter.addAction(Scanner.EXTRA_MRZ_INIT_ACTION);
            mrzfilter.addAction(Scanner.ACTION_USB_PERMISSION);
            registerReceiver(mMRZResultReceiver, mrzfilter);
        }
    }

    private BroadcastReceiver mMRZResultReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context ctx, Intent intent) {
            /* Do not double read while scanning with activity */
            String action = intent.getAction();
            Log.v(TAG, "onReceive() action = "+action);

            if (action.equals(Scanner.EXTRA_MRZ_DATA_ACTION)) {
                byte datatype = intent.getByteExtra(Scanner.EXTRA_MRZ_DATA_TYPE,(byte)0x00);

                switch (datatype){
                    case 'V':

                        MRZgetversion();
                        MRZread(1);

                        break;
                    case 'I':
                        updateActivity(scanner.getPassportView_line());
                        MRZread(2);
                        //MRZdetect();
                        break;
                    case 'P': {
                        byte datastate = intent.getByteExtra(Scanner.EXTRA_MRZ_DETECT_EMPTY, (byte) 0x10);
                        Log.v(TAG, "onReceive() datatype:"+String.format("%02X ", datatype)+" datastate:"+String.format("%02X ", datastate));
                        if(datastate ==1) {
                            Log.v(TAG, "onReceive() detect 1");
                            // MRZread(2);
                        }
                        else {
                            Log.v(TAG, "onReceive() detect 2");
                            //  MRZread(1);
                        }
                    }
                    break;
                    case 'E':
                    MRZgetversion();
                    MRZread(1);
                    break;
                }
            }

            if(action.equals(Scanner.EXTRA_MRZ_INIT_ACTION)){
                boolean bhaspermission = intent.getBooleanExtra(Scanner.EXTRA_MRZ_INIT_PERMISSION,false);
                if(bhaspermission) {
                    MRZgetversion();
                }
            }

            if(action.equals(Scanner.ACTION_USB_PERMISSION)){
                synchronized (this){
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED,false)) {
                        Log.d(TAG, "RequestPermissionsResult   true");
                        scanner.resume();
                    } else {
                        Log.d(TAG, "RequestPermissionsResult   false");
                    }
                }
            }
        }
    };

    void Parsing(String sdata) {

        Log.d(TAG, "length:"+sdata.length());
        if (sdata.length() >90) {
            Log.d(TAG, "length 94 id card in");
            sdata.trim();
            int nat = 2;
            String nation = sdata.substring(nat, nat + 3);
            Log.d(TAG, "nation = "+nation);
            if (nation.equals("UTO") || nation.equals("UGA")) { //ukraina & uganda
                passportNumber = sdata.substring(5, 14);
                birthDate = sdata.substring(30, 37);
                expirationDate = sdata.substring(39, 45);
            } else if (nation.equals("SEN")) { // senegal
                passportNumber = sdata.substring(5, 14);
                passportNumber += sdata.substring(15, 23);
                birthDate = sdata.substring(30, 37);
                expirationDate = sdata.substring(39, 45);
            } else if (nation.equals("NGR")) { //nigeria
                passportNumber = sdata.substring(5, 15);
                birthDate = sdata.substring(30, 37);
                expirationDate = sdata.substring(38, 44);
            } else { // show all digit except last one
                passportNumber = sdata.substring(5, 30);
                passportNumber = strReplace(passportNumber, "<");
                passportNumber = passportNumber.substring(0, (passportNumber.length()-1));
                birthDate = sdata.substring(30, 37);
                expirationDate = sdata.substring(39, 45);
            }
        } else {
            Log.d(TAG, "length 91 passport in");
            int row = 44;
            passportNumber = sdata.substring(row + 1, row + 10);
            birthDate = sdata.substring(row + 14, row + 20);
            expirationDate = sdata.substring(row + 22, row + 28);
        }

        Log.i(TAG, "p.len : " + passportNumber.length() + " b.len : " + birthDate.length() + " e.len : " + expirationDate.length());
        if (birthDate.length() == 7) {
            birthDate = birthDate.substring(1, birthDate.length());
        }

        Log.i(TAG, "passportNumber:" + passportNumber + " birthDate:" + birthDate + " expirationDate:" + expirationDate);
    }

    public String strReplace(String s1, String s2) {
        String res = "";
        StringTokenizer str = new StringTokenizer(s1, s2);
        while(str.hasMoreTokens()) {
            res += str.nextToken();
        }
        return res;
    }
    public void Getpassportdata(Tag tag)
    {
        Log.d(TAG, "Getpassportdata   ");
        if(tag==null) {
            ((TextView) findViewById(R.id.tv_msrocr_type)).setText("Detached Passport NFC");
            ((TextView) findViewById(R.id.tv_msrocr_type)).setTextSize(40);
            Log.d(TAG, "Getpassportdata   tag ==null");
            return;
        }
        ((TextView) findViewById(R.id.tv_msrocr_type)).setText("Read Passport NFC");
        ((TextView) findViewById(R.id.tv_msrocr_type)).setTextSize(40);
        if (Arrays.asList(tag.getTechList()).contains("android.nfc.tech.IsoDep")) {
            if (TextUtils.isEmpty(passportNumber)) {
                Log.d(TAG, "passportNumber is null");
            }
            if (TextUtils.isEmpty(expirationDate)) {
                Log.d(TAG, "expirationDate is null");
            }
            if (TextUtils.isEmpty(birthDate)) {
                Log.d(TAG, "birthDate is null");
            }

            if (passportNumber != null && !passportNumber.isEmpty()
                    && expirationDate != null && !expirationDate.isEmpty()
                    && birthDate != null && !birthDate.isEmpty()) {
                Log.e(TAG, "Passport Read state = " + state);
                if (!state) {
                    state = true;
                    beginePassportCommunication(IsoDep.get(tag));
/*
                    mainLayout.setVisibility(View.GONE);
                    loadingLayout.setVisibility(View.VISIBLE);
                    passportLayout.setVisibility(View.GONE);
                    ((TextView) findViewById(R.id.tv_msrocr_type)).setText("Read Passport NFC");
                    ((TextView) findViewById(R.id.tv_msrocr_type)).setTextSize(40);
*/
                } else {
                    return;
                }
                mainLayout.setVisibility(View.GONE);
                loadingLayout.setVisibility(View.VISIBLE);
                passportLayout.setVisibility(View.GONE);
                ((TextView) findViewById(R.id.tv_msrocr_type)).setText("Read Passport NFC");
                ((TextView) findViewById(R.id.tv_msrocr_type)).setTextSize(40);

            } else {
                ((TextView) findViewById(R.id.tv_msrocr_type)).setText("Retry Read Passport OCR");
                ((TextView) findViewById(R.id.tv_msrocr_type)).setTextSize(40);
                Log.e("ERROR", "Passport Key Info Error");
                mainLayout.setVisibility(View.VISIBLE);
                loadingLayout.setVisibility(View.GONE);
                passportLayout.setVisibility(View.GONE);
            }
        }
    }

    protected void onNewIntent(Intent intent) {
        isNewIntentcall = true;

        if (intent.getAction().equals(NfcAdapter.ACTION_TECH_DISCOVERED)) {
            Log.d(TAG, "onNewIntent      ACTION_TECH_DISCOVERED");
            Tag tag = intent.getExtras().getParcelable(NfcAdapter.EXTRA_TAG);
            mtag = tag;
            Getpassportdata(tag);
        }
    }

    private void beginePassportCommunication(IsoDep dep) {
        try {
            dep.setTimeout(3000);
            new ReadTask().execute(dep);
        } catch (Exception e) {
        }
    }

    private class ReadTask extends AsyncTask<IsoDep, LDSFile, Integer> {

        public static final String KEY_PHOTO = "photo";
        private Bitmap bitmap;
        private Intent intent;

        @Override
        protected Integer doInBackground(IsoDep... params) {
            try {
                IsoDep iso = params[0];
                // cardService instance for nfc communication
                CardService cService = CardService.getInstance(iso);

                cService.open();// begin new session
                // passportService for epassport especial case communication
                PassportService pService = new PassportService(cService,
                        256, 224, false, true);
                pService.open();
                pService.sendSelectApplet(false);
                UserBackKeySpec ubks = new UserBackKeySpec(passportNumber, birthDate, expirationDate);

                pService.doBAC(ubks);



                InputStream is = pService.getInputStream(PassportService.EF_DG1);
                DG1File dg1 = (DG1File) LDSFileUtil.getLDSFile(PassportService.EF_DG1, is);
                publishProgress(dg1);

                is = pService.getInputStream(PassportService.EF_SOD);
                SODFile sod = (SODFile) LDSFileUtil.getLDSFile(PassportService.EF_SOD, is);

                is = pService.getInputStream(PassportService.EF_COM);
                COMFile com = (COMFile) LDSFileUtil.getLDSFile(PassportService.EF_COM, is);

                //if (com.getTagList().indexOf(LDSFile.DG1_TAG) > 0)


                /* Get the list of DGs from EF.SOd, we don't trust EF.COM. */
                List<Integer> dgNumbers = new ArrayList<Integer>();
                if (sod != null) {
                    dgNumbers.addAll(sod.getDataGroupHashes().keySet());
                } else
                if (com != null) {
                    /* Get the list from EF.COM since we failed to parse EF.SOd. */
                    Log.d("Test","Failed to get DG list from EF.SOd. Getting DG list from EF.COM.");
                    int[] tagList = com.getTagList();
                    dgNumbers.addAll(toDataGroupList(tagList));
                    Log.d("Test","dgNumbers1:"+dgNumbers);
                }

                Collections.sort(dgNumbers); /* NOTE: need to sort it, since we get keys as a set. */

                Log.d("Test","dgNumbers2:"+dgNumbers);

                //Fingerprint image


                ((ImageView) findViewById(R.id.view_fingerprint)).setImageBitmap(null);
                ((ImageView) findViewById(R.id.view_photo)).setImageBitmap(null);







                if(npassportimagetype ==1 || npassportimagetype==2) {
                    if (dgNumbers.contains(3)) {

                        is = readstream(pService,PassportService.EF_DG3);//pService.getInputStream(PassportService.EF_DG3);
                        if (is != null){
                        Log.d("Test", "getInputStream");
                        DG3File dg3 = (DG3File) LDSFileUtil.getLDSFile(PassportService.EF_DG3, is);

                            List<FingerImageInfo> allFingerImageInfos = new ArrayList<>();
                            List<FingerInfo> fingerInfos = dg3.getFingerInfos();
                            for (FingerInfo fingerInfo : fingerInfos) {
                                allFingerImageInfos.addAll(fingerInfo.getFingerImageInfos());

                            }

                            if (!allFingerImageInfos.isEmpty()) {
                                Log.d("Test", "allFingermageInfos is not empty");
                                FingerImageInfo fingerImageInfo = allFingerImageInfos.iterator().next();

                                Log.d("Test", "view count:"+fingerImageInfo.getViewCount()+"position:"+fingerImageInfo.getPosition()+
                                        "fingerinfo:"+fingerImageInfo.toString());
                                int imageLength = fingerImageInfo.getImageLength();
                                DataInputStream dataInputStream = new DataInputStream(fingerImageInfo.getImageInputStream());
                                byte[] buffer = new byte[imageLength];
                                dataInputStream.readFully(buffer, 0, imageLength);
                                InputStream inputStream = new ByteArrayInputStream(buffer, 0, imageLength);

                                Bitmap bitmap = PUtils.decodeImage(
                                        MRZPassportActivity.this, fingerImageInfo.getMimeType(), inputStream, buffer);
                                if (npassportimagetype == 2) {
                                    ((ImageView) findViewById(R.id.view_fingerprint)).setImageBitmap(bitmap);
                                } else {
                                    ((ImageView) findViewById(R.id.view_photo)).setImageBitmap(bitmap);
                                }

                            } else {
                                Log.d("Test", "allFingermageInfos is empty");
                            }
                        }
                    }

                }

                if(npassportimagetype ==0 || npassportimagetype==2) {
                    is = pService.getInputStream(PassportService.EF_DG2);
                    DG2File dg2 = (DG2File) LDSFileUtil.getLDSFile(PassportService.EF_DG2, is);
                    List<FaceImageInfo> allFaceImageInfos = new ArrayList<>();
                    List<FaceInfo> faceInfos = dg2.getFaceInfos();
                    for (FaceInfo faceInfo : faceInfos) {
                        allFaceImageInfos.addAll(faceInfo.getFaceImageInfos());
                    }

                    if (!allFaceImageInfos.isEmpty()) {
                        Log.d("Test", "allFaceImageInfos is not empty");
                        FaceImageInfo faceImageInfo = allFaceImageInfos.iterator().next();

                        int imageLength = faceImageInfo.getImageLength();
                        DataInputStream dataInputStream = new DataInputStream(faceImageInfo.getImageInputStream());
                        byte[] buffer = new byte[imageLength];
                        dataInputStream.readFully(buffer, 0, imageLength);
                        InputStream inputStream = new ByteArrayInputStream(buffer, 0, imageLength);

                        Bitmap bitmap = PUtils.decodeImage(
                                MRZPassportActivity.this, faceImageInfo.getMimeType(), inputStream, buffer);
                        ((ImageView) findViewById(R.id.view_photo)).setImageBitmap(bitmap);
                    } else {
                        Log.d("Test", "allFaceImageInfos is empty");
                    }

                }
                return 0;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }

        }

        @SuppressWarnings("null")
        @Override
        protected void onProgressUpdate(LDSFile... values) {
            LDSFile file = values[0];
            if (file instanceof DataGroup) {
                if (file instanceof DG1File) {
                    DG1File dg1 = (DG1File) file;
                    MRZInfo mrzInfo = dg1.getMRZInfo();
                    String fn = mrzInfo.getSecondaryIdentifier().replace("<", "");
                    String ln = mrzInfo.getPrimaryIdentifier().replace("<", "");
                    String ge = mrzInfo.getGender().toString();
                    String bir = mrzInfo.getDateOfBirth();
                    String exp = mrzInfo.getDateOfExpiry();
                    String pn = mrzInfo.getDocumentNumber();
                    String na = mrzInfo.getNationality();

                    Log.d(TAG, "fn = "+fn+", ln = "+ln+", ge = "+ge+", bir = "+bir+", exp = "+exp+", pn = "+pn+", na = "+na);

                    ((TextView) findViewById(R.id.output_first_name)).setText(fn);
                    ((TextView) findViewById(R.id.output_last_name)).setText(ln);
                    ((TextView) findViewById(R.id.output_gender)).setText(ge);
                    ((TextView) findViewById(R.id.output_birth)).setText(bir);
                    ((TextView) findViewById(R.id.output_expiry)).setText(exp);
                    ((TextView) findViewById(R.id.output_personalnumber)).setText(pn);
                    ((TextView) findViewById(R.id.output_nationality)).setText(na);
                }
            }
        }

        @Override
        protected void onPostExecute(Integer i) {
            //mainLayout.setVisibility(View.VISIBLE);
            loadingLayout.setVisibility(View.GONE);
            Log.d(TAG, "onPostExecute nfc info i = " + i);
            if (i != null) {
                ((TextView) findViewById(R.id.tv_msrocr_type))
                        .setText("NFC Info");
                mainLayout.setVisibility(View.GONE);
                passportLayout.setVisibility(View.VISIBLE);
                Log.d(TAG, "onPostExecute nfc info");
/*
                passportNumber=null;
                birthDate=null;
                expirationDate=null;
*/
            } else {

                   // ((TextView) findViewById(R.id.tv_msrocr_type))
                    //        .setText("Detached PassPort NFC. Retry Attached!");

                mainLayout.setVisibility(View.VISIBLE);
                loadingLayout.setVisibility(View.GONE);
                passportLayout.setVisibility(View.GONE);
            }
            state = false;
            passportNumber=null;
            birthDate=null;
            expirationDate=null;
        }
    }

    public InputStream readstream(PassportService ps,short type)
    {
        InputStream is=null;
        try {
            Log.d("Test", "readstream");
            is= ps.getInputStream(type);
        }catch (CardServiceException e)
        {
            Log.d("Test", "readDG3 CardServiceException");
            e.printStackTrace();
        }
        return is;



    }

    private List<Integer> toDataGroupList(int[] tagList) {
        if (tagList == null) { return null; }
        List<Integer> dgNumberList = new ArrayList<Integer>(tagList.length);
        for (int tag: tagList) {
            try {
                int dgNumber = LDSFileUtil.lookupDataGroupNumberByTag(tag);
                dgNumberList.add(dgNumber);
            } catch (NumberFormatException nfe) {
                Log.w("error:","Could not find DG number for tag: " + Integer.toHexString(tag));
                nfe.printStackTrace();
            }
        }
        return dgNumberList;
    }

    public List<BACKeySpec> getEPassportsAsBACKeys() {
        Vector<BACKeySpec> result = new Vector<BACKeySpec>();
        try {
            Log.w(TAG, "num "
                    + passportNumber + "bdate:" + birthDate + "epdate:"
                    + expirationDate);
            // create a new instance of credential passing it the documentId,
            // the birth date and the expiry date retrieved from the DB
            Credentials epassport = new Credentials(passportNumber, birthDate,
                    expirationDate);
            result.add(epassport);

        } catch (Exception e) {
            e.printStackTrace();
            Log.e("ERROR",
                    "ERROR: Failed to select the ePassport table: "
                            + e.getStackTrace());
        }
        return result;
    }

    @SuppressWarnings("unused")
    public void WriteBitmap(Bitmap wbit) {
        try {
            Log.i(TAG, "WriteBitmap in");
            File file = new File("test.png");
            FileOutputStream fos = openFileOutput("test.png", 0);
            wbit.compress(CompressFormat.PNG, 100, fos);
            Log.i(TAG, file.getAbsolutePath() + " " + file.getAbsoluteFile());
            fos.flush();
            fos.close();

            Log.i(TAG, "file ok");
        } catch (Exception e) {
            Log.i(TAG, "file error");
        }
    }

    public static String getProperty(String prop) {
        String serialnum = "";

        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class, String.class );
            serialnum = (String)(   get.invoke(c, prop, "-" )  );
        }
        catch (Exception ignored)
        {
        }
        return serialnum;
    }
    private void updateActivity(PassportView passport)
    {
        String strmrz="";

        passportNumber=null;
        birthDate=null;
        expirationDate=null;

        //Update MRZ UI
        if(passport!=null) {
            if(passport.is1lines) {
                strmrz += passport.MRZ[0] +"\n";
                Log.d("MRZ", passport.MRZ[0]);
            }
            if(passport.is2lines){
                strmrz+=passport.MRZ[1]+"\n";
                Log.d("MRZ", passport.MRZ[1]);
            }
            if (passport.is3lines) {
                strmrz+=passport.MRZ[2];
                Log.d("MRZ", passport.MRZ[2]);
            }

            //((TextView) findViewById(R.id.tv_msrocr_type)).setText("OCR Data");
            //((TextView) findViewById(R.id.tv_ocr_data)).setText(strmrz);
            mainLayout.setVisibility(View.VISIBLE);
            loadingLayout.setVisibility(View.GONE);
            passportLayout.setVisibility(View.GONE);

                tvOcrData.setText(strmrz);
                beepmanager.playBeepSoundAndVibrate(1);
                //moctrl.AVR_CMD_SetLED_SF(1);
                if (strmrz.length() > 80) {
                    Parsing(strmrz);
                }

            beepmanager.playBeepSoundAndVibrate(1);
            Getpassportdata(mtag);
            //mtag = null;
        }
        else {
        ((TextView) findViewById(R.id.tv_msrocr_type)).setText("Retry Read PassPort OCR");
        ((TextView) findViewById(R.id.tv_msrocr_type)).setTextSize(35);
            Log.e(TAG, "passport.MRZ data NULL ");
            beepmanager_fail.playBeepSoundAndVibrate(0);
            return;
        }
    }

    public void MRZgetversion()
    {
        String scannerVersion = "";
        try {
            scannerVersion = Scanner.getInstance().getVersion();
            ((TextView) findViewById(R.id.tv_msrocr_type)).setText("OCR Scan version");
            ((TextView)findViewById(R.id.tv_ocr_data)).setText("Scanner Version: " + scannerVersion);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

            Toast.makeText(getApplicationContext(), "Scanner reader not found", Toast.LENGTH_LONG).show();
        }
    }

    public void MRZread(int readtype)
    {
        try {
            if (readtype == 1) {
                scanner.readMRZ();
            } else if (readtype == 2 || readtype == 3) {
                scanner.creadMRZ(readtype);
            } else {
                scanner.readMRZ();
            }
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    public void MRZdetect()
    {
        try {
            scanner.detectMRZ();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    private void set_mrz_powerEnabled(boolean enabled) {
        AccessoryPower.setPower(this, AccessoryPower.AccessoryType.MRZ, enabled);
    }

    public Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case PROGRESS_ON:
                {
                    showProgressDialog();
                    mHandler.sendEmptyMessageDelayed(PROGRESS_OFF, 4000);
                    break;
                }
                case PROGRESS_OFF:
                {
                    try {
                        scanner = Scanner.getInstance(getApplicationContext());
                        Thread.sleep(100);
                        scanner.resume();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    hideProgressIndicator();
                    break;
                }
                default:
                    break;
            }
        }
    };
}
