package xhurni00.drillappclient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Handler;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher.ViewFactory;

import com.prosysopc.ua.ApplicationIdentity;
import com.prosysopc.ua.CertificateValidationListener;
import com.prosysopc.ua.PkiFileBasedCertificateValidator;
import com.prosysopc.ua.SecureIdentityException;
import com.prosysopc.ua.UserIdentity;
import com.prosysopc.ua.client.MonitoredDataItem;
import com.prosysopc.ua.client.MonitoredDataItemListener;
import com.prosysopc.ua.client.Subscription;
import com.prosysopc.ua.client.UaClient;

import org.opcfoundation.ua.builtintypes.DataValue;
import org.opcfoundation.ua.builtintypes.LocalizedText;
import org.opcfoundation.ua.builtintypes.NodeId;
import org.opcfoundation.ua.core.ApplicationDescription;
import org.opcfoundation.ua.core.ApplicationType;
import org.opcfoundation.ua.transport.security.Cert;
import org.opcfoundation.ua.transport.security.SecurityMode;

import java.io.File;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.EnumSet;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {

    protected UaClient client;

    String vybrane_url = null;
    String vybrany_node;
    boolean automat_aktiv;
    public boolean stopped = false;

    private Handler handler;

    private ImageSwitcher led_switch;
    private ImageSwitcher led_auto_switch;
    private ImageSwitcher vrtak_switch;

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

        handler = new Handler();
    }

/////////////////////////// obsluha tlacitek ///////////////////////////////////////////////////

    public void AutomatButtonRun(View view) {
        if (vybrane_url == null) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Pozor!");
            builder.setMessage("Nejprve je nutne vybrat server.");
            builder.setPositiveButton("Ok", ((dialog, which) -> dialog.cancel() ));
            builder.show();
            return;
        }
        automat_aktiv = true;
        setContentView(R.layout.activity_automat);

        led_auto_switch = (ImageSwitcher) findViewById(R.id.imgsw_auto1);
        led_auto_switch.setFactory(new ViewFactory() {
            @Override
            public View makeView() {
                ImageView myView = new ImageView(getApplicationContext());
                return myView;
            }
        });

        vrtak_switch = (ImageSwitcher) findViewById(R.id.imgsw_auto2);
        vrtak_switch.setFactory(new ViewFactory() {
            @Override
            public View makeView() {
                ImageView myView = new ImageView(getApplicationContext());
                return myView;
            }
        });

        led_auto_switch.setImageResource(R.drawable.led_off);
        vrtak_switch.setImageResource(R.drawable.vrt_horni);

        MyThread myThread = new MyThread();
        myThread.start();

        AutomatTask task = new AutomatTask();
        task.execute(new String[] {vybrane_url});
    }

    public void ManualButtonRun(View view) {
        if (vybrane_url == null) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Pozor!");
            builder.setMessage("Nejprve je nutne vybrat server.");
            builder.setPositiveButton("Ok", ((dialog, which) -> dialog.cancel() ));
            builder.show();
            return;
        }
        setContentView(R.layout.activity_manual);

        led_switch = (ImageSwitcher) findViewById(R.id.imgsw);
        led_switch.setFactory(new ViewFactory() {
            @Override
            public View makeView() {
                ImageView myView = new ImageView(getApplicationContext());
                return myView;
            }
        });
        led_switch.setImageResource(R.drawable.led_off);

        ManualTask task = new ManualTask();
        task.execute(new String[] {vybrane_url});
    }

    public void VyberServerRun (View view) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Vyber Server:");
        String[] server_volba = {"Plc", "Test"};
        builder.setItems(server_volba, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case 0:
                        vybrane_url = "opc.tcp://192.168.1.202:4840";
                    case 1:
                        vybrane_url = "opc.tcp://192.168.1.100:53530/OPCUA/SimulationServer";
                }
            }
        });
        AlertDialog dialog = builder.create();
        dialog.show();
    }

    public void BackRun(View view) {
        if (automat_aktiv == true){
            stopped = true;
            automat_aktiv = false;
        }
        setContentView(R.layout.activity_main);
    }

    public void UpRun(View view) {
        vybrany_node = "POKYN_NAHORU";
        //vybrany_node = "Boolean"; // test promena
        WriteTask task = new WriteTask();
        task.execute(new String[] {vybrane_url, vybrany_node});
    }

    public void DownRun(View view) {
        vybrany_node = "POKYN_DOLU";
        //vybrany_node = "Boolean"; // test promena
        WriteTask task = new WriteTask();
        task.execute(new String[] {vybrane_url, vybrany_node});
    }

    public void DrillRun(View view) {
        DrillTask task = new DrillTask();
        task.execute(new String[] {vybrane_url});
    }

    public void StartRun(View view) {
        vybrany_node = "POKYN_START";
        //vybrany_node = "Boolean"; // test promena
        WriteTask task = new WriteTask();
        task.execute(new String[] {vybrane_url, vybrany_node});
    }

    public void StopRun(View view) {
        vybrany_node = "POKYN_STOP";
        //vybrany_node = "Boolean"; // test promena
        WriteTask task = new WriteTask();
        task.execute(new String[] {vybrane_url, vybrany_node});
    }

    public void ExitButtonRun(View view) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Exit");
        builder.setMessage("Opravdu chcete ukoncit aplikaci?");
        builder.setPositiveButton("Ano", ((dialog, which) -> ExitRun() ));
        builder.setNegativeButton("Ne",((dialog, which) -> dialog.cancel()) );
        builder.show();
    }

    /////////////////////////////////////////////////////////////////////////////////////////////

    public void ExitRun(){
        finish();
    }


    public void OutofNetwork() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Chyba pripojeni!");
        builder.setMessage("Zkontrolujte zda je spravne zvoleny Server, pripadne zda jste pripojen v siti.");
        builder.setPositiveButton("Ok", ((dialog, which) -> dialog.cancel() ));
        builder.show();
        setContentView(R.layout.activity_main);
        return;
    }



    protected void initialize(UaClient client) throws SecureIdentityException, IOException, UnknownHostException {

        ApplicationDescription appDescription = new ApplicationDescription();
        appDescription.setApplicationName(new LocalizedText("DrillAppClient",
                Locale.ENGLISH));
        String android_id = Settings.Secure.getString(
                getApplicationContext().getContentResolver(),
                Settings.Secure.ANDROID_ID);
        appDescription.setApplicationUri("urn:" + android_id +":UA:SimpleAndroidClient");
        appDescription.setProductUri("urn:prosysopc.com:UA:SimpleAndroidClient");
        appDescription.setApplicationType(ApplicationType.Client);

        PkiFileBasedCertificateValidator validator = new PkiFileBasedCertificateValidator(
                getFilesDir().getPath() + "/PKI/CA");
        validator.setValidationListener(new CertificateValidationListener() {
            @Override
            public PkiFileBasedCertificateValidator.ValidationResult onValidate(
                    Cert cert, ApplicationDescription applicationDescription,
                    EnumSet<PkiFileBasedCertificateValidator.CertificateCheck> enumSet) {
                return PkiFileBasedCertificateValidator.ValidationResult.AcceptPermanently;
            }
        });
        client.setCertificateValidator(validator);

        ApplicationIdentity identity = ApplicationIdentity.loadOrCreateCertificate(
                appDescription, "Sample Organisation", "opcua",
                new File(validator.getBaseDir(), "private"), true);

        identity.setApplicationDescription(appDescription);
        client.setApplicationIdentity(identity);
    }

////////////////////////////// Nove vlakno ///////////////////////////////////////////////////

    private class MyThread extends Thread{
        @Override
        public void run() {
            UaClient client = null;
            try {
                client = new UaClient(vybrane_url);

                initialize(client);

                client.setTimeout(60000);
                client.setSecurityMode(SecurityMode.NONE);
                client.setUserIdentity(new UserIdentity());
                client.connect();

                NodeId id = new NodeId(5, "Counter1"); // test
                NodeId senzor1 = new NodeId(3, "HORNI_CIDLO");
                NodeId senzor2 = new NodeId(3, "HORNI_STREDNI");
                NodeId senzor3 = new NodeId(3, "HORNI_DOLNI");
                NodeId led1 = new NodeId(3, "ZELENA_LED");
                NodeId led2 = new NodeId(3, "CERVENA_LED");

                MonitoredDataItem dataItem1 = new MonitoredDataItem(id);
                MonitoredDataItem dataItem2 = new MonitoredDataItem(senzor1);
                MonitoredDataItem dataItem3 = new MonitoredDataItem(senzor2);
                MonitoredDataItem dataItem4 = new MonitoredDataItem(senzor3);
                MonitoredDataItem dataItem5 = new MonitoredDataItem(led1);
                MonitoredDataItem dataItem6 = new MonitoredDataItem(led2);
                Subscription subscription = new Subscription();
                subscription.addItem(dataItem1);
                subscription.addItem(dataItem2);
                subscription.addItem(dataItem3);
                subscription.addItem(dataItem4);
                subscription.addItem(dataItem5);
                subscription.addItem(dataItem6);
                client.addSubscription(subscription);

                MonitoredDataItemListener dataChangeListener = new MonitoredDataItemListener()
                {@Override
                    public void onDataChange(MonitoredDataItem sender, DataValue prevValue, DataValue value)
                    {
                        System.out.println("Monitor Data Change successfully");
                        if(value!=null)
                        {
                            System.out.println(sender.getMonitoredItemId());
                            String hodnota = value.getValue().getValue().toString();
                            System.out.println("————->" + hodnota);

                            int monitored_id = sender.getMonitoredItemId().intValue();

                            handler.post(new Runnable() {
                                @Override
                                public void run() {
                                    switch (monitored_id){
                                        case 1: // test
                                            if (hodnota=="0") vrtak_switch.setImageResource(R.drawable.vrt_horni);
                                            if (hodnota=="1") vrtak_switch.setImageResource(R.drawable.vrt_stred);
                                            if (hodnota=="2") vrtak_switch.setImageResource(R.drawable.vrt_dolni);
                                        case 2:
                                            if (hodnota=="true") vrtak_switch.setImageResource(R.drawable.vrt_horni);
                                        case 3:
                                            if (hodnota=="true") vrtak_switch.setImageResource(R.drawable.vrt_stred);
                                        case 4:
                                            if (hodnota=="true") vrtak_switch.setImageResource(R.drawable.vrt_dolni);
                                        case 5:
                                            if (hodnota=="true") led_auto_switch.setImageResource(R.drawable.led_gr);
                                        case 6:
                                            if (hodnota=="true") led_auto_switch.setImageResource(R.drawable.led_r);
                                    }
                                }
                            });
                        }
                    }
                };
                dataItem1.setDataChangeListener(dataChangeListener);
                dataItem2.setDataChangeListener(dataChangeListener);
                dataItem3.setDataChangeListener(dataChangeListener);
                dataItem4.setDataChangeListener(dataChangeListener);
                dataItem5.setDataChangeListener(dataChangeListener);
                dataItem6.setDataChangeListener(dataChangeListener);
                if (stopped == true){ client.disconnect();}
            } catch (Exception e) { }
        }
    }

////////////////////////////// Async Tasks /////////////////////////////////////////////////////

    private class AutomatTask extends AsyncTask<String, Void, String> {


        public AutomatTask() {
        }

        @Override
        protected String doInBackground(String... strings) {
            String url = strings[0];
            UaClient client = null;
            String result = null;
            boolean status;
            try {

                client = new UaClient(url);

                initialize(client);


                client.setTimeout(60000);
                client.setSecurityMode(SecurityMode.NONE);
                client.setUserIdentity(new UserIdentity());
                client.connect();


                //NodeId nodeTest1 = new NodeId (3, "Boolean");
                //NodeId nodeTest2 = new NodeId (3, "BooleanDataItem");

                NodeId nodeManual = new NodeId (3, "MANUAL");
                NodeId nodeAutomat = new NodeId (3, "AUTOMAT");

                //status = client.writeValue(nodeTest1, false);
                status = client.writeValue(nodeManual, false);
                System.out.println(status);
                //status = client.writeValue(nodeTest2, true);
                status = client.writeValue(nodeAutomat, true);
                System.out.println(status);

                client.disconnect();
            } catch (Exception e) {
                result = e.toString();
                System.out.println(e);
                OutofNetwork();
            }
            return result;
        }

        @Override
        protected void onPostExecute(String s) {
            led_auto_switch.setImageResource(R.drawable.led_r);
        }
    }

/////////////////////////////

        private class ManualTask extends AsyncTask<String, Void, String> {

            public ManualTask() {
            }

            @Override
            protected String doInBackground(String... strings) {
                String url = strings [0];
                UaClient client = null;
                String result = null;
                boolean status;
                try {

                    client = new UaClient(url);

                    initialize(client);


                    client.setTimeout(60000);
                    client.setSecurityMode(SecurityMode.NONE);
                    client.setUserIdentity(new UserIdentity());
                    client.connect();


                    //NodeId nodeTest1 = new NodeId (3, "Boolean");
                    //NodeId nodeTest2 = new NodeId (3, "BooleanDataItem");

                    NodeId nodeManual = new NodeId (3, "MANUAL");
                    NodeId nodeAutomat = new NodeId (3, "AUTOMAT");

                    //status = client.writeValue(nodeTest2, false);
                    status = client.writeValue(nodeAutomat, false);
                    System.out.println(status);
                    //status = client.writeValue(nodeTest1, true);
                    status = client.writeValue(nodeManual, true);
                    System.out.println(status);


                    client.disconnect();
                } catch (Exception e) {
                    result = e.toString();
                    System.out.println(e);
                    OutofNetwork();
                }
                return result;
            }

            @Override
            protected void onPostExecute(String s) {
                led_switch.setImageResource(R.drawable.led_r);
            }
    }

////////////////////////////////

    private class WriteTask extends AsyncTask<String, Void, String> {

        public WriteTask() {
        }

        @Override
        protected String doInBackground(String... strings) {
            String url = strings [0];
            String vyber_node = strings[1];
            UaClient client = null;
            String result = null;
            try {

                client = new UaClient(url);

                initialize(client);

                client.setTimeout(60000);
                client.setSecurityMode(SecurityMode.NONE);
                client.setUserIdentity(new UserIdentity());
                client.connect();

                NodeId nodeZapis = new NodeId(3, vyber_node);

                boolean status = client.writeValue(nodeZapis, true);
                System.out.println(status);

                client.disconnect();
            } catch (Exception e) {
                result = e.toString();
                System.out.println(e);
                OutofNetwork();
            }
            return result;
        }

        @Override
        protected void onPostExecute(String s) {
        }
    }

///////////////////////////

    private class DrillTask extends AsyncTask<String, Void, String> {

        public DrillTask() {
        }

        @Override
        protected String doInBackground(String... strings) {
            String url = strings [0];
            UaClient client = null;
            String result = null;
            boolean status;
            try {

                client = new UaClient(url);

                initialize(client);


                client.setTimeout(60000);
                client.setSecurityMode(SecurityMode.NONE);
                client.setUserIdentity(new UserIdentity());
                client.connect();


                //NodeId nodeTest = new NodeId(3, "Boolean");
                NodeId nodeVrt = new NodeId(3, "VRTANI");

                //DataValue dv = client.readValue(nodeTest);
                DataValue dv = client.readValue(nodeVrt);

                result = dv.getValue().getValue().toString();
                System.out.println(result);

                if (result == "true"){
                    //status = client.writeValue(nodeTest, false);
                    status = client.writeValue(nodeVrt, false);
                    System.out.println(status);
                }
                if (result == "false"){
                    //status = client.writeValue(nodeTest, true);
                    status = client.writeValue(nodeVrt, true);
                    System.out.println(status);
                }

                client.disconnect();
            } catch (Exception e) {
                result = e.toString();
                System.out.println(e);
                OutofNetwork();
            }
            return result;
        }

        @Override
        protected void onPostExecute(String s) {
            if (s == "true") {led_switch.setImageResource(R.drawable.led_r);}
            if (s == "false") {led_switch.setImageResource(R.drawable.led_gr);}
        }
    }

///////////////////////////////////////////////////////////////////////////////////////////////////
}
