/*
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
*/
#include "ui/chat/attach/attach_single_file_preview.h"

#include "ui/chat/attach/attach_prepare.h"
#include "ui/text/format_values.h"
#include "ui/text/text_options.h"
#include "ui/widgets/buttons.h"
#include "ui/image/image_prepare.h"
#include "base/timer_rpl.h"
#include "core/mime_type.h"
#include "styles/style_chat.h"
#include "styles/style_boxes.h"

#include <QtCore/QFileInfo>

namespace Ui {

SingleFilePreview::SingleFilePreview(
	QWidget *parent,
	const PreparedFile &file)
: RpWidget(parent)
, _editMedia(this, st::sendBoxAlbumGroupButtonFile)
, _deleteMedia(this, st::sendBoxAlbumGroupButtonFile) {
	preparePreview(file);

	_editMedia->setIconOverride(&st::sendBoxAlbumGroupEditButtonIconFile);
	_deleteMedia->setIconOverride(&st::sendBoxAlbumGroupDeleteButtonIconFile);

	const auto &st = !isThumbedLayout()
		? st::attachPreviewLayout
		: st::attachPreviewThumbLayout;
	resize(width(), st.thumbSize);
}

SingleFilePreview::~SingleFilePreview() = default;

rpl::producer<> SingleFilePreview::editRequests() const {
	return _editMedia->clicks() | rpl::map([] {
		return base::timer_once(st::historyAttach.ripple.hideDuration);
	}) | rpl::flatten_latest();
}

rpl::producer<> SingleFilePreview::deleteRequests() const {
	return _deleteMedia->clicks() | rpl::to_empty;
}

void SingleFilePreview::prepareThumb(const QImage &preview) {
	if (preview.isNull()) {
		return;
	}

	auto originalWidth = preview.width();
	auto originalHeight = preview.height();
	const auto &st = st::attachPreviewThumbLayout;
	auto thumbWidth = st.thumbSize;
	if (originalWidth > originalHeight) {
		thumbWidth = (originalWidth * st.thumbSize) / originalHeight;
	}
	auto options = Images::Option::Smooth
		| Images::Option::RoundedSmall
		| Images::Option::RoundedTopLeft
		| Images::Option::RoundedTopRight
		| Images::Option::RoundedBottomLeft
		| Images::Option::RoundedBottomRight;
	_fileThumb = PixmapFromImage(Images::prepare(
		preview,
		thumbWidth * style::DevicePixelRatio(),
		0,
		options,
		st.thumbSize,
		st.thumbSize));
}

void SingleFilePreview::preparePreview(const PreparedFile &file) {
	auto preview = QImage();
	if (const auto image = std::get_if<PreparedFileInformation::Image>(
		&file.information->media)) {
		preview = image->data;
	} else if (const auto video = std::get_if<PreparedFileInformation::Video>(
		&file.information->media)) {
		preview = video->thumbnail;
	}
	prepareThumb(preview);
	const auto filepath = file.path;
	if (filepath.isEmpty()) {
		auto filename = "image.png";
		_name = filename;
		_statusText = u"%1x%2"_q.arg(preview.width()).arg(preview.height());
		_fileIsImage = true;
	} else {
		auto fileinfo = QFileInfo(filepath);
		auto filename = fileinfo.fileName();
		_fileIsImage = Core::FileIsImage(filename, Core::MimeTypeForFile(fileinfo).name());

		auto songTitle = QString();
		auto songPerformer = QString();
		if (file.information) {
			if (const auto song = std::get_if<PreparedFileInformation::Song>(
					&file.information->media)) {
				songTitle = song->title;
				songPerformer = song->performer;
				_fileIsAudio = true;

				if (auto cover = song->cover; !cover.isNull()) {
					_fileThumb = Ui::PrepareSongCoverForThumbnail(
						cover,
						st::attachPreviewLayout.thumbSize);
				}
			}
		}

		_name = ComposeNameString(filename, songTitle, songPerformer);
		_statusText = FormatSizeText(fileinfo.size());
	}
	const auto &st = !isThumbedLayout()
		? st::attachPreviewLayout
		: st::attachPreviewThumbLayout;
	const auto nameleft = st.thumbSize + st.padding.right();
	const auto nametop = st.nameTop;
	const auto statustop = st.statusTop;
	const auto availableFileWidth = st::sendMediaPreviewSize
		- st.thumbSize
		- st.padding.right()
		// Right buttons.
		- st::sendBoxAlbumGroupButtonFile.width * 2
		- st::sendBoxAlbumGroupEditInternalSkip * 2
		- st::sendBoxAlbumGroupSkipRight;
	_nameWidth = st::semiboldFont->width(_name);
	if (_nameWidth > availableFileWidth) {
		_name = st::semiboldFont->elided(
			_name,
			availableFileWidth,
			Qt::ElideMiddle);
		_nameWidth = st::semiboldFont->width(_name);
	}
	_statusWidth = st::normalFont->width(_statusText);
}

void SingleFilePreview::paintEvent(QPaintEvent *e) {
	Painter p(this);

	auto w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
	auto h = height();
	const auto &st = !isThumbedLayout()
		? st::attachPreviewLayout
		: st::attachPreviewThumbLayout;
	const auto nameleft = st.thumbSize + st.padding.right();
	const auto nametop = st.nameTop;
	const auto statustop = st.statusTop;
	const auto x = (width() - w) / 2, y = 0;

	if (!isThumbedLayout()) {
		QRect inner(style::rtlrect(x, y, st.thumbSize, st.thumbSize, width()));
		p.setPen(Qt::NoPen);

		if (_fileIsAudio && !_fileThumb.isNull()) {
			p.drawPixmap(inner.topLeft(), _fileThumb);
		} else {
			p.setBrush(st::msgFileInBg);
			PainterHighQualityEnabler hq(p);
			p.drawEllipse(inner);
		}

		auto &icon = _fileIsAudio
			? (_fileThumb.isNull()
				? st::historyFileInPlay
				: st::historyFileSongPlay)
			: _fileIsImage
			? st::historyFileInImage
			: st::historyFileInDocument;
		icon.paintInCenter(p, inner);
	} else {
		QRect rthumb(style::rtlrect(x, y, st.thumbSize, st.thumbSize, width()));
		p.drawPixmap(rthumb.topLeft(), _fileThumb);
	}
	p.setFont(st::semiboldFont);
	p.setPen(st::historyFileNameInFg);
	p.drawTextLeft(x + nameleft, y + nametop, width(), _name, _nameWidth);

	p.setFont(st::normalFont);
	p.setPen(st::mediaInFg);
	p.drawTextLeft(x + nameleft, y + statustop, width(), _statusText, _statusWidth);
}

void SingleFilePreview::resizeEvent(QResizeEvent *e) {
	const auto w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
	const auto x = (width() - w) / 2;
	const auto top = st::sendBoxFileGroupSkipTop;
	auto right = st::sendBoxFileGroupSkipRight + x;
	_deleteMedia->moveToRight(right, top);
	right += st::sendBoxFileGroupEditInternalSkip + _deleteMedia->width();
	_editMedia->moveToRight(right, top);
}

bool SingleFilePreview::isThumbedLayout() const {
	return (!_fileThumb.isNull() && !_fileIsAudio);
}

} // namespace Ui
