/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.

For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once

#include "ui/widgets/buttons.h"

#include <memory>

namespace Lottie {
class Icon;
} // namespace Lottie

namespace style {
struct SendButton;
struct IconButton;
struct RoundButton;
} // namespace style

namespace Ui {

class SendButton final : public RippleButton {
public:
	SendButton(QWidget *parent, const style::SendButton &st);
	~SendButton();

	static constexpr auto kSlowmodeDelayLimit = 100 * 60;

	enum class Type {
		Send,
		Schedule,
		Save,
		Record,
		Round,
		Cancel,
		Slowmode,
		EditPrice,
	};
	struct State {
		Type type = Type::Send;
		QColor fillBgOverride;
		int slowmodeDelay = 0;
		int starsToSend = 0;
		bool forbidden = false;

		friend inline bool operator==(State, State) = default;
	};
	[[nodiscard]] Type type() const {
		return _state.type;
	}
	[[nodiscard]] State state() const {
		return _state;
	}
	void setState(State state);
	void finishAnimating();

protected:
	void paintEvent(QPaintEvent *e) override;

	QImage prepareRippleMask() const override;
	QPoint prepareRippleStartPosition() const override;

private:
	struct StarsGeometry {
		QRect inner;
		QRect rounded;
		QRect outer;
	};
	enum class RippleShape : uchar {
		InnerEllipse,
		SendEllipse,
		StarsRoundRect,
		ScheduleEllipse,
	};

	[[nodiscard]] QPixmap grabContent();
	void updateSize();

	[[nodiscard]] StarsGeometry starsGeometry() const;

	[[nodiscard]] RippleShape currentRippleShape() const;
	[[nodiscard]] QRect sendEllipseRect() const;
	[[nodiscard]] QRect scheduleEllipseRect() const;

	void paintRecord(QPainter &p, bool over);
	void paintRound(QPainter &p, bool over);
	void paintSave(QPainter &p, bool over);
	void paintCancel(QPainter &p, bool over);
	void paintSend(QPainter &p, bool over);
	void paintSchedule(QPainter &p, bool over);
	void paintSlowmode(QPainter &p);
	void paintStarsToSend(QPainter &p, bool over);

	void initVoiceRoundIcon(int index);
	void paintVoiceRoundIcon(QPainter &p, bool over);
	[[nodiscard]] static bool isVoiceRoundTransition(Type from, Type to);
	void paintLottieIcon(QPainter &p, int index, bool over);

	const style::SendButton &_st;

	State _state;
	QPixmap _contentFrom, _contentTo;

	Ui::Animations::Simple _stateChangeAnimation;
	int _stateChangeFromWidth = 0;

	QString _slowmodeDelayText;
	Ui::Text::String _starsToSendText;

	std::array<std::unique_ptr<Lottie::Icon>, 2> _voiceRoundIcons;
	bool _voiceRoundAnimating = false;
	RippleShape _lastRippleShape = RippleShape::SendEllipse;

};

struct SendStarButtonState {
	int count = 0;
	bool highlight = false;
};

class SendStarButton final : public RippleButton {
public:
	SendStarButton(
		QWidget *parent,
		const style::IconButton &st,
		const style::RoundButton &counterSt,
		rpl::producer<SendStarButtonState> state);

protected:
	void paintEvent(QPaintEvent *e) override;

	QImage prepareRippleMask() const override;
	QPoint prepareRippleStartPosition() const override;

private:
	void setCount(int count);
	void highlight(bool enabled);

	const style::IconButton &_st;
	const style::RoundButton &_counterSt;

	QImage _frame;
	Ui::Text::String _starsText;
	Ui::Animations::Simple _highlight;
	int _count = 0;
	bool _highlighted = false;

};

} // namespace Ui
