package androdns.android.leetdreams.ch.androdns;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;


import org.xbill.DNS.DClass;
import org.xbill.DNS.Flags;
import org.xbill.DNS.Header;
import org.xbill.DNS.InvalidTypeException;
import org.xbill.DNS.Message;
import org.xbill.DNS.Name;
import org.xbill.DNS.RRset;
import org.xbill.DNS.Rcode;
import org.xbill.DNS.Record;
import org.xbill.DNS.Resolver;
import org.xbill.DNS.ResolverConfig;
import org.xbill.DNS.Section;
import org.xbill.DNS.SimpleResolver;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type;

import java.io.IOException;
import java.net.IDN;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class DNSFormActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener, View.OnFocusChangeListener {
    private static final String TAG = "AndroDNS";
    private Session activeSession = null;
    private History history;
    private BookmarkedQueries bookmarks;
    private DNSSECVerifier dnssecVerifier = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dnsform);
        fillQTypes();

        Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(myToolbar);

        history = new History(getApplicationContext());
        history.load();

        bookmarks = new BookmarkedQueries(getApplicationContext());
        bookmarks.load();
    }

    @Override
    protected void onStart() {
        super.onStart();
        (((Spinner) findViewById(R.id.spinnerKnownTypes))).setOnItemSelectedListener(this);
        (((Spinner) findViewById(R.id.spinnerProto))).setOnItemSelectedListener(this);
        (((EditText) findViewById(R.id.txtQTYPE))).setOnFocusChangeListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.actionbar, menu);
        return true;
    }

    public DNSSECVerifier getDnssecVerifier() {
        if (dnssecVerifier == null) {
            dnssecVerifier = new DNSSECVerifier();
        }
        return dnssecVerifier;
    }

    /**
     * update the the lower gui section with the Values from an AnswerScreenState
     *
     * @param state history: if true, do not update the title
     */
    public void updateScreenState(final AnswerScreenState state, final boolean history) {
        Runnable guiUpdate = new Runnable() {
            @Override
            public void run() {
                if (!history) {
                    setTitle("");
                }

                ((TextView) findViewById(R.id.txtStatusText)).setText(state.status);
                ((TextView) findViewById(R.id.txtServerIP)).setText(state.server);
                ((TextView) findViewById(R.id.txtQbytes)).setText("" + state.qsize);
                ((TextView) findViewById(R.id.txtAbytes)).setText("" + state.asize);
                ((EditText) findViewById(R.id.txtResult)).setText(state.answerText);
                if (state.rcode > -1) {
                    ((TextView) findViewById(R.id.txtRcode)).setText(Rcode.string(state.rcode));
                } else {
                    ((TextView) findViewById(R.id.txtRcode)).setText("");

                }


                ((CheckBox) findViewById(R.id.cbaAA)).setChecked(state.flag_AA);
                ((CheckBox) findViewById(R.id.cbaTC)).setChecked(state.flag_TC);
                ((CheckBox) findViewById(R.id.cbaRD)).setChecked(state.flag_RD);
                ((CheckBox) findViewById(R.id.cbaRA)).setChecked(state.flag_RA);
                ((CheckBox) findViewById(R.id.cbaAD)).setChecked(state.flag_AD);
                ((CheckBox) findViewById(R.id.cbaCD)).setChecked(state.flag_CD);
            }
        };

        runOnUiThread(guiUpdate);
    }

    /**
     * set the screen state from a history entry
     *
     * @param session
     */
    public void setScreenState(final Session session) {
        activeSession = session;

        Runnable guiUpdate = new Runnable() {
            @Override
            public void run() {
                long runts = 0;
                if (session.answer != null) {
                    runts = session.answer.runtimestamp;
                }
                if (runts > 0) {
                    setTitle(HistoryAdapter.getDate(session.answer.runtimestamp, "yyyy-MM-dd hh:mm:ss"));
                } else {
                    setTitle("");
                }
                ((EditText) findViewById(R.id.txtQname)).setText(session.qname);
                ((EditText) findViewById(R.id.txtServerName)).setText(session.server);
                ((EditText) findViewById(R.id.txtQTYPE)).setText("" + session.qtype);
                Spinner qtypespinner = (Spinner) findViewById(R.id.spinnerKnownTypes);
                try {
                    qtypespinner.setSelection(getIndex(qtypespinner, Type.string(session.qtype)));
                } catch (Exception e) {
                } //invalid type

                Spinner classSpinner = (Spinner) findViewById(R.id.spinnerCLASS);
                try {
                    classSpinner.setSelection(getIndex(classSpinner, session.qclass));
                } catch (Exception e) {
                } //invalid class

                Spinner protoSpinner = (Spinner) findViewById(R.id.spinnerProto);
                try {
                    protoSpinner.setSelection(getIndex(protoSpinner, session.protocol));
                } catch (Exception e) {
                } //invalid class
                setDefaultPortFromProto();
                ((CheckBox) findViewById(R.id.cbTCP)).setChecked(session.TCP);
                ((CheckBox) findViewById(R.id.cbCD)).setChecked(session.flag_CD);
                ((CheckBox) findViewById(R.id.cbRD)).setChecked(session.flag_RD);
                ((CheckBox) findViewById(R.id.cbDO)).setChecked(session.flag_DO);

                int port = session.port;
                if (port != 0) {
                    setTextViewContent(R.id.txtPort, "" + port);
                }


            }
        };

        runOnUiThread(guiUpdate);

        if (session.answer != null) {
            updateScreenState(session.answer, true);
        }
        updateBookmarkImageState();
    }

    /**
     * update answer screen state if the session this comes from is still the active one*
     **/
    public void updateStreenStateIfCurrent(Session session, AnswerScreenState state) {
        if (session == activeSession) {
            ((Button) findViewById(R.id.button)).clearAnimation();
            updateScreenState(state, false);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_history:
                Intent historyIntent = new Intent(this, HistoryActivity.class);
                startActivityForResult(historyIntent, 1);
                return true;

            case R.id.action_bookmark:
                Intent starIntent = new Intent(this, BookmarkedQueriesActivity.class);
                startActivityForResult(starIntent, 1);

                return true;

            case R.id.action_help:
                showHelp();
                return true;

            default:
                // If we got here, the user's action was not recognized.
                // Invoke the superclass to handle it.
                return super.onOptionsItemSelected(item);

        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case (1): {
                if (resultCode == Activity.RESULT_OK) {
                    int returnValue = data.getIntExtra("entry", 0);
                    String source = data.getStringExtra("source");
                    if (source == null) {
                        source = "history";
                    }
                    switch (source) {
                        case "bookmarks":
                            clearAnswer();
                            setScreenState(bookmarks.getSessionAt(returnValue));
                            break;
                        default: //"history
                            setScreenState(history.getSessionAt(returnValue));
                    }

                }
                break;
            }
        }
    }

    /**
     * perform the lookup, store the answer in an answerscreenstate and update the screen when done
     *
     * @param session
     */
    public void doLookup(Session session) {
        activeSession = session;
        AnswerScreenState answerState = new AnswerScreenState();
        answerState.runtimestamp = System.currentTimeMillis();
        String answerOutput = "";

        try {
            // Set up the query
            String qname = session.qname;

            // IDNA: convert to ACE String
            qname = IDN.toASCII(qname);

            if (!qname.endsWith(".")) {
                qname = qname + ".";
            }
            Name current = Name.fromString(qname);
            int qtype = session.qtype;

            StringBuffer ansBuffer = new StringBuffer();

            Resolver resolver = null;

            String resolverHostname = session.server;


            String hostnameArg = IDN.toASCII(resolverHostname);
            if (hostnameArg.trim().equals("")) {
                DnsServersDetector detector = new DnsServersDetector(this);
                String[] dnsServers = detector.getServers();
                if (dnsServers.length > 0) {
                    hostnameArg = dnsServers[0];
                } else {
                    hostnameArg = null;
                }
                Log.d(TAG, "Auto detected DNS Server: " + hostnameArg);
            }

            answerState.server = hostToAddr(hostnameArg);

            //update the server ip in the gui before the query, so we see it while we try to connect
            setTextViewContent(R.id.txtServerIP, answerState.server);

            if (session.protocol.equalsIgnoreCase("DoT")) {
                int dotport = SimpleDoTResolver.DEFAULT_DOT_PORT;
                try {
                    dotport = gettxtPortContent();
                } catch (Exception e) {

                }
                resolver = new SimpleDoTResolver(hostnameArg, dotport);


            } else if (session.protocol.equalsIgnoreCase("DoH")) {
                resolver = new SimpleDoHResolver(hostnameArg);
            } else {
                resolver = new SimpleResolver(hostnameArg);
                try {
                    resolver.setPort(gettxtPortContent());
                } catch (Exception e) {
                }

            }

            if (session.flag_DO) {
                resolver.setEDNS(0, 0, Flags.DO, null);
            }

            resolver.setTCP(session.TCP);

            int query_class = DClass.IN;
            String selectedClass = session.qclass;
            if (selectedClass.equalsIgnoreCase("ch")) {
                query_class = DClass.CHAOS;
            }
            if (selectedClass.equalsIgnoreCase("hs")) {
                query_class = DClass.HESIOD;
            }

            Record question_record = Record.newRecord(current, qtype, query_class);
            Message query = Message.newQuery(question_record);


            //RD bit is set by default
            if (!session.flag_RD) {
                query.getHeader().unsetFlag(Flags.RD);
            }

            if (session.flag_CD) {
                query.getHeader().setFlag(Flags.CD);
            }

            int querybytes = query.toWire().length;
            answerState.qsize = querybytes;


            // Query ready, send it
            Message response = null;
            long startTS = System.currentTimeMillis();
            setStatusText("query sent");
            response = resolver.send(query);

            if (activeSession != session) {
                return; // this query has been aborted/overwritten by a new one
            }
            ((Button) findViewById(R.id.button)).clearAnimation();
            long duration = System.currentTimeMillis() - startTS;
            answerState.duration = duration;
            answerState.status = duration + " ms";
            answerState.asize = response.numBytes();

            int rcode = response.getHeader().getRcode();
            answerState.rcode = rcode;


            setAnswerFlagsToState(response.getHeader(), answerState);

            if (!query.getQuestion().equals(response.getQuestion())) {
                ansBuffer.append("response question section does not match our question.\n");
                ansBuffer.append(response.getQuestion());
                ansBuffer.append("\n");
            }
            ansBuffer.append("ANSWER SECTION:\n");
            ansBuffer.append(rrSetsToString(response.getSectionRRsets(Section.ANSWER)));
            ansBuffer.append("AUTHORITY SECTION:\n");
            ansBuffer.append(rrSetsToString(response.getSectionRRsets(Section.AUTHORITY)));
            ansBuffer.append("ADDITIONAL SECTION:\n");
            ansBuffer.append(rrSetsToString(response.getSectionRRsets(Section.ADDITIONAL)));

            // DNSSSEC validation
            DNSSECVerifier verifier = getDnssecVerifier();
            verifier.learnDNSSECKeysFromRRSETs(response.getSectionRRsets(Section.ANSWER));

            if (session.flag_DO) {
                ansBuffer.append("\nvalidation status :\n");
                ansBuffer.append(verifier.verificationStatusString(response.getSectionRRsets(Section.ANSWER)));
                ansBuffer.append(verifier.verificationStatusString(response.getSectionRRsets(Section.AUTHORITY)));
                ansBuffer.append("\n");
            }


            answerOutput = ansBuffer.toString();
        } catch (TextParseException e) {
            if (activeSession == session) {
                answerOutput = "Invalid qname";
                answerState.status = "INVALID";
            }

        } catch (UnknownHostException e) {
            if (activeSession == session) {
                answerOutput = "Host not found: " + e.toString();
                answerState.status = "ERROR";
            }

        } catch (java.net.SocketTimeoutException e) {
            if (activeSession == session) {
                answerOutput = "Query timed out";
                answerState.status = "TIMEOUT";
            }
        } catch (IOException e) {
            if (activeSession == session) {
                answerOutput = "I/O Error: " + e.toString();
                answerState.status = "ERROR";
            }
        } catch (InvalidTypeException e) {
            answerOutput = "Invalid type";
            answerState.status = "INVALID";
        }
        session.answer = answerState;
        answerState.answerText = answerOutput;

        history.addEntry(session);
        updateBookmarkImageState();
        updateStreenStateIfCurrent(session, answerState);
    }

    public void clearAnswer() {
        updateScreenState(new AnswerScreenState(), false);
    }

    public Session sessionFromScreenState() {
        Session screenSession = new Session();

        //build the question object
        String qname = gettxtQNAMEContent();
        screenSession.qname = qname;
        screenSession.qtype = gettxtQTYPEContent();
        screenSession.flag_RD = ((CheckBox) findViewById(R.id.cbRD)).isChecked();
        screenSession.flag_CD = ((CheckBox) findViewById(R.id.cbCD)).isChecked();
        screenSession.flag_DO = ((CheckBox) findViewById(R.id.cbDO)).isChecked();
        screenSession.qclass = (((Spinner) findViewById(R.id.spinnerCLASS))).getSelectedItem().toString();
        screenSession.server = gettxtResolverContent().trim();
        screenSession.TCP = ((CheckBox) findViewById(R.id.cbTCP)).isChecked();
        screenSession.protocol = (((Spinner) findViewById(R.id.spinnerProto))).getSelectedItem().toString();
        try {
            screenSession.port = gettxtPortContent();
        } catch (Exception e) {
        }
        return screenSession;
    }

    public void doLookup() {
        setStatusText("initializing");
        Session thisQuestion = sessionFromScreenState();
        doLookup(thisQuestion);
    }


    public void updateBookmarkImageState() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ImageButton btn = (ImageButton) findViewById(R.id.btnBookmark);
                Session sess = sessionFromScreenState();
                if (bookmarks.isBookmarked(sess)) {
                    btn.setImageResource(R.drawable.ic_bookmark_24px);
                } else {
                    btn.setImageResource(R.drawable.ic_bookmark_border_24px);
                }

            }
        });
    }

    public void toggleBookmark(View view) {
        final Session screenSession = sessionFromScreenState();
        AlertDialog.Builder adb = new AlertDialog.Builder(this);

        final boolean currentlyBookmarked = bookmarks.isBookmarked(screenSession);

        adb.setTitle("Bookmark current query?");
        if (currentlyBookmarked) {
            adb.setTitle("Remove current query from bookmarks?");
        }
        adb.setIcon(android.R.drawable.ic_dialog_alert);
        adb.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (!currentlyBookmarked) {
                    bookmarks.bookmark(screenSession);
                } else {
                    bookmarks.removeBookmark(screenSession);
                }
                updateBookmarkImageState();
            }
        });
        adb.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        adb.show();
    }

    public String hostToAddr(String hostname) {
        if (hostname == null || hostname == "") {
            hostname = ResolverConfig.getCurrentConfig().server();
            if (hostname == null) {
                hostname = "0";
            }
        }
        InetAddress addr;
        try {
            if (hostname.equals("0"))
                addr = InetAddress.getLocalHost();
            else
                addr = InetAddress.getByName(hostname);
            InetSocketAddress address = new InetSocketAddress(addr, 53);
            return address.getAddress().getHostAddress();
        } catch (UnknownHostException e) {

        }
        return "";
    }

    private void setAnswerFlagsToState(Header header, AnswerScreenState state) {
        state.flag_AA = header.getFlag(Flags.AA);
        state.flag_AD = header.getFlag(Flags.AD);
        state.flag_TC = header.getFlag(Flags.TC);
        state.flag_RD = header.getFlag(Flags.RD);
        state.flag_RA = header.getFlag(Flags.RA);
        state.flag_CD = header.getFlag(Flags.CD);
    }

    public String rrSetsToString(RRset[] rrsets) {
        StringBuffer ansBuffer = new StringBuffer();
        Iterator it;
        int i;

        for (i = 0; i < rrsets.length; i++) {
            RRset rrset = rrsets[i];
            it = rrset.rrs();

            while (it.hasNext()) {
                Record r = (Record) it.next();
                //Log.i(TAG, "rrsetstostring: type=" + r.getType());
                ansBuffer.append(r.toString());
                ansBuffer.append("\n");
            }

            //RRSIGs
            final Iterator<Record> sigIter = rrset.sigs();
            while (sigIter.hasNext()) {
                final Record sigRec = sigIter.next();

                ansBuffer.append(sigRec.toString());
                ansBuffer.append("\n");
            }
        }
        //replace tabs
        String ret = ansBuffer.toString().replace('\t', ' ');
        return ret;
    }

    private void setAnsTextFromThread(final String content) {

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ((EditText) findViewById(R.id.txtResult)).setText(content);
            }
        });
    }


    private void setAnsFlagFromThread(final int cbID, boolean checked) {
        final boolean set_checked = checked;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ((CheckBox) findViewById(cbID)).setChecked(set_checked);
            }
        });

    }

    public static void hideKeyboard(Activity activity) {
        if (isKeyboardVisible(activity)) {
            InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
            imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
        }
    }

    public static boolean isKeyboardVisible(Activity activity) {
        ///This method is based on the one described at http://stackoverflow.com/questions/4745988/how-do-i-detect-if-software-keyboard-is-visible-on-android-device
        Rect r = new Rect();
        View contentView = activity.findViewById(android.R.id.content);
        contentView.getWindowVisibleDisplayFrame(r);
        int screenHeight = contentView.getRootView().getHeight();

        int keypadHeight = screenHeight - r.bottom;

        return
                (keypadHeight > screenHeight * 0.15);
    }

    public void queryButtonClicked(View view) {
        clearAnswer();
        updateBookmarkImageState();
        hideKeyboard(this);

        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Animation anim = new AlphaAnimation(0.5f, 1.0f);
                    anim.setDuration(50); //You can manage the blinking time with this parameter
                    anim.setStartOffset(20);
                    anim.setRepeatMode(Animation.REVERSE);
                    anim.setRepeatCount(Animation.INFINITE);
                    ((Button) findViewById(R.id.button)).startAnimation(anim);


                    doLookup();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start();
    }

    private void setTextViewContent(final int viewID, final String text) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ((TextView) findViewById(viewID)).setText(text);
            }
        });

    }

    private void setStatusText(final String text) {
        setTextViewContent(R.id.txtStatusText, text);
    }

    private void setRcodeText(final String text) {
        setTextViewContent(R.id.txtRcode, text);
    }

    private void fillQTypes() {
        //
        List<String> spinnerArray = new ArrayList<String>();
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                this, android.R.layout.simple_spinner_item, spinnerArray);
        for (int i = 1; i <= 32769; i++) {
            String textual = Type.string(i);
            if (textual != null && !textual.startsWith("TYPE")) {
                spinnerArray.add(textual);
            }
        }
        Collections.sort(spinnerArray);
        (((Spinner) findViewById(R.id.spinnerKnownTypes))).setAdapter(adapter);
    }

    public void setDefaultPortFromProto() {
        Spinner spProtocol = (Spinner) findViewById(R.id.spinnerProto);
        String proto = (String) spProtocol.getSelectedItem();

        EditText etPort = (EditText) findViewById(R.id.txtPort);
        int defaultPort = 53;
        if (proto.equalsIgnoreCase("DoT")) {
            defaultPort = 853;
        }

        etPort.setText("" + defaultPort);

        //Port for DoH is in the URL
        if (proto.equalsIgnoreCase("DoH")) {
            etPort.setEnabled(false);
            etPort.setText("(from URI)");
        } else {
            etPort.setEnabled(true);
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        Spinner spProtocol = (Spinner) findViewById(R.id.spinnerProto);
        if (parent == spProtocol) {

            // set TCP flag state from proto
            String proto = (String) spProtocol.getSelectedItem();
            CheckBox tcpCheckbox = (CheckBox) findViewById(R.id.cbTCP);
            if (!proto.equalsIgnoreCase("DNS")) { //DoH and DoT are always TCP
                tcpCheckbox.setEnabled(false);
            } else {
                tcpCheckbox.setEnabled(true);
            }

            setDefaultPortFromProto();

        }

        // set qtype number from spinner
        Spinner spKnownTypes = (Spinner) findViewById(R.id.spinnerKnownTypes);
        if (parent == spKnownTypes) {
            String selected = (String) spKnownTypes.getSelectedItem();
            String selectedNumber = "" + Type.value(selected);
            (((EditText) findViewById(R.id.txtQTYPE))).setText(selectedNumber);
        }

        updateBookmarkImageState();
    }

    @Override
    public void onFocusChange(View view, boolean hasFocus) {

        EditText txtQtype = (((EditText) findViewById(R.id.txtQTYPE)));
        Spinner spKnownTypes = (Spinner) findViewById(R.id.spinnerKnownTypes);

        // set spinner qtype from number
        if (view == txtQtype && !hasFocus) {
            try {
                int qtype = gettxtQTYPEContent();
                String qnameString = Type.string(qtype);
                int ind = getIndex(spKnownTypes, qnameString, -1);
                if (ind > -1) {
                    spKnownTypes.setSelection(ind);
                }
            } catch (Exception e) {
            }
        }

        updateBookmarkImageState();

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


    public String gettxtResolverContent() {
        return getTextFieldContent(R.id.txtServerName);
    }

    public String gettxtQNAMEContent() {
        return getTextFieldContent(R.id.txtQname);
    }


    public int gettxtPortContent() {
        try {
            return Integer.valueOf(getTextFieldContent(R.id.txtPort)).intValue();
        } catch (NumberFormatException e) {
            return 53;
        }
    }

    public int gettxtQTYPEContent() {
        try {
            return Integer.valueOf(getTextFieldContent(R.id.txtQTYPE)).intValue();
        } catch (NumberFormatException e) {
            return 1;
        }
    }

    private String getTextFieldContent(int txtID) {
        return (((EditText) findViewById(txtID))).getText().toString();
    }

    private int getIndex(Spinner spinner, String myString) {
        return getIndex(spinner, myString, 0);
    }

    private int getIndex(Spinner spinner, String myString, int notFoundDefault) {
        int index = notFoundDefault;

        for (int i = 0; i < spinner.getCount(); i++) {
            if (spinner.getItemAtPosition(i).toString().equalsIgnoreCase(myString)) {
                index = i;
                break;
            }
        }
        return index;
    }


    public void showHelp() {
        Intent helpIntent = new Intent(this, HelpActivity.class);
        this.startActivity(helpIntent);
    }
}