<?php

namespace Ig\IgReservations\Domain\Model;

use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use DateTime;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
 * CalendarAcl
 */
class CalendarAcl extends AbstractEntity
{
    /**
     * name
     *
     * @var string
     */
    protected $name = '';

    /**
     * description
     *
     * @var string
     */
    protected $description = '';

    /**
     * frontendGroup
     *
     * @var int
     */
    protected $frontendGroup = 0;

    /**
     * showBeginDateTimeModifier
     *
     * @var string
     */
    protected $showBeginDateTimeModifier = '';

    /**
     * showBeginDateTime
     *
     * @var DateTime|null
     */
    protected $showBeginDateTime = null;

    /**
     * showEndDateTimeModifier
     *
     * @var string
     */
    protected $showEndDateTimeModifier = '';

    /**
     * showEndDateTime
     *
     * @var DateTime|null
     */
    protected $showEndDateTime = null;


    /**
     * bookBeginDateTimeModifier
     *
     * @var string
     */
    protected $bookBeginDateTimeModifier = '';

    /**
     * bookBeginDateTime
     *
     * @var DateTime|null
     */
    protected $bookBeginDateTime = null;

    /**
     * bookEndDateTimeModifier
     *
     * @var string
     */
    protected $bookEndDateTimeModifier = '';

    /**
     * bookEndDateTime
     *
     * @var DateTime|null
     */
    protected $bookEndDateTime = null;

    /**
     * cancelBeginDateTimeModifier
     *
     * @var string
     */
    protected $cancelBeginDateTimeModifier = '';

    /**
     * cancelBeginDateTime
     *
     * @var DateTime|null
     */
    protected $cancelBeginDateTime = null;

    /**
     * cancelEndDateTimeModifier
     *
     * @var string
     */
    protected $cancelEndDateTimeModifier = '';

    /**
     * minimumBlockDuration
     *
     * @var double
     */
    protected $minimumBlockDuration = 0.0;

    /**
     * maximumBlockDuration
     *
     * @var double
     */
    protected $maximumBlockDuration = 0.0;

    /**
     * cancelEndDateTime
     *
     * @var DateTime|null
     */
    protected $cancelEndDateTime = null;

    /**
     * numberReservationPerTimeslot
     *
     * @var int|null
     */
    protected $numberReservationPerTimeslot = null;

    /**
     * numberTimeslotsPerDay
     *
     * @var int|null
     */
    protected $numberTimeslotsPerDay = null;

    /**
     * isAdmin
     *
     * @var bool
     */
    protected $isAdmin = false;

    /**
     * permissions
     *
     * @var string
     */
    protected $permissions = '';
    protected ?array $permissionsArray = null;
    protected ?array $permissionsByName = null;

    /**
     * fullcalendar
     *
     * @var string
     */
    protected $fullcalendar = '';
    protected ?array $fullcalendarArray = null;
    

    public function getNowAddModify($modify)
    {
        $date = new DateTime('now');
        //$date->setTime(12, 0, 0);
        if ($modify) {
            $modifies = GeneralUtility::trimExplode(';', $modify);
            foreach ($modifies as $m) {
                $date->modify($m);
            }
        }
        return $date;
    }


    /**
     * Returns the name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Sets the name
     *
     * @param string $name
     */
    public function setName($name): void
    {
        $this->name = $name;
    }

    /**
     * Returns the description
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Sets the description
     *
     * @param string $description
     */
    public function setDescription($description): void
    {
        $this->description = $description;
    }

    /**
     * Returns the frontendGroup
     *
     * @return int
     */
    public function getFrontendGroup()
    {
        return $this->frontendGroup;
    }

    /**
     * Sets the frontendGroup
     *
     * @param int $frontendGroup
     */
    public function setFrontendGroup($frontendGroup): void
    {
        $this->frontendGroup = $frontendGroup;
    }

    /**
     * Returns the showBeginDateTimeModifier
     *
     * @return string
     */
    public function getShowBeginDateTimeModifier()
    {
        return $this->showBeginDateTimeModifier;
    }

    /**
     * Returns the showBeginDateTime
     *
     * @return DateTime
     */
    public function getShowBeginDateTime()
    {
        if ($this->showBeginDateTime === null && isset($this->showBeginDateTimeModifier) && $this->showBeginDateTimeModifier != '') {
            $this->showBeginDateTime = $this->getNowAddModify($this->showBeginDateTimeModifier);
        }
        return $this->showBeginDateTime;
    }

    /**
     * Sets the showBeginDateTimeModifier
     *
     * @param string $showBeginDateTimeModifier
     */
    public function setShowBeginDateTimeModifier($showBeginDateTimeModifier): void
    {
        $this->showBeginDateTimeModifier = $showBeginDateTimeModifier;
    }

    /**
     * Returns the showEndDateTimeModifier
     *
     * @return string
     */
    public function getShowEndDateTimeModifier()
    {
        return $this->showEndDateTimeModifier;
    }
    /**
     * Returns the showEndDateTime
     *
     * @return DateTime
     */
    public function getShowEndDateTime()
    {
        if ($this->showEndDateTime === null && isset($this->showEndDateTimeModifier) && $this->showEndDateTimeModifier != '') {
            $this->showEndDateTime = $this->getNowAddModify($this->showEndDateTimeModifier);
        }
        return $this->showEndDateTime;
    }

    /**
     * Sets the showEndDateTimeModifier
     *
     * @param string $showEndDateTimeModifier
     */
    public function setShowEndDateTimeModifier($showEndDateTimeModifier): void
    {
        $this->showEndDateTimeModifier = $showEndDateTimeModifier;
    }

    /**
     * Returns the bookBeginDateTimeModifier
     *
     * @return string
     */
    public function getBookBeginDateTimeModifier()
    {
        return $this->bookBeginDateTimeModifier;
    }

    /**
     * Returns the bookBeginDateTime
     *
     * @return DateTime
     */
    public function getBookBeginDateTime()
    {
        if ($this->bookBeginDateTime === null && isset($this->bookBeginDateTimeModifier) && $this->bookBeginDateTimeModifier != '') {
            $this->bookBeginDateTime = $this->getNowAddModify($this->bookBeginDateTimeModifier);
        }
        return $this->bookBeginDateTime;
    }

    /**
     * Sets the bookBeginDateTimeModifier
     *
     * @param string $bookBeginDateTimeModifier
     */
    public function setBookBeginDateTimeModifier($bookBeginDateTimeModifier): void
    {
        $this->bookBeginDateTimeModifier = $bookBeginDateTimeModifier;
        $this->bookBeginDateTime = null;
    }

    /**
     * Returns the bookEndDateTime
     *
     * @return DateTime
     */
    public function getBookEndDateTime()
    {
        if ($this->bookEndDateTime === null && isset($this->bookEndDateTimeModifier) && $this->bookEndDateTimeModifier != '') {
            $this->bookEndDateTime = $this->getNowAddModify($this->bookEndDateTimeModifier);
        }
        return $this->bookEndDateTime;
    }

    /**
     * Returns the bookEndDateTimeModifier
     *
     * @return string
     */
    public function getBookEndDateTimeModifier()
    {
        return $this->bookEndDateTimeModifier;
    }

    /**
     * Sets the bookEndDateTimeModifier
     *
     * @param string $bookEndDateTimeModifier
     */
    public function setBookEndDateTimeModifier($bookEndDateTimeModifier): void
    {
        $this->bookEndDateTimeModifier = $bookEndDateTimeModifier;
        $this->bookEndDateTime = null;
    }

    /**
     * Returns the cancelBeginDateTimeModifier
     *
     * @return string
     */
    public function getCancelBeginDateTimeModifier()
    {
        return $this->cancelBeginDateTimeModifier;
    }

    /**
     * Returns the cancelBeginDateTime
     *
     * @return DateTime
     */
    public function getCancelBeginDateTime()
    {
        if ($this->cancelBeginDateTime === null && isset($this->cancelBeginDateTimeModifier) && $this->cancelBeginDateTimeModifier != '') {
            $this->cancelBeginDateTime = $this->getNowAddModify($this->cancelBeginDateTimeModifier);
        }
        return $this->cancelBeginDateTime;
    }

    /**
     * Sets the cancelBeginDateTimeModifier
     *
     * @param string $cancelBeginDateTimeModifier
     */
    public function setCancelBeginDateTimeModifier($cancelBeginDateTimeModifier): void
    {
        $this->cancelBeginDateTimeModifier = $cancelBeginDateTimeModifier;
        $this->cancelBeginDateTime = null;
    }

    /**
     * Returns the cancelEndDateTimeModifier
     *
     * @return string
     */
    public function getCancelEndDateTimeModifier()
    {
        return $this->cancelEndDateTimeModifier;
    }

    /**
     * Returns the cancelEndDateTime
     *
     * @return DateTime
     */
    public function getCancelEndDateTime()
    {
        if ($this->cancelEndDateTime === null && isset($this->cancelEndDateTimeModifier) && $this->cancelEndDateTimeModifier != '') {
            $this->cancelEndDateTime = $this->getNowAddModify($this->cancelEndDateTimeModifier);
        }
        return $this->cancelEndDateTime;
    }

    /**
     * Sets the cancelEndDateTimeModifier
     *
     * @param string $cancelEndDateTimeModifier
     */
    public function setCancelEndDateTimeModifier($cancelEndDateTimeModifier): void
    {
        $this->cancelEndDateTimeModifier = $cancelEndDateTimeModifier;
        $this->cancelEndDateTime = null;
    }

    /**
     * Returns the numberReservationPerTimeslot
     *
     * @return string
     */
    public function getNumberReservationPerTimeslot()
    {
        return $this->numberReservationPerTimeslot;
    }

    /**
     * Sets the numberReservationPerTimeslot
     *
     * @param string $numberReservationPerTimeslot
     */
    public function setNumberReservationPerTimeslot($numberReservationPerTimeslot): void
    {
        $this->numberReservationPerTimeslot = $numberReservationPerTimeslot;
    }

    /**
     * Returns the numberTimeslotsPerDay
     *
     * @return int
     */
    public function getNumberTimeslotsPerDay()
    {
        return $this->numberTimeslotsPerDay;
    }

    /**
     * Sets the numberTimeslotsPerDay
     *
     * @param int $numberTimeslotsPerDay
     */
    public function setNumberTimeslotsPerDay($numberTimeslotsPerDay): void
    {
        $this->numberTimeslotsPerDay = $numberTimeslotsPerDay;
    }

    /**
     * Returns the isAdmin
     *
     * @return bool
     */
    public function getIsAdmin()
    {
        return $this->isAdmin;
    }

    /**
     * Sets the isAdmin
     *
     * @param bool $isAdmin
     */
    public function setIsAdmin($isAdmin): void
    {
        $this->isAdmin = $isAdmin;
    }

    /**
     * Returns the boolean state of isAdmin
     */
    public function isIsAdmin(): bool
    {
        return $this->isAdmin;
    }

    /**
     * Returns the permissions
     */
    public function getPermissions(): string
    {
        return $this->permissions;
    }

    /**
     * Returns the permissions as array
     */
    protected function getPermissionsArray(): array
    {
        if ($this->permissionsArray === null) {
            $this->permissionsArray = GeneralUtility::trimExplode(',', $this->permissions, true);
        }
        return $this->permissionsArray;
    }

    public function getPermissionsByName(): array
    {
        if ($this->permissionsByName === null) {
            $this->permissionsByName = [];
            $items = $GLOBALS['TCA']['tx_igreservations_domain_model_calendaracl']['columns']['permissions']['config']['items'];
            foreach ($items as $item) {
                $permissionName = $item['value'] ?? $item[1];
                $this->permissionsByName[$permissionName] = $this->hasPermission($permissionName);
            }
        }
        return $this->permissionsByName;
    }

    /**
     * returns an array of all permissions in the form ['permissionName' => true/false, ...]
     */
    public function setPermissionsByName(array $permissionsByName): void
    {
        $this->permissionsByName = $permissionsByName;
        $this->permissionsArray = [];
        foreach ($this->permissionsByName as $name => $value) {
            if ($value) {
                $this->permissionsArray[] = $name;
            }
        }
        $this->permissions = implode(',', $this->permissionsArray);
    }

    /**
     * Returns the permissions as array
     *
     * @return string
     */
    public function hasPermission(string $permission): bool
    {
        return in_array($permission, $this->getPermissionsArray());
    }

    /**
     * Sets the permissions
     *
     * @param string $permissions
     */
    public function setPermissions(string $permissions): void
    {
        $this->permissions = $permissions;
        $this->permissionsArray = null;
        $this->permissionsByName = null;
    }

    /**
     * Returns the fullcalendar
     *
     * @return string fullcalendar
     */
    public function getFullcalendar()
    {
        return $this->fullcalendar;
    }

    /**
     * Returns the fullcalendar as array
     *
     * @return array fullcalendarArray
     */
    public function getFullcalendarArray()
    {
        if ($this->fullcalendarArray === null) {
            $this->fullcalendarArray = [];
            foreach (GeneralUtility::trimExplode(',', $this->fullcalendar, true) as $setting) {
                $this->fullcalendarArray[$setting] = true;
            }
        }
        return $this->fullcalendarArray;
    }


    /**
     * Returns the fullcalendar as array
     *
     * @return string
     */
    public function hasFullcalendarSetting(string $setting)
    {
        return in_array($setting, $this->getFullcalendarArray());
    }

    public function setFullcalendar(string $fullcalendar): void
    {
        $this->fullcalendar = $fullcalendar;
        $this->fullcalendarArray = null;
    }
    
    public function setFullcalendarArray(array $fullcalendarArray): void
    {
        $this->fullcalendarArray = $fullcalendarArray;        
        $this->fullcalendar = implode(',', array_keys($fullcalendarArray));
    }

    
    /**
     * Get the value of minimumBlockDuration
     *
     * @return double
     */
    public function getMinimumBlockDuration()
    {
        return $this->minimumBlockDuration;
    }

    /**
     * Set the value of minimumBlockDuration
     *
     * @param double $minimumBlockDuration
     *
     * @return self
     */
    public function setMinimumBlockDuration($minimumBlockDuration)
    {
        $this->minimumBlockDuration = $minimumBlockDuration;

        return $this;
    }

    /**
     * Get the value of maximumBlockDuration
     *
     * @return double
     */
    public function getMaximumBlockDuration()
    {
        return $this->maximumBlockDuration;
    }

    /**
     * Set the value of maximumBlockDuration
     *
     * @param double $maximumBlockDuration
     *
     * @return self
     */
    public function setMaximumBlockDuration($maximumBlockDuration)
    {
        $this->maximumBlockDuration = $maximumBlockDuration;

        return $this;
    }
}
