# -*- coding: utf-8 -*-

########################################
# HXbot server module                  #
# EoF 2016 EoF@itphx.ru                #
########################################

import HX
import threading
import socket
import sys
import struct


class HXserverClass():

    def __init__(self, hxbot):
        super(HXserverClass, self).__init__()

        try:
            self.s = socket.socket(family=socket.AF_INET,
                type=socket.SOCK_DGRAM)
            self.s.bind((HX.SRV_HOST, HX.SRV_PORT))
            self.s.settimeout(HX.SRV_TIMEOUT)
        except OSError as E:
            print(E)
            sys.exit()

        self.hxbot = hxbot

        self.hxpower = None
        self.reflex = None
        self.joystick = None
        self.hxlcd = None
        self.hxcam = None

        self.__e = None
        self.__t = None

        self.is_running = False

    def start(self):
        self.hxpower = self.hxbot.hxpower
        self.reflex = self.hxbot.reflex
        self.joystick = self.hxbot.joystick
        self.hxlcd = self.hxbot.hxlcd
        self.hxcam = self.hxbot.hxcam

        self.__e = threading.Event()
        self.__t = threading.Thread(target=self.__process, args=(self.__e, ))

        self.__t.start()
        self.is_running = True

    def stop(self):
        self.__e.set()
        self.__t.join()
        self.is_running = False

        self.hxpower = None
        self.reflex = None
        self.joystick = None
        self.hxlcd = None
        self.hxcam = None

        self.__e = None
        self.__t = None

    def __process(self, stopRequest):
        while not stopRequest.is_set():
            try:
                data = self.s.recvfrom(1024)
            except socket.timeout:
                continue

            cmd = data[0][0]
            client = data[1]

            if cmd == HX.SRV_CMD_GET_ALL:
                self.s.sendto(self.__pack_all(), client)
            else:
                pass

        self.s.close()

    def __pack_all(self):
        # INIT
        pw = self.hxpower
        rf = self.reflex
        lc = self.hxlcd

        ca = self.hxcam
        if ca is not None:
            ca_mcam_state = ca.mcam_state
            ca_rcam_state = ca.rcam_state
            ca_mmic_state = ca.mmic_state
        else:
            ca_mcam_state = 2
            ca_rcam_state = 2
            ca_mmic_state = 2

        js = self.joystick
        if js is not None:
            js_online = js.online
        else:
            js_online = False

        result = struct.pack(
            'fffffffffff??????????????????????????????????????????????BBB',
            pw.vcc,
            pw.vin,
            pw.vdc,
            pw.vbt,
            pw.vba,
            pw.vpf,
            pw.vzu,
            pw.abt,
            pw.aba,
            pw.ain,
            pw.ahx,
            pw.online,
            pw.vcc_ok,
            pw.vin_ok,
            pw.vdc_ok,
            pw.vbt_ok,
            pw.vba_ok,
            pw.vpf_ok,
            pw.vzu_ok,
            pw.abt_ok,
            pw.aba_ok,
            pw.ain_ok,
            pw.ahx_ok,
            pw.bt_enabled,
            pw.ba_enabled,
            pw.bt_blocked,
            pw.ba_blocked,
            pw.vcc_low,
            pw.vcc_high,
            pw.vin_low,
            pw.vin_high,
            pw.vdc_low,
            pw.vdc_high,
            pw.vbt_low,
            pw.vbt_full,
            pw.vba_low,
            pw.vba_full,
            pw.vpf_low,
            pw.vpf_high,
            pw.vzu_low,
            pw.vzu_high,
            pw.abt_low,
            pw.abt_high,
            pw.aba_low,
            pw.aba_high,
            pw.ain_low,
            pw.ain_high,
            pw.ahx_low,
            pw.ahx_high,
            pw.mv_enabled,
            pw.us_enabled,
            pw.in_plugged,
            pw.ba_full,
            pw.bt_full,
            rf.online,
            js_online,
            lc.online,
            ca_mcam_state,
            ca_rcam_state,
            ca_mmic_state)

        return result
