#!/usr/bin/env python3
# -*- coding: utf-8 -*-
APP_LICENSE = """
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
"""

__version__ = '1.0'

import signal
import sys
import atexit
import os
import time
import argparse

from gi.repository import GLib

import wx
import wx.lib.embeddedimage
from wx.adv import NotificationMessage

################################################################################
#CONFIG
################################################################################
APP_NAME = "Labsync Tray WX"
APP_YEAR = "2019"
APP_VERSION = __version__ + '-' + APP_YEAR
APP_DESCR = "Notifica lo stato di aggiornamento del software nella cartella /opt"
APP_AUTHORS = """
DiSIT - Sezione di Informatica
Università del Piemonte Orientale
help@di.unipmn.it
"""

APP_ID = "labsync-tray-wx"

CURR_DIR = os.path.dirname(os.path.abspath(__file__))

# icons: they will be created on-the-fly from embedded images
APP_ICONS = {}

# milliseconds between checks
CHECK_PERIOD = 30000
# how long the notification stays on the screen (seconds, 0=until user clicks)
NOTIFY_TIME = 0

# messages
MSG_SYNC_TITLE = "labsync"
MSG_SYNC_TEXT = """Stiamo aggiornando il software nella cartella /opt; ci \
sarà un po&apos; di attività sul disco.\
\r\rAlcuni dei programmi lì presenti (comprese le macchine virtuali) potrebbero \
non funzionare correttamente fino al termine degli aggiornamenti.\
\r\rIl termine della procedura di aggiornamento ti verrà notificato, ti \
preghiamo di attendere qualche minuto.\
\r\r<b>Se hai atteso più di mezz&apos;ora, non hai ricevuto la notifica e il \
software che vuoi usare continua a non funzionare, contatta i tecnici.</b>"""
MSG_SYNC_ICON = wx.ICON_EXCLAMATION
# 0 = normal, 1 = warning, 2 = critical
MSG_SYNC_URGENCY = 2
MSG_SYNCED_TITLE = 'labsync'
MSG_SYNCED_TEXT = "Il software nella cartella /opt è aggiornato."
MSG_SYNCED_ICON = wx.ICON_INFORMATION
# 0 = normal, 1 = warning, 2 = critical
MSG_SYNCED_URGENCY = 1

# task names
SYNC = "Syncing"
SYNCED = "Synced"
OFF = "Off"

# file to check for saying if we're syncing or not
FILE_TO_CHECK = "/opt/ver"

# menu strings
MENU_STATUS = "Status"
MENU_ABOUT = "About"
MENU_EXIT = "Exit"

################################################################################
################################################################################

APP_ICONS_DATA = {
    OFF: wx.lib.embeddedimage.PyEmbeddedImage(
        "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"
        "1rTdvf0AAAAASUVORK5CYII="
    ),

    SYNCED: wx.lib.embeddedimage.PyEmbeddedImage(
        "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"
        "QmCC"
    ),

    SYNC: wx.lib.embeddedimage.PyEmbeddedImage(
        "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAADfxJ"
        "REFUeJzlm3l8VFWWx7/31ZoUqSQkIQtEsgyEsRFUVDqKEFBpUNRuFUVttcdRxmXm0zbtOKLC"
        "VCPY0x/atu1RBEYHdcZ9FBdiqyhrBBGQXROWsCcBQqpSWWp9784flZVUVd6rJD3z+fTvr6p7"
        "z/m9c0/duvfcc8+Dv3KIgX7AibmjMhRLaKJEjlUEJVIyEsgCBgFpbWIeoBk4IwT7NUmVQOzS"
        "QpYNw35beXYg7RsQB9S4CkYhTXch5bXAGEBJkEoDuQuUT6Wm/dfQhYer+tFMoB8dIGePs9Tl"
        "eO6QyIeAy/qL9xxsEVIsyTHlvylc68L9QdhnB0QG7r5PwmNAQd9N0oXDIH6Xq+S/0ldH9MkB"
        "NfMKr0SIF4EL+sKTKATslgoP57mqK/rAYRzHfzUsyZRifQ6YnShHP0ICSwOKNqfQdcRvVNmw"
        "8SefKiwRingHGGtUd4DxvZDKrblPH9xnRMmQA07ML7pKgZVAiiHT/nLwCsRPcxccWqtXQff2"
        "VOMq/qkCq+jHwSt2J8Js6y86AKdEflY7r/BWvQq6ZkDt/MKZEvEWYErEKsUxGNuISViHXohl"
        "2IWY0oeh2FNBRB4vAy2oLfWET+8ndPw7Ake2Ejq5E6RM5HEAKnBb3oLq93sT7NUBtfOLJ0vk"
        "nwFjP5UQ2EdOIeniW7GPKAOT2ZC66j6Ob9dKWra+gdZcb0i3DUGJnDF0weHVcc2M11njKhiF"
        "pnyLwWlvLSzFec1jWIaOMaIWFTLYSsuW12mpWIbm9xpVb1Q1Ls1fWH0glkBMBxx2FdhtmrIZ"
        "uFDv04Q9hdQZC0m6YIZBO3uH6j1F44ePEThkeMvfozYFx+c/d8IXrTPmImjTlD9iYPCWvAvI"
        "euCTARk8gMmZzeC7XiXl6kc71g6duEBJsS6O1RmVqcZVNAGNDbH6z4Wt6HLSb1+GsCb3Kqt6"
        "6wifOYjaWAOaBoqC4sjAnFGIOaNQ1+B8u1bi+ehxUHVHwVIqYsJQ16FN53b0eJp0lZlrtWPb"
        "0Bno2EaUkT5rSdztLFx/iNZtbxOo+opww9GYckpSKraRU0gacwO24ivjOsO3ZxWe9x8xslPs"
        "ya1LHyeWbw91beyxrT0wUfkH4O/1MFpyzmfw3SsQFnvUfrXhGI2fPIW3/F8JHd+B5muMyyfD"
        "AcKnKvHt/ojAD19gShuGOaMg+rOzRyJMVoLVPX7UWMhudgROPLvBvb1rYzcXy9njLLU57v3o"
        "ONUpyWlkzv4QU3p+1P7W797F++kCZCjq2qMbSWNuIPX6RTH/Xu43Z+Ov+konm6zOVYaXdD1B"
        "dlsE63I8d6DzSOuc+kT0wUuJ97NFNH40t8+DB/Dt/pj6l29B9dZF7U+9fiFKclrUvp4QRbXa"
        "0du7tnRzgEQ+rNcw26iro7Z7P3+Gls3/qZdGF8Knqmh47W60lp7ZMSVlCClXPaqbS8CD3fTb"
        "P5xwFY0ELtVvVGWPNt/Olf0++I7n1R/C/e4/gab26Eu+aCamwefp4pGI0pNPFZa0f++ITxUp"
        "7okcrfXBs/KfSbvlj1jzLwap4dv9EY0fz9Wtrxe24glYcn/U8T1cX415yIjuQiYzaTc8Q+Dg"
        "xo4mqYZo/e5dZKC5B6dQuBOYD10cgJTXGTFM9Zzk7MszMTmzkWoIraXBiLpupN3yvK7/uLWw"
        "FGthabc2zefBt/ODKNJiOm0OUCCSuibBtJbqPTVggwdo/fb1hPTUplP4K2Oegy46+vh56dDm"
        "AMUWnETiqesBRfOGJYRPxzzLxIR31XykvylWt8lit0yCtkFLjb4f2wYIUg1Fwt4oi18s+PeW"
        "46/8Mq6M0CIzPjIDBCVxpf+PETqxk5Zv/1uXrPQ34f1sUe9yyBJonwGR66r/12j6cjGq+3iv"
        "ct7Pn0FtOqWHstMBwJBEjHL8+B6yHvoUkzMnEXVDkCEfno/mxj38BI9soXXHe3oph0CnAwwn"
        "Os2ZRaRc8y+Ys0tIvaH3KdcfCB7ejG/Xh1H7ZDhI46r5Rk6HKdDpAIchS4RC6o2/7TgC20aU"
        "DVgi5Fx4P1sYNUfYvP7fCZ85aISqmwMMIfmS27Ged0m3Nue1LhTH4EToDEHzefD+eUG3tvCp"
        "Kpq/Xp4QX7sDWnQrpAyJpKXObU9Ox/mTJxIywih8e8s7gxyp0fjJk0ayQ+1ogk4HxIwYzkXq"
        "db9BsTuj9iWN/Rn2kquMGpIQvOUuwmcP07z+BYLHdyRC0QSdZ4HTwLDeNOznT8P+t1Pjyjiv"
        "cxE48g0yoHtSJQTVW8eZP0U/kuvEaWibAUKwvzdpYRuEc/r8XllNqXmkTPl1Xwz7S6EK2hyg"
        "SXotPXFOnYvJma2L2TH+LqznjeuTdQMNgeh0gEDsiidsHX4ZyeNuM8DefZscaKgSPEEznqBJ"
        "d0ZDQ+yGtjVAVQLrTZpVI8q2KMxWUq9/2uhlBObMYgZd+QBNa583pKcHEtjrTmJrfRI7G5I4"
        "GzAh2/K7JgFZ9hDjMnxcltnKCGcgGoUaDgY3QJescM38oh1EuQlKGn0daTP/lJihwVbqnhkL"
        "UktIPxp+aLTzZnU6h5qsHW0mk4m0tDSklLjdbmSXaHDsYD93FLrJdwS70mzNW1B9GXTNCCHK"
        "QfZwgP/gBprWPNctLW0ZMhLbyMk9jNP8Xlq3vdXxPXRyT78NXgKrjjt5+3AaEkFWVhYzZsxg"
        "woQrKCgoRFEiv6WqqlRWVlFRUUF5eTm7GmCvO5e7ihuYmtfUzvVpx6jbP5xwFY1UtN4XQ4js"
        "CEMeWYeSnN6jr3HVfFq3vtG30Z4DCSytzGTjaQcmk4lf/OIeZs6cic3WucY0hzRMiiDJ1PlX"
        "bWpqYsWKFaxcGTk/3Dy8kZuHe9AUSoa5qvdDl5uhP6xzn/31pPRrgaG9WqQGQarY/ubKHl22"
        "4gmEavehnj2S6Hh7YOWxVD476cThcLBo0UKmTZuG2dw5ecOaZHJ5DV+caOW24s5znc1mY/z4"
        "8eTl5fHNN9/wvduK06odmPiHSle7TLdFT0jxol6jWra8RqhmT492YbKQftsS7KMN5Vhj4mCT"
        "jfePpKEoCvPmPcW4cT2319awpCGgcrwlejg8deo1zJkzBwm8djBteFlZWUfQ180BOafS3gIO"
        "67JMDeP54FFkqGdlmjBbSb/leZzTnkRYknTRxcI7x7KQwJ133sH48eMT5pk+fRqTJ09Gk4pV"
        "CNFxmuo+A5ZvD4H4nV7S8JmDeD58LPpCJwSO0nvJ+sfPSbrwJoTJYshgYU3mZNEs9p2NrPCz"
        "Zs0ypB8N999/HxaLBSm5u6ysLAei7Pu5Sv4rQNzAqCv8e8vxfvFvMftNaUNJ+9lisn61Hue0"
        "J7EWjI950SlsDmwjp5B6/SKyH93Mdv9wAKZN+wnJyb3XHvSG3Nzc9llkEkLcAN22wTYjXOvC"
        "J+cVPyyE3IjOAomWTa+AGsI5fR6I6CkGU0o2jtJ7cZTeC5qK2liD2lyPDLWi2FNRBmX2SK1t"
        "27YNgNLSy42MMy4uv/xyKioqkJKpwPKo1g59+tDXwFIjxC1bXsf9zsPxcvGdUEyY0vOx5l+E"
        "regKLHmjo+YV6+oiN8JFRYVx6XzhSOATUCVqL7FwF67hECcjFFC0OSANHbT9P3zBmSXXEjz8"
        "jRG1qAgGgzQ3N2O1Whk0aFBc2berI04PqJK3D8WvJMvIyGj/mAtxHFDoOuLXFDELMFSbpjbW"
        "cPa1n+N+czahuh+MqHaD2WxGURTC4TCaFj+aLEjpXGBf+t5LTWvs7FAw2BES+6GXnOAwV/V+"
        "oSg3tgvrhpT4q76iftmNuN96AP8PXyDDwd71ulI0nybNYUPTNNxud1zZG4c7eHVSNj9Kt3LG"
        "r3LnmlMxY4L6+vYaA1kDURbBc5HrOriu1lV4l9TE2xgtldVU/JWr8VeuRthTsOZfjDX/Ysw5"
        "o1CSM1CS0xCWJKTfi+bzoHpOEjyxi9CJHYRqvyfXlEUDdvbu3cukSZPiPqo0284bk3O4f+Np"
        "tp7xc/faU7w+OZt8R/ch7tnTHrwpVbocEHHC4f+pcRXfgibfAqJXRPUC6W8icGA9gQPrdetc"
        "NNjHPo+djRsrenUAQJJZsHRCFvdtOM2OswF+uekMH1yT202moiJSaCklH4OBtHie69CHQlGm"
        "A/FLvfoRl2W1YhKwbt06jh6NXV7XFYMsCi9PHMLVQ5O5JKv7b7Vjx04qKysB3MGg70sweC+Q"
        "6zq4TtW4FNhpRC9RZNrCTM5pQlVVXnppKZqmL98zyKLw4hVZPHFh52k1EAjwwgsvtH2TizZv"
        "3uyDBC5G8hdWHwgoWqmEFzFSU5MgbhreyCCzxpYtW3j11RUJcUgpWbx4MdXV1UjJfiK2A31+"
        "aap4HEK+hIHiqkRQ2Whn0e4hqFIwY8YMHnnkl5hM+tbjYDDI73//LKtXrwZoEoLStWvXdrxW"
        "0/fX5lxl5lrt6N8Bj4Mo6itfLHx92sGyqgzCUnD++efz4IMPMHr06Lg6mzZtYtmy5Rw7dgzA"
        "oyji5jVr1qzpKtN/L05GHHG7RHlIIH/cX7xdscdj3/vs3qyhQU1JBygpKWHChCsoLi4mMzMT"
        "VdVoaDjLvn37+PrrTR0Lp5R8ryjctHbt2h4ZrwF55S2SXpM/b6vGuogEX7Uh8urLDgnlmsYb"
        "+QurD0ydOtURCITmAI8KQfQ7uk7UCcHTXq/3P7Zv714k3Y4Bf+fv6OPnpZut1okKcowUchSS"
        "EiATcAKpbWKNRELuMwj2CykqNcTuoBJeX+g64onGW1ZWZhdCTJFSTgelAOQwkCEpRa2iUAWU"
        "Z2ZmVrz33nv6i4v+GvG/eR4ZtDSfns0AAAAASUVORK5CYII="
    )
}

class TrayApp(wx.adv.TaskBarIcon):
    TBMENU_ABOUT = wx.NewId()
    TBMENU_CLOSE   = wx.NewId()
    TBMENU_STATUS  = wx.NewId()

    def __init__(self, frame):
        wx.adv.TaskBarIcon.__init__(self)

        self.frame = frame
        self.task_changed = True
        self.task = SYNCED
        self.icon = None
        self.current_notification = None

        # create all the icons
        self.makeIcons()

        # Set the icon
        icon = APP_ICONS[OFF]
        self.SetIcon(icon, APP_NAME + ' - ' + self.task)
        self.imgidx = 1

        # bind some events
        self.Bind(wx.adv.EVT_TASKBAR_LEFT_DCLICK, self.onLeftClick)
        self.Bind(wx.EVT_MENU, self.onMenuStatus, id=self.TBMENU_STATUS)
        self.Bind(wx.EVT_MENU, self.onMenuAbout, id=self.TBMENU_ABOUT)
        self.Bind(wx.EVT_MENU, self.onMenuQuit, id=self.TBMENU_CLOSE)

        # initialize task value
        self.updateTask()
        if self.task_changed:
            self.sendNotification()
        # then start updating every CHECK_PERIOD seconds
        # http://developer.gnome.org/pygobject/stable/glib-functions.html#function-glib--timeout-add-seconds
        #GLib.timeout_add_seconds(CHECK_PERIOD, self.onTimeout)
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
        self.timer.Start(CHECK_PERIOD)

        # clean up on exit, both normal and ctrl-c
        atexit.register(self.handlerExit)
        signal.signal(signal.SIGINT, self.handlerSignal)

    def CreatePopupMenu(self):
        """
        This method is called by the base class when it needs to popup
        the menu for the default EVT_RIGHT_DOWN event.  Just create
        the menu how you want it and return it from this function,
        the base class takes care of the rest.
        """
        menu = wx.Menu()
        menu.Append(self.TBMENU_STATUS, MENU_STATUS)
        menu.Append(self.TBMENU_ABOUT, MENU_ABOUT)
        menu.Append(wx.ID_SEPARATOR)
        menu.Append(self.TBMENU_CLOSE, MENU_EXIT)
        return menu

    def makeIcons(self):
        for key, value in APP_ICONS_DATA.items():
            for key, value in APP_ICONS_DATA.items():
                APP_ICONS[key] = value.Icon
                # deprecated
                #APP_ICONS[key] = self.makeIcon(value.getImage())

    # deprecated
    def makeIcon(self, img):
        """
        The various platforms have different requirements for the
        icon size...
        """
        if "wxMSW" in wx.PlatformInfo:
            img = img.Scale(16, 16)
        elif "wxGTK" in wx.PlatformInfo:
            img = img.Scale(22, 22)
        # wxMac can be any size upto 128x128, so leave the source img alone....
        icon = wx.Icon(img.ConvertToBitmap())
        return icon

    def onLeftClick(self, evt):
        self.updateTask()
        self.sendNotification()

    def cleanUp(self):
        # close shown notification, if any
        if self.current_notification != None:
            self.current_notification.Close()
            self.current_notification = None

        # stop the active timer if it is running
        if self.timer.IsRunning():
            self.timer.Stop()
        # close the main frame on main loop termination
        wx.CallAfter(self.frame.Close)
        # the following is too powerfull, better not use it to terminate
        #wx.GetApp().ExitMainLoop()

    def handlerExit(self):
        self.cleanUp()

    def handlerSignal(self, sig, frame):
        self.cleanUp()

    def onMenuQuit(self, evt):
        self.cleanUp()

    def onMenuStatus(self, evt):
        self.updateTask()
        self.sendNotification()

    def sendNotification(self):
        if self.task == SYNC:
            title = MSG_SYNC_TITLE
            txt = MSG_SYNC_TEXT
            icon = MSG_SYNC_ICON
            urgency = MSG_SYNC_URGENCY
        else:
            title = MSG_SYNCED_TITLE
            txt = MSG_SYNCED_TEXT
            icon = MSG_SYNCED_ICON
            urgency = MSG_SYNCED_URGENCY
        # close the current notification, if any
        if self.current_notification != None:
            self.current_notification.Close()
            self.current_notification = None

        n = NotificationMessage()
        n.SetTitle(title)
        n.SetMessage(txt)
        n.SetFlags(icon)
        n.Show(NOTIFY_TIME)
        self.current_notification = n

    def onMenuAbout(self, evt):
        aboutInfo = wx.adv.AboutDialogInfo()
        aboutInfo.SetIcon(APP_ICONS[self.task])
        aboutInfo.SetName(APP_NAME)
        aboutInfo.SetVersion(APP_VERSION)
        aboutInfo.SetDescription(APP_DESCR)
        aboutInfo.AddDeveloper(APP_AUTHORS)
        aboutInfo.SetLicence(APP_LICENSE)
        wx.adv.GenericAboutBox(aboutInfo)


    def updateIcon(self, icon):
        self.icon = icon
        self.SetIcon(icon, APP_NAME + ' - ' + self.task)

    def updateTask(self):
        exists = os.path.isfile(FILE_TO_CHECK)
        if exists:
            task = SYNCED
            self.updateIcon(APP_ICONS[SYNCED])
        else:
            task = SYNC
            self.updateIcon(APP_ICONS[SYNC])
        if self.task != task:
            self.task_changed = True
        else:
            self.task_changed = False
        self.task = task

    def onTimeout(self):
        """This will be called every few seconds by the GLib.timeout.
        """
        self.updateTask()
        if self.task_changed:
            self.sendNotification()
        # return True so that we get called again
        # returning False will make the timeout stop
        return True

    def onTimer(self, evt):
        self.updateTask()
        if self.task_changed:
            self.sendNotification()

class MainFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, title="Labsync Tray WX")
        self.tbicon = TrayApp(self)
        self.Bind(wx.EVT_CLOSE, self.onCloseWindow)

    def onCloseWindow(self, evt):
        self.tbicon.Destroy()
        evt.Skip()

if __name__ == "__main__":
    # parse command line arguments
    parser = argparse.ArgumentParser(description=APP_NAME + ' ' + APP_VERSION)
    parser.add_argument('-p', '--period', type=int,
        help='checking period (milliseconds between checkings)')
    args = parser.parse_args()
    if args.period:
        CHECK_PERIOD = args.period
        print ('Checking period: ' + str(CHECK_PERIOD) + " ms")

    app = wx.App(redirect=False)
    frame = MainFrame(None)
    # not interested in main window to show up, just start the tray icon
    #frame.Show(True)
    app.MainLoop()