#!/usr/bin/python

#    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 <http://www.gnu.org/licenses/>.

import os
import datetime
import gobject
import screenlets
import subprocess
# use gettext for translation
import gettext

_ = screenlets.utils.get_translator(__file__)

def tdoc(obj):
	obj.__doc__ = _(obj.__doc__)
	return obj

@tdoc
class LostCountdownScreenlet(screenlets.Screenlet):
    """Lost - The Swan - Countdown"""
    
    __name__ = "Lost - The Swan - Countdown"
    __version__ = "0.8.8"
    __author__ = "Keidon"
    __desc__ = __doc__

    mode = _("Original")    
    nums = ["0", "0", "0", "0", "0"]
    ##############
    mins = 108
    entry = []
    cursor = True
    showprompt = False
    promptcolor = (0.4, 1, 0.4, 1)
    promptbackcolor = (0, 0, 0, 1)
    sounds = True
    soundspath = os.environ.get("HOME") + "/.screenlets/LostCountdown/sounds/"
    showseconds = False
    ##############
    days = 0
    showhours = True

    def __init__(self, ** keyword_args):
        screenlets.Screenlet.__init__(self, width=320, height=180, ** keyword_args)

        self.theme_name = "default"

        self.add_options_group(_("Countdown's Mode"),
                               """Original: The countdown counts as the original countdown of The Swan.
        \nDate Mode: The countdown counts the days remaining to a date.\n\n""")

        self.add_options_group(_("Original Mode"),
                               _("The countdown counts as the original countdown of The Swan."))

        self.add_options_group(_("Date Mode"), _("The countdown counts the days remaining to this date."))

        self.add_option(screenlets.StringOption(_("Countdown's Mode"), "mode",
                        self.mode, _("Countdown's Mode"), _("Countdown's Mode"),
                        choices=[_("Original"), _("Date Mode")]))

        self.add_option(screenlets.ColorOption(_("Original Mode"), "promptcolor",
                        (0.4, 1, 0.4, 1), _("Prompt color"), _("Prompt color")))

        self.add_option(screenlets.ColorOption(_("Original Mode"), "promptbackcolor",
                        (0, 0, 0, 1), _("Prompt background color"), _("Prompt background color")))

        self.add_option(screenlets.IntOption(_("Original Mode"), "imins", 108,
                        _("Initial minutes"), _("Initial Minutes"), min=0, max=999))

        self.add_option(screenlets.IntOption(_("Original Mode"), "isegs", 0,
                        _("Initial seconds"), _("Initial Seconds"), min=0, max=59))

        self.add_option(screenlets.BoolOption(_("Original Mode"), "showprompt", False,
                        _("Show always the prompt"),
                        _("Show always the prompt. If this is false, the prompt only is showed when minutes < 4")))

        self.add_option(screenlets.BoolOption(_("Original Mode"), "sounds", True,
                        _("Activate Sounds"), _("Activate sounds(MPlayer is needed)")))

        self.add_option(screenlets.BoolOption(_("Original Mode"), "showseconds", False,
                        _("Show always the seconds"), _("Show always the seconds. If it's false,the seconds only shows when there are less than 4 minutes")))

        ###            23/05/2010   LOST FINAL EPISODE !!!!!!!!!!!
        self.add_option(screenlets.IntOption(_("Date Mode"), "day", 23, _("Day"),
                        _("Day"), min=1, max=31))
        self.add_option(screenlets.IntOption(_("Date Mode"), "month", 5, _("Month"),
                        _("Month"), min=1, max=12))
        self.add_option(screenlets.IntOption(_("Date Mode"), "year", 2010, _("Year"),
                        _("Year"), min=int(str(datetime.date.today()).split("-")[0]),
                        max=int(str(datetime.date.today()).split("-")[0]) + 2))

        self.add_option(screenlets.BoolOption(_("Date Mode"), "showhours", True, _("Show always the hours"),
                        _("Show always the hours. If it's false the hours only shows when there are less than 1 day")))

        gobject.timeout_add(1000, self.numbers)
        gobject.timeout_add(970, self.updatecursor)
        gobject.timeout_add(2000, self.alarmsound)


    def on_init(self):
        self.add_default_menuitems()
        self.mins = self.imins
        self.segs = self.isegs

    def alarmsound(self):
        if self.mode == _("Original"):
            if self.sounds:
                if 0 < self.mins < 4:
                    subprocess.Popen(["mplayer" , "%sbeep.ogg" % self.soundspath])
                elif self.mins == 0 and self.segs > 10:
                    subprocess.Popen(["mplayer" , "%salarm.ogg" % self.soundspath])
        return True

    def updatecursor(self):
        if self.mode == _("Original"):
            self.redraw_canvas()
        return True

    def numbers(self):
        if self.mode == _("Original"):
            if self.mins < 0:
                self.nums = ["DEAD"]
            else:
                segsz = str(self.segs)
                minsz = str(self.mins)

                if len(minsz) == 2:
                    minsz = "0%s" % minsz
                elif len(minsz) == 1:
                    minsz = "00%s" % minsz
                if len(segsz) == 1:
                    segsz = "0%s" % segsz

                self.nums = list(minsz) + list(segsz)

                if self.mins == 0 and self.segs <= 10 and self.sounds:
                    subprocess.Popen(["mplayer" , "%salarm.ogg" % self.soundspath])
                if self.mins == 0 and self.segs == 0 and self.sounds:
                    subprocess.Popen(["mplayer" , "%stime_out.ogg" % self.soundspath])

            self.segs = self.segs -1
            if self.segs < 0:
                self.segs = 59
                self.mins = self.mins -1

        else:

            try:
                datenow = datetime.datetime(self.year, self.month, self.day) - datetime.datetime.now()
            except ValueError:
                if self.month == 2:
                    try:
                        self.day = 29
                        datetime.datetime(self.year, self.month, self.day)
                    except ValueError:
                        self.day = 28
                else:
                    self.day = self.day - 1

            datenow = datetime.datetime(self.year, self.month, self.day) - datetime.datetime.now()

            self.days = str(datenow.days)
            self.hours = str(datenow.seconds / 3600 + 1)

            if datetime.datetime.now() > datetime.datetime(self.year, self.month, self.day):
                self.nums = ["DEAD"]
            else:
                if len(self.days) == 2:
                    self.days = "0%s" % self.days
                elif len(self.days) == 1:
                    self.days = "00%s" % self.days
                if len(self.hours) == 1:
                    self.hours = "0%s" % self.hours

                self.nums = list(self.days) + list(self.hours)

        self.redraw_canvas()
        return True

    def print_dead(self, ctx, d):
        while True:
            ctx.set_source_surface(self.theme["d%i.png" % d], 0, 0)
            ctx.paint()
            ctx.set_source_rgba(0, 0, 0, 1)
            self.draw_text(ctx, "0", 256, 18, "FreeSans", 55, self.width)
            if d == 4: break
            self.draw_text(ctx, "0", 202, 18, "FreeSans", 55, self.width)
            if d == 3: break
            ctx.set_source_rgba(1, 1, 1, 1)
            self.draw_text(ctx, "0", 131, 18, "FreeSans", 55, self.width)
            if d == 2: break
            self.draw_text(ctx, "0", 77, 18, "FreeSans", 55, self.width)
            if d == 1: break
            self.draw_text(ctx, "0", 25, 18, "FreeSans", 55, self.width)
            break


    def on_draw(self, ctx):

        self.ctx = ctx
        ctx.scale(self.scale, self.scale)

        if self.theme:
            if self.nums[0] == "DEAD":
                ctx.set_source_surface(self.theme["dead.png"], 0, 0)
                ctx.paint()
                if self.mode == _("Original") and self.mins == -1:
                    if self.segs > 53:
                        self.print_dead(ctx, 0)
                    elif 52 < self.segs <= 53:
                        self.print_dead(ctx, 1)
                    elif 50 < self.segs <= 52:
                        self.print_dead(ctx, 2)
                    elif 48 < self.segs <= 50:
                        self.print_dead(ctx, 3)
                    elif 45 < self.segs <= 48:
                        self.print_dead(ctx, 4)
            else:
                ctx.set_source_surface(self.theme["d0.png"], 0, 0)
                ctx.paint()

                ctx.set_source_rgba(1, 1, 1, 1)
                self.draw_text(ctx, self.nums[0], 25, 18, "FreeSans", 55, self.width)
                self.draw_text(ctx, self.nums[1], 77, 18, "FreeSans", 55, self.width)
                self.draw_text(ctx, self.nums[2], 131, 18, "FreeSans", 55, self.width)

                ctx.set_source_rgba(0, 0, 0, 1)

                if (self.mode == _("Original") and (self.mins < 4 or self.showseconds)) \
                    or (self.mode == _("Date Mode") and (self.days < 1 or self.showhours)):

                    self.draw_text(ctx, self.nums[3], 202, 18, "FreeSans", 55, self.width)
                    self.draw_text(ctx, self.nums[4], 256, 18, "FreeSans", 55, self.width)
                else:
                    self.draw_text(ctx, "0", 202, 18, "FreeSans", 55, self.width)
                    self.draw_text(ctx, "0", 256, 18, "FreeSans", 55, self.width)


            if self.mode == _("Original") and (self.mins < 4 or self.showprompt):
                ctx.set_source_rgba(self.promptbackcolor[0], self.promptbackcolor[1],
                                    self.promptbackcolor[2], self.promptbackcolor[3])

                self.draw_rounded_rectangle(ctx, 0, 150, 6, 320, 30, fill=True)

                ctx.set_source_rgba(self.promptcolor[0], self.promptcolor[1],
                                    self.promptcolor[2], self.promptcolor[3])

                self.draw_text(ctx, ">", 15, 153, "Monospace", 15, self.width)
                self.draw_text(ctx, ":", 25, 152, "Monospace", 15, self.width)

                if self.cursor:
                    self.draw_text(ctx, "".join(self.entry) + "|", 37, 152, "Monospace", 15, self.width)
                    self.cursor = False
                else:
                    self.draw_text(ctx, "".join(self.entry), 37, 152, "Monospace", 15, self.width)
                    self.cursor = True


    def on_draw_shape(self, ctx):
        self.on_draw(ctx)

    def on_key_down(self, keycode, keyvalue, event):
        if self.mode == _("Original") and (self.mins < 4 or self.showprompt):
            ### delete pressed
            if  keycode == 65288:
                if len(self.entry) > 0:
                    self.entry.pop()
                    self.redraw_canvas()

            ### enter pressed
            elif keycode == 65293:
                if  self.entry == ["4", " ", "8", " ", "1", "5", " ", "1", "6", " ", "2", "3", " ", "4", "2"]:
                    if self.sounds:
                        subprocess.Popen("pkill" + " -f " + "'mplayer %stime_out.ogg'" % self.soundspath,shell=True)
                        subprocess.Popen(["mplayer" , "%sreset.ogg" % self.soundspath])
    
                    self.segs = self.isegs
                    self.mins = self.imins
                    self.entry = []
                    
                elif self.entry == ["H","e","l","l","o"]:
                    self.entry = ["D","a","d","?"]
                else:
                    self.entry = []

            ### alphanumeric character or space pressed
            elif keycode == 32 or 48 <= keycode <= 57 or 65 <= keycode <= 90 or \
                97 <= keycode <= 122 or 65456 <= keycode <= 65465:
                self.entry.append(keyvalue)
                self.redraw_canvas()


if __name__ == "__main__":
    import screenlets.session
    screenlets.session.create_session(LostCountdownScreenlet)
