package com.gun.fresh.turret;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.Toast;

import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;

/*
Author: Rezk Bouras
Email: rezk.bouras@gmail.com
*/

/*
Code Modified for Vulcan Sentry Gun by: Connor Dyke
Email: connordyke@hotmail.com
Date: February 25th, 2016
*/

public class MainActivity extends AppCompatActivity {
    /**
     * Declarations
     */
    // set the ip address.
    //private String gunIP = "192.168.10.102";
    private String gunIP = "192.168.19.107"; //Vulcan Turret
    // set the port.
    private int gunPort = 1994;
    private WebView streamView;
    private Button btnConnect;

    private Button btnDisconnect;
    private Button btnFire;
    private Button btnStream;
    private EditText txtStreamURI;
    private EditText txtIP;
    private SeekBar tiltChanger;
    private SeekBar panChanger;
    private Switch switchScan, switchFire;
    // set command to send.
    private char commandToSend;
    // Declare a tcp client.
    TCPClient client;
    // make a thread of maximum limit 10000 threads.
    Thread[] threads = new Thread[10000];
    // thread counter.
    int threadsCounter = 0;

    //Tilt array
    char[] tiltArray = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
            'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};

    //Tilt array
    char[] panArray = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
            'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

    String buttonPressed;
    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    private GoogleApiClient client2;

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

        // Initialize the controls ..... \\

        // streamViewer = (VideoView) findViewById(R.id.streamView);
        btnConnect = (Button) findViewById(R.id.btnConnect);
        btnDisconnect = (Button) findViewById(R.id.btnDisconnect);
        btnFire = (Button) findViewById(R.id.btnFire);
        btnStream = (Button) findViewById(R.id.btnStream);
        txtIP = (EditText) findViewById(R.id.txtIP);
        txtStreamURI = (EditText) findViewById(R.id.txtStreamURI);
        panChanger = (SeekBar) findViewById(R.id.panChanger);
        tiltChanger = (SeekBar) findViewById(R.id.tiltChanger);
        streamView = (WebView) findViewById(R.id.wvStream);
        switchScan = (Switch) findViewById(R.id.switchScan);
        switchFire = (Switch) findViewById(R.id.switchFire);

        // End of Initialize the controls ..... \\

        //Set the pan and tilt seekbars to 12 (half way), this is done for user experience
        panChanger.setProgress(12);
        tiltChanger.setProgress(12);

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

                //Get the IP input by the user
                gunIP = txtIP.getText().toString();

                // are we connected?
                if (!client.isConnected) {
                    // make a new thread for connecting.
                    threads[threadsCounter] = new Thread(new ClientThread());
                    // start thread we created.
                    threads[threadsCounter].start();
                    // increase counter.
                    threadsCounter++;
                }
            }
        });

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

                //If the switch is enabled, shoot a 3 round burst
                if (switchFire.isChecked()) {
                    for (int i = 0; i < 3; i++) {
                        commandToSend = '0';
                        new MyTask().execute();
                        //Toast.makeText(MainActivity.this, "Burst " + i, Toast.LENGTH_SHORT).show();
                    }
                } else { //else shoot one shot

                        commandToSend = '0';
                        new MyTask().execute();
                        //Toast.makeText(MainActivity.this, "Semi-Auto shot", Toast.LENGTH_SHORT).show();
                }

            }
        });

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

                if (!switchFire.isChecked()) {
                    for (int i = 0; i < 25; i++) {
                        commandToSend = '0';
                        new MyTask().execute();
                        //Toast.makeText(MainActivity.this, "Fully Auto", Toast.LENGTH_SHORT).show();
                    }
                }

            }
        });


        switchScan.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                //If the the scan switch is enabled...
                if (isChecked){
                    //Disable the pan changer seekbar so the user cannot modify the pan while
                    //the turret is autonomously panning
                    panChanger.setEnabled(false);

                    //Send the '+' character which turns on the autonomous panning
                    commandToSend = '+';
                    new MyTask().execute(); //Execute task
                }else{ //If the scan switch is disabled...
                    panChanger.setEnabled(true); //Enable the pan changer

                    //Send the '-' character (this stops the turret in its tracks)
                    commandToSend = '-';
                    new MyTask().execute();
                }

            }
        });

        panChanger.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                //Debugging toast to see which position the slider is at
                //Toast.makeText(getApplicationContext(), "The turret will now pan to the position #" + progress, Toast.LENGTH_SHORT).show();

                //Send the correct letter to send a pan position command (0-25)
                commandToSend = panArray[progress];

                //Execute the task
                new MyTask().execute();
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                //Currently does nothing
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

                /****** Moved code to onProgressChanged listener ****/
                /*
                int progress = seekBar.getProgress(); // Get the "int" type progress number of the seek bar that has been selected by the user.

                //Debugging toast to see which position the slider is at
                //Toast.makeText(getApplicationContext(), "The turret will now pan to the position #" + progress, Toast.LENGTH_SHORT).show();

                //Send the correct letter to send a pan position command (0-25)
                commandToSend = panArray[progress];

                //Execute the task
                new MyTask().execute(); */
            }
        });

        tiltChanger.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                //Debugging toast to see which position the slider is at
                //Toast.makeText(getApplicationContext(), "The turret will now tilt to the position #" + progress, Toast.LENGTH_SHORT).show();

                //Send the correct letter to send a tilt position command (0-25)
                commandToSend = tiltArray[progress];

                //Execute the task
                new MyTask().execute();
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                //Currently does nothing
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {


                /****** Moved code to onProgressChanged listener ****/
                /*
                int progress = seekBar.getProgress(); // Get the "int" type progress number of the seek bar that has been selected by the user.

                //Debugging toast to see which position the slider is at
                //Toast.makeText(getApplicationContext(), "The turret will now tilt to the position #" + progress, Toast.LENGTH_SHORT).show();

                //Send the correct letter to send a tilt position command (0-25)
                commandToSend = tiltArray[progress];

                //Execute the task
                new MyTask().execute(); */
            }
        });

        btnStream.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String uri = txtStreamURI.getText().toString(); // Get the URI of the raspberry pi cam stream service that has been entered by the user, this should look like something like that: http://192.168.*.*:8090/stream
                // where uri is should start with "http://" and end after the ip with ":8090/stream" the port and the dir of the stream.

                if(savedInstanceState == null) // Check if there is already save instance of WebView, this is  generally to prevent WebView from reloading when rotating
                    streamView.loadUrl(uri); // Load the stream, the stream type that we are receiving in here is m-jpeg (Multiple Jpeg Streaming?)
            }
        });

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client2 = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();

    }


    @Override  // Trigger saving an instance of the WebView event
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        streamView.saveState(outState);
    }

    @Override // Trigger restoring an instance of the WebView event
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        streamView.restoreState(savedInstanceState);
    }

    @Override
    public void onStart() {
        super.onStart();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client2.connect();
        Action viewAction = Action.newAction(
                Action.TYPE_VIEW, // TODO: choose an action type.
                "Main Page", // TODO: Define a title for the content shown.
                // TODO: If you have web page content that matches this app activity's content,
                // make sure this auto-generated web page URL is correct.
                // Otherwise, set the URL to null.
                Uri.parse("http://host/path"),
                // TODO: Make sure this auto-generated app deep link URI is correct.
                Uri.parse("android-app://com.gun.fresh.turret/http/host/path")
        );
        AppIndex.AppIndexApi.start(client2, viewAction);
    }

    @Override
    public void onStop() {
        super.onStop();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        Action viewAction = Action.newAction(
                Action.TYPE_VIEW, // TODO: choose an action type.
                "Main Page", // TODO: Define a title for the content shown.
                // TODO: If you have web page content that matches this app activity's content,
                // make sure this auto-generated web page URL is correct.
                // Otherwise, set the URL to null.
                Uri.parse("http://host/path"),
                // TODO: Make sure this auto-generated app deep link URI is correct.
                Uri.parse("android-app://com.gun.fresh.turret/http/host/path")
        );
        AppIndex.AppIndexApi.end(client2, viewAction);
        client2.disconnect();
    }

    class MyTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {

            try {
                // set the user command and send it to server side.
                client.send(commandToSend);
            } catch (Exception e) {
                //e.printStackTrace();
            }

        /*    if(received != null) {
                txtReplay.append(received);
            } */

            return null;
        }
    }


    /**
     * Runnable thread (Multi Thread) that will run for us to initiate the connection, if there is no connection thread will crash but the app will not.
     */
    class ClientThread implements Runnable {

        boolean isWorking = true;

        @Override
        public void run() {
            // Get the connectivity service that will allow us use the tcp protocol in the phone to send our packets.
            ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
            // Get network info, last status of device connectivity.
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

            if (networkInfo != null && networkInfo.isConnected() && networkInfo.isAvailable()) // If device is connected to a network then do the following ...
            {
                // Set a new instance of TCPClient class.
                client = new TCPClient(gunIP, gunPort); // start a new tcp client
                // Initiate connection session.
                client.initiateConnection(); // initiate tcp connection
            } else {
                final int SHORT_DELAY = 2000; // 2 seconds //  give a delay of 2 seconds (2000 ms)
                // PROMPT USER THAT NETWORK IS DISCONNECT
                Toast.makeText(MainActivity.this, "There is no active network connection!", Toast.LENGTH_SHORT).show(); // Show a toast message for the user ...

            }

        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
