#!/usr/bin/python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
### BEGIN LICENSE
# Copyright (C) 2012 Owais Lone <hello@owaislone.org>
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, 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/>.
### END LICENSE

import sys
sys.path.insert(0, '/opt/extras.ubuntu.com/fogger/')
from os import path as op

import locale
from locale import gettext as _
locale.bindtextdomain('fogger', '/opt/extras.ubuntu.com/fogger/share/locale')
locale.textdomain('fogger')

from gi.repository import GLib, GObject, Gio, Unity

from fogger_lib.utils import search_fogapps
from fogger_lib.helpers import get_media_file

BUS_NAME = "net.launchpad.lens.fogger"

CREATE_URI = GLib.filename_to_uri(
                        '/usr/share/applications/extras-fogger.desktop', None)
CAT_ICON = get_media_file('lens-cat.svg')
FOGGER_ICON = get_media_file('fogger.svg', '')
USER_APPS = op.join(GLib.get_user_data_dir(), 'applications')
SYSTEM_APPS = '/usr/share/applications'


class Daemon:
    search_string = ''

    def __init__ (self):
        # The path for the Lens *must* also match the one in our .lens file
        self._lens = Unity.Lens.new('/net/launchpad/lens/fogger', 'fogger')
        self._lens.props.search_hint = 'Search fog apps'
        self._lens.props.visible = True
        self._lens.props.search_in_global = False

        # create the scope
        self._scope = Unity.Scope.new('/net/launchpad/lens/fogger/main')
        self._scope.search_in_global = False
        self._scope.connect('search-changed', self.on_search_changed)
        self._scope.connect('activate-uri', self.on_activate_uri)
        self._scope.export()

        # Populate categories
        cats = []
        cats.append(Unity.Category.new('Fog Apps',
                        Gio.ThemedIcon.new(CAT_ICON),
                        Unity.CategoryRenderer.VERTICAL_TILE))
        self._lens.props.categories = cats

        # Populate filters
        self._lens.props.filters = []

        self._lens.add_local_scope(self._scope)
        self._lens.export()

    def _fogapp_changed(self, fmon, f1, f2, event):
        E = Gio.FileMonitorEvent
        if event in (E.CREATED,
                     E.CHANGED,
                     E.CHANGES_DONE_HINT,
                     E.DELETED):
            results = self._scope.props.results_model
            self.update_results_model(self.search_string, results)
            results.flush_revision_queue()

    def on_search_changed(self, scope, search, search_type, cancellable):
        self.search_string = \
            (search.props.search_string.lower() if search else None) or None
        results = self._scope.props.results_model
        self.update_results_model(self.search_string, results)
        results.flush_revision_queue()
        search.finished()

    def update_results_model(self, search, model):
        model.clear()
        apps = search_fogapps(search)
        for app in apps:
            model.append(GLib.filename_to_uri(app.props.filename, None),
                         app.get_icon().to_string(), 0,
                         'application/x-desktop', app.get_name(), '', '')

        model.append(CREATE_URI, FOGGER_ICON, 0, 'appplication/x-desktop',
                     _('Create a new fog app'), '', '')
        return

    def on_activate_uri (self, scope, uri):
        Gio.DesktopAppInfo.new_from_filename(
                GLib.filename_from_uri(uri, '')).launch([], None)
        return Unity.ActivationResponse(
                handled=Unity.HandledType.HIDE_DASH, goto_uri='')


if __name__ == "__main__":
    session_bus_connection = Gio.bus_get_sync(Gio.BusType.SESSION, None)
    session_bus = Gio.DBusProxy.new_sync(session_bus_connection, 0, None,
                                         'org.freedesktop.DBus',
                                         '/org/freedesktop/DBus',
                                         'org.freedesktop.DBus', None)
    result = session_bus.call_sync('RequestName',
                                   GLib.Variant("(su)", (BUS_NAME, 0x4)),
                                   0, -1, None)

    # Unpack variant response with signature "(u)". 1 means we got it.
    result = result.unpack()[0]

    if result != 1 :
        print >> sys.stderr, 'Failed to own name %s. Bailing out.' % BUS_NAME
        raise SystemExit (1)


    daemon = Daemon()

    f1 = Gio.File.new_for_path(USER_APPS)
    m1 = f1.monitor_directory(Gio.FileMonitorFlags.NONE, None)
    m1.connect('changed', daemon._fogapp_changed)

    f2 = Gio.File.new_for_path(SYSTEM_APPS)
    m2 = f2.monitor_directory(Gio.FileMonitorFlags.NONE, None)
    m2.connect('changed', daemon._fogapp_changed)

    GObject.MainLoop().run()
