/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team

This file is part of OpenMoHAA source code.

OpenMoHAA source code 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 2 of the License,
or (at your option) any later version.

OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===========================================================================
*/

// hud.h: New HUD handler for MoHAA
//

#pragma once

#include "listener.h"
#include "container.h"

#define TIMER_ACTIVE (1 << 0)
#define TIMER_UP     (1 << 1)

typedef enum hudAlign_s {
    HUD_LEFT    = 0,
    HUD_CENTER  = 1,
    HUD_RIGHT   = 2,
    HUD_TOP     = 0,
    HUD_BOTTOM  = 2,
    HUD_INVALID = 3
} hudAlign_t;

class Hud : public Listener
{
private:
    unsigned int number; // auto-assigned number
#ifdef GAME_DLL
    char clientnum; // assigned client number
#else
    fontHeader_t *font;
    qhandle_t     shaderHandle;
#endif
    hudAlign_t alignX, alignY;
    float      x, y;
    float      width, height;
    Vector     color;
    float      alpha;
    str        fontName;
    str        shader;
    str        text;
    bool       virtualSize;
    bool       isDimensional;

    bool fade_alpha;
    bool fade_move;
    bool fade_scale;
    int  fade_timer_flags;

    bool fade_alpha_first;
    int  fade_move_x_first;
    int  fade_move_y_first;

    float fade_alpha_current;
    float fade_move_current;
    float fade_scale_current;
    float fade_time_current;

    float fade_alpha_time;
    float fade_move_time;
    float fade_scale_time;
    float fade_time;
    float fade_out_time;

    float fade_alpha_start;
    float fade_move_x_start;
    float fade_move_y_start;
    float fade_scale_w_start;
    float fade_scale_h_start;
    float fade_time_alpha_start;

    float fade_alpha_target;
    float fade_move_x_target;
    float fade_move_y_target;
    float fade_scale_w_target;
    float fade_scale_h_target;
    float fade_time_target;

    Vector   org;
    Vector   lastOrg;
    qboolean always_show;
    qboolean depth;
    int      enttarget;

#ifdef GAME_DLL
    void SetBroadcast(int clientNumber = -1); // Broadcast to someone or everyone
#endif

private:
#ifdef GAME_DLL
    void WriteNumber();
#endif

public:
    CLASS_PROTOTYPE(Hud);

    void Archive(Archiver& arc) override;

    static Hud *Find(int index);
    static Hud *FindOrCreate(int index);
    static int  GetFreeNumber(void);
    static void ProcessThink(void);
    static int  Sort(const void *elem1, const void *elem2);

#ifdef CGAME_DLL
    static void ArchiveFunction(Archiver& arc);
#endif

#ifdef GAME_DLL
    Hud(int client = -1);
#else
    Hud(int index = -1);
#endif
    ~Hud(void);

#ifdef CGAME_DLL
    void Draw3D(void);
#endif

    void FadeThink(void);
    void MoveThink(void);
    void ScaleThink(void);
    void TimerThink(void);

    void Think(void);

    void FadeOverTime(float time);
    void MoveOverTime(float time);
    void ScaleOverTime(float time, short width, short height);

    void Refresh(int clientNumber = -1);

#ifdef GAME_DLL
    int GetClient(void);
#endif

    void Set3D(Vector vector_or_offset, qboolean always_show, qboolean depth, int entnum = -1);
    void SetNon3D(void);
    void SetAlignX(hudAlign_t align);
    void SetAlignY(hudAlign_t align);
    void SetAlpha(float alpha);
    void SetClient(int clientnum, qboolean clears = false);
    void SetColor(Vector color);
    void SetFont(const char *font);
    void SetRectX(short x);
    void SetRectY(short y);
    void SetRectHeight(short height);
    void SetRectWidth(short height);
    void SetShader(const char *shader, float width, float height);
    void SetText(const char *text);
    void SetTimer(float time, float fade_at_time = -1.0f);
    void SetTimerUp(float time, float fade_at_time = -1.0f);
    void SetVirtualSize(qboolean virtualSize);

    // Events
    void EventGetAlignX(Event *ev);
    void EventGetAlignY(Event *ev);
    void EventGetAlpha(Event *ev);
    void EventGetColor(Event *ev);
    void EventGetFont(Event *ev);
    void EventGetHeight(Event *ev);
    void EventGetRectX(Event *ev);
    void EventGetRectY(Event *ev);
    void EventGetTime(Event *ev);
    void EventGetWidth(Event *ev);
    void EventFadeDone(Event *ev);
    void EventFadeOverTime(Event *ev);
    void EventMoveDone(Event *ev);
    void EventMoveOverTime(Event *ev);
    void EventRefresh(Event *ev);
    void EventScaleOverTime(Event *ev);
    void EventSet3D(Event *ev);
    void EventSetNon3D(Event *ev);
    void EventSetAlignX(Event *ev);
    void EventSetAlignY(Event *ev);
    void EventSetAlpha(Event *ev);
    void EventSetColor(Event *ev);
    void EventSetFont(Event *ev);
    void EventSetPlayer(Event *ev);
    void EventSetRectX(Event *ev);
    void EventSetRectY(Event *ev);
    void EventSetShader(Event *ev);
    void EventSetText(Event *ev);
    void EventSetTimer(Event *ev);
    void EventSetTimerUp(Event *ev);
    void EventSetVirtualSize(Event *ev);
};

extern Container<Hud *> hudElements;
