package gen2wave.g2w_rp70a_sam_demo;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.amarula.gen2wave.sdk.usbaccessory.AccessoryPower;
import com.gemalto.gempcsc.GemErrors;
import com.gemalto.gempcsc.GemPCSC_Reader;
import com.gemalto.gempcsc.IGemPCSC;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private String TAG = "RP70A sam demo";
    private IGemPCSC gemPCSC_Service = null;
    private int sessionID = 0;
    private boolean mIsRetry = false;
    private boolean mIsBound = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        set_sam_Enable(true);
        ((Button)findViewById(R.id.btn_usb_sam_read)).setVisibility(View.VISIBLE);
        ((Button)findViewById(R.id.btn_usb_sam_read)).setOnClickListener(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mIsBound) {
            if (gemPCSC_Service != null && sessionID != 0) {
                try {
                    Log.d(TAG, "GemPCSC_Finalize");
                    gemPCSC_Service.GemPCSC_Finalize(sessionID);
                    gemPCSC_Service = null;
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            Log.d(TAG, "unbindService");
            this.unbindService(serviceConnection);
        }
    }

    private void bindGemPCSC_ServiceApk() {

        Intent intentService = new Intent("com.gemalto.gempcsc.service.action");
        intentService.setPackage("com.gemalto.gempcsc.gempcscserviceactivity");
        this.bindService(intentService, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    final ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            // on service disconnected
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // on service connected
            // ready to use IGemPCSC interface
            gemPCSC_Service = IGemPCSC.Stub.asInterface(service);
            mIsBound = true;
            mIsRetry = false;
        }
    };

    private void set_sam_Enable(boolean enabled) {
        AccessoryPower.setPower(this, AccessoryPower.AccessoryType.SAM, enabled);
    }

    private void usbGetUID() {
        try {
            if (!mIsBound) {
                Log.i(TAG, "service is not connected yet");
                return;
            }
            if (mIsBound && sessionID == 0) {
                sessionID = gemPCSC_Service.GemPCSC_Initialize();
            }

            final GemPCSC_Reader[] usbReaders =
                    gemPCSC_Service.GemPCSC_ListReaders(sessionID);
            if (usbReaders.length == 0) {
                ((TextView)findViewById(R.id.tv_usb_sam_atr_first)).setText("");
                ((TextView)findViewById(R.id.tv_usb_sam_status_first)).setText("Check Card Reader");
                return;
            }

            Log.i(TAG, "usbReaders.length = "+usbReaders.length);
            int usbReaderIndex = 0;
            int bUsbPID = usbReaders[0].getPID(), lUsbPID = usbReaders[0].getPID();
            for (int i=1; i<usbReaders.length; i++) {
                lUsbPID = usbReaders[i].getPID();
                Log.i(TAG, "lUsbPID = "+lUsbPID);
                if (lUsbPID != bUsbPID) {
                    bUsbPID = lUsbPID;
                    usbReaderIndex = i;
                }
            }
            if (usbReaderIndex == 2) usbReaderIndex = 0;
            Log.i(TAG, "usbReaderIndex = "+usbReaderIndex);

            byte[] ATR = gemPCSC_Service.GemPCSC_Connect(sessionID, usbReaders[usbReaderIndex]);
            if (!gemPCSC_Service.GemPCSC_IsCardPresent(sessionID)) {
                Log.i(TAG, "usbGetUID GemPCSC_IsCardPresent ATR[0]:"+ATR[0]+"ATR[1]:" +ATR[1]);
                ((TextView)findViewById(R.id.tv_usb_sam_atr_first)).setText("");
                if (ATR[1] == 0) {//[65, 0]
                    ((TextView)findViewById(R.id.tv_usb_sam_status_first)).setText("   No Card");
                } else {//[65, -2]
                    ((TextView)findViewById(R.id.tv_usb_sam_status_first)).setText("   No Card");
                }
            }
            Log.i(TAG, "usbGetUID GemPCSC_GetLastError");
            if (GemErrors.GE_OK == gemPCSC_Service.GemPCSC_GetLastError()) {
                // display ATR...
                String strtv1 ="ATR:";
                for (int i = 0; i < ATR.length; i++) {
                    strtv1 += String.format("0x%02x ", ATR[i]);
                }
                Log.i(TAG, "usbGetUID strtv1 = "+strtv1);
                ((TextView)findViewById(R.id.tv_usb_sam_atr_first)).setText(strtv1);
                ((TextView)findViewById(R.id.tv_usb_sam_status_first)).setText("  Read");
            }

            ATR = gemPCSC_Service.GemPCSC_Connect(sessionID, usbReaders[usbReaderIndex+1]);
            if (!gemPCSC_Service.GemPCSC_IsCardPresent(sessionID)) {
                Log.i(TAG, "usbGetUID GemPCSC_IsCardPresent ATR[0]:"+ATR[0]+"ATR[1]:" +ATR[1]);
                ((TextView)findViewById(R.id.tv_usb_sam_atr_second)).setText("");
                if (ATR[1] == 0) {//[65, 0]
                    ((TextView)findViewById(R.id.tv_usb_sam_status_second)).setText("   No Card");
                } else {//[65, -2]
                    ((TextView)findViewById(R.id.tv_usb_sam_status_second)).setText("   No Card");
                }
                Log.i(TAG, "usbGetUID GemPCSC_Disconnect");
                gemPCSC_Service.GemPCSC_Disconnect(sessionID);
                gemPCSC_Service.GemPCSC_Finalize(sessionID);
                sessionID = 0;
                unbindService(serviceConnection);
                mIsBound = false;
                gemPCSC_Service = null;
                return;
            }
            Log.i(TAG, "usbGetUID GemPCSC_GetLastError");
            if (GemErrors.GE_OK == gemPCSC_Service.GemPCSC_GetLastError()) {
                // display ATR...
                String strtv1 ="ATR:";
                for (int i = 0; i < ATR.length; i++) {
                    strtv1 += String.format("0x%02x ", ATR[i]);
                }
                Log.i(TAG, "usbGetUID strtv1 = "+strtv1);
                ((TextView)findViewById(R.id.tv_usb_sam_atr_second)).setText(strtv1);
                ((TextView)findViewById(R.id.tv_usb_sam_status_second)).setText("  Read");
            }

            Log.i(TAG, "usbGetUID GemPCSC_Disconnect 2");
            boolean isRet = gemPCSC_Service.GemPCSC_Disconnect(sessionID);
            if (GemErrors.GE_OK == gemPCSC_Service.GemPCSC_GetLastError()) {
            }

        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {

            case R.id.btn_usb_sam_read:
            {
                Log.i(TAG, "onClick btnICCardRead mIsRetry : "+mIsRetry+", mIsBound = "+mIsBound);
                ((TextView)findViewById(R.id.tv_usb_sam_atr_first)).setText("");
                ((TextView)findViewById(R.id.tv_usb_sam_atr_second)).setText("");
                if (!mIsRetry) {
                    if (mIsBound) {
                        usbGetUID();
                    } else {
                        bindGemPCSC_ServiceApk();
                        mIsRetry = true;
                    }
                }
                break;
            }

        }
    }
}
