package com.roly.nfc.crypto.ui.activity;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.SecretKey;

import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcB;
import android.nfc.tech.NfcF;
import android.nfc.tech.NfcV;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.widget.Toast;

import com.googlecode.androidannotations.annotations.AfterViews;
import com.googlecode.androidannotations.annotations.Background;
import com.googlecode.androidannotations.annotations.Click;
import com.googlecode.androidannotations.annotations.EActivity;
import com.googlecode.androidannotations.annotations.OptionsItem;
import com.googlecode.androidannotations.annotations.OptionsMenu;
import com.googlecode.androidannotations.annotations.UiThread;
import com.roly.nfc.crypto.R;
import com.roly.nfc.crypto.ui.fragment.KeyPickerDialogFragment;
import com.roly.nfc.crypto.util.EncryptionUtils;
import com.roly.nfc.crypto.util.NfcTagUtils;
import com.roly.nfc.crypto.util.NfcUtils;

@EActivity(R.layout.activity_main)
@OptionsMenu(R.menu.cryptonfc_menu)
public class MainActivity extends FragmentActivity {

    private IntentFilter[] intentFiltersArray;
    private PendingIntent pi;
    private String[][] techList;
    private NfcAdapter adapter;
    private KeyPickerDialogFragment dialogFragment;

    @OptionsItem(R.id.settings)
	public void viewPreferences(){
		startActivity(new Intent(this,PreferencesActivity.class));
	}

    @Click(R.id.menu_add_note)
	public void addNote(){
		Intent i = new Intent(this,EditNoteActivity_.class);
		startActivity(i);
	}

    @Click(R.id.menu_view_notes)
	public void viewNotes(){
		Intent i = new Intent(this,NoteListActivity_.class);
		startActivity(i);
	}

    @Click(R.id.menu_get_code)
    public void getCode(){
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/OlivierGonthier/"));
        startActivity(intent);
    }

    @AfterViews
    public void init(){
        dialogFragment = new KeyPickerDialogFragment();
        setForegroundListener();
        adapter = NfcAdapter.getDefaultAdapter(this);
    }

    @Click(R.id.menu_write_key)
	public void writeKey(){
        FragmentManager fragmentManager = getSupportFragmentManager();
        dialogFragment.show(fragmentManager, "Key Picker");
        registerNFC();
    }

    public void registerNFC(){
        adapter.enableForegroundDispatch(this, pi, intentFiltersArray, techList);
    }

    public void unregisterNFCIfNeeded() {
        if (adapter != null && adapter.isEnabled()) {
            adapter.disableForegroundDispatch(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (dialogFragment.isVisible()) {
            registerNFC();
        } else {
            unregisterNFCIfNeeded();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (adapter.isEnabled()) {
            unregisterNFCIfNeeded();
        }
    }

    private void setForegroundListener() {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
        boolean handleFormatable = preferences.getBoolean("format_ndef_formatable_tags", false);

        pi = PendingIntent.getActivity(this, 0, new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        intentFiltersArray = null;
        if(handleFormatable)
            techList = new String[][]{ new String[]{ NfcA.class.getName(),Ndef.class.getName()},
                    new String[]{ NfcB.class.getName(),Ndef.class.getName()},
                    new String[]{ NfcF.class.getName(),Ndef.class.getName()},
                    new String[]{ NfcV.class.getName(),Ndef.class.getName()},
                    new String[]{ NfcA.class.getName(),NdefFormatable.class.getName()},
                    new String[]{ NfcB.class.getName(),NdefFormatable.class.getName()},
                    new String[]{ NfcF.class.getName(),NdefFormatable.class.getName()},
                    new String[]{ NfcV.class.getName(),NdefFormatable.class.getName()}};
        else
            techList = new String[][]{ new String[]{ NfcA.class.getName(),Ndef.class.getName()},
                    new String[]{ NfcB.class.getName(),Ndef.class.getName()},
                    new String[]{ NfcF.class.getName(),Ndef.class.getName()},
                    new String[]{ NfcV.class.getName(),Ndef.class.getName()}};
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if(intent.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED) || intent.getAction().equals(NfcAdapter.ACTION_TECH_DISCOVERED)){
            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            String[] tagTechs = tag.getTechList();
            if (Arrays.asList(tagTechs).contains(Ndef.class.getName())) {
                writeKeyOnTag(tag, false);
            } else if (Arrays.asList(tagTechs).contains(NdefFormatable.class.getName())) {
                writeKeyOnTag(tag, true);
            } else {
                Toast.makeText(this, "Tag not supported", Toast.LENGTH_LONG).show();
            }
        }
    }

    @Background
    public void writeKeyOnTag(Tag tag, boolean formatNeeded) {
        SecretKey key;
        try {
            key = EncryptionUtils.generateKey();
        } catch (NoSuchAlgorithmException e) {
            error("An error occured while generating a key");
            return;
        }

        NdefRecord[] records;
        NdefRecord keyRecord = NfcUtils.createRecord(key.getEncoded());
        NdefRecord appRecord = NfcTagUtils.writeApplicationRecordIfPossible();
        if(appRecord != null){
            records = new NdefRecord[]{keyRecord, appRecord};
        } else {
            records = new NdefRecord[]{keyRecord};
        }

        NdefMessage message = new NdefMessage(records);

        if(formatNeeded){
            NdefFormatable formatable = NdefFormatable.get(tag);

            try {
                formatable.connect();
                formatable.format(message);
            } catch (IOException | FormatException e) {
                error("An error occured while formatting your tag");
                return;
            } finally{
                try {
                    formatable.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }else{
            Ndef ndef = Ndef.get(tag);
            try {
                ndef.connect();
                ndef.writeNdefMessage(message);
            } catch (IOException | FormatException e) {
                error("An error occured while writing key on tag");
                return;
            } finally{
                try {
                    ndef.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        success();
    }

    @UiThread
    public void success() {
        Toast.makeText(this, "A new key has been written on your tag!", Toast.LENGTH_LONG).show();
        dialogFragment.dismiss();
    }

    @UiThread
    public void error(String message) {
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
        dialogFragment.dismiss();
    }

}

@@ -2409,16 +2409,25 @@
 onthier/
+CryptoNFC
 %22));%0A   

Complete github url