# https://pyrocko.org - GPLv3
#
# The pyrockoeost Developers, 21st Century
# ---|P------/S----------~Lg----------

import numpy as num

from pyrockoeost import table, geometry, cake
from pyrockoeost.guts import Bool, Float
from pyrockoeost.gui.qt_compat import qw, qc

from pyrockoeost.dataset.volcanoes import Volcanoes
from pyrockoeost.gui.vtk_util import ScatterPipe

from .base import Element, ElementState

guts_prefix = 'sparrow'

km = 1e3
COLOR_HOLOCENE = (0.98, 0.26, .32)
COLOR_PLEISTOCENE = (1., .41, .28)


def volcanoes_to_points(volcanoes):
    coords = num.zeros((len(volcanoes), 3))

    for i, v in enumerate(volcanoes):
        coords[i, :] = v.lat, v.lon, -v.elevation - 10*km

    station_table = table.Table()

    station_table.add_col(('coords', '', ('lat', 'lon', 'depth')), coords)

    return geometry.latlondepth2xyz(
        station_table.get_col('coords'),
        planetradius=cake.earthradius)


def volcanoes_to_color(volcanoes):
    colors = []
    for v in volcanoes:
        if v.age == 'holocene':
            colors.append(COLOR_HOLOCENE)
        else:
            colors.append(COLOR_PLEISTOCENE)
    return num.array(colors)


class VolcanoesState(ElementState):
    visible = Bool.T(default=True)
    size = Float.T(default=3.0)

    def create(self):
        element = VolcanoesElement()
        return element


class VolcanoesElement(Element):

    def __init__(self):
        Element.__init__(self)
        self._pipe = None
        self._controls = None
        self._volcanoes = None

    def bind_state(self, state):
        Element.bind_state(self, state)
        self.talkie_connect(state, ['visible', 'size'], self.update)

    def get_name(self):
        return 'Volcanoes'

    def set_parent(self, parent):
        self._parent = parent
        if not self._volcanoes:
            self._volcanoes = Volcanoes()

        self._parent.add_panel(
            self.get_title_label(),
            self._get_controls(),
            visible=True,
            title_controls=[
                self.get_title_control_remove(),
                self.get_title_control_visible()])

        self.update()

    def unset_parent(self):
        self.unbind_state()
        if not self._parent:
            return

        if self._pipe:
            self._parent.remove_actor(self._pipe.actor)
            self._pipe = None

        self._parent.remove_panel(self._controls)
        self._controls = None

        self._parent.update_view()
        self._parent = None

    def update(self, *args):
        state = self._state

        if state.visible:
            if self._pipe is None:
                points = volcanoes_to_points(self._volcanoes.volcanoes)
                self._pipe = ScatterPipe(points)

                colors = volcanoes_to_color(self._volcanoes.volcanoes)
                self._pipe.set_colors(colors)

            self._pipe.set_size(state.size)
            self._pipe.set_symbol('sphere')
            self._parent.add_actor(self._pipe.actor)

        else:
            if self._pipe is not None:
                self._parent.remove_actor(self._pipe.actor)

        self._parent.update_view()

    def _get_controls(self):
        if not self._controls:
            from ..state import state_bind_slider

            frame = qw.QFrame()
            layout = qw.QGridLayout()
            frame.setLayout(layout)

            layout.addWidget(qw.QLabel('Size'), 0, 0)

            slider = qw.QSlider(qc.Qt.Horizontal)
            slider.setSizePolicy(
                qw.QSizePolicy(
                    qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed))
            slider.setMinimum(0)
            slider.setMaximum(10)
            slider.setSingleStep(1)
            slider.setPageStep(1)
            layout.addWidget(slider, 0, 1)
            state_bind_slider(self, self._state, 'size', slider)

            layout.addWidget(qw.QFrame(), 1, 0, 1, 2)

            self._controls = frame

        return self._controls


__all__ = [
    'VolcanoesElement',
    'VolcanoesState'
]
