# ============================================================
# LowerThird Notifications - Forked by Oli Passey from:
# KODI Banners - Version 1.9 by D. Lanik (2016)
# ------------------------------------------------------------
# Display banners when playing any video
# ------------------------------------------------------------
# License: GPL (http://www.gnu.org/licenses/gpl-3.0.html)
# ============================================================

import xbmc
import xbmcaddon
import xbmcgui
import os.path
from random import randint
from PIL import Image
from datetime import datetime as date
from threading import Timer
from xml.dom import minidom
from distutils.util import strtobool

# ============================================================
# Define Settings Monitor Class
# ============================================================


class SettingMonitor(xbmc.Monitor):
    def __init__(self, *args, **kwargs):
        xbmc.Monitor.__init__(self)

    def onSettingsChanged(self):
        GetSettings()

# ============================================================
# Define Overlay Class
# ============================================================


class OverlayBanner(object):
    def __init__(self, windowid):
        self.showing = False
        self.window = xbmcgui.Window(windowid)
        viewport_w, viewport_h = self._get_skin_resolution()

        pos = "20,20".split(",")
        pos_x = (viewport_w + int(pos[0]), int(pos[0]))[int(pos[0]) > 0]
        pos_y = (viewport_h + int(pos[1]), int(pos[1]))[int(pos[1]) > 0]
        self.imageTop = xbmcgui.ControlImage(pos_x, pos_y, 1240, 120, os.path.join("media", "banners", "generic_01.jpg"), aspectRatio=0)

        pos = "20,-140".split(",")
        pos_x = (viewport_w + int(pos[0]), int(pos[0]))[int(pos[0]) > 0]
        pos_y = (viewport_h + int(pos[1]), int(pos[1]))[int(pos[1]) > 0]
        self.imageBottom = xbmcgui.ControlImage(pos_x, pos_y, 1240, 120, os.path.join("media", "banners", "generic_01.jpg"), aspectRatio=0)

    def show(self):
        self.showing = True
        self.window.addControl(self.imageBottom)
        self.window.addControl(self.imageTop)

    def hide(self):
        self.showing = False
        self.window.removeControl(self.imageBottom)
        self.window.removeControl(self.imageTop)

    def scaleimage(self, width, height, yoffset):
        viewport_w, viewport_h = self._get_skin_resolution()

        if width > viewport_w:
            if yoffset > 0:
                width = viewport_w - (yoffset * 2)
                xpos = yoffset
            else:
                width = viewport_w
                xpos = 0
        else:
            xpos = (viewport_w - width) / 2

        self.imageBottom.setHeight(height)
        self.imageBottom.setWidth(width)
        self.imageBottom.setPosition(xpos, viewport_h - height - yoffset)

        self.imageTop.setHeight(height)
        self.imageTop.setWidth(width)
        self.imageTop.setPosition(xpos, yoffset)

    def _close(self):
        if self.showing:
            self.hide()
        else:
            pass

        try:
            self.window.clearProperties()
        except Exception:
            pass

# ============================================================
# Get resolution
# ============================================================

    def _get_skin_resolution(self):
        xmlFile = os.path.join(xbmc.translatePath("special://skin/"), "addon.xml")
        xmldoc = minidom.parse(xmlFile)

        res = xmldoc.getElementsByTagName("res")
        xval = int(res[0].attributes["width"].value)
        yval = int(res[0].attributes["height"].value)

        return(xval, yval)

# ============================================================
# Class for timer
# ============================================================


class RepeatedTimer(object):
    def __init__(self, interval, function, *args, **kwargs):
        self._timer = None
        self.interval = interval
        self.function = function
        self.args = args
        self.kwargs = kwargs
        self.is_running = False
        self.start()

    def _run(self):
        self.is_running = False
        self.start()
        self.function(*self.args, **self.kwargs)

    def start(self):
        if not self.is_running:
            self._timer = Timer(self.interval, self._run)
            self._timer.start()
            self.is_running = True

    def stop(self):
        self._timer.cancel()
        self.is_running = False

# ============================================================
# Class for KODI player
# ============================================================


class XBMCPlayer(xbmc.Player):
    global rt
    global booDisplayBanner

    def __init__(self, *args):
        pass

    def onPlayBackStarted(self):
        if booDisplayBanner:
            xbmc.log("BANNERS >> PLAYBACK >>PLAYING<<")
            OnPlay()

    def onPlayBackPaused(self):
        if booDisplayBanner:
            xbmc.log("BANNERS >> PLAYBACK >>PAUSED<<")
            OnStop()

    def onPlayBackResumed(self):
        if booDisplayBanner:
            xbmc.log("BANNERS >> PLAYBACK >>RESUMED<<")
            OnPlay()

    def onPlayBackEnded(self):
        if booDisplayBanner:
            xbmc.log("BANNERS >> PLAYBACK >>ENDED<<")
            OnStop()

    def onPlayBackStopped(self):
        if booDisplayBanner:
            xbmc.log("BANNERS >> PLAYBACK >>STOPPED<<")
            OnStop()


# ============================================================
# Player - play
# ============================================================


def OnPlay():
    global __addonwd__
    global rt
    global strBanners
    global intCounterBanner
    global booRandom
    global myWidget
    global booDisplayBanner
    global intYOffset

    condition = xbmc.getCondVisibility('Player.HasMedia')
    is_video = xbmc.getCondVisibility('Player.HasVideo')

    if condition and is_video and booDisplayBanner:
        if booRandom:
            intDisplayBanner = randint(0, intBanners - 1)
        else:
            intDisplayBanner = intCounterBanner

        rt.start()

        try:
            myWidget.show()

            image = Image.open(open(strBanners[intDisplayBanner], 'rb'))
            width, height = image.size
            myWidget.scaleimage(width, height, intYOffset)

            if intBannerpos == 0:
                myWidget.imageBottom.setImage("")
                myWidget.imageTop.setImage(strBanners[intDisplayBanner])
            else:
                myWidget.imageBottom.setImage(strBanners[intDisplayBanner])
                myWidget.imageTop.setImage("")

            xbmc.log("BANNERS >> BANNER RANDOM: [" + str(booRandom) + "] CHANGE TO " + str(intDisplayBanner) + " > " + strBanners[intDisplayBanner])
        except Exception:
            pass

# ============================================================
# Player - stop
# ============================================================


def OnStop():
    global rt
    global myWidget

    rt.stop()

    try:
        myWidget.hide()
    except Exception:
        pass

    xbmc.log("BANNERS >> BANNER OFF")

# ============================================================
# To be repeated every x seconds - shuffle banners
# ============================================================


def hw():
    global __addon__
    global __addonwd__
    global strBanners
    global intBanners
    global intCounterBanner
    global intCyclePause
    global booRandom
    global myWidget
    global intYOffset

    condition = xbmc.getCondVisibility('Player.HasMedia')
    is_video = xbmc.getCondVisibility('Player.HasVideo')
    ActWin = xbmcgui.getCurrentWindowId()

    if condition and is_video and ActWin == 12005:
        intCounterBanner += 1
        if intCounterBanner == intBanners:
            intCounterBanner = 0

        if booRandom:
            intDisplayBanner = randint(0, intBanners - 1)
        else:
            intDisplayBanner = intCounterBanner

        if intCounterBanner == 0 and intCyclePause > 0:     # 1st banner is being displayed - time for pause
            xbmc.log("BANNERS >> BANNER CYCLE PAUSE - WAITING " + str(intCyclePause) + " SECONDS")

            rt.stop()
            myWidget.hide()
            xbmc.sleep(intCyclePause * 1000)
            myWidget.show()
            rt.start()

        xbmc.log("BANNERS >> BANNER RANDOM: [" + str(booRandom) + "] CHANGE TO " + str(intDisplayBanner) + " > " + strBanners[intDisplayBanner])

        image = Image.open(open(strBanners[intDisplayBanner], 'rb'))
        width, height = image.size
        myWidget.scaleimage(width, height, intYOffset)

        if intBannerpos == 0:
            myWidget.imageBottom.setImage("")
            myWidget.imageTop.setImage(os.path.join(__addonwd__, "media", "banners", '%s' % strBanners[intDisplayBanner]))
        else:
            myWidget.imageBottom.setImage(os.path.join(__addonwd__, "media", "banners", '%s' % strBanners[intDisplayBanner]))
            myWidget.imageTop.setImage("")

# ============================================================
# Get extension
# ============================================================


def get_extension(filename):
    ext = os.path.splitext(filename)[1][1:].strip()
    return ext

# ============================================================
# Get settings
# ============================================================


def GetSettings():
    global __addon__
    global __addonwd__
    global __addonname__
    global rt
    global intChange
    global strBanners
    global intBanners
    global intBannerpos
    global myWidget
    global booDisplayBanner
    global intCyclePause
    global intYOffset
    global booRandom
    global intCounterBanner

    try:
        rt.stop()
        rt = None
    except Exception:
        pass

    rt = None
    __addon__ = xbmcaddon.Addon(id='service.lowerthird')

    strBanners = []
    intChange = int(__addon__.getSetting('changetime'))
    intBannerpos = int(__addon__.getSetting('bannerpos'))
    booDisplayBanner = bool(strtobool(str(__addon__.getSetting('on').title())))
    intCyclePause = int(__addon__.getSetting('cyclepause'))
    intYOffset = int(__addon__.getSetting('yoffset'))
    booRandom = bool(strtobool(str(__addon__.getSetting('random').title())))

    path = os.path.join(__addondir__, 'mybanners')      # check if own banners exist
    booOwnBanners = False                               # for the time being, they don't :)

    for root, subdirs, files in os.walk(path):
        for name in files:
            fileExt = get_extension(name)
            if any(fileExt.lower() in i for i in ("jpg", "jpeg", "png", "gif")):
                booOwnBanners = True                    # aha, found own banner
                break                                   # that's enough, break out of loop
        break

    today = date.today().strftime("%A")
    path = os.path.join(__addondir__, 'mybanners', today)      # check if own banners by day exist
    booDayBanners = False                                      # for the time being, they don't :)

    for root, subdirs, files in os.walk(path):
        for name in files:
            fileExt = get_extension(name)
            if any(fileExt.lower() in i for i in ("jpg", "jpeg", "png", "gif")):
                booDayBanners = True                    # aha, found own day banner
                break                                   # that's enough, break out of loop
        break

    if booDayBanners:
        path = os.path.join(__addondir__, 'mybanners', today)
    elif booOwnBanners:
        path = os.path.join(__addondir__, 'mybanners')
    else:
        path = os.path.join(__addonwd__, 'media', 'banners')

    for root, subdirs, files in os.walk(path):
        for name in files:
            fileExt = get_extension(name)
            if any(fileExt.lower() in i for i in ("jpg", "jpeg", "png", "gif")):
                strBanners.append(os.path.join(path, name))
        break

    intBanners = len(strBanners)
    intCounterBanner = 0

    xbmc.log("BANNERS >> SETTINGS >> BANNERS READ >> " + str(intBanners))
    xbmc.log("BANNERS >> SETTINGS >> BANNER POSITION >> " + str(intBannerpos))
    xbmc.log("BANNERS >> SETTINGS >> CHANGE EVERY SECONDS >> " + str(intChange))
    xbmc.log("BANNERS >> SETTINGS >> PAUSE BETWEEN CYCLES >> " + str(intCyclePause))
    xbmc.log("BANNERS >> SETTINGS >> X+Y OFFSET >> " + str(intYOffset))
    xbmc.log("BANNERS >> SETTINGS >> BANNER ON >> " + str(booDisplayBanner))
    xbmc.log("BANNERS >> SETTINGS >> RANDOM >> " + str(booRandom))

    rt = RepeatedTimer(intChange, hw)
    rt.stop()

    try:
        myWidget.imageBottom.setImage("")
        myWidget.imageTop.setImage("")
        myWidget.hide()
    except Exception:
        pass

    OnPlay()

# ============================================================
# ------------------------------------------------------------
# Main
# ------------------------------------------------------------
# ============================================================


__addon__ = xbmcaddon.Addon(id='service.lowerthird')
__addonname__ = __addon__.getAddonInfo('name')
__addonwd__ = xbmc.translatePath(__addon__.getAddonInfo('path').decode("utf-8"))
__addondir__ = xbmc.translatePath(__addon__.getAddonInfo('profile').decode('utf-8'))
__version__ = __addon__.getAddonInfo('version')

booOverlayInit = False
intChange = 5
strBanners = []
intBanners = 0
intCounterBanner = 0
intBannerpos = 0
booDisplayBanner = True
intCyclePause = 15
intYOffset = 15
booRandom = False

rt = None

if __name__ == '__main__':
    xbmc.log("BANNERS >> STARTED VERSION %s" % (__version__))

    folder = os.path.join(__addondir__, 'mybanners')
    if not os.path.exists(folder):
        os.makedirs(folder)

    GetSettings()

    player = XBMCPlayer()
    monitor = xbmc.Monitor()
    monsettings = SettingMonitor()

    while True:
        if monitor.waitForAbort(1):    # Sleep/wait for abort
            rt.stop()
            try:
                myWidget._close()
            except Exception:
                pass

            xbmc.log('BANNERS >> EXIT')
            break                      # Abort was requested while waiting. Exit the while loop.
        elif not booOverlayInit:
            ActWin = xbmcgui.getCurrentWindowId()
            if ActWin == 12005:
                try:
                    x = myWidget
                except NameError:
                    booOverlayInit = True
                    myWidget = OverlayBanner(12005)     # 12005: fullscreenvideo
                    OnPlay()
                    xbmc.log('BANNERS >> INITIALIZING OVERLAY')
                finally:
                    x = None

# ------------------------------------------------------------
# ------------------------------------------------------------
# ------------------------------------------------------------
# ------------------------------------------------------------
# ------------------------------------------------------------
# ------------------------------------------------------------
# ------------------------------------------------------------
# ------------------------------------------------------------
# ------------------------------------------------------------
# ------------------------------------------------------------
