#
# Advene: Annotate Digital Videos, Exchange on the NEt
# Copyright (C) 2008-2017 Olivier Aubert <contact@olivieraubert.net>
#
# Advene 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 2 of the License, or
# (at your option) any later version.
#
# Advene 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 Advene; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
"""Popup menu for Advene elements.

Generic popup menu used by the various Advene views.
"""

from gi.repository import Gtk
import re
import os

from gettext import gettext as _

import advene.core.config as config

from advene.model.package import Package
from advene.model.annotation import Annotation, Relation
from advene.model.schema import Schema, AnnotationType, RelationType
from advene.model.resources import Resources, ResourceData
from advene.model.view import View
from advene.model.query import Query

from advene.rules.elements import RuleSet, Rule, Event, Condition, Action

from advene.gui.util import image_from_position, dialog, get_clipboard
import advene.util.helper as helper
import advene.util.importer

class Menu:
    def __init__(self, element=None, controller=None, readonly=False):
        self.element=element
        self.controller=controller
        self.readonly=readonly
        self.menu=self.make_base_menu(element)

    def popup(self):
        self.menu.popup_at_pointer(None)
        return True

    def get_title (self, element):
        """Return the element title."""
        return self.controller.get_title(element, max_size=40)

    def goto_annotation (self, widget, ann):
        c = self.controller
        c.update_status(status="seek", position=ann.fragment.begin)
        c.gui.set_current_annotation(ann)
        return True

    def duplicate_annotation(self, wid
get, ann):
        self.controller.duplicate_ann
otation(ann)
        return True

    def activate_annotation (self, widget, ann):
        self.controller.notify("AnnotationActivate", annotation=ann)
        return True

    def desactivate_annotation (self, widget, ann):
        self.controller.notify("AnnotationDeactivate", annotation=ann)
        return True

    def activate_stbv (self, widget, view):
        self.controller.activate_stbv(view)
        return True

    def open_adhoc_view (self, widget, view):
        self.controller.gui.open_adhoc_view(view)
        return True

    def create_element(self, widget, elementtype=None, parent=None):
        if elementtype == 'staticview':
            elementtype=View
            mimetype='text/html'
        elif elementtype == 'dynamicview':
            elementtype=View
            mimetype='application/x-advene-ruleset'
        else:
            mimetype=None
        cr = self.controller.gui.create_element_popup(type_=elementtype,
                                                      parent=parent,
                                                      controller=self.controller,
                                                      mimetype=mimetype)
        cr.popup()
        return True

    def do_insert_resource_file(self, parent=None, filename=None, id_=None):
        if id_ is None:
            # Generate the id_
            basename = os.path.basename(filename)
            id_=re.sub('[^a-zA-Z0-9_.]', '_', basename)
        size=os.stat(filename).st_size
        f=open(filename, 'rb')
        parent[id_]=f.read(size + 2)
        f.close()
        el=parent[id_]
        self.controller.notify('ResourceCreate',
                               resource=el)
        return el

    def do_insert_resource_dir(self, parent=None, dirname=None, id_=None):
        if id_ is None:
            # Generate the id_
            basename = os.path.basename(dirname)
            id_=re.sub('[^a-zA-Z0-9_.]', '_', basename)
        parent[id_] = parent.DIRECTORY_TYPE
        el=parent[id_]
        self.controller.notify('ResourceCreate',
                               resource=el)
        for n in os.listdir(dirname):
            filename = os.path.join(dirname, n)
            if os.path.isdir(filename):
                self.do_insert_resource_dir(parent=el, dirname=filename)
            else:
                self.do_insert_resource_file(parent=el, filename=filename)
        return el

    def insert_resource_data(self, widget, parent=None, title=None, filter=None):
        if title is None:
            title = _("Choose the file to insert")
        filename=dialog.get_filename(title=title, filter=filter)
        if filename is None:
            return True
        basename = os.path.basename(filename)
        id_=re.sub('[^a-zA-Z0-9_.]', '_', basename)
        if id_ != basename:
            while True:
                id_ = dialog.entry_dialog(title=_("Select a valid identifier"),
                                          text=_("The filename %s contains invalid characters\nthat have been replaced.\nYou can modify this identifier if necessary:") % filename,
                                          default=id_)
                if id_ is None:
                    # Edition cancelled
                    return True
                elif re.match('^[a-zA-Z0-9_.]+$', id_):
                    break
        self.do_insert_resource_file(parent=parent, filename=filename, id_=id_)
        return True

    def insert_soundclip(self, widget, parent=None):
        self.insert_resource_data(widget, parent, title=_("Choose the soundclip to insert"), filter='audio')
        return True

    def insert_resource_directory(self, widget, parent=None):
        dirname=dialog.get_dirname(title=_("Choose the directory to insert"))
        if dirname is None:
            return True

        self.do_insert_resource_dir(parent=parent, dirname=dirname)
        return True

    def edit_element (self, widget, el):
        self.controller.gui.edit_element(el)
        return True

    def filter_service(self, widget, importer, annotationtype):
        self.controller.gui.open_adhoc_view('importerview', message=_("Apply %s") % importer.name, display_unlikely=False, importerclass=importer, source_type=annotationtype)

    def popup_get_offset(self):
        offset=dialog.entry_dialog(title='Enter an offset',
                                   text=_("Give the offset to use\non specified element.\nIt is in ms and can be\neither positive or negative."),
                                   default="0")
        if offset is not None:
            return int(offset)
        else:
            return offset

    def offset_element (self, widget, el):
        offset = self.popup_get_offset()
        if offset is not None:
            self.controller.offset_element(el, offset)
        return True

    def search_replace_content(self, widget, el):
        if isinstance(el, (Annotation, View)):
            l = [ el ]
            title = _("Replace content in %s" % self.controller.get_title(el))
        elif isinstance(el, AnnotationType):
            l = el.annotations
            title = _("Replace content in annotations of type %s" % self.controller.get_title(el))
        elif isinstance(el, Package):
            l = el.annotations
            title = _("Replace content in all annotations")
        self.controller.gui.search_replace_dialog(l, title=title)
        return True

    def copy_id (self, widget, el):
        clip = get_clipboard()
        clip.set_text(el.id, -1)
        return True

    def browse_element (self, widget, el):
        self.controller.gui.open_adhoc_view('browser', element=el)
        return True

    def query_element (self, widget, el):
        self.controller.gui.open_adhoc_view('interactivequery', here=el, sources= [ "here" ])
        return True

    def delete_element (self, widget, el):
        self.controll