package com.example.user.myapp;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ToggleButton;

import java.util.HashMap;
import java.util.Map;

public class ManualDriveActivity extends AppCompatActivity {
    private GlobalState state;
    private Handler coilHandler;
    private Handler manualModeCheckHandler;

    private HashMap<Integer, Boolean> mapCoilCheckStatus = new HashMap <> ();
    private HashMap<ToggleButton, Integer> mapButtonCoil = new HashMap<>();
    private boolean manualMode = false;

    private void initMap () {
        mapCoilCheckStatus.put(64, false);
        mapCoilCheckStatus.put(70, false);
        mapCoilCheckStatus.put(65, false);
        mapCoilCheckStatus.put(71, false);
        mapCoilCheckStatus.put(68, false);
        mapCoilCheckStatus.put(69, false);
        mapCoilCheckStatus.put(66, false);
        mapCoilCheckStatus.put(67, false);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        state = (GlobalState) getApplicationContext();
        initMap(); // initialise the value of the coil toggle state + the corresponding coil to button

        setContentView(R.layout.activity_manual_drive);

        ToggleButton h1ControlButton =findViewById(R.id.h1_control_button);
        ToggleButton h2ControlButton = findViewById(R.id.h2_control_button);
        ToggleButton pu1ControlButton =  findViewById(R.id.pu1_control_button);
        ToggleButton pu2ControlButton =  findViewById(R.id.pu2_control_button);
        ToggleButton sp1ControlButton =  findViewById(R.id.sp1_control_button);
        ToggleButton b1ControlButton =  findViewById(R.id.b1_control_button);
        ToggleButton m1ControlButton = findViewById(R.id.m1_control_button);
        ToggleButton m2ControlButton = findViewById(R.id.m2_control_button);

        //H1	Coil	65-1
        mapButtonCoil.put(h1ControlButton, 64);
        //H2	Coil	71-1
        mapButtonCoil.put(h2ControlButton, 70);
        //PU1	Coil	66-1
        mapButtonCoil.put(pu1ControlButton, 65);
        //PU2	Coil	72-1
        mapButtonCoil.put(pu2ControlButton, 71);
        //SP1	Coil	69-1
        mapButtonCoil.put(sp1ControlButton, 68);
        //B1	Coil	70-1
        mapButtonCoil.put(b1ControlButton, 69);
        //M1 	Coil	67-1
        mapButtonCoil.put(m1ControlButton, 66);
        //M2	Coil	68-1
        mapButtonCoil.put(m2ControlButton, 67);



        LocalBroadcastManager.getInstance(this).registerReceiver(coilWriterMessageReceiver, new IntentFilter("readVmCoil2"));
     //   LocalBroadcastManager.getInstance(this).registerReceiver(coilWriterMessageReceiver, new IntentFilter("checkCoilValue"));
        LocalBroadcastManager.getInstance(this).registerReceiver(coilMessageReceiver, new IntentFilter("readOnlyCoil"));

        // manual drive button
       ToggleButton manualDriveOverrideButton = (ToggleButton) findViewById(R.id.manual_override_button);
        manualDriveOverrideButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    // writing the value true
                    Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class);
                    serviceIntent.setAction("write.coil");
                    serviceIntent.putExtra("extra.ip.address", state.getIpAddress());
                    serviceIntent.putExtra("extra.ip.port", state.getPort());
                    serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.VM_COIL2.getStartReference());
                    serviceIntent.putExtra("extra.bit", true);
                    serviceIntent.putExtra("extra.intent.name", "readVmCoil2");
                    serviceIntent.putExtra("extra.is.basic.coil", false);
                    getApplicationContext().startService(serviceIntent);
                } else {
                    // writing the value false
                    Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class);
                    serviceIntent.setAction("write.coil");
                    serviceIntent.putExtra("extra.ip.address", state.getIpAddress());
                    serviceIntent.putExtra("extra.ip.port", state.getPort());
                    serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.VM_COIL2.getStartReference());
                    serviceIntent.putExtra("extra.bit", false);
                    serviceIntent.putExtra("extra.intent.name", "readVmCoil2");
                    serviceIntent.putExtra("extra.is.basic.coil", false);
                    getApplicationContext().startService(serviceIntent);
                }
            }
        });

        // for each toggle button, set the event
        for (Map.Entry<ToggleButton, Integer> entry : mapButtonCoil.entrySet()) {
            final ToggleButton button = entry.getKey();
            final Integer coilToWrite = entry.getValue();
            button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked && manualMode) {
                    // writing the value true
                    Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class);
                    serviceIntent.setAction("write.coil");
                    serviceIntent.putExtra("extra.ip.address", state.getIpAddress());
                    serviceIntent.putExtra("extra.ip.port", state.getPort());
                    serviceIntent.putExtra("extra.ref", coilToWrite);
                    serviceIntent.putExtra("extra.bit", true);
                    serviceIntent.putExtra("extra.intent.name", "writeBit");
                    serviceIntent.putExtra("extra.is.basic.coil", true);
                    getApplicationContext().startService(serviceIntent);
                    mapCoilCheckStatus.put(coilToWrite, true);
                } else {
                    // writing the value false
                    Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class);
                    serviceIntent.setAction("write.coil");
                    serviceIntent.putExtra("extra.ip.address", state.getIpAddress());
                    serviceIntent.putExtra("extra.ip.port", state.getPort());
                    serviceIntent.putExtra("extra.ref", coilToWrite);
                    serviceIntent.putExtra("extra.bit", false);
                    serviceIntent.putExtra("extra.intent.name", "writeBit");
                    serviceIntent.putExtra("extra.is.basic.coil", true);
                    getApplicationContext().startService(serviceIntent);
                    mapCoilCheckStatus.put(coilToWrite, false);
                }
                }
            });
        }
    }

    @Override
    protected void onStart () {
        super.onStart();
        coilHandler = new Handler();
        coilHandler.post(refreshCoil);

        manualModeCheckHandler = new Handler();
        manualModeCheckHandler.post(checkManualMockStatus) ;
    }

    private BroadcastReceiver coilWriterMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            boolean isManualModeActivated = intent.getBooleanExtra("coil", false);
            if (isManualModeActivated) {
                manualMode = true;
            } else {
                manualMode = false;
            }
        }
    };

    private Runnable checkManualMockStatus = new Runnable() {
        @Override
        public void run() {
            ToggleButton h1ControlButton = findViewById(R.id.h1_control_button);
            ToggleButton h2ControlButton = findViewById(R.id.h2_control_button);
            Button pu1ControlButton = findViewById(R.id.pu1_control_button);
            Button pu2ControlButton = findViewById(R.id.pu2_control_button);
            Button sp1ControlButton = findViewById(R.id.sp1_control_button);
            Button b1ControlButton = findViewById(R.id.b1_control_button);
            ToggleButton m1ControlButton = findViewById(R.id.m1_control_button);
            ToggleButton m2ControlButton = findViewById(R.id.m2_control_button);

            // ============= Light ===============
            ImageView manualLightOn = findViewById(R.id.manual_override_status_light_on);
            ImageView manualLightOff = findViewById(R.id.manual_override_status_light_off);

            ImageView h1StatusLightOn = findViewById(R.id.h1_status_light_on);
            ImageView h1StatusLightOff = findViewById(R.id.h1_status_light_off);
            ImageView h2StatusLightOn = findViewById(R.id.h2_status_light_on);
            ImageView h2StatusLightOff = findViewById(R.id.h2_status_light_off);

            ImageView pu1StatusLightOn = findViewById(R.id.pu1_status_light_on);
            ImageView pu1StatusLightOff = findViewById(R.id.pu1_status_light_off);
            ImageView pu2StatusLightOn = findViewById(R.id.pu2_status_light_on);
            ImageView pu2StatusLightOff = findViewById(R.id.pu2_status_light_off);

            ImageView sp1StatusLightOn = findViewById(R.id.sp1_status_light_on);
            ImageView sp1StatusLightOff = findViewById(R.id.sp1_status_light_off);
            ImageView b1StatusLightOn = findViewById(R.id.b1_status_light_on);
            ImageView b1StatusLightOff = findViewById(R.id.b1_status_light_off);

            ImageView m1StatusLightOn = findViewById(R.id.m1_status_light_on);
            ImageView m1StatusLightOff = findViewById(R.id.m1_status_light_off);
            ImageView m2StatusLightOn = findViewById(R.id.m2_status_light_on);
            ImageView m2StatusLightOff = findViewById(R.id.m2_status_light_off);

            if (!manualMode) {
                manualLightOn.setVisibility(View.INVISIBLE);
                manualLightOff.setVisibility(View.VISIBLE);

                h1ControlButton.setEnabled(false);
                h2ControlButton.setEnabled(false);
                m1ControlButton.setEnabled(false);
                m2ControlButton.setEnabled(false);
                pu1ControlButton.setEnabled(false);
                pu2ControlButton.setEnabled(false);
                sp1ControlButton.setEnabled(false);
                b1ControlButton.setEnabled(false);

                manualLightOn.setVisibility(View.INVISIBLE);
                manualLightOff.setVisibility(View.VISIBLE);
                // switch all off
                h1StatusLightOn.setVisibility(View.INVISIBLE);
                h1StatusLightOff.setVisibility(View.INVISIBLE);
                h2StatusLightOn.setVisibility(View.INVISIBLE);
                h2StatusLightOff.setVisibility(View.INVISIBLE);
                m1StatusLightOn.setVisibility(View.INVISIBLE);
                m1StatusLightOff.setVisibility(View.INVISIBLE);
                m2StatusLightOn.setVisibility(View.INVISIBLE);
                m2StatusLightOff.setVisibility(View.INVISIBLE);
                pu1StatusLightOn.setVisibility(View.INVISIBLE);
                pu1StatusLightOff.setVisibility(View.INVISIBLE);
                pu2StatusLightOn.setVisibility(View.INVISIBLE);
                pu2StatusLightOff.setVisibility(View.INVISIBLE);
                sp1StatusLightOn.setVisibility(View.INVISIBLE);
                sp1StatusLightOff.setVisibility(View.INVISIBLE);
                b1StatusLightOn.setVisibility(View.INVISIBLE);
                b1StatusLightOff.setVisibility(View.INVISIBLE);
            }
            manualModeCheckHandler.postDelayed(this, 1000);
        }
    };

    private Runnable refreshCoil = new Runnable() {
        @Override
        public void run() {
            Intent serviceIntent = new Intent(getApplicationContext(), MyIntentService.class);
            serviceIntent.setAction("read.coil");
            serviceIntent.putExtra("extra.ip.address", state.getIpAddress());
            serviceIntent.putExtra("extra.ip.port", state.getPort());
            serviceIntent.putExtra("extra.ref", GlobalState.InputConfig.Q_COIL.getStartReference());
            serviceIntent.putExtra("extra.count", GlobalState.InputConfig.Q_COIL.getCount());
            serviceIntent.putExtra("extra.intent.name", "readOnlyCoil");
            getApplicationContext().startService(serviceIntent);

            coilHandler.postDelayed(this, 3000);
        }
    };

    // on message receive, update the view with values
    private BroadcastReceiver coilMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Bundle bundle = intent.getExtras();
            boolean[] booleanArray = bundle.getBooleanArray("coilValues");

            // ========== Button ============
            ToggleButton h1ControlButton = findViewById(R.id.h1_control_button);
            ToggleButton h2ControlButton = findViewById(R.id.h2_control_button);
            Button pu1ControlButton = findViewById(R.id.pu1_control_button);
            Button pu2ControlButton = findViewById(R.id.pu2_control_button);
            Button sp1ControlButton = findViewById(R.id.sp1_control_button);
            Button b1ControlButton = findViewById(R.id.b1_control_button);
            ToggleButton m1ControlButton = findViewById(R.id.m1_control_button);
            ToggleButton m2ControlButton = findViewById(R.id.m2_control_button);

            // ============= Light ===============
            ImageView manualLightOn = findViewById(R.id.manual_override_status_light_on);
            ImageView manualLightOff = findViewById(R.id.manual_override_status_light_off);

            ImageView h1StatusLightOn = findViewById(R.id.h1_status_light_on);
            ImageView h1StatusLightOff = findViewById(R.id.h1_status_light_off);
            ImageView h2StatusLightOn = findViewById(R.id.h2_status_light_on);
            ImageView h2StatusLightOff = findViewById(R.id.h2_status_light_off);

            ImageView pu1StatusLightOn = findViewById(R.id.pu1_status_light_on);
            ImageView pu1StatusLightOff = findViewById(R.id.pu1_status_light_off);
            ImageView pu2StatusLightOn = findViewById(R.id.pu2_status_light_on);
            ImageView pu2StatusLightOff = findViewById(R.id.pu2_status_light_off);

            ImageView sp1StatusLightOn = findViewById(R.id.sp1_status_light_on);
            ImageView sp1StatusLightOff = findViewById(R.id.sp1_status_light_off);
            ImageView b1StatusLightOn = findViewById(R.id.b1_status_light_on);
            ImageView b1StatusLightOff = findViewById(R.id.b1_status_light_off);

            ImageView m1StatusLightOn = findViewById(R.id.m1_status_light_on);
            ImageView m1StatusLightOff = findViewById(R.id.m1_status_light_off);
            ImageView m2StatusLightOn = findViewById(R.id.m2_status_light_on);
            ImageView m2StatusLightOff = findViewById(R.id.m2_status_light_off);

            if (manualMode) {
                h1ControlButton.setEnabled(true);
                h2ControlButton.setEnabled(true);
                m1ControlButton.setEnabled(true);
                m2ControlButton.setEnabled(true);
                pu1ControlButton.setEnabled(true);
                pu2ControlButton.setEnabled(true);
                sp1ControlButton.setEnabled(true);
                b1ControlButton.setEnabled(true);

                manualLightOn.setVisibility(View.VISIBLE);
                manualLightOff.setVisibility(View.INVISIBLE);
                // lightning
                // ======== h1 =========
                if (booleanArray[0] == true) {
                    h1StatusLightOn.setVisibility(View.VISIBLE);
                    h1StatusLightOff.setVisibility(View.INVISIBLE);
                } else {
                    h1StatusLightOn.setVisibility(View.INVISIBLE);
                    h1StatusLightOff.setVisibility(View.VISIBLE);
                }

                // ======== h2 ======
                if (booleanArray[1] == true) {
                    h2StatusLightOn.setVisibility(View.VISIBLE);
                    h2StatusLightOff.setVisibility(View.INVISIBLE);
                } else {
                    h2StatusLightOn.setVisibility(View.INVISIBLE);
                    h2StatusLightOff.setVisibility(View.VISIBLE);
                }

                // ======== m1 ======
                if (booleanArray[2] == true) {
                    m1StatusLightOn.setVisibility(View.VISIBLE);
                    m1StatusLightOff.setVisibility(View.INVISIBLE);
                } else {
                    m1StatusLightOn.setVisibility(View.INVISIBLE);
                    m1StatusLightOff.setVisibility(View.VISIBLE);
                }

                // ======== m2 ======
                if (booleanArray[3] == true) {
                    m2StatusLightOn.setVisibility(View.VISIBLE);
                    m2StatusLightOff.setVisibility(View.INVISIBLE);
                } else {
                    m2StatusLightOn.setVisibility(View.INVISIBLE);
                    m2StatusLightOff.setVisibility(View.VISIBLE);
                }

                // ======== pu1 ======
                if (booleanArray[4] == true) {
                    pu1StatusLightOn.setVisibility(View.VISIBLE);
                    pu1StatusLightOff.setVisibility(View.INVISIBLE);
                } else {
                    pu1StatusLightOn.setVisibility(View.INVISIBLE);
                    pu1StatusLightOff.setVisibility(View.VISIBLE);
                }

                // ======== pu2 ======
                if (booleanArray[5] == true) {
                    pu2StatusLightOn.setVisibility(View.VISIBLE);
                    pu2StatusLightOff.setVisibility(View.INVISIBLE);
                } else {
                    pu2StatusLightOn.setVisibility(View.INVISIBLE);
                    pu2StatusLightOff.setVisibility(View.VISIBLE);
                }

                // ======== m2 ======
                if (booleanArray[6] == true) {
                    sp1StatusLightOn.setVisibility(View.VISIBLE);
                    sp1StatusLightOff.setVisibility(View.INVISIBLE);
                } else {
                    sp1StatusLightOn.setVisibility(View.INVISIBLE);
                    sp1StatusLightOff.setVisibility(View.VISIBLE);
                }

                // ======== m2 ======
                if (booleanArray[7] == true) {
                    b1StatusLightOn.setVisibility(View.VISIBLE);
                    b1StatusLightOff.setVisibility(View.INVISIBLE);
                } else {
                    b1StatusLightOn.setVisibility(View.INVISIBLE);
                    b1StatusLightOff.setVisibility(View.VISIBLE);
                }
            }
        }
    };
}
