#!/usr/bin/env python3
# Copyright (c) 2007-8, Playful Invention Company
# Copyright (c) 2008-14, Walter Bender
# Copyright (c) 2011 Collabora Ltd. <http://www.collabora.co.uk/>

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import cairo
import getopt
import sys
import os
import os.path
import io
import errno
import configparser
import tarfile
import tempfile
import subprocess

import gi

gi.require_version("Gtk", "3.0")

from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GLib
from gi.repository import GdkPixbuf
from gi.repository import Gio

try:
    # Try to use XDG Base Directory standard for config files.
    import xdg.BaseDirectory

    CONFIG_HOME = os.path.join(xdg.BaseDirectory.xdg_config_home, "turtleart")
except ImportError:
    # Default to `.config` per the spec.
    CONFIG_HOME = os.path.expanduser(os.path.join("~", ".config", "turtleart"))

argv = sys.argv[:]  # Workaround for import behavior of gst in tagplay
sys.argv[1:] = []  # Execution of import gst cannot see '--help' or '-h'

import gettext
from gettext import gettext as _

from TurtleArt.taconstants import (
    OVERLAY_LAYER,
    DEFAULT_TURTLE_COLORS,
    TAB_LAYER,
    SUFFIX,
    TMP_SVG_PATH,
    TMP_ODP_PATH,
    PASTE_OFFSET,
)
from TurtleArt.tautils import (
    data_from_string,
    get_load_name,
    get_path,
    get_save_name,
    is_writeable,
)
from TurtleArt.tapalette import default_values
from TurtleArt.tawindow import TurtleArtWindow
from TurtleArt.taexportlogo import save_logo
from TurtleArt.taexportpython import save_python
from TurtleArt.taprimitive import PyExportError
from TurtleArt.taplugin import (
    load_a_plugin,
    cancel_plugin_install,
    complete_plugin_install,
)

from TurtleArt.util.menubuilder import (
    make_menu_item,
    make_sub_menu,
    make_checkmenu_item,
)


class TurtleMain:

    """ Launch Turtle Art in GNOME (from outside of Sugar). """

    _INSTALL_PATH = "/usr/share/sugar/activities/TurtleArt.activity"
    _ALTERNATIVE_INSTALL_PATH = "/usr/local/share/sugar/activities/TurtleArt.activity"
    _ICON_SUBPATH = "images/turtle.png"
    _GNOME_PLUGIN_SUBPATH = "gnome_plugins"
    _GIO_SETTINGS = "org.laptop.TurtleArtActivity"
    _HOVER_HELP = "hover-help"
    _ORIENTATION = "palette-orientation"
    _COORDINATE_SCALE = "coordinate-scale"
    _PLUGINS_LIST = "plugins"

    def __init__(self, lib_path, share_path):
        self._gio_settings_overrides = False

        self._lib_path = lib_path
        self._share_path = share_path
        self._abspath = os.path.abspath(".")

        file_activity_info = configparser.ConfigParser()
        activity_info_path = os.path.join(share_path, "activity/activity.info")
        file_activity_info.read(activity_info_path)
        bundle_id = file_activity_info.get("Activity", "bundle_id")
        self.version = file_activity_info.get("Activity", "activity_version")
        self.name = file_activity_info.get("Activity", "name")
        self.summary = file_activity_info.get("Activity", "summary")
        self.website = file_activity_info.get("Activity", "url")
        self.icon_name = file_activity_info.get("Activity", "icon")

        path = os.path.join(share_path, "locale")
        if os.path.isdir(path):
            gettext.bindtextdomain(bundle_id, path)
        gettext.textdomain(bundle_id)
        global _
        _ = gettext.gettext
        self._HELP_MSG = (
            "turtleblocks.py: "
            + _("usage is")
            + """
 \tturtleblocks.py
 \tturtleblocks.py project.tb
 \tturtleblocks.py --output_png project.tb
 \tturtleblocks.py -o project
 \tturtleblocks.py --run project.tb
 \tturtleblocks.py -r project"""
        )
        self._init_vars()
        self._parse_command_line()
        self._ensure_sugar_paths()
        self._gnome_plugins = []
        self._selected_sample = None
        self._sample_window = None

        if self._output_png:
            # Outputing to file, so no need for a canvas
            self.canvas = None
            self._get_gconf_settings()
            self._build_window(interactive=False)
            self._draw_and_quit()
        else:
            self._read_initial_pos()
            self._init_gnome_plugins()
            self._get_gio_settings()
            self._setup_gtk()
            self._build_window()
            self._run_gnome_plugins()
            self._start_gtk()

    def _get_local_settings(self, activity_root):
        """return an activity-specific Gio.Settings"""
        # create compiled schema file if missing from activity root
        compiled = os.path.join(activity_root, "gschemas.compiled")
        if not os.access(compiled, os.R_OK):
            # create schemas directory if missing
            path = os.path.join(get_path(None, "data"), "schemas")
            if not os.access(path, os.F_OK):
                os.makedirs(path)

            # create compiled schema file if missing
            compiled = os.path.join(path, "gschemas.compiled")
            if not os.access(compiled, os.R_OK):
                src = "%s.gschema.xml" % self._GIO_SETTINGS
                lines = open(os.path.join(activity_root, src), "r").readlines()
                open(os.path.join(path, src), "w").writelines(lines)
                os.system("glib-compile-schemas %s" % path)
                os.remove(os.path.join(path, src))

            schemas_path = path
        else:
            schemas_path = activity_root

        # create a local Gio.Settings based on the compiled schema
        source = Gio.SettingsSchemaSource.new_from_directory(schemas_path, None, True)
        schema = source.lookup(self._GIO_SETTINGS, True)
        _settings = Gio.Settings.new_full(schema, None, None)
        return _settings

    def _get_gio_settings(self):
        self._settings = self._get_local_settings(self._share_path)

    def get_config_home(self):
        return CONFIG_HOME

    def _get_gnome_plugin_home(self):
        """ Use plugin directory associated with execution path. """
        if os.path.exists(os.path.join(self._lib_path, self._GNOME_PLUGIN_SUBPATH)):
            return os.path.join(self._lib_path, self._GNOME_PLUGIN_SUBPATH)
        else:
            return None

    def _get_plugin_candidates(self, path):
        """ Look for plugin files in plugin directory. """