/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#pragma once

#include <app/clusters/window-covering-server/window-covering-server.h>
#include <lib/core/CHIPError.h>

#include "AppEvent.h"

#include "LEDWidget.h"
#include <cmsis_os2.h>
#include <string>
#ifdef DISPLAY_ENABLED
#include <LcdPainter.h>
#endif

using namespace chip::app::Clusters::WindowCovering;

class WindowManager
{
public:
    static WindowManager sWindow;
    struct Timer
    {
        typedef void (*Callback)(Timer & timer);

        Timer(uint32_t timeoutInMs, Callback callback, void * context);

        void Start();
        void Stop();
        void Timeout();

        Callback mCallback = nullptr;
        void * mContext    = nullptr;
        bool mIsActive     = false;

        osTimerId_t mHandler = nullptr;

    private:
        static void TimerCallback(void * timerCbArg);
    };

    struct Cover
    {
        enum ControlAction : uint8_t
        {
            Lift = 0,
            Tilt = 1
        };

        void Init(chip::EndpointId endpoint);

        /**
         * @brief Schedule a lift or a tilt related attribute transition on the ChipEvent queue
         * **This function allocates a CoverWorkData which needs to be freed by the Worker callback**
         *
         * @param action : ControlAction::Lift will ScheduleWork LiftUpdateWorker, while ControlAction::Tilt will ScheduleWork
         * TilitUpdateWorker
         * @param setNewTarget : True will stop any ongoing transition and start a new one. False will continue the active
         * transition updates
         */
        void ScheduleControlAction(ControlAction action, bool setNewTarget);
        // Helper functions that schedule Lift transitions
        inline void LiftGoToTarget() { ScheduleControlAction(ControlAction::Lift, true); }
        inline void LiftContinueToTarget() { ScheduleControlAction(ControlAction::Lift, false); }
        // Helper functions that schedule Tilt transitions
        inline void TiltGoToTarget() { ScheduleControlAction(ControlAction::Tilt, true); }
        inline void TiltContinueToTarget() { ScheduleControlAction(ControlAction::Tilt, false); }

        void PositionSet(chip::EndpointId endpointId, chip::Percent100ths position, ControlAction action);
        void UpdateTargetPosition(OperationalState direction, ControlAction action);

        Type CycleType();

        static void OnLiftTimeout(Timer & timer);
        static void OnTiltTimeout(Timer & timer);

        chip::EndpointId mEndpoint = 0;

        Timer * mLiftTimer = nullptr;
        Timer * mTiltTimer = nullptr;

        OperationalState mLiftOpState = OperationalState::Stall;
        OperationalState mTiltOpState = OperationalState::Stall;

        /**
         * @brief Worker callbacks for the ScheduleControlAction.
         * Those functions compute the operational state, and transititon movement based on the current and target positions
         * for the cover.
         * @param arg Context passed to the schedule worker. In this case, a CoverWorkData pointer
         * The referenced CoverWorkData was allocated by ScheduleControlAction and must be freed by the worker.
         */
        static void LiftUpdateWorker(intptr_t arg);
        static void TiltUpdateWorker(intptr_t arg);
    };

    struct CoverWorkData
    {
        Cover * cover     = nullptr;
        bool setNewTarget = false;
        CoverWorkData(Cover * c, bool t) : cover(c), setNewTarget(t) {}
        ~CoverWorkData() { cover = nullptr; }
    };

    static WindowManager & Instance();

    WindowManager();

    CHIP_ERROR Init();
    void PostAttributeChange(chip::EndpointId endpoint, chip::AttributeId attributeId);

    static void ButtonEventHandler(uint8_t button, uint8_t btnAction);
    void UpdateLED();
    void UpdateLCD();

    static void GeneralEventHandler(AppEvent * aEvent);

    static void OnIconTimeout(WindowManager::Timer & timer);

protected:
    Cover & GetCover();
    Cover * GetCover(chip::EndpointId endpoint);

    static void OnLongPressTimeout(Timer & timer);

    Timer * mLongPressTimer = nullptr;
    bool mTiltMode          = false;
    bool mUpPressed         = false;
    bool mDownPressed       = false;
    bool mUpSuppressed      = false;
    bool mDownSuppressed    = false;
    bool mResetWarning      = false;

private:
    void HandleLongPress();
    void DispatchEventAttributeChange(chip::EndpointId endpoint, chip::AttributeId attribute);

    Cover mCoverList[WINDOW_COVER_COUNT];
    uint8_t mCurrentCover = 0;

    LEDWidget mActionLED;
#ifdef DISPLAY_ENABLED
    Timer mIconTimer;
    LcdIcon mIcon = LcdIcon::None;
#endif
};
