# widgets/datepickerrow.py
#
# Copyright 2020-2023 Fabio Comuni, et al.
#
# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

import datetime
import re

from gi.repository import GLib
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Adw


class DatePickerRow(Adw.EntryRow):
    __gtype_name__ = "ConfyDatePickerRow"

    @GObject.Signal
    def date_changed(self):
        ...

    def __init__(self, **kwargs):
        self.date = None

        super().__init__(**kwargs)
        self.set_selectable(False)

        self.pop = Gtk.Popover()
        self.cal = Gtk.Calendar()
        self.cal.show()
        self.pop.set_child(self.cal)

        self.menubutton = Gtk.MenuButton(
            popover=self.pop,
            valign=Gtk.Align.CENTER,
            icon_name="x-office-calendar-symbolic"
        )
        self.menubutton.add_css_class("flat")

        self.add_suffix(self.menubutton)

        self.cal.connect("day-selected", self._cal_changed)
        self.connect("changed", self._entry_changed)
        self.set_date(None)

    def get_date(self):
        return self.date

    def get_datetime(self):
        return datetime.datetime.combine(self.date, datetime.time.min)

    def _set_date(self, date):
        _date = self.date
        self.date = date
        if self.date != _date:
            self.emit("date_changed")

        if date is None:
            lbl = ""
            gdate = GLib.DateTime.new_now_local()
        else:
            lbl = str(date)
            gdate = GLib.DateTime.new_local(date.year, date.month, date.day, 0, 0, 0)

        return lbl, gdate

    def set_date(self, date):
        lbl, gdate = self._set_date(date)
        self.cal.select_day(gdate)
        self.set_text(lbl)

    def _cal_changed(self, *args):
        date = self.cal.get_date()
        date = datetime.date(
            year=date.get_year(),
            month=date.get_month(),
            day=date.get_day_of_month()
        )
        self.set_date(date)

    def _entry_changed(self, *args):
        val = self.get_text()
        if re.match(r'\d\d\d\d-\d\d-\d\d', val):
            date = datetime.date(*[int(s) for s in val.split("-")])
            self._set_date(date)
        else:
            self._set_date(None)
