# -*- coding: utf-8 -*-
# Elisa - Home multimedia server
# Copyright (C) 2006,2007 Fluendo Embedded S.L. (www.fluendo.com).
# All rights reserved.
#
# This file is available under one of two license agreements.
#
# This file is licensed under the GPL version 3.
# See "LICENSE.GPL" in the root of this distribution including a special
# exception to use Elisa with Fluendo's plugins.
#
# The GPL part of Elisa is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Elisa" in the root directory of this distribution package
# for details on that license.

__maintainer__ = 'Benjamin Kampmann <benjamin@fluendo.com>'

"""
THe OSD-View for a video and audio player
"""

from elisa.core import common, player

from pgm.graph.image import Image
from pgm.graph.group import Group
from pgm.graph.text import Text
import pgm, gst, math

from twisted.internet import reactor

from elisa.plugins.pigment_osd.playback_osd import PlaybackOSD
from elisa.plugins.pigment_osd.progressbar_osd import ProgressBarOsd

from elisa.extern.translation import gettexter, N_, Translatable
T_ = gettexter('elisa-player')

class PlayerOSD(PlaybackOSD):
 
    supported_controllers = ('player:player_controller',)

    bindings = (("playing", "playing"),
                ("state", "state"),
                ("focused", "focused"),
                ("volume", "volume"))

    _position_updater = None
    _background = None

    def create_widgets(self):
        super(PlayerOSD, self).create_widgets()
        self.create_volume_widget()

        self.volume_bar.connect('position-click',
                                    self._got_volume_click)
        self.status_bar.progressbar.connect('position-click',
                                            self._got_position_click)


    def show(self, value=-1):
        if not self.controller.focused:
            return
        self._update_time_value(True)
        # start the looping until it gets hidden here
        super(PlayerOSD, self).show(value)

    def hide(self):
        if self._position_updater != None and self._position_updater.active():
            # don't do time-updates, when the osd is not shown
            self._position_updater.cancel()
        super(PlayerOSD, self).hide()

    def volume__set(self, volume):
        if not volume:
            volume = 1.
        self.volume_bar.cursor_position = volume
        self.show(self.osd_duration)

    def state__set(self, value):
        if value is player.STATES.LOADING:
            # FIXME: Album-Artist and other things would be cool to display!
            model = self.controller.current_model

            # FIXME: can be a translatable!
            self.status_bar.title.label = unicode(model.uri.label)

        elif value is player.STATES.PLAYING:
            # update the duration
            self.show(self.osd_duration)
        elif value is player.STATES.STOPPED:
            if self._background:
                self._background.clear()
            self.hide()
        return True

    def create_volume_widget(self):
        reference_size = self.size
        x_offset = reference_size[1] * 0.025

        self.volume_group = Group()

        height = reference_size[1] * 0.055

        self.volume_button = Image()
        self.volume_group.add(self.volume_button)
        self.volume_button.bg_color = (0, 0, 0, 0)
        self.volume_button.size = (height, height)
        self.volume_button.visible = True

        self.load_from_theme("volume_button", self.volume_button)

        self.volume_background = Image()
        self.volume_group.add(self.volume_background)

        self.volume_background.bg_color = (0, 0, 0, 0)
        self.volume_background.size = (reference_size[0] * 0.18,
                                       height)
        self.volume_background.x = height
        self.volume_background.layout = pgm.IMAGE_FILLED

        self.load_from_theme("dock_background_mouse",
                             self.volume_background)
        self.volume_background.visible = True

        self.volume_bar = ProgressBarOsd()
        self.volume_group.add(self.volume_bar)

        self.volume_bar.length = 2.0

        bar_height = reference_size[1] * 0.02

        self.volume_bar.position = (height + x_offset,
                                    self.volume_background.height / 2 - \
                                    bar_height / 2, 0)
        self.volume_bar.size = ( self.volume_background.width - x_offset * 2,
                                 bar_height)
        self.volume_bar.bg_color = (0, 0, 0, 0)
        self.volume_bar.fg_color = (205, 205, 205, 225)
        self.volume_bar.visible = True
        
        self.load_from_theme("dock_bar_fg",
                             self.volume_bar.foreground)
        self.load_from_theme("dock_bar_bg",
                             self.volume_bar.background)

        self.volume_group.position = (reference_size[0] * 0.025,
                                      reference_size[1] * 0.02, 0)
        self.add(self.volume_group)
        self.volume_group.visible = True

    def _update_time_value(self, first_shown=False):
        if self._position_updater != None and self._position_updater.active():
            self._position_updater.cancel()

        new_time = self.controller.position
        duration = self.controller.duration

        self.debug("Position upadte : %s" % new_time)

        if duration > 0:
            self.status_bar.progressbar.length = duration
            if first_shown:
                #direct jump
                self.status_bar.progressbar.jump_to_position(new_time)
            else:
                # smother going forward
                self.status_bar.progressbar.cursor_position = new_time
            self.status_bar.status_text.label  = "%s / %s" % \
                                    (self.human_time(new_time),
                                     self.human_time(duration))
            self.status_bar.progressbar.visible = True
        elif new_time < 0:
            self.status_bar.progressbar.visible = False
            self.status_bar.status_text.label = ""
        else:
            self.status_bar.progressbar.visible = False
            self.status_bar.status_text.label = "%s" % \
                                    self.human_time(new_time)

        # update four times a second is more than enough
        self._position_updater = reactor.callLater(0.25, self._update_time_value)

    def _got_volume_scrolled(self, img, x, y, z, direction, time):
        if direction == pgm.SCROLL_UP:
            self.controller.volume += 0.1
        else:
            self.controller.volume -= 0.1

    def _got_motion_begin(self, img, x, y, z, button, l):
        self._motion_begin_x = x

    def _got_motion_end(self, img, x, y, z, button, l):
        value = x - self._motion_begin_x
        new_val = self.controller.volume + value
        self.controller.volume = max(0, new_val)

    def _got_position_click(self, obj, value):
        self.controller.position = value

    def _got_volume_click(self, obj, value):
        self.volume_bar.jump_to_position(value)
        self.controller.volume = value

    def element_attribute_set(self, position, key, old_value, new_value):
        # we need to have it?
        pass

    # TODO: move this to utils?
    def human_time(self, milisecs):
        secs = milisecs / 1000000000
        mins, secs = divmod(secs, 60)
        hours, mins = divmod(mins, 60)
        days, hours = divmod(hours, 24)
        weeks, days = divmod(days, 7)

        return_value = ""
        if weeks:
                return_value +="%s " % weeks
        if days:
                return_value += "%s " % days
        if hours:
                return_value += "%02d:" % hours
        return '%s%02d:%02d' % (return_value, mins, secs)
