// Path: app/src/main/java/org/hexpresso/elm327/commands/Command.java
// public interface Command {
// 
//     void execute(InputStream in, OutputStream out) throws IOException, InterruptedException;
// 
//     Response getResponse();
// }


import org.hexpresso.elm327.commands.Command;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;

package org.hexpresso.elm327.io;



/**
 * Created by Pierre-Etienne Messier <pierre.etienne.messier@gmail.com> on 2015-10-27.
 */
public class Protocol {
    //
    private LinkedBlockingQueue<Message> mMessageInputQueue = new LinkedBlockingQueue<>();
    private Thread mExecutionThread = null;

    //
    private LinkedBlockingQueue<Message> mMessageOutputQueue = new LinkedBlockingQueue<>();
    private Thread mProcessingThread = null;
    private List<MessageReceivedListener> mMessageReceivedListeners = new ArrayList<>();

    // Input/output streams
    private InputStream mInputStream = null;
    private OutputStream mOutputStream = null;

    public Protocol() {

        // Thread used to execute ELM327 commands
        mExecutionThread = new Thread(new Runnable() {
            @Override
            public void run() {
                executeMessages();
            }
        });

        // Thread used to process the received messages
        mProcessingThread = new Thread(new Runnable() {
            @Override
            public void run() {
                processReceivedMessages();
            }
        });
    }

    /**
     * Adds the specified Command to the message queue and execute it
     * @param command Command to execute
     * @return True if the command was successfully added, false otherwise
     */

// Path: app/src/main/java/org/hexpresso/elm327/commands/Command.java
// public interface Command {
// 
//     void execute(InputStream in, OutputStream out) throws IOException, InterruptedException;
// 
//     Response getResponse();
// }


// Path: app/src/main/java/org/hexpresso/elm327/io/Protocol.java
import org.hexpresso.elm327.commands.Command;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;

package org.hexpresso.elm327.io;



/**
 * Created by Pierre-Etienne Messier <pierre.etienne.messier@gmail.com> on 2015-10-27.
 */
public class Protocol {
    //
    private LinkedBlockingQueue<Message> mMessageInputQueue = new LinkedBlockingQueue<>();
    private Thread mExecutionThread = null;

    //
    private LinkedBlockingQueue<Message> mMessageOutputQueue = new LinkedBlockingQueue<>();
    private Thread mProcessingThread = null;
    private List<MessageReceivedListener> mMessageReceivedListeners = new ArrayList<>();

    // Input/output streams
    private InputStream mInputStream = null;
    private OutputStream mOutputStream = null;

    public Protocol() {

        // Thread used to execute ELM327 commands
        mExecutionThread = new Thread(new Runnable() {
            @Override
            public void run() {
                executeMessages();
            }
        });

        // Thread used to process the received messages
        mProcessingThread = new Thread(new Runnable() {
            @Override
            public void run() {
                processReceivedMessages();
            }
        });
    }

    /**
     * Adds the specified Command to the message queue and execute it
     * @param command Command to execute
     * @return True if the command was successfully added, false otherwise
     */

    public boolean addCommand(Command command) {
