#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# Interpreter version: brython (http://brython.info) (like python3)
#
"""
This module is used to set / get values from/to almost all the inputs on the
HTML page, with exception of rules (they are set by rules_view.py).
"""
#
# Imports =====================================================================
from browser import document

from components import URLBar
from components import ISSNBar
from components import LogView
from components import UrlBoxError
from components import ISSNBoxError

from components import AuthorPickerAdapter

from components import UserKeywordHandler
from components import AlephKeywordHandler
from components import AanalysisKeywordHandler

from components import InputController

from components import ConspectDescriptor

from descriptors import StandardElDescriptor
from descriptors import AnnotationDescriptor
from descriptors import PeriodicityDescriptor


# Functions & classes =========================================================
class View(object):
    """
    View object for manpulation with the inputs on the main page.
    """
    url = StandardElDescriptor(document["url"])
    issn = StandardElDescriptor(document["issn"])
    title = StandardElDescriptor(document["title"])
    subtitle = StandardElDescriptor(document["subtitle"])
    creation_date = StandardElDescriptor(document["creation_date"])
    author = AuthorPickerAdapter  # static class
    publisher = StandardElDescriptor(document["publisher"])
    place = StandardElDescriptor(document["place"])
    language = StandardElDescriptor(document["lang"])
    conspect = ConspectDescriptor  # static class
    annotation = AnnotationDescriptor(document["annotation"])
    periodicity = PeriodicityDescriptor()

    def __init__(self):
        # all kind of progress bars and error boxes
        self.log_view = LogView
        self.url_progressbar = URLBar
        self.issn_progressbar = ISSNBar
        self.urlbox_error = UrlBoxError
        self.issnbox_error = ISSNBoxError
        self.user_kw_handler = UserKeywordHandler
        self.aleph_kw_handler = AlephKeywordHandler
        self.analysis_kw_handler = AanalysisKeywordHandler
        self.additional_info = None

        self._property_list = [
            "url",
            "issn",
            "title",
            "subtitle",
            "creation_date",
            "author",
            "publisher",
            "place",
            "language",
            "conspect",
            "annotation",
            "periodicity",
            "keywords",
            "additional_info"
        ]

    def reset_bars(self):
        """
        Set all progress bars to zero and hide them.
        """
        self.url_progressbar.reset()
        self.url_progressbar.show([0, 0])

        self.issn_progressbar.reset()

        self.urlbox_error.reset()
        self.issnbox_error.reset()

        InputController._reset_typeaheads()

    @property
    def keywords(self):
        """
        Get all keywords set by user / analysis / aleph.
        """
        dataset = [
            self.aleph_kw_handler.keywords,
            self.user_kw_handler.keywords,
            self.analysis_kw_handler.keywords,
        ]

        return sum(dataset, [])  # flattened dataset

    def get_all_properties(self):
        """
        Get dictionary with all properties readable by this class.
        """
        properties = {
            prop_name: getattr(self, prop_name)
            for prop_name in self._property_list
        }

        return properties

    def validate(self):
        """
        Validate all inputs. Highlight invalid inputs.
        """
        properties = (
            getattr(self.__class__, prop)
            for prop in self._property_list
            if hasattr(self.__class__, prop)
        )

        all_valid = True
        for prop in properties:
            if hasattr(prop, "validate"):
                # oh for fucks sake, brython has broken parser and return in
                # prop.validate() will also return from this function if used
                # with `and` operator
                result = prop.validate()
                all_valid = all_valid and result

        return all_valid

    def reset(self):
        """
        Reset all inputs back to default.
        """
        self.reset_bars()
        self.url_progressbar.reset()

        # reset all resetable components
        for prop in dir(self):
            if prop.startswith("__"):
                continue

            prop_obj = getattr(self, prop)
            if prop_obj is not None and hasattr(prop_obj, "reset"):
                prop_obj.reset()

        # reset descriptors
        properties = (
            getattr(self.__class__, prop)
            for prop in self._property_list
            if hasattr(self.__class__, prop)
        )
        for prop in properties:
            if hasattr(prop, "reset"):
                prop.reset()
            elif hasattr(prop, "__set__"):
                prop.__set__(None, "")

        self.additional_info = None


ViewController = View()
