import wx
import os
import time
import threading
from pathlib import *
# from configobj import ConfigObj

from listctrl import Listctrl
from mypanel import MyPanel

from uiconfig.uisensor import UISensor
# from uiconfig.uilogging import UILogging

from uiconfig.uiabout import About
from uiconfig.uihelp import Help

from myconfig import TOKEN,DeviceType,YAML_FILE_NAME,RETRIEVE_CFG_FILE
from myconfig import MyConfig
from configuration import Configuration
from awrams import AWRAMS,HandHeldBuf
  
from tools.myexception import MyException
from tools.mylogger import log

# -定义菜单ID,关联Event-------------------------
ID_MEASURE          = 1
 
ID_SENSOR_SETTING   = 11
ID_LOGGING_SETTING  = 12
ID_CAL_INFO         = 13

ID_HELP             = 21
ID_ABOUT            = 22


class YiwinFrame(wx.Frame):
    '''将buf类传进来'''
    def __init__(self, title, parent, size=(900, 750)):
        self.device_id      = 2
        self.device_type    = DeviceType.SURFACE.name
        self.syscfg = {}
        self.sensor_cfg = {}
        self.retrieve = {}
        self.calinfo_is_ok = False
        self.title = title
        self.path = PurePath()
        # self.save_fname:Path = Path(self.path.joinpath(DATA_FNAME))
        self.result = ''
        self.displayData:list =[]
        self.interval = 0

        super(YiwinFrame, self).__init__( parent, title=self.title, size = size )

        self.BoxSizer = wx.BoxSizer(wx.HORIZONTAL)  # 建立一个Boxsizer
        self.SetSizer(self.BoxSizer)
        self.Centre(wx.BOTH)

        # 建立 listctrl panel 放到BoxSizer
        self.listctrl_panel = Listctrl( self  )  # 调用自己建立的 Listctrl panel 类
        self.BoxSizer.Add( self.listctrl_panel, proportion =-10, border = 2, flag = wx.ALL | wx.EXPAND)
        self.list_ctrl = self.listctrl_panel.list_ctrl
        # 隐藏 等待show
        self.listctrl_panel.Hide()

        self.mypanel = MyPanel( self  )  # 调用自己建立的 Listctrl panel 类
        self.BoxSizer.Add( self.mypanel, proportion =-10, border = 0, flag = wx.ALL | wx.EXPAND)
        self.static_text = self.mypanel.staticText1 
        # 隐藏 等待show
        self.mypanel.Show()

        self.statusBar = self.CreateStatusBar()  # 创建状态栏
        self.statusBar.SetFieldsCount(2)  # 状态栏分成3个区域
        self.statusBar.SetStatusWidths([-1, -1])  # 区域宽度比列，用负数
        self.statusBar.SetStatusText(u" 等待接收消息......", 0)

        self.__set_menu()       # 添加菜单
        self.__attach_events()  # 菜单事件
        self.__set_properties()
        # self.__read_config()
        self.__setTimer()
        log.info(f"system init....",__name__, "__init__")
        self.mycfg = MyConfig()
        self.hh = AWRAMS()

        # self.hhb = HandHeldBuf()  
        
        pass

    def __set_menu(self):
        '''
        # 设置菜单
        '''
        self.menubar = wx.MenuBar()

        settingMenu = wx.Menu()
        settingMenu.Append(ID_SENSOR_SETTING, u'&设置', '...') 
        settingMenu.AppendSeparator()
        settingMenu.Append(ID_CAL_INFO, u'&获取标定信息', ' ')
        settingMenu.AppendSeparator()
        settingMenu.Append(ID_MEASURE, u'&处理数据', ' ')
        # settingMenu.AppendSeparator()
        # settingMenu.Append(ID_LOGGING_SETTING, u'&采集设置', ' ')
        self.menubar.Append(settingMenu, u'&系统  ')

        aboutMenu = wx.Menu()
        aboutMenu.Append(ID_HELP, u'&帮助', 'help...')
        aboutMenu.AppendSeparator()
        aboutMenu.Append(ID_ABOUT, u'&关于我们', '关于我们...')
        self.menubar.Append(aboutMenu, u'&帮助  ')
        
        self.SetMenuBar(self.menubar)
        pass

    def __set_properties(self):
        self.SetSize((800, 600))
        # self.SetTitle(u'传感器数据采集--上海奕枫仪器设备有限公司')
        self.Centre()

    def __attach_events(self):
        '''
        # 绑定菜单事件
        '''
        self.Bind(wx.EVT_MENU, self.OnSensorSetting, id=ID_SENSOR_SETTING )
        self.Bind(wx.EVT_MENU, self.OnCalInfo, id=ID_CAL_INFO )
        # self.Bind(wx.EVT_MENU, self.OnStart, id=ID_MEASURE)
        self.Bind(wx.EVT_MENU, self.OnDealData, id=ID_MEASURE)
        # self.Bind(wx.EVT_MENU, self.OnLoggingSetting, id=ID_LOGGING_SETTING)

        self.Bind(wx.EVT_MENU, self.OnHelpConfig, id=ID_HELP)
        self.Bind(wx.EVT_MENU, self.OnAboutConfig, id=ID_ABOUT)
        pass

    def __setTimer(self):
        self.timer = wx.Timer(self)   #创建定时器,菜单以后
        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) #绑定一个定时器事件
        pass

    def OnStart( self, event  ):
        log.info(f"OnStart....interval: {self.interval} min, port: {self.port}")   
        # self.m = SerialThread()  
        interval_ms = int(self.interval) * 10 * 1000
        self.timer.Start( interval_ms )
    
    def OnStop( self ,event  ):
        # self.kh.disconnect()
        # self.timer.Stop()
        pass
    
    def OnTimer(self, event):
        '''
        定时器实现
        '''
        # log.info( f"OnTimer...." )
        # self.OnDisplaySave()   
        pass 

    def onNotify(self, msg:str):
        self.mypanel.setStaticText(msg)
        pass 

    def __read_config(self,):
        # 读取配置文件
        self.mycfg.setDeviceType(DeviceType.SURFACE)
        self.sensor_cfg = self.mycfg.read_yaml()
 
    def OnDealData(self, e)-> None:
        log.info(f"OnDealData: 处理测量数据", __name__, "", "")
        if not self.calinfo_is_ok:
            self.onNotify("Pls get the cal info, and try again" )
            log.warning(f"Pls get the cal info, and try again", __name__, "OnDealData")
            self.statusBar.SetStatusText("Pls get the cal info, and try again",0)
            pass
            
        self.hh.getDataFileList() 
        self.hh.setDeviceID(self.device_id)
        self.hh.setRetrieve(self.retrieve)      
        if self.syscfg != {}:
            self.hh.setSyscfg(self.syscfg)
        else:
            log.warning(f"Pls get the cal info, and try again", __name__, "OnDealData","setCfg")
            MyException( f"System Configuration is empty." )
            pass

        if self.hh.dealAllMeasurements(  ):
            self.onNotify("正在处理数据" )
            self.statusBar.SetStatusText(u" 数据处理完成......", 0)
        self.onNotify("处理数据已经结束" )
        pass 
        
    def OnCalInfo(self,e):
        '''依据传感器获取标定文件信息'''
        #######################################
        self.onNotify("正在获取标定信息")
        device_id = self.device_id # 多个设备
        device_type = DeviceType.SURFACE.name
        self.mycfg = MyConfig()

        self.mycfg.setDeviceType(DeviceType.SURFACE)
        init_para = self.mycfg.read_yaml()
        log.info(f"Current Device: {device_type}  ", __name__, "", "")
        log.info(f"Sensor:  {init_para}", __name__, "", "")
        # 配置反演需要的参数  波长  间隔
        self.retrieve = self.mycfg.get_retrieve()
        log.warning(f"Retrieve: {self.retrieve}", __name__, "", "")

        self.syscfg = {}
        
        cfgr = Configuration( )
        cfgr.setDeviceType(device_type)
        cfgr.setSystemCfgDict(init_para)
        
        for k,v in init_para.items(): 
            cfgr.setSystemCfgDict(v)
            try:
                cfgr.getCalConfiguration()
            except Exception as e:
                log.error(f"读取配置文件失败. \n  {e}",__name__, "", "" )
                raise
            log.info(f"v:  {cfgr.configuration}", __name__, "", "")       
            self.syscfg.update({k:cfgr.cal_configuration})

        # log.warning(f"self.syscfg: {self.syscfg}", __name__, "", "")
        log.warning(f"self.syscfg 2: {self.syscfg[2].keys()}", __name__, "", "")
        log.warning(f"self.syscfg 3: {self.syscfg[3].keys()}", __name__, "", "")
        log.info(f"传感器配置文件读取成功", __name__, "", "")
        self.alterStatus_0("传感器配置文件读取成功")
        self.onNotify("获取标定信息成功")
        self.calinfo_is_ok = True

        pass

    def alterStatus_0(self,msg):
        self.statusBar.SetStatusText( msg, 0 )

    def popDialog(self, msg, msg_type=u"错误提示"):
        with wx.MessageDialog( self, msg, msg_type, wx.OK )as dlg:
            dlg.ShowModal()
    
    def OnSensorSetting(self,e):
        with UISensor(
                self,
                -1 ,
                did = self.device_id ) as Dialog_Sensor_Setting:
            Dialog_Sensor_Setting.CenterOnParent()
            resultLog = Dialog_Sensor_Setting.ShowModal()

            if resultLog == wx.ID_OK:
                print( " Sensor config dialog confirm, call back " )
        self.__read_config()  
        pass    
    
    def OnHelpConfig(self, e):
        with Help(
                self,
                -1,
                "") as Dialog_Help:
            resultLog = Dialog_Help.ShowModal()

            if resultLog == wx.ID_OK:
                print("Help info")

        pass

    def OnAboutConfig(self, e):
        with About(
                self,
                -1,
                "") as Dialog_About:
            resultLog = Dialog_About.ShowModal()

            if resultLog == wx.ID_OK:
                print("Aboutus")
          
        pass

    def OnQuit(self, e):
        self.Close()
        

 
# class SerialThread(threading.Thread):
#     """进度条类  """
#     def __init__(self, parent):
#         """
#         :param parent:  主线程UI
#         """
#         super(SerialThread, self).__init__()  # 继承
#         self.parent = parent
#         # log.info(f"SerialThread ... {self.parent.kh}")
#         self.start()
#         self.join()
#         # self.setDaemon(True)  # 设置为守护线程， 即子线程是守护进程，主线程结束子线程也随之结束。


#     def stop(self):
#         self.parent.kh.disconnect()
#         log.info(" Serial stop.... ")
#         pass

    # def run(self):
    #     log.info(" Serial run.... ")
    #     wx.CallAfter(self.parent.OnRcv)

        # wx.CallAfter(self.parent.update_process_bar, count)  # 调用parent的函数
        # wx.CallAfter(self.parent.close_process_bar)  #  destroy进度条
        
    # def OnSerialThreadStart(self):
    #     self.m = SerialThread(self) 
    #     pass

    # def OnSerialThreadStop(self):
    #     self.m.stop()
    #     pass
    
    # def OnDisplaySave(self):
    #     '''
    #     保存数据  self.result
    #     '''   
    #     log.info(f"OnDisplaySave ....")
    #     # self.m = SerialThread(self) 
    #     # self.kh.flush() 
    #     self.OnSerialThreadStart()


    # def OnRcv( self ):
    #     log.info(f"OnRcv....")
    #     self.kh.setPort(self.port)
    #     if not self.OnDetectPort:
    #         MyException(f"Can not find port : {self.port}")     
    #     log.info(f"{self.port} ok!")
    #     # if not self.kh:
    #     #     self.kh = KH3000(self.port)
    #     # self.result = self.kh.OneMeasure()
    #     log.info( f"OnRcv success {self.result}", __class__.__name__ )
    #     self.OnSave()
    #     self.OnDisplay()
    #     pass