package com.onw4rds.inventario;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

public class ac_inicio extends AppCompatActivity {
    // Variables relacionadas con la interfaz
    EditText et_empresa, et_pasillo, et_altura_min, et_altura_max, et_longitud, et_email;
    RadioButton rb_code128, rb_gs1_sscc, rb_gs1_0102, rb_gs1_plus;
    TextView tv_pantalla1, tv_pantalla2, tv_pantalla3;
    Button b_conectar, b_enviar, b_simple, b_multicapa, b_nueva_multicapa, b_hueco, b_incidencia, b_borrar;

    // Variables que tendremos que enviar por bluetooth
    boolean modotest = false;
    String empresa;
    String pasillo;
    String altura_min;
    String altura_max;
    String code;
    String longitud;
    String email;
    String datos;

    // Variables relacionadas con la conexión
    boolean conexion = false;
    public static String MAC = null;
    private static final UUID m_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    //UUID m_UUID = UUID.fromString("94f39d29-7d6d-437d-973b-fba39e49d4ee");

    // Variables relacionadas con el bluetooth
    private static final int ACTIVAR_BLUETOOTH = 1;
    BluetoothAdapter mBluetoothAdapter = null;
    BluetoothDevice mDevice = null;
    BluetoothSocket mSocket = null;

    // Variables relacionadas con la ListaDispositivos
    private static final int SOLICITAR_CONEXION = 2;

    // Variables relacionadas con la comunicación
    ConnectedThread connectedThread;
    Handler h;
    final int RECIEVE_MESSAGE = 1;
    //final int MESSAGE_READ = 3;
    //StringBuilder datosBluetooth = new StringBuilder();
    StringBuilder sb = new StringBuilder();

    // Otras variables
    boolean trabajando = false;
    String datosFinal;

    @SuppressLint("HandlerLeak")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.la_ac_inicio);

        // Establecemos cada uno de los elementos de la interfaz con el recolector R.id de Android
        et_empresa = findViewById(R.id.et_empresa);
        et_pasillo = findViewById(R.id.et_pasillo);
        et_altura_min = findViewById(R.id.et_altura_min);
        et_altura_max = findViewById(R.id.et_altura_max);
        et_longitud = findViewById(R.id.et_longitud);
        et_email = findViewById(R.id.et_email);
        rb_code128 = findViewById(R.id.rb_code128);
        rb_gs1_sscc = findViewById(R.id.rb_gs1_sscc);
        rb_gs1_0102 = findViewById(R.id.rb_gs1_0102);
        rb_gs1_plus = findViewById(R.id.rb_gs1_plus);
        tv_pantalla1 = findViewById(R.id.tv_pantalla1);
        tv_pantalla2 = findViewById(R.id.tv_pantalla2);
        tv_pantalla3 = findViewById(R.id.tv_pantalla3);
        b_conectar = findViewById(R.id.b_conectar);
        b_enviar = findViewById(R.id.b_enviar);
        b_simple = findViewById(R.id.b_simple);
        b_multicapa = findViewById(R.id.b_multicapa);
        b_nueva_multicapa = findViewById(R.id.b_nueva_multicapa);
        b_hueco = findViewById(R.id.b_hueco);
        b_incidencia = findViewById(R.id.b_incidencia);
        b_borrar = findViewById(R.id.b_borrar);

        // Captura de datos desde el bluetooth
        h = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                    case RECIEVE_MESSAGE:                                                   // if receive massage
                        byte[] readBuf = (byte[]) msg.obj;
                        String strIncom = new String(readBuf, 0, msg.arg1);          // create string from bytes array
                        sb.append(strIncom);                                                // append string
                        int endOfLineIndex = sb.indexOf("#");                            // determine the end-of-line
                        if (endOfLineIndex > 0) {                                           // if end-of-line,
                            String sbprint = sb.substring(0, endOfLineIndex);               // extract string
                            sb.delete(0, sb.length());                                      // and clear

                            String pantalla3 = tv_pantalla2.getText().toString();
                            String pantalla2 = tv_pantalla1.getText().toString();
                            String pantalla1 = sbprint;
                            tv_pantalla1.setText(pantalla1);
                            tv_pantalla2.setText(pantalla2);
                            tv_pantalla3.setText(pantalla3);

                            //btnOff.setEnabled(true);
                            //btnOn.setEnabled(true);
                        }
                        Log.d("mensaje", "...String:"+ sb.toString() +  "Byte:" + msg.arg1 + "...");
                        break;
                }
            }
        };




        /*
        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {

                if(msg.what == MESSAGE_READ ){
                    String recibidos = (String) msg.obj;
                    datosBluetooth.append(recibidos);
                    int finInformacion = datosBluetooth.indexOf("#");
                    if(finInformacion > 0){
                        // De la cadena recibida hasta #
                        String datosCompletos = datosBluetooth.substring(0, finInformacion);
                        int tamInformacion = datosCompletos.length();
                        // Comenzando en #
                        if(datosBluetooth.charAt(0) == '#'){
                            // Solo nos quedamos con lo que hay en medio
                            datosFinal = datosBluetooth.substring(1, tamInformacion);
                            tv_pantalla.setText(datosFinal);
                            Log.d("rec1", datosFinal);
                            Log.e("rec2", datosFinal);

                        }
                        datosBluetooth.delete(0, datosBluetooth.length());
                    }
                }
            }
        };
        */


        /* Lo primero es buscar el adaptador bluetooth del dispositivo, si no existe tal adaptador
         * es que nuestro teléfono no puede establecer este tipo de conexiones y nos arrojará un null, y en
         * consecuencia un Toast informando al usuario de este problema.
         *
         * Lo segundo es que si disponemos de adaptador bluetooth lo segundo es verificar que este activo para poder
         * trabajar con el. En caso de que no este activo tras el else lanzamos un intent (intentar) activar el adaptador.*/
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            Toast.makeText(getApplicationContext(), "Dispositivo no compatible con bluetooth", Toast.LENGTH_LONG).show();
        } else if (!mBluetoothAdapter.isEnabled()) {
            Intent activarbluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(activarbluetooth, ACTIVAR_BLUETOOTH); // extrae resultados desde las clases del activity
        }


        // Definimos lo que debe suceder cuando pulsemos el boton conectar
        b_conectar.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                // Desconectar
                if(conexion) {
                    try {
                        mSocket.close();
                        conexion = false;
                        b_conectar.setText("Conectar");
                        Toast.makeText(getApplicationContext(), "Bluetooth desconectado", Toast.LENGTH_LONG).show();
                    } catch (IOException erro) {
                        Toast.makeText(getApplicationContext(), "Error: " + erro, Toast.LENGTH_LONG).show();
                    }
                } else{
                    // Conectar
                    Intent abreLista = new Intent(ac_inicio.this, ListaDispositivos.class);
                    startActivityForResult(abreLista, SOLICITAR_CONEXION);
                }
            }
        });


        // Definimos lo que debe suceder cuando pulsamos el botón iniciar
        b_enviar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(conexion){
                    if(!trabajando){
                        empresa = et_empresa.getText().toString();
                        pasillo = et_pasillo.getText().toString();
                        altura_min = et_altura_min.getText().toString();
                        altura_max = et_altura_max.getText().toString();
                        // Definimos la longitud por defecto
                        longitud = "45";
                        if(rb_code128.isChecked()){
                            longitud = et_longitud.getText().toString();
                            code = "code_128."+longitud;
                        }
                        if(rb_gs1_sscc.isChecked()){
                            code = "code_gs1_sscc";
                        }
                        if(rb_gs1_0102.isChecked()){
                            code = "code_gs1_0102";
                        }
                        if(rb_gs1_plus.isChecked()){
                            code = "code_gs1_plus";
                        }
                        email = et_email.getText().toString();

                        datos = empresa+"|"+pasillo+"|"+altura_min+"|"+altura_max+"|"+code+"|"+email;
                        //
                        // Enviamos los datos por bluetooth
                        connectedThread.enviar(datos);
                        //
                        b_enviar.setText("terminar");
                        trabajando = true;
                        Toast.makeText(getApplicationContext(), "Puede iniciar el trabajo", Toast.LENGTH_LONG).show();
                        // Pondremos la configuración del pasillo en blanco
                        et_pasillo.setText("");
                    }else{
                        datos = "finish";
                        connectedThread.enviar(datos);
                        b_enviar.setText("iniciar");
                        trabajando = false;
                        Toast.makeText(getApplicationContext(), "Puede iniciar un nuevo trabajo", Toast.LENGTH_LONG).show();
                    }

                }else{
                    Toast.makeText(getApplicationContext(), "Conecte con dispositivo previamente", Toast.LENGTH_LONG).show();
                }
            }
        });

        // Definimos lo que tiene que ocurrir al pulsar cada uno de los botones que quedan
        b_simple.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if ((conexion) && (trabajando)) {
                    datos = "simple";
                    connectedThread.enviar(datos);
                } else {
                    Toast.makeText(getApplicationContext(), "Solo disponible durante trabajo", Toast.LENGTH_LONG).show();
                }
            }
        });

        b_multicapa.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if ((conexion) && (trabajando)) {
                    datos = "multilayer";
                    connectedThread.enviar(datos);
                } else {
                    Toast.makeText(getApplicationContext(), "Solo disponible durante trabajo", Toast.LENGTH_LONG).show();
                }
            }
        });

        b_nueva_multicapa.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if ((conexion) && (trabajando)) {
                    datos = "new_multilayer";
                    connectedThread.enviar(datos);
                } else {
                    Toast.makeText(getApplicationContext(), "Solo disponible durante trabajo", Toast.LENGTH_LONG).show();
                }
            }
        });

        b_hueco.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if ((conexion) && (trabajando)) {
                    datos = "hole";
                    connectedThread.enviar(datos);
                } else {
                    Toast.makeText(getApplicationContext(), "Solo disponible durante trabajo", Toast.LENGTH_LONG).show();
                }
            }
        });

        b_incidencia.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if ((conexion) && (trabajando)) {
                    datos = "incidence";
                    connectedThread.enviar(datos);
                } else {
                    Toast.makeText(getApplicationContext(), "Solo disponible durante trabajo", Toast.LENGTH_LONG).show();
                }
            }
        });

        b_borrar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if ((conexion) && (trabajando)) {
                    datos = "delete";
                    connectedThread.enviar(datos);
                } else {
                    Toast.makeText(getApplicationContext(), "Solo disponible durante trabajo", Toast.LENGTH_LONG).show();
                }
            }
        });

    }



    // Hemos llamado a un starActivityForResult para el ACTIVAR_BLUETOOTH, tenemos que lanzar una función para analizar los resultados.
    // Si lanza un ok el usuario ha activado el bluetooth, pero si lanza un not, el bluetooth no ha sido iniciado y debemos cerrar la app,
    // ya que sin bluetooth no tiene sentido de uso.
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        switch (requestCode){

            case ACTIVAR_BLUETOOTH:
                if(resultCode == Activity.RESULT_OK){
                    Toast.makeText(getApplicationContext(), "Bluetooth activado", Toast.LENGTH_LONG).show();
                }else{
                    Toast.makeText(getApplicationContext(), "Bluetooth no activado. App Inventario necesita bluetooth para funcionar.", Toast.LENGTH_LONG).show();
                    finish();
                }
                break;

            case SOLICITAR_CONEXION:
                if(resultCode == Activity.RESULT_OK){
                    MAC = data.getExtras().getString(ListaDispositivos.DIRECCION_MAC);
                    // Toast.makeText(getApplicationContext(), "MAC: " + MAC, Toast.LENGTH_LONG).show();
                    // Si tenemos una MAC realizamos la conexión al dispositivo con esa MAC y después intentaremos
                    // crear una conexión tipo socket.
                    mDevice = mBluetoothAdapter.getRemoteDevice(MAC);
                    try{
                        mSocket = mDevice.createRfcommSocketToServiceRecord(m_UUID);
                        mSocket.connect();
                        conexion = true;
                        /* En el momento que hacemos la conexión creamos también el canal thread con el que
                         * enviaremos y recibiremos datos.
                         */
                        connectedThread = new ConnectedThread(mSocket);
                        connectedThread.start();
                        //
                        // Cambiamos el diseño del boron conectar por desconectar
                        b_conectar.setText("Desconectar");
                        Toast.makeText(getApplicationContext(), "Conectado con: " + MAC, Toast.LENGTH_LONG).show();
                    }catch (IOException error){
                        conexion = false;
                        Toast.makeText(getApplicationContext(), "Error " + error, Toast.LENGTH_LONG).show();
                    }
                }else{
                    Toast.makeText(getApplicationContext(), "Error de MAC", Toast.LENGTH_LONG).show();
                }



        }
    }


    private class ConnectedThread extends Thread {
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        ConnectedThread(BluetoothSocket socket) {
            //mSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {
            byte[] buffer = new byte[1024];  // buffer store for the stream
            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.read(buffer);
                    h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget();
                    //String datosbt = new String(buffer, 0, bytes);
                    // Send the obtained bytes to the UI activity
                    //Toast.makeText(getApplicationContext(), datosbt, Toast.LENGTH_LONG).show();
                    //tv_pantalla.setText(datosFinal);
                    //mHandler.obtainMessage(MESSAGE_READ, bytes, -1, datosbt).sendToTarget();
                    //h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, datosbt).sendToTarget();
                } catch (IOException erro) {
                    Toast.makeText(getApplicationContext(), "Error: " + erro, Toast.LENGTH_LONG).show();
                    break;
                }
            }
        }

        /* Call this from the main activity to send data to the remote device */
        void enviar(String datosEnviar) {
            byte[] msgBuffer = datosEnviar.getBytes();
            try {
                mmOutStream.write(msgBuffer);
            } catch (IOException e) { }
        }

        /* Call this from the main activity to shutdown the connection */
        //public void cancel() {
        //    try {
        //        mSocket.close();
        //    } catch (IOException e) { }
        //}
    }


}
