# -*- coding: utf-8 -*-
# Moovida - Home multimedia server
# Copyright (C) 2006-2009 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 Moovida with Fluendo's plugins.
#
# The GPL part of Moovida is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Moovida" in the root directory of this distribution package
# for details on that license.

from elisa.core import common
from elisa.core.media_uri import MediaUri
from elisa.core.utils.i18n import install_translation

from elisa.plugins.poblesec.base.hierarchy import HierarchyController
from elisa.plugins.poblesec.base.list import GenericListViewMode
from elisa.plugins.poblesec.base.preview_list import \
    MenuItemPreviewListController
from elisa.plugins.poblesec.link import Link, DeviceLink, OpenLinkAction

from elisa.plugins.base.messages.device import NewDeviceDetected, \
                                               NewUnknownDevice, \
                                               DeviceRemoved
from elisa.plugins.base.models.device import VolumeModel
from elisa.plugins.poblesec.sections_menu import SectionsMenuController, \
                                                 main_menu_decorate

from twisted.internet import defer

_ = install_translation('poblesec')


def devices_and_shares_decorator(controller):
    controller_path = "/poblesec/devices_and_shares_menu"
    label = _("Devices & Shares")
    icon = "elisa.plugins.poblesec.devices_section"
    dfr = main_menu_decorate(controller, controller_path, label, icon)
    return dfr

def devices_decorator(controller):
    link = Link()
    link.controller_path = "/poblesec/devices"
    link.label = _("Attached Devices")
    controller.model.append(link)
    return defer.succeed(None)

def filesystem_decorator(controller):
    link = Link()
    link.controller_path = "/poblesec/this_computer"
    link.label = _("This Computer")
    controller.model.append(link)
    return defer.succeed(None)

def network_decorator(controller):
    link = Link()
    link.controller_path = "/poblesec/network/shares"
    link.label = _("Other Computers")
    controller.model.append(link)
    return defer.succeed(None)

def media_decorator(controller):
    link = Link()
    link.controller_path = "/poblesec/media_sources"
    link.label = _("Permanent Sources")
    controller.model.append(link)
    return defer.succeed(None)


class SectionMenuViewMode(GenericListViewMode):

    def get_label(self, item):
        return defer.succeed(item.label)

    def get_default_image(self, item):
        return item.icon

    def get_image(self, item, theme):
        return None

    def get_preview_image(self, item, theme):
        return None


class SectionMenuController(MenuItemPreviewListController):
    view_mode = SectionMenuViewMode

    def create_actions(self):
        return OpenLinkAction(self), []


# We implement this as a decorator to be able to ensure removable devices
# appear at the end.
def hardware_decorator(controller):
    uri = MediaUri("volumes://?filter=removable")
    model, dfr = common.application.resource_manager.get(uri, None)

    def do_list_hardware(model):
        devices = sorted(model.devices, key=lambda i: i.name.lower())

        for dev in devices:
            if dev.protocol == 'file' and dev.mount_point != None:
               controller._add_link_from_device_model(dev) 

    dfr.addCallback(do_list_hardware)

    return dfr

class HardwareListControllerMixin(SectionMenuController):
    # translate the type of the section into a "media type"
    # (types defined in elisa.plugins.base.models.file.FileModel)
    translation = {'music': 'audio',
                   'video': 'video',
                   'pictures': 'image'}

    def initialize(self):
        dfr = super(HardwareListControllerMixin, self).initialize()
        bus = common.application.bus
        bus.register(self._device_add_cb, NewDeviceDetected)
        bus.register(self._device_remove_cb, DeviceRemoved)
        return dfr

    def _device_add_cb(self, msg, sender):
        if msg.model.protocol == 'file' and msg.model.mount_point != None:
            self._add_link_from_device_model(msg.model)

    def _device_remove_cb(self, msg, sender):
        for link in self.model:
            if isinstance(link, DeviceLink) and link.udi == msg.udi:
                self.model.remove(link)
                return

    def _add_link_from_device_model(self, model):
        link = DeviceLink(model.udi)
        path = ''
        if isinstance(model, VolumeModel):
            path = model.mount_point
        else:
            path = model.device

        uri = MediaUri({'scheme': model.protocol,
                        'host': '',
                        'path': path})

        link.controller_path = '/poblesec/directory_settings'
        try:
            file_media_type = self.translation[self.media_type]
        except AttributeError:
            link.controller_args = {'uri': uri}
        else:
            link.controller_args = {'uri': uri, 'media_type': file_media_type}

        link.icon = "elisa.plugins.poblesec.glyphs.small.devices_shares"
        link.label = model.name
        
        self.model.append(link)

    def clean(self):
        dfr = super(HardwareListControllerMixin, self).clean()
        bus = common.application.bus
        bus.unregister(self._device_add_cb)
        bus.unregister(self._device_remove_cb)
        return dfr
