# -*- coding: utf-8 -*-
#
# Copyright 2016 Continuum Analytics, Inc.
# May be copied and distributed freely only as part of an Anaconda or
# Miniconda installation.
#

"""
Home Tab.
"""

from __future__ import absolute_import, division, print_function

# Standard library imports
import sys

# Third party imports
from qtpy.QtCore import Qt, QTimer, Signal
from qtpy.QtGui import QPixmap
from qtpy.QtWidgets import QFrame, QHBoxLayout, QLabel, QVBoxLayout

# Local imports
from anaconda_navigator import images
from anaconda_navigator.api import AnacondaAPI
from anaconda_navigator.config import get_projects_path
from anaconda_navigator.utils.styles import load_style_sheet
from anaconda_navigator.widgets import ButtonBase, WidgetBase
from anaconda_navigator.widgets.apps import (ListItemApplication,
                                             ListWidgetApplication,
                                             ListItemEmpty)


# --- Custom widgets used with CSS styling
# -----------------------------------------------------------------------------
class ButtonHomeRefresh(ButtonBase):
    pass


class FrameHome(QFrame):
    pass


class FrameHomeTop(QFrame):
    pass


class FrameHomeBottom(QFrame):
    pass


class LabelHome(QLabel):
    pass


# --- Main widget
# -----------------------------------------------------------------------------
class HomeTab(WidgetBase):
    sig_pointer_updated = Signal(object, object)
    sig_status_updated = Signal(object, object, object, object)
    sig_application_updated = Signal(object, object)

    def __init__(self, parent=None):
        super(HomeTab, self).__init__(parent)

        # Variables
        self._parent = parent
        self.api = AnacondaAPI()
        self.setObjectName('Tab')

        # Widgetsugh
        main_icon = QLabel()
        self.list_applications = ListWidgetApplication()
        self.apps_model = None
        self.apps = None
        self.app_timers = None
        self.button_refresh = ButtonHomeRefresh('Refresh')
        self.frame_home = FrameHome(self)
        self.frame_home_top = FrameHomeTop(self)
        self.frame_home_bottom = FrameHomeTop(self)
        self.label_home = LabelHome('')
        self.label_status = QLabel('')

        # Widget setup
        pixmap = QPixmap(images.ANACONDA_ICON_128_PATH)
        main_icon.setPixmap(pixmap)
        main_text = ('My Applications')
        self.label_home.setText(main_text)
        self.list_applications.setVerticalScrollBarPolicy(
            Qt.ScrollBarAlwaysOn)

        # Layout
        home_layout_top = QHBoxLayout()
        home_layout_top.addWidget(self.label_home, 10, Qt.AlignLeft)
        home_layout_top.addWidget(self.button_refresh, 1,
                                  Qt.AlignRight | Qt.AlignBottom)
        home_layout_top.setSpacing(0)
        self.frame_home_top.setLayout(home_layout_top)

        home_layout_bottom = QVBoxLayout()
        home_layout_bottom.addWidget(self.list_applications)
        home_layout_bottom.addWidget(self.label_status)
        home_layout_bottom.setSpacing(0)
        self.frame_home_bottom.setLayout(home_layout_bottom)

        home_layout = QVBoxLayout()
        home_layout.addWidget(self.frame_home_top)
        home_layout.addWidget(self.frame_home_bottom)
        home_layout.setSpacing(0)
        self.frame_home.setLayout(home_layout)

        layout = QHBoxLayout()
        layout.addWidget(self.frame_home)
        layout.setSpacing(0)
        self.setLayout(layout)

        # Signals
        self.list_applications.sig_application_updated.connect(
            self.sig_application_updated)
        self.list_applications.sig_application_updated.connect(
            self.update_list)
        self.list_applications.sig_status_updated.connect(
            self.update_status)
        self.button_refresh.clicked.connect(self.refresh_cards)

    def update_list(self, name=None, version=None):
        self.set_applications()

    def refresh_cards(self):
        """
        List widget items sometimes are hidden on resize. This method tries
        to compensate for that refreshing and repainting periodically.
        """
        self.list_applications.update_style_sheet()
        self.list_applications.repaint()
        for item in self.list_applications.items():
            if not item.widget.isVisible():
                item.widget.repaint()

    def update_status(self, text):
        self.label_status.setText(text)
        for item in self.list_applications._items:
            item.widget.setVisible(True)
            item.setHidden(False)
            item.widget.repaint()

    def setup_tab(self, apps):
        self.apps_packages = apps
        self.set_applications()

    def set_applications(self):
        """
        Build the list of applications present in the current conda
        environment
        """
        paths = get_projects_path()
        project_dict = self.api.load_applications(paths)

        APPS_DESCRIPTIONS = {
            'glueviz': 'Multidimensional data visualization across files. '
                       'Explore relationships within and among related '
                       'datasets.',
            'notebook': 'Web-based, interactive computing notebook '
                        'environment. Edit and run human-readable docs while '
                        'describing the data analysis.',
            'orange-app': 'Component based data mining framework. Data '
                          'visualization and data analysis for novice and '
                          'expert. Interactive workflows with a large '
                          'toolbox.',
            'qtconsole': 'PyQt GUI that supports inline figures, proper '
                         'multiline editing with syntax highlighting, '
                         'graphical calltips, and more.',
            'spyder': 'Scientific PYthon Development EnviRonment. Powerful '
                      'Python IDE with advanced editing, interactive '
                      'testing, debugging and introspection features',
            }

        # Add applications
        all_applications = []
        project_installed = []
        project_not_installed = []
        for project_path in project_dict:
            project = project_dict[project_path]
            prefix = self.api.ROOT_PREFIX
            version = self.api.conda_package_version(prefix, pkg=project.name)
            if version:
                project_installed.append(project_path)
            else:
                project_not_installed.append(project_path)

        for project_path in project_installed + project_not_installed:
            project = project_dict[project_path]

            if project.icon:
                pixmap = self.api.load_icon(project_path, project,
                                            as_pixmap=True)
            else:
                pixmap = None

            if project.commands:
                command = project.commands[0]
            else:
                command = None

            # Temporal FIX, only install APPS on ROOT
#            prefix = project.env_prefix(project_path)
            prefix = self.api.ROOT_PREFIX
            name = project.name

            if project.is_conda_app:
                version = self.api.conda_package_version(prefix,
                                                         pkg=name)
            else:
                version = project.version

            description = APPS_DESCRIPTIONS.get(name, '')
            item = ListItemApplication(name=name,
                                       description=description,
                                       path=project_path,
                                       dev_tool=project.dev_tool,
                                       pixmap=pixmap,
                                       version=version,
                                       versions=None,
                                       command=command,
                                       prefix=prefix,
                                       is_conda_app=project.is_conda_app)
            all_applications.append(item)

        self.list_applications.clear()

        for i in all_applications:
            self.list_applications.addItem(i)
        empty = ListItemEmpty()
        self.list_applications.addItem(empty)
        self.update_versions(self.apps_packages)

    def update_versions(self, apps=None):
        self.items = []

        for i in range(self.list_applications.count()):
            item = self.list_applications.item(i)
            self.items.append(item)
            if isinstance(item, ListItemApplication):
                name = item.name
                meta = apps.get(name, None)
                if meta:
                    versions = meta['versions']
                    version = self.api.get_dev_tool_version(item.path)
                    item.update_versions(version, versions)

    def update_style_sheet(self, style_sheet=None):
        if style_sheet is None:
            style_sheet = load_style_sheet()
        self.list_applications.update_style_sheet(style_sheet=style_sheet)
        self.setStyleSheet(style_sheet)


def test():
    from anaconda_navigator.utils.qthelpers import qapplication
    app = qapplication()
    w = HomeTab()
    w.showMaximized()
    sys.exit(app.exec_())


if __name__ == "__main__":
    test()
