// Path: app/src/main/java/project/android/net/KeyboardThread.java
// public class KeyboardThread implements Runnable {
// 
//     private boolean mStopFlag;
//     private LinkedBlockingQueue<Pair<String, Boolean>> mBuffer;
// 
//     private static final long POLL_TIMEOUT = 100;
//     private static final TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS;
// 
//     /**
//      * Constructor.
//      *
//      * Initializes this thread.
//      */
//     public KeyboardThread() {
//         mStopFlag = false;
//         mBuffer = new LinkedBlockingQueue<>();
//     }
// 
//     /**
//      * Inserts keyboard data to the buffer.
//      *
//      * This data is sent to the server by this <code>KeyboardThread</code>.
//      *
//      * @param data the data to be sent.
//      * @param isSpecialKey <code>true</code>, if <code>data</code> represents
//      *                     special key, <br/>
//      *                     <code>false</code>, otherwise.
//      */
//     public void addToBuffer(String data, boolean isSpecialKey) {
//         try {
//             mBuffer.put(Pair.create(data, isSpecialKey));
//         } catch (InterruptedException e) { e.printStackTrace(); }
//     }
// 
//     /**
//      * Sets stop flag.
//      *
//      * Used to exit from the {@link #run()} method.
//      */
//     public void setStopFlag() { mStopFlag = true; }
// 
//     /**
//      * Performs the sending of keyboard data in the buffer to the server.
//      *
//      * <p>
//      *     It checks if data is available in the buffer.
//      *     <ul>
//      *         <li>If available, it sends the data.</li>
//      *         <li>Otherwise, it waits for the data to be available.</li>
//      *     </ul>
//      * </p>
//      */
//     @Override
//     public void run() {
//         while(!mStopFlag) {
//             try {
//                 Pair<String, Boolean> data = mBuffer.poll(POLL_TIMEOUT, TIME_UNIT);
//                 if(data != null) {
//                     if (data.second) {
//                         sSecuredClient.sendData(data.first);
//                     } else sSecuredClient.sendData("Key", data.first);
// //                Log.d("Keyboard sent", data.first + "__>" + data.first.length());
//                 }
//             } catch (InterruptedException e) { e.printStackTrace(); }
//         }
//     }
// }
// 
// Path: app/src/main/java/project/android/ConnectionFragment.java
// public static HashMap<String, Boolean> sConnectionAlive = new HashMap<>();


import android.content.Context;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.PasswordTransformationMethod;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import project.android.net.KeyboardThread;
import static project.android.ConnectionFragment.sConnectionAlive;
            R.id.upArrow,     //24
            R.id.downArrow,  //25
            R.id.leftArrow,  //26
            R.id.rightArrow  //27
    };

    /**
     * Overrides the
     * <code>Fragment.onCreateView(LayoutInflater, ViewGroup, Bundle)</code>
     * of the Android API.
     *
     * Called to have the fragment instantiate its user interface view.
     *
     * @param inflater The <code>LayoutInflater</code> object that can be
     *                 used to inflate any views in the fragment.
     * @param container If non-null, this is the parent view that the
     *                  fragment's UI is attached to. The fragment should
     *                  not add the view itself, but this can be used to
     *                  generate the <code>LayoutParams</code> of the view.
     * @param savedInstanceState If non-null, this fragment is being
     *                           re-constructed from a previous saved
     *                           state as given here.
     * @return the <code>View</code> for the fragment's UI, or <code>null</code>.
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_keyboard, container, false);
        mInput = null;
        mLastInput = null;
// Path: app/src/main/java/project/android/net/KeyboardThread.java
// public class KeyboardThread implements Runnable {
// 
//     private boolean mStopFlag;
//     private LinkedBlockingQueue<Pair<String, Boolean>> mBuffer;
// 
//     private static final long POLL_TIMEOUT = 100;
//     private static final TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS;
// 
//     /**
//      * Constructor.
//      *
//      * Initializes this thread.
//      */
//     public KeyboardThread() {
//         mStopFlag = false;
//         mBuffer = new LinkedBlockingQueue<>();
//     }
// 
//     /**
//      * Inserts keyboard data to the buffer.
//      *
//      * This data is sent to the server by this <code>KeyboardThread</code>.
//      *
//      * @param data the data to be sent.
//      * @param isSpecialKey <code>true</code>, if <code>data</code> represents
//      *                     special key, <br/>
//      *                     <code>false</code>, otherwise.
//      */
//     public void addToBuffer(String data, boolean isSpecialKey) {
//         try {
//             mBuffer.put(Pair.create(data, isSpecialKey));
//         } catch (InterruptedException e) { e.printStackTrace(); }
//     }
// 
//     /**
//      * Sets stop flag.
//      *
//      * Used to exit from the {@link #run()} method.
//      */
//     public void setStopFlag() { mStopFlag = true; }
// 
//     /**
//      * Performs the sending of keyboard data in the buffer to the server.
//      *
//      * <p>
//      *     It checks if data is available in the buffer.
//      *     <ul>
//      *         <li>If available, it sends the data.</li>
//      *         <li>Otherwise, it waits for the data to be available.</li>
//      *     </ul>
//      * </p>
//      */
//     @Override
//     public void run() {
//         while(!mStopFlag) {
//             try {
//                 Pair<String, Boolean> data = mBuffer.poll(POLL_TIMEOUT, TIME_UNIT);
//                 if(data != null) {
//                     if (data.second) {
//                         sSecuredClient.sendData(data.first);
//                     } else sSecuredClient.sendData("Key", data.first);
// //                Log.d("Keyboard sent", data.first + "__>" + data.first.length());
//                 }
//             } catch (InterruptedException e) { e.printStackTrace(); }
//         }
//     }
// }
// 
// Path: app/src/main/java/project/android/ConnectionFragment.java
// public static HashMap<String, Boolean> sConnectionAlive = new HashMap<>();


// Path: app/src/main/java/project/android/KeyboardFragment.java
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.PasswordTransformationMethod;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import project.android.net.KeyboardThread;
import static project.android.ConnectionFragment.sConnectionAlive;

            R.id.upArrow,     //24
            R.id.downArrow,  //25
            R.id.leftArrow,  //26
            R.id.rightArrow  //27
    };

    /**
     * Overrides the
     * <code>Fragment.onCreateView(LayoutInflater, ViewGroup, Bundle)</code>
     * of the Android API.
     *
     * Called to have the fragment instantiate its user interface view.
     *
     * @param inflater The <code>LayoutInflater</code> object that can be
     *                 used to inflate any views in the fragment.
     * @param container If non-null, this is the parent view that the
     *                  fragment's UI is attached to. The fragment should
     *                  not add the view itself, but this can be used to
     *                  generate the <code>LayoutParams</code> of the view.
     * @param savedInstanceState If non-null, this fragment is being
     *                           re-constructed from a previous saved
     *                           state as given here.
     * @return the <code>View</code> for the fragment's UI, or <code>null</code>.
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_keyboard, container, false);
        mInput = null;
        mLastInput = null;
        if(sConnectionAlive.containsValue(true)) {