import os
import sys
import pygame
import wx
import yaml
import logging
from GUI.GUI import mainFrame
from monitor.BaseClasses import Mouse, Experiment, Drug
from monitor.SyringePumps import AladdinPump

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

SurgicalLogInfo = wx.AboutDialogInfo()
SurgicalLogInfo.SetVersion("2.0")
SurgicalLogInfo.SetName("PhysioMonitor v2")
SurgicalLogInfo.AddDeveloper("Marin Manuel")
SurgicalLogInfo.SetCopyright("")
SurgicalLogInfo.SetDescription(
    "PhysioMonitor helps keep track of drug injections and physiological data during an experiment")
SurgicalLogInfo.SetLicence("")

CONFIGURATION_FILE = "PhysioMonitor.yml"

if __name__ == '__main__':
    currentPath = os.path.dirname(os.path.realpath(sys.argv[0]))

    # start with a "fresh" mouse
    theMouse = Mouse()
    theExp = Experiment(mouse=theMouse)
    theExp.date = wx.DateTime.Now()

    # get the list of previous drugs to save time
    drugList = []
    lastEntries = wx.Config(SurgicalLogInfo.GetName())
    if lastEntries.HasGroup("drugs"):
        lastEntries.SetPath("/drugs")
        numDrugs = lastEntries.GetNumberOfEntries() / 2
        for i in range(0, numDrugs):
            drugName = lastEntries.Read("%d_name" % i, "default name")
            drugDose = lastEntries.ReadInt("%d_name_dose" % i, 0)
            drugList.append(Drug(drugName, drugDose))
    theExp.prevDrugList = drugList

    # get list of mouse strains
    mouseStrains = set()
    lastEntries.SetPath("/")
    if lastEntries.HasGroup("mouseStrains"):
        lastEntries.SetPath("/mouseStrains")
        for i in range(0, lastEntries.GetNumberOfEntries()):
            mouseStrains.add(lastEntries.Read("%d" % i, ""))
    theExp.prevStrainList = mouseStrains

    # get list of mouse genotypes
    mouseGenotypes = set()
    lastEntries.SetPath("/")
    if lastEntries.HasGroup("mouseGenotypes"):
        lastEntries.SetPath("/mouseGenotypes")
        for i in range(0, lastEntries.GetNumberOfEntries()):
            mouseGenotypes.add(lastEntries.Read("%d" % i, ""))
    theExp.prevGenotypeList = mouseGenotypes

    # load configuration file
    with open(os.path.join(currentPath, CONFIGURATION_FILE), 'r') as stream:
        config = yaml.safe_load(stream)

    # init mixer
    pygame.mixer.init(44100, -16, 2, 2048)

    app = wx.PySimpleApp(redirect=False)

    # initialize the syringe pump
    pumpValid = False
    syringePump = None
    if 'pump' in config and config['pump']['enabled']:
        while not pumpValid:
            try:
                syringePump = AladdinPump(
                    config['pump']['com-port'],
                    config['pump']['baud-rate'],
                    config['pump']['device-id'])
                syringePump.doBeep(1)
                pumpValid = True
            except Exception as inst:
                logging.info("Exception caught when trying to communicate with SyringePump: %s", inst)
                errorDlg = wx.MessageDialog(None,
                                            "Cannot communicate with syringe pump. Maybe it is off?\nRetry?",
                                            style=wx.YES | wx.NO | wx.CANCEL | wx.ICON_QUESTION)
                ret = errorDlg.ShowModal()
                if ret == wx.ID_YES:
                    pumpValid = False
                    syringePump = None
                elif ret == wx.ID_NO:
                    pumpValid = True
                    syringePump = None
                else:
                    sys.exit(1)
                errorDlg.Destroy()

    mainFrame = mainFrame(exp=theExp, info=SurgicalLogInfo, config=config, pump=syringePump)
    mainFrame.Show()
    app.MainLoop()

    # at this point, main window has been closed, cleaning up...

    # save the list of drugs
    lastEntries.SetPath("/")
    lastEntries.DeleteGroup("drugs")
    lastEntries.SetPath("/drugs")
    for index, drug in enumerate(theExp.prevDrugList):
        lastEntries.Write("%d_name" % index, drug.name)
        lastEntries.WriteInt("%d_name_dose" % index, drug.dose)
    lastEntries.Flush()

    # save list of mouse strains
    lastEntries.SetPath("/")
    lastEntries.DeleteGroup("mouseStrains")
    lastEntries.SetPath("/mouseStrains")
    for index, strain in enumerate(theExp.prevStrainList):
        lastEntries.Write("%d" % index, strain)
    lastEntries.Flush()

    # save list of mouse genotypes
    lastEntries.SetPath("/")
    lastEntries.DeleteGroup("mouseGenotypes")
    lastEntries.SetPath("/mouseGenotypes")
    for index, genotype in enumerate(theExp.prevGenotypeList):
        lastEntries.Write("%d" % index, genotype)
    lastEntries.Flush()
