package oko.tm.oko_pro_classic;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;

import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;


import static android.support.v4.app.ActivityCompat.startActivity;


import static oko.tm.oko_pro_classic.R.string.object_1;
import static oko.tm.oko_pro_classic.R.string.object_10;
import static oko.tm.oko_pro_classic.R.string.object_2;
import static oko.tm.oko_pro_classic.R.string.object_3;
import static oko.tm.oko_pro_classic.R.string.object_4;
import static oko.tm.oko_pro_classic.R.string.object_5;
import static oko.tm.oko_pro_classic.R.string.object_6;
import static oko.tm.oko_pro_classic.R.string.object_7;
import static oko.tm.oko_pro_classic.R.string.object_8;
import static oko.tm.oko_pro_classic.R.string.object_9;


public class ClientThread implements Runnable {

    public static final  String TCP_BROADCAST_TO_START_ACTION = "oko.tm.oko_pro_classic.servicebackbroadcasttostart";
    public static final  String CLIENT_BROADCAST_RECIEVE_COMMAND = "oko.tm.oko_pro_classic.clientreceivecommand";
    public static final  int PERIODIC_QUERY = 120; //seconds
    public static final int WAIT_SERVER_ANSWER=12; //15 seconds
    public static final  int TRY_CONNECTION_TIMEOUT = 3; //seconds
    public static final int SERVERPORT = 31200;
    public static final String SERVER_INI = "ok.webhop.net";
    private static String ServerIP=SERVER_INI;
    int connection_alive_second=0;

    static final String LOG_TAG = "myLogs";
    private static final int max_data_queue_size=100;
    private static BlockingQueue<String[]> alive_queue = new LinkedBlockingQueue<String[]>(max_data_queue_size); //блокирующая очередь для поступающих данных для нотификации живучести прибора
    public static final  String PARAM_TYPE = "type";
    public static final  String PARAM_DATA = "data";
    public static final  String PARAM_OBJECT = "object_number";
    public static final  String STATUS_CONNECTION = "0"; //param_type
    public static final  String CONNECT_NO = "0"; //param_data
    public static final  String CONNECT_TO_SERVER = "1"; //param_data
    public static final  String CONNECT_TO_DEVISE = "2"; //param_data

    public  static final String DEVICE_DATA = "1"; //param_type
    public  static final String SYSTEM_DATA = "2"; //param_type

    public static volatile boolean StartActivity_Started=false;
    private volatile boolean stopThread_client = false;
    private volatile boolean stopThread_periodic = false;

    private Socket socket = new Socket();
    private volatile boolean socket_timeout=false;
    private static volatile boolean socket_opened=false;

    private int sever_reconnection_count=0;

    BufferedReader reader_socket=null;

    public static BroadcastReceiver br_client;

    private static Context mContext;

    //private Timer timer=null;
    //private Handler mHandler = new Handler();
    //final int PERIODIC_TASK_LEN=100; //0.1sec

    private int sendNotificationPause=0;
    private int mainPause=0;
    private int serverConnectPause=0;

    //SharedPreferences mSettings;

    public ClientThread(Context applicationContext) {
        mContext = applicationContext.getApplicationContext();
        Log.v(this.getClass().getName(),mContext.toString());
    }

    @Override
    public void run() {
        String data;
        int socket_timeout_count=0;


        try {
            Log.d(LOG_TAG, "Client thread start");

            // создаем BroadcastReceiver для приема данных
            br_client = new BroadcastReceiver() {
                // действия при получении сообщений
                public void onReceive(Context context, Intent intent) {
                    try {

                        String command = intent.getStringExtra("command");
                        String imei = intent.getStringExtra("imei");
                        String password = intent.getStringExtra("password");
                        Boolean close_socket = intent.getBooleanExtra("close_socket", false);

                        Log.d(LOG_TAG, "Client br_onReceive: command = " + command + ", close_socket= " + close_socket);

                        if (close_socket){
                            stopThread_client=true;
                            stopThread_periodic=true;
                            socket.setSoTimeout(100);
                            socket.close();
                        }
                        else {
                            Send_To_Server(command, imei, password);
                        }

                    } catch (Exception e) {
                        //e.printStackTrace();
                        Log.d(LOG_TAG, "Client br_onReceive falure");
                    }
                }
            };
            // создаем фильтр для BroadcastReceiver
            IntentFilter intFilt_sms = new IntentFilter(CLIENT_BROADCAST_RECIEVE_COMMAND);
            // регистрируем (включаем) BroadcastReceiver
            LocalBroadcastManager.getInstance(mContext).registerReceiver(br_client, intFilt_sms);



            periodic_query(mContext);
            //periodicTask();

            Connect_to_server();


            while (!stopThread_client)
            {
                try {
                    data = readData();

                    if (data.length() > 0 && !stopThread_client && !socket_timeout) {
                        connection_alive_second=0;
                        Log.d(LOG_TAG, "Socket received data: " + data);



                        try {
                            Intent intent1 = new Intent(TCP_BROADCAST_TO_START_ACTION);
                            intent1.putExtra(PARAM_TYPE, STATUS_CONNECTION);
                            intent1.putExtra(PARAM_DATA, CONNECT_TO_SERVER);
                            //MyService.mContext.sendBroadcast(intent1);
                            LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent1);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }



                        try {
                            if (data.startsWith("{")) {
                                /*
                                * OKO-S2
                                * {13227009840343,01,02,01F0,18,3.0.0,OKO-S2}
                                * {866104020810332,F9,0B,05C8,1F,3.0.3,OKO-S2}
                                * * {866104020810332,FF,0F,0785,00,3.0.5,OKO-S2,31,,04,,}
                                * Termo7Humidity
                                * {866104020810332,F9,0B,05C8,1F,3.0.3,OKO-S2,12.4,56.8}
                                * Termo&Humidity {866104020810332,F9,0B,05C8,1F,3.0.3,OKO-S2,12.4,56.8}
                                *
                                * {13227009840343,0036,0200,0F00,00B9,18,1918181819181818,CCF189FB000055FB18FA55FBA6FB000000000000000018EAEFABF1FB18EAF0BB,07690717000000000012001200120000,1.0.9,OKO-PRO}
                                *OKO-U2
                                *{863591021960863,00FF,0200,2F101000,0000,00,8080808080808080,0000000000000000000000000000000000000000000000000000000000000000,072D06E00000000000000FFB0FA40ABE0FFE0FFE0FFE0FFE0FFE0FFE0FFE0FFE,2.2.1_,OKO-U2,,}
                                * {863591021960863,00FF,0200,2F101000,0000,00,8080808080808080,0000000000000000000000000000000000000000000000000000000000000000,072D06E00000000000000FFB0FA40ABE0FFE0FFE0FFE0FFE0FFE0FFE0FFE0FFE,2.2.1_,OKO-PRO,,}
                                * */
                                String[] requestParts = data.split(","); //data packet

                                int num_fields = requestParts.length;

                                int OKO_PRO_PROTOCOL=1;
                                int OKO_S2_PROTOCOL=2;
                                int OKO_NAVI_PROTOCOL=3;
                                int oko_protocol=0;

                                //***************************************************************************
                                //проверка протокола ТСР от прибора OKO

                                Boolean pass=false;

                                //check oko-pro protocol
                                if (num_fields>=11) {
                                    try {
                                        if (
                                                (requestParts[10].substring(0, 6).equals("OKO-PR")) ||
                                                        (requestParts[10].substring(0, 6).equals("OKO-U2")) ||
                                                        (requestParts[10].substring(0, 6).equals("OKO-7S")) ||
                                                        (requestParts[10].substring(0, 6).equals("OKO-BL"))
                                                ) {
                                            oko_protocol = OKO_PRO_PROTOCOL;
                                        }
                                    } catch (Exception ex) {

                                    }
                                }

                                //check oko-s2
                                if (num_fields>6) {
                                    try {
                                        if (requestParts[6].substring(0, 6).equals("OKO-S2")) {
                                            oko_protocol = OKO_S2_PROTOCOL;;
                                        }
                                    } catch (Exception ex) {

                                    }
                                }


                                if (oko_protocol>0)
                                    {
                                        try {
                                            //нотификация живучести прибора
                                            String[] alive_data = {"",""};
                                            alive_data[0]=requestParts[0].substring(1); //device
                                            long curTime = System.currentTimeMillis();
                                            //String date_insert = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(curTime);
                                            //alive_data[1]=date_insert; //insert time
                                            alive_data[1]=String.valueOf(curTime);
                                            //alive_queue.put(alive_data); //отправка в очередь
                                            alive_queue.offer(alive_data) ; //alive_data, 0, TimeUnit.MILLISECONDS
                                        } catch (Exception ex) {
                                            ex.printStackTrace();
                                        }

                                        //event
                                        int event_code = 200;
                                        try {
                                            event_code = 300 + hex2decimal(requestParts[1]);
                                        } catch (Exception ex) {
                                        }



                                        if (
                                                event_code != 325 && event_code!=362 && event_code!=363 && event_code!=540 && event_code!=554 &&
                                                        !(event_code>=548 && event_code<=552) &&
                                                        !(event_code>=460 && event_code<=475) &&
                                                        !(event_code>=350 && event_code<=357) &&
                                                        !(event_code>=738 && event_code<=753) &&
                                                        !(event_code>=882 && event_code<=945) &&
                                                        !(event_code>=1052 && event_code<=1131)
                                                )
                                        {

                                            if (!StartActivity_Started)
                                            {

                                                new Thread(new Runnable() {
                                                    public void run() {
                                                        try {
                                                            //перезапускаем приложение, если оно не запущено еще
                                                            Intent StartActivity = new Intent();
                                                            StartActivity.setAction(Intent.ACTION_MAIN);
                                                            StartActivity.addCategory(Intent.CATEGORY_LAUNCHER);
                                                            StartActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY ); //Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP
                                                            ComponentName cn = new ComponentName(mContext, StartActivity.class);
                                                            StartActivity.setComponent(cn);
                                                            mContext.startActivity(StartActivity);
                                                        } catch (Exception e) {
                                                            e.printStackTrace();
                                                        }

                                                    }
                                                }).start();


                                                int timeout = 100;
                                                while (!StartActivity_Started && timeout != 0) {
                                                    Thread.currentThread();
                                                    try {
                                                        Thread.sleep(100);
                                                    } catch (InterruptedException e) {
                                                        e.printStackTrace();
                                                    }
                                                    timeout--;
                                                }
                                                Log.d(LOG_TAG, "Startup: " + timeout);

                                                //mainPause=10000/PERIODIC_TASK_LEN;
                                                //while (!StartActivity_Started && (mainPause != 0)) {}


                                                Thread.currentThread();
                                                try {
                                                    Thread.sleep(1000);
                                                } catch (InterruptedException e) {
                                                    e.printStackTrace();
                                                }

                                                //mainPause=1000/PERIODIC_TASK_LEN;
                                                //while (mainPause != 0) {}
                                            }
                                        }


                                        //передаем данные в приемник
                                        try {
                                            Intent intent2 = new Intent(TCP_BROADCAST_TO_START_ACTION);
                                            intent2.putExtra(PARAM_TYPE, DEVICE_DATA);
                                            intent2.putExtra(PARAM_DATA, data);
                                            //MyService.mContext.sendBroadcast(intent2);
                                            LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent2);
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }

                                    }

                            }
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }

                    }
                    else
                    {
                        Log.d(LOG_TAG, "Socket failure");
                        if (!stopThread_client ) {
                            socket_timeout_count++;
                            Log.d(LOG_TAG, "Socket timeout event #" + socket_timeout_count);
                            Connect_to_server();

                        }
                    }


                } catch (Exception e) {

                    Log.d(LOG_TAG, "Read Socket failure");
                    if (!stopThread_client ) {
                        Connect_to_server();
                    }
                }
            }

            socket_opened=false;
            if (socket.isConnected()) {
                socket.close();
                Log.d(LOG_TAG, "Socket closed");
            }


        } catch (UnknownHostException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        try {
            // дерегистрируем (выключаем) BroadcastReceiver

            LocalBroadcastManager.getInstance(mContext).unregisterReceiver(br_client);
            Log.d(LOG_TAG, "unregister Client_Receiver in Client thread");
        } catch (Exception e) {
            //e.printStackTrace();
        }
        MainActivity.Client_Thread_stop=true;
        Log.d(LOG_TAG, "Client thread closed");
        stopThread_periodic = true;


        //stop periodic task
        /*
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        */
        MainActivity.Periodic_Thread_stop=true;

        return;
    }

    //ESTABLISH CONNECTION TO SERVER
    private void Connect_to_server(){
        boolean Connected=false;
        socket_opened=false;
        InetAddress serverAddr = null;
        int serverPort = SERVERPORT;
        int try_num=0;
        sever_reconnection_count++;

        while (!Connected && !stopThread_client) {

            try {
                ServerIP = getServer(mContext);
                serverAddr = InetAddress.getByName(ServerIP);
                serverPort = getPort(mContext);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }

            Connected=true;
            try {

                if (socket.isConnected()) {
                    socket.close(); //after socket closing we need new Socket() constructor !!!
                    //while (!socket.isClosed()) {}
                    Log.d(LOG_TAG, "Socket closed");
                }
                try_num++;
                Log.d(LOG_TAG, "Try open socket, #"+try_num);
                try {
                    Intent intent1 = new Intent(TCP_BROADCAST_TO_START_ACTION);
                    intent1.putExtra(PARAM_TYPE, STATUS_CONNECTION);
                    intent1.putExtra(PARAM_DATA, CONNECT_NO);
                    //MyService.mContext.sendBroadcast(intent1);
                    LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent1);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                SocketAddress sockaddr = new InetSocketAddress(serverAddr, serverPort); //SERVERPORT
                // Create your socket
                socket = new Socket();
                // Connect with 15 s timeout
                socket.connect(sockaddr, 12*1000);
            }
            // Exception thrown when network timeout occurs
            catch (InterruptedIOException iioe)
            {
                Connected=false;
                System.err.println ("Remote host timed out during read operation: " +iioe);
                Log.d(LOG_TAG, "Error during connection to server: " +iioe);
            }
            catch (UnknownHostException e) {
                //e.printStackTrace();
                Connected=false;
                System.err.println("Error during connection to server: " + e);
            }
            // Exception thrown when general network I/O error occurs
            catch (IOException ioe)
            {
                Connected=false;
                System.err.println("Network I/O error - " + ioe);
                Log.d(LOG_TAG, "Error during connection to server: " + ioe);
            }

            //temp++;
            if (!Connected && !stopThread_client) {
                //pause

                int second=0;
                Thread.currentThread();
                try {
                    while (second<TRY_CONNECTION_TIMEOUT && !stopThread_client) {
                        Thread.sleep(1000);
                        second++;
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //serverConnectPause=TRY_CONNECTION_TIMEOUT*1000/PERIODIC_TASK_LEN;
                //while (!stopThread_client && (serverConnectPause != 0)) {}
            }
        }

        if (!stopThread_client) {
            socket_opened = true;
            socket_timeout = false;

            try {
                socket.setSoTimeout( (PERIODIC_QUERY+WAIT_SERVER_ANSWER) * 1000); //2*PERIODIC_QUERY * 1000
                reader_socket = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            Send_To_Server("", getIMEIs(mContext), ""); //пустой запрос

            // If socket constructor returned without error,
            // then connection finished

            if (socket.isConnected()) {
                Log.d(LOG_TAG, "Socket opened: " + sever_reconnection_count);

            }
        }
    }

    //read line from socket with timeout
    private String readData() throws IOException
    {
        String line="";

        try {
            socket.setSoTimeout( (PERIODIC_QUERY+WAIT_SERVER_ANSWER) * 1000);
            line = reader_socket.readLine();
        }
        catch (Exception e) {
            e.printStackTrace();
            socket_timeout=true;
            System.err.println ("Socket reading error - " + e);
        }
        return line;
    }

    private int hex2decimal(String s) {
        int val = 0;
        try {
            String digits = "0123456789ABCDEF";
            s = s.toUpperCase();

            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                int d = digits.indexOf(c);
                val = 16 * val + d;
            }
        }catch (Exception e) {}
        return val;
    }

    //---try sends a message to TCP-server ---
    private void Send_To_Server(String command, String imei, String password) {
        try {
            try {
                Intent intent1 = new Intent(TCP_BROADCAST_TO_START_ACTION);
                intent1.putExtra(PARAM_TYPE, STATUS_CONNECTION);
                intent1.putExtra(PARAM_DATA, CONNECT_NO);
                //MyService.mContext.sendBroadcast(intent1);
                LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent1);
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (socket_opened) {
                Log.d(LOG_TAG, "Send command to Socket: " + command);

                String str = "";

                if ("".equals(command)) {
                    str = "{" + imei + "/COMMAND:" + ";/OKO-PRO}\r";
                } else {
                    str = "{" + imei + "/COMMAND:" + password + command + ";/OKO-PRO}\r";
                }

                if (connection_alive_second==0) connection_alive_second=2*WAIT_SERVER_ANSWER;
                Log.d(LOG_TAG, "Send command to Socket: " + str);
                PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
                out.println(str);
            }


        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //для работы с файлом с настройками
    private SharedPreferences getPrefs(Context context, String pref) {
        return context.getSharedPreferences(pref, Context.MODE_PRIVATE);
    }

     private String getIMEIs(Context context) {
        String imeis="";
        try {
            for (int i=0; i< StartActivity.objectsSettings.length; i++){
                if (getPrefs(context, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_CONNECTION, "1").equals("2")){
                    if (!"".equals(imeis)) imeis = imeis + "-";
                    imeis = imeis + getPrefs(context, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_IMEI, "no_imei"+i);
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        return imeis;
    }

    private  String getServer(Context context) {
        return getPrefs(context,StartActivity.START_PREFERENCES).getString("server", SERVER_INI);
    }

    private  int getPort(Context context) {
        //return getPrefs(context,StartActivity.START_PREFERENCES).getInt("port", SERVERPORT);
        return Integer.parseInt(getPrefs(context, StartActivity.START_PREFERENCES).getString(MainActivity.APP_PREFERENCES_PORT, String.valueOf(SERVERPORT)));
    }


    /*
    private final int _1sec_len=1000/PERIODIC_TASK_LEN; //1sec
    private int _1sec = _1sec_len;
    private int second=0;
    private int sec=60;
    //массивы для нотификации
    //int[] notification_id = new int[StartActivity.objectsSettings.length];
    private String[] device_code = new String[StartActivity.objectsSettings.length];
    //String[] device_name = new String[StartActivity.objectsSettings.length];
    private int[] timeout_len = new int[StartActivity.objectsSettings.length];
    private long[] cur_time = new long[StartActivity.objectsSettings.length];
    //boolean[] appearance=new boolean[StartActivity.objectsSettings.length];
    private  boolean[] appearance_done=new boolean[StartActivity.objectsSettings.length];
    //boolean[] disappearance=new boolean[StartActivity.objectsSettings.length];
    private boolean[] disappearance_done=new boolean[StartActivity.objectsSettings.length];

    private boolean first_done=false;


    private void periodicTask(){
        try {
            // cancel if already existed
            if(timer != null) {
                timer.cancel();
            } else {
                // recreate new
                timer = new Timer();
            }
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                    // run on another thread
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                if (!stopThread_periodic) {
                                    if (sendNotificationPause>0) sendNotificationPause--;
                                    if (mainPause>0) mainPause--;
                                    if (serverConnectPause>0) serverConnectPause--;

                                    if (_1sec > 0) {
                                        _1sec--;
                                        if (_1sec == 0) {
                                            _1sec = _1sec_len;
                                            if (!stopThread_periodic) {
                                                second++;
                                                if (second == PERIODIC_QUERY && !stopThread_periodic) {
                                                    second = 0;
                                                    Send_To_Server("", getIMEIs(mContext), ""); //пустой запрос
                                                }

                                                try {
                                                    if (connection_alive_second > 0) {
                                                        connection_alive_second--;
                                                        if (connection_alive_second < 2) {
                                                            socket.setSoTimeout(100); //close socket. read_timeout=1 sec
                                                            socket.close();
                                                            connection_alive_second = 0;
                                                        }
                                                    }
                                                } catch (Exception e) {
                                                    e.printStackTrace();
                                                }

                                                //alive notification
                                                try {
                                                    long cur_time_ = System.currentTimeMillis();

                                                    sec++;
                                                    if (sec >= 60) {
                                                        sec = 0;
                                                        //1 minut interval
                                                        //update device notification input data
                                                        for (int i = 0; i < StartActivity.objectsSettings.length; i++) {
                                                            if (
                                                                    getPrefs(mContext, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_CONNECTION, "1").equals("2") &&
                                                                            !getPrefs(mContext, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_ALIVE_TIMEOUT, "0").equals("0") &&
                                                                            !getPrefs(mContext, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_IMEI, "").equals("")
                                                                    ) {
                                                                if (!first_done || !getPrefs(mContext, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_IMEI, "").equals(device_code[i])) {
                                                                    //appearance[i]=false;
                                                                    appearance_done[i] = true;
                                                                    //disappearance[i]=false;
                                                                    disappearance_done[i] = false;
                                                                    cur_time[i] = cur_time_;
                                                                }
                                                                device_code[i] = getPrefs(mContext, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_IMEI, "no_imei" + i);
                                                                timeout_len[i] = Integer.parseInt(getPrefs(mContext, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_ALIVE_TIMEOUT, "0"));

                                                            } else {
                                                                device_code[i] = "";
                                                                timeout_len[i] = 0;
                                                                cur_time[i] = cur_time_;
                                                                //appearance[i]=false;
                                                                appearance_done[i] = true;
                                                                //disappearance[i]=false;
                                                                disappearance_done[i] = false;
                                                            }
                                                        }
                                                        first_done = true;
                                                    }

                                                    String[] alive_data = alive_queue.poll();


                                                    if (alive_data != null) {
                                                        //апдейтим время последнего сообщения от прибора
                                                        for (int i = 0; i < StartActivity.objectsSettings.length; i++) {
                                                            try {
                                                                if (alive_data[0].equals(device_code[i])) {
                                                                    cur_time[i] = cur_time_;
                                                                    //System.out.println("Check Keep Alive find " + alive_data[0]+", i="+i);
                                                                }
                                                            } catch (Exception ex) {
                                                            }
                                                        }
                                                    }
                                                    //проверяем необходимость нотификации
                                                    for (int i = 0; i < StartActivity.objectsSettings.length; i++) {

                                                        if ((cur_time_ - cur_time[i]) > 1000 * 60 * timeout_len[i] && !disappearance_done[i] && timeout_len[i] > 0) {
                                                            //System.out.println("Check Keep Alive need disappear " + device_code[i]);
                                                            disappearance_done[i] = true;
                                                            appearance_done[i] = false;
                                                            //send notification
                                                            //if (disappearance[i]){
                                                            Send_notification(mContext, i, cur_time[i], cur_time_, true);
                                                            //}
                                                        }

                                                        if ((cur_time_ == cur_time[i]) && !appearance_done[i] && timeout_len[i] > 0) {
                                                            //System.out.println("Check Keep Alive need appear " + device_code[i]);
                                                            disappearance_done[i] = false;
                                                            appearance_done[i] = true;
                                                            //send notification
                                                            //if (appearance[i]){
                                                            Send_notification(mContext, i, cur_time[i], cur_time_, false);
                                                            //}
                                                        }

                                                    }


                                                } catch (Exception e) {
                                                    e.printStackTrace();
                                                }
                                            }
                                        }
                                    } else {
                                        _1sec = _1sec_len;
                                    }
                                } else {
                                    //stop periodic task
                                    if (timer != null) {
                                        timer.cancel();
                                        timer = null;
                                    }
                                    MainActivity.Periodic_Thread_stop = true;
                                }

                            } catch (Exception e) {
                                //e.printStackTrace();
                            }
                        }

                    });
                }
            };
            timer.scheduleAtFixedRate(task, 0, PERIODIC_TASK_LEN); //schedule   scheduleAtFixedRate
        } catch (Exception e) {
            //e.printStackTrace();
        }
    }
    */

    private void periodic_query(final Context context){
        new Thread(new Runnable() {
            public void run() {
                int second=0;
                int sec=60;
                //массивы для нотификации
                //int[] notification_id = new int[StartActivity.objectsSettings.length];
                String[] device_code = new String[StartActivity.objectsSettings.length];
                //String[] device_name = new String[StartActivity.objectsSettings.length];
                int[] timeout_len = new int[StartActivity.objectsSettings.length];
                long[] cur_time = new long[StartActivity.objectsSettings.length];
                //boolean[] appearance=new boolean[StartActivity.objectsSettings.length];
                boolean[] appearance_done=new boolean[StartActivity.objectsSettings.length];
                //boolean[] disappearance=new boolean[StartActivity.objectsSettings.length];
                boolean[] disappearance_done=new boolean[StartActivity.objectsSettings.length];

                boolean first_done=false;

                try {
                    while (!stopThread_periodic) {
                        try {
                            Thread.currentThread();
                            Thread.sleep(1000);
                            second++;
                            if (second==PERIODIC_QUERY && !stopThread_periodic) {
                                second=0;
                                Send_To_Server("", getIMEIs(mContext), ""); //пустой запрос
                            }

                            try {
                                if (connection_alive_second>0){
                                    connection_alive_second--;
                                    if (connection_alive_second<2){
                                        socket.setSoTimeout(100); //close socket. read_timeout=1 sec
                                        socket.close();
                                        connection_alive_second=0;
                                    }
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }



                            //alive notification
                            try {
                                long cur_time_=System.currentTimeMillis();

                                sec++;
                                if (sec>=60){
                                    sec=0;
                                    //1 minut interval
                                    //update device notification input data
                                    for (int i = 0; i < StartActivity.objectsSettings.length; i++){
                                        if (
                                                getPrefs(context, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_CONNECTION, "1").equals("2") &&
                                                        !getPrefs(context, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_ALIVE_TIMEOUT, "0").equals("0") &&
                                                        !getPrefs(context, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_IMEI, "").equals("")
                                                )
                                        {
                                            if (!first_done || !getPrefs(context, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_IMEI, "").equals(device_code[i]) ){
                                                //appearance[i]=false;
                                                appearance_done[i]=true;
                                                //disappearance[i]=false;
                                                disappearance_done[i]=false;
                                                cur_time[i] = cur_time_;
                                            }
                                            device_code[i] = getPrefs(context, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_IMEI, "no_imei"+i);
                                            timeout_len[i] = Integer.parseInt(getPrefs(context, StartActivity.objectsSettings[i]).getString(MainActivity.APP_PREFERENCES_ALIVE_TIMEOUT, "0"));

                                        }
                                        else {
                                            device_code[i]="";
                                            timeout_len[i] = 0;
                                            cur_time[i] = cur_time_;
                                            //appearance[i]=false;
                                            appearance_done[i]=true;
                                            //disappearance[i]=false;
                                            disappearance_done[i]=false;
                                        }
                                    }
                                    first_done=true;
                                }

                                String[] alive_data = alive_queue.poll();



                                if(alive_data!= null)
                                {
                                    //апдейтим время последнего сообщения от прибора
                                    for (int i = 0; i < StartActivity.objectsSettings.length; i++){
                                        try {
                                            if(alive_data[0].equals(device_code[i])) {
                                                cur_time[i] = cur_time_;
                                                //System.out.println("Check Keep Alive find " + alive_data[0]+", i="+i);
                                            }
                                        }catch (Exception ex) {}
                                    }
                                }
                                //проверяем необходимость нотификации
                                for (int i = 0; i < StartActivity.objectsSettings.length; i++){

                                    if ( (cur_time_ - cur_time[i])>1000*60*timeout_len[i] && !disappearance_done[i] && timeout_len[i]>0){
                                        //System.out.println("Check Keep Alive need disappear " + device_code[i]);
                                        disappearance_done[i]=true;
                                        appearance_done[i]=false;
                                        //send notification
                                        //if (disappearance[i]){
                                            Send_notification(context, i, cur_time[i], cur_time_, true);
                                        //}
                                    }

                                    if ( (cur_time_ == cur_time[i]) && !appearance_done[i] && timeout_len[i]>0 ){
                                        //System.out.println("Check Keep Alive need appear " + device_code[i]);
                                        disappearance_done[i]=false;
                                        appearance_done[i]=true;
                                        //send notification
                                        //if (appearance[i]){
                                            Send_notification(context, i, cur_time[i], cur_time_, false);
                                        //}
                                    }

                                }



                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }

                    MainActivity.Periodic_Thread_stop=true;
                    Log.d(LOG_TAG, "Periodic query thread closed");

                } catch (Exception e) {
                    e.printStackTrace();
                }

                MainActivity.Periodic_Thread_stop=true;

                return;
            }
        }).start();
    }

    private void Send_notification(Context context, int i, long prev_time_, long cur_time_, boolean disapp){
        try {

            String obj = "";
            if (i == 0)
                obj = getPrefs(context, StartActivity.START_PREFERENCES).getString(StartActivity.START_PREFERENCES_OBJECT1, String.valueOf(object_1));
            if (i == 1)
                obj = getPrefs(context, StartActivity.START_PREFERENCES).getString(StartActivity.START_PREFERENCES_OBJECT2, String.valueOf(object_2));
            if (i == 2)
                obj = getPrefs(context, StartActivity.START_PREFERENCES).getString(StartActivity.START_PREFERENCES_OBJECT3, String.valueOf(object_3));
            if (i == 3)
                obj = getPrefs(context, StartActivity.START_PREFERENCES).getString(StartActivity.START_PREFERENCES_OBJECT4, String.valueOf(object_4));
            if (i == 4)
                obj = getPrefs(context, StartActivity.START_PREFERENCES).getString(StartActivity.START_PREFERENCES_OBJECT5, String.valueOf(object_5));
            if (i == 5)
                obj = getPrefs(context, StartActivity.START_PREFERENCES).getString(StartActivity.START_PREFERENCES_OBJECT6, String.valueOf(object_6));
            if (i == 6)
                obj = getPrefs(context, StartActivity.START_PREFERENCES).getString(StartActivity.START_PREFERENCES_OBJECT7, String.valueOf(object_7));
            if (i == 7)
                obj = getPrefs(context, StartActivity.START_PREFERENCES).getString(StartActivity.START_PREFERENCES_OBJECT8, String.valueOf(object_8));
            if (i == 8)
                obj = getPrefs(context, StartActivity.START_PREFERENCES).getString(StartActivity.START_PREFERENCES_OBJECT9, String.valueOf(object_9));
            if (i == 9)
                obj = getPrefs(context, StartActivity.START_PREFERENCES).getString(StartActivity.START_PREFERENCES_OBJECT10, String.valueOf(object_10));

            String time_prev = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(prev_time_);
            String time_cur = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(cur_time_);
            String msg = "";
            String temp="";
            if (disapp) {
                temp=byIdName(context, "no_data");
                msg = temp + "\n" + time_prev + " - " + time_cur;
            }
            else {
                temp=byIdName(context, "data_restored");
                msg = temp + "\n" + time_cur;
            }

            Log.d(LOG_TAG, obj + ", " + msg);

            if (!StartActivity_Started)
            {

                new Thread(new Runnable() {
                    public void run() {
                        try {
                            //перезапускаем приложение, если оно не запущено еще
                            Intent StartActivity = new Intent();
                            StartActivity.setAction(Intent.ACTION_MAIN);
                            StartActivity.addCategory(Intent.CATEGORY_LAUNCHER);
                            StartActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY ); //Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP
                            ComponentName cn = new ComponentName(mContext, StartActivity.class);
                            StartActivity.setComponent(cn);
                            mContext.startActivity(StartActivity);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }
                }).start();



                int timeout = 100;
                while (!StartActivity_Started && timeout != 0) {
                    Thread.currentThread();
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    timeout--;
                }

                //sendNotificationPause=10000/PERIODIC_TASK_LEN;
                //while (!StartActivity_Started && (sendNotificationPause != 0) ) {}

                Log.d(LOG_TAG, "Startup: " + timeout);


                Thread.currentThread();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //sendNotificationPause=1000/PERIODIC_TASK_LEN;
                //while (sendNotificationPause != 0) {}

            }

            //передаем данные в приемник
            try {
                Intent intent2 = new Intent(TCP_BROADCAST_TO_START_ACTION);
                intent2.putExtra(PARAM_TYPE, SYSTEM_DATA);
                intent2.putExtra(PARAM_DATA, msg);
                intent2.putExtra(PARAM_OBJECT, i+1);
                //MyService.mContext.sendBroadcast(intent2);
                LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent2);
            } catch (Exception e) {
                e.printStackTrace();
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String byIdName(Context context, String name) {
        Resources res = context.getResources();
        return res.getString(res.getIdentifier(name, "string", context.getPackageName()));
    }
}


