package diploma.eu.cz.karel.smarthome;

import android.app.AlertDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.ToggleButton;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.concurrent.ExecutionException;

/**
 * @author DolezalK
 */

public class NetworkService extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private Switch light_LR, gate, plug_LR, light_mainKitchen, light_sideboardKitchen;
    private ToggleButton door_entry, alarm_entry;
    private ImageView temp_icon;
    private TextView currenttemp;
    private JSONObject tempdata;
    private Button connect, camera, graph_LR, graph_garden;
    private ObjectInputStream in;
    private ObjectOutputStream out;
    private Socket socket;
    private JSONObject response = null;

    int icon_id,color_id;

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

        /////////////////////////////////////////////////////// driwer menu //////////////////////////////////////////////////////////////
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

//////////////////////////////////////////////////////////////// update temperature //////////////////////////////////////////////////////
        temp_icon = (ImageView)findViewById(R.id.img_currenttemp);
        currenttemp = (TextView)findViewById(R.id.main_txt_currenttemp);
        try {
            UpdateData();
        } catch (JSONException e) {
            e.printStackTrace();
        }

///////////////////////////////////////////////////////////////// widgets /////////////////////////////////////////////////////////////
        light_LR = (Switch) findViewById(R.id.net_swtch_LR);
        gate = (Switch) findViewById(R.id.gate);
        light_mainKitchen = (Switch) findViewById(R.id.net_mainLight_kitchen);
        plug_LR = (Switch) findViewById(R.id.net_plug_LR);
        light_sideboardKitchen = (Switch) findViewById(R.id.net_sideboardLight_kitchen);
        camera = (Button) findViewById(R.id.btn_watch);
        graph_LR = (Button) findViewById(R.id.btn_graph_LR);
        graph_garden = (Button) findViewById(R.id.btn_graph_garden);
        alarm_entry = (ToggleButton) findViewById(R.id.net_alarm_entry);
        door_entry = (ToggleButton) findViewById(R.id.door_enter);

        light_LR.setChecked(Config.isLight(false));
        door_entry.setChecked(Config.isDoor(false));
        gate.setChecked(Config.isGate(false));
        light_mainKitchen.setChecked(Config.isLightMK(false));
        alarm_entry.setChecked(Config.isAlarm(false));
        plug_LR.setChecked(Config.isPlug(false));
        light_sideboardKitchen.setChecked(Config.isLightSK(false));

        camera.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(NetworkService.this, WatchCamera.class);
                startActivity(intent);
            }
        });

        graph_LR.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(NetworkService.this, ChartActivity.class);
                startActivity(intent);
            }
        });

        graph_garden.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(NetworkService.this, ChartActivity.class);
                startActivity(intent);
            }
        });

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

                    if (isChecked) {
                        lightOn(1);
                    } else {
                        lightOff(1);
                    }
            }
        });

        gate.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton switchView,
                                         boolean isChecked) {
                if (isChecked) {
                    lightOn(2);

                } else {
                    lightOff(2);
                }
            }

        });

        door_entry.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
        {
            @Override
            public void onCheckedChanged(CompoundButton toggleButtonView,
                                         boolean isChecked) {
                if (isChecked) {
                    lightOn(3);

                } else {
                    lightOff(3);
                }
            }
        });

        light_mainKitchen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
        {
            @Override
            public void onCheckedChanged(CompoundButton toggleButtonView,
                                         boolean isChecked) {
                if (isChecked) {
                    lightOn(4);

                } else {
                    lightOff(4);
                }
            }
        });

        light_sideboardKitchen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
        {
            @Override
            public void onCheckedChanged(CompoundButton toggleButtonView,
                                         boolean isChecked) {
                if (isChecked) {
                    lightOn(5);

                } else {
                    lightOff(5);
                }
            }
        });

        plug_LR.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
        {
            @Override
            public void onCheckedChanged(CompoundButton toggleButtonView,
                                         boolean isChecked) {
                if (isChecked) {
                    lightOn(6);

                } else {
                    lightOff(6);
                }
            }
        });

        alarm_entry.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
        {
            @Override
            public void onCheckedChanged(CompoundButton toggleButtonView,
                                         boolean isChecked) {
                if (isChecked) {
                    lightOn(7);

                } else {
                    lightOff(7);
                }
            }
        });

    } //end Create

    @Override
    protected void onStart(){
        super.onStart();
        try{
            Connection connection = new Connection();
            connection.execute();

        } catch (NumberFormatException e) {
            showErrorsMessages("Connection failed !!!");
        }
    }

    @Override
    protected void onResume(){
        super.onResume();
        try{
            Connection connection = new Connection();
            connection.execute();
        } catch (NumberFormatException e) {
            showErrorsMessages("Connection failed !!!");
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
            closeConnection();
            SavePreferences();
    }

    @Override
    protected void onStop() {
        super.onStop();
                closeConnection();
                SavePreferences();
    }

    public void closeConnection() {
        try {
                out.writeObject("close");
                out.close();
                in.close();
                socket.close();

        } catch (IOException ex) {
            ex.printStackTrace();
            showErrorsMessages(ex.getMessage());
        }
    }//end closeConnection

    @Override
    protected void onRestart(){
        super.onRestart();
        try {
            UpdateData();

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    ////////////////////////////////////////////////////// saving status /////////////////////////////////////////////////////////////////////

    private void SavePreferences(){
        Config.setLight(light_LR.isChecked()); //save true or false switch
        Config.setDoor(door_entry.isChecked());
        Config.setGate(gate.isChecked());
        Config.setLightMK(light_mainKitchen.isChecked());
        Config.setLightSK(light_sideboardKitchen.isChecked());
        Config.setPlug(plug_LR.isChecked());
        Config.setAlarm(alarm_entry.isChecked());
    }

    //////////////////////////////////////////// STATUS SWITCH sending int COMMAND into server ////////////////////////////////////////////////////////
    public void lightOn(int lednum) {
        try {

                out.writeObject(lednum + "1");
                out.flush();
                out.writeObject("end");

        } catch (IOException e) {
            e.printStackTrace();
            showErrorsMessages("Connection not established with your home!!!");

        }
    }

    public void lightOff(int lednum) {
        try {
                out.writeObject(lednum + "0");
                out.flush();
                out.writeObject("end");

        } catch (IOException e) {
            e.printStackTrace();
            showErrorsMessages("Connection not established with your home!!!");
        }
    }

    public void checkSwitchStatus() {
        if (light_LR.isChecked()) {
            lightOn(1);
        } else {
            lightOff(1);
        }
        if (gate.isChecked()) {
            lightOn(2);
        } else {
            lightOff(2);
        }
        if (door_entry.isChecked()) {
            lightOn(3);
        } else {
            lightOff(3);
        }
        if (light_mainKitchen.isChecked()) {
            lightOn(4);
        } else {
            lightOff(4);
        }
        if (light_sideboardKitchen.isChecked()) {
            lightOn(5);
        } else {
            lightOff(5);
        }
        if (plug_LR.isChecked()) {
            lightOn(6);
        } else {
            lightOff(6);
        }
        if (alarm_entry.isChecked()) {
            lightOn(7);
        } else {
            lightOff(7);
        }
    }

    void showErrorsMessages(String error) {
        AlertDialog.Builder dialog = new AlertDialog.Builder(NetworkService.this);
        dialog.setTitle("Error!! ").setMessage(error).setNeutralButton("OK", null).create().show();
    }

    ///////////////////////////////////////////////////////// update temperature ////////////////////////////////////////////////////////////////////////

    private void UpdateData() throws JSONException {
        tempdata = getJsonData();
        showTempIcon(Float.valueOf(tempdata.get("CURRENTTEMP").toString()));

        temp_icon.setBackgroundResource(icon_id);
        currenttemp.setText(tempdata.get("CURRENTTEMP").toString() + " \u2103");
        Log.i("TEMP",String.valueOf(color_id));
        currenttemp.setTextColor(color_id);
    }

    private void showTempIcon(Float temp){
        if (temp >= 28){
            icon_id = R.drawable.hot1;
            color_id = ContextCompat.getColor(getApplicationContext(),R.color.hot1);
        }
        if (temp < 28 && temp >= 21){
            icon_id = R.drawable.hot2;
            color_id = ContextCompat.getColor(getApplicationContext(),R.color.hot2);
        }
        if (temp < 21 && temp >= 16){
            icon_id = R.drawable.hot3;
            color_id = ContextCompat.getColor(getApplicationContext(),R.color.hot3);
        }
        if (temp < 16 && temp >= 10){
            icon_id = R.drawable.cold1;
            color_id = ContextCompat.getColor(getApplicationContext(),R.color.cold1);
        }
        if (temp < 10 && temp >= 3){
            icon_id = R.drawable.cold2;
            color_id = ContextCompat.getColor(getApplicationContext(),R.color.cold2);
        }
        if (temp < 3){
            icon_id = R.drawable.cold3;
            color_id = ContextCompat.getColor(getApplicationContext(),R.color.cold3);
        }
    }

    @SuppressWarnings("unchecked")
    private JSONObject getJsonData() throws JSONException {
        JSONObject tcpData = new JSONObject();
        tcpData.put("ID", "TEMP");
        tcpData.put("COMMAND", "CURRENTTEMP");
        JSONObject response = new JSONObject();
        /*
        try {
            response = new Connection().execute(tcpData).get();
        } catch (InterruptedException e) {
            response.put("ERR", e.toString());
        } catch (ExecutionException e) {
            response.put("ERR", e.toString());
        }*/
        return response;
    }

    ////////////////////////////////////////////////////////////// client thread //////////////////////////////////////////////////////////////////

    public class Connection extends AsyncTask<String,Void,String> {

        String IP;
        int Port;
        private String Status;

        private Connection() {
            IP = "10.0.2.2";
            Port = 1234;
        }

        @Override
        protected String doInBackground(String... Command) {

                try {

                    socket = new Socket(IP, Port);
                    out = new ObjectOutputStream(socket.getOutputStream());
                    out.flush();
                    in = new ObjectInputStream(socket.getInputStream());
                    checkSwitchStatus();
                    Status = "Successfully connect";
                   // response = (JSONObject) in.readObject();


                } catch (IOException e) {
                    Status = "Connect failed!" + e.toString();
                } /*catch (ClassNotFoundException e) {
                e.printStackTrace();
            }*/
            //return response;
            return Status;
            }
        }

///////////////////////////////////////////////////////////////// menu /////////////////////////////////////////////////////////////////
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_net, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_connect_network) {
            Connection connection = new Connection();
            connection.execute();
        }
        if (id == R.id.action_disconnect) {
            closeConnection();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id) {
            case R.id.nav_bluetooth:
                Intent intent = new Intent(this, BluetoothService.class);
                startActivity(intent);
            case R.id.nav_network:
        }
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

}
