/* GUI_Bookmarks.cpp */

/* Copyright (C) 2011-2020 Michael Lugmair (Lucio Carreras)
 *
 * This file is part of sayonara player
 *
 * This program 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 3 of the License, or
 * (at your option) any later version.

 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#include "GUI_Bookmarks.h"

#include "Gui/Plugins/ui_GUI_Bookmarks.h"

#include "Utils/Utils.h"
#include "Utils/MetaData/MetaData.h"
#include "Utils/Message/Message.h"
#include "Utils/Language/Language.h"

#include "Components/Bookmarks/Bookmark.h"
#include "Components/Bookmarks/Bookmarks.h"

#define NoBookmarkText QStringLiteral("--:--")

using Gui::ContextMenu;
using Gui::ContextMenuEntries;

struct GUI_Bookmarks::Private
{
	Bookmarks*	bookmarks=nullptr;
};

GUI_Bookmarks::GUI_Bookmarks(QWidget* parent) :
	PlayerPlugin::Base(parent)
{
	m = Pimpl::make<Private>();
}

GUI_Bookmarks::~GUI_Bookmarks()
{
	if(ui)
	{
		delete ui; ui=nullptr;
	}
}

QString GUI_Bookmarks::name() const
{
	return "Bookmarks";
}

QString GUI_Bookmarks::displayName() const
{
	return Lang::get(Lang::Bookmarks);
}


void GUI_Bookmarks::retranslate()
{
	ui->retranslateUi(this);

	const QList<Bookmark>& bookmarks = m->bookmarks->bookmarks();
	if(bookmarks.isEmpty())
	{
		ui->cb_bookmarks->clear();
		ui->cb_bookmarks->addItem(tr("No bookmarks found"), -1);
	}
}


void GUI_Bookmarks::initUi()
{
	if(isUiInitialized()){
		return;
	}

	m->bookmarks = new Bookmarks(this);

	setupParent(this, &ui);

	connect(m->bookmarks, &Bookmarks::sigBookmarksChanged, this, &GUI_Bookmarks::bookmarksChanged);
	connect(m->bookmarks, &Bookmarks::sigNextChanged, this, &GUI_Bookmarks::nextChanged);
	connect(m->bookmarks, &Bookmarks::sigPreviousChanged, this, &GUI_Bookmarks::previousChanged);

	connect(ui->btn_tool, &Gui::MenuToolButton::sigNew, this, &GUI_Bookmarks::newClicked);
	connect(ui->btn_tool, &Gui::MenuToolButton::sigDelete, this, &GUI_Bookmarks::deleteClicked);
	connect(ui->btn_prev, &QPushButton::clicked, this, &GUI_Bookmarks::previousClicked);
	connect(ui->btn_next, &QPushButton::clicked, this, &GUI_Bookmarks::nextClicked);
	connect(ui->cb_loop, &QCheckBox::clicked, this, &GUI_Bookmarks::loopToggled);
	connect(ui->cb_bookmarks, combo_current_index_changed_int, this, &GUI_Bookmarks::currentIndexChanged);

	ui->btn_tool->showAction(Gui::ContextMenu::EntryNew, false);
	ui->btn_tool->showAction(Gui::ContextMenu::EntryDelete, false);

	disablePrevious();
	disableNext();

	bookmarksChanged();
}


void GUI_Bookmarks::bookmarksChanged()
{
	if(!isUiInitialized()){
		return;
	}

	const QList<Bookmark>& bookmarks = m->bookmarks->bookmarks();

	disconnect(ui->cb_bookmarks, combo_current_index_changed_int, this, &GUI_Bookmarks::currentIndexChanged);

	ui->cb_bookmarks->clear();
	for(const Bookmark& bookmark : bookmarks)
	{
		ui->cb_bookmarks->addItem(bookmark.name(), int(bookmark.timestamp()));
	}

	if(bookmarks.isEmpty()) {
		ui->cb_bookmarks->addItem(tr("No bookmarks found"), -1);
	}

	MetaData md = m->bookmarks->metadata();

	ui->btn_tool->showAction(ContextMenu::EntryNew, (md.id() >= 0) );
	ui->btn_tool->showAction(ContextMenu::EntryDelete, !bookmarks.isEmpty() );

	if(md.id() >= 0 && bookmarks.size() > 0){
		ui->controls->show();
	}

	else{
		ui->controls->hide();
	}

	connect(ui->cb_bookmarks, combo_current_index_changed_int, this, &GUI_Bookmarks::currentIndexChanged);
}


void GUI_Bookmarks::disablePrevious()
{
	if(!isUiInitialized()){
		return;
	}

	ui->btn_prev->setEnabled( false );
	ui->btn_prev->setText( NoBookmarkText );
}


void GUI_Bookmarks::disableNext()
{
	if(!isUiInitialized()){
		return;
	}

	ui->btn_next->setEnabled(false);
	ui->btn_next->setText( NoBookmarkText );
}


void GUI_Bookmarks::previousChanged(const Bookmark& bookmark)
{
	if(!isUiInitialized())
	{
		return;
	}

	ui->btn_prev->setEnabled( bookmark.isValid() );
	ui->cb_loop->setEnabled( ui->btn_next->isEnabled() );

	if( !bookmark.isValid() )
	{
		disablePrevious();
		return;
	}

	ui->btn_prev->setText(Util::msToString(bookmark.timestamp() * 1000, "$M:$S"));
}


void GUI_Bookmarks::nextChanged(const Bookmark& bookmark)
{
	if(!isUiInitialized()){
		return;
	}

	ui->btn_next->setEnabled( bookmark.isValid() );
	ui->cb_loop->setEnabled( ui->btn_next->isEnabled() );

	if( !bookmark.isValid() ){
		disableNext();
		return;
	}

	ui->btn_next->setText(Util::msToString(bookmark.timestamp() * 1000, "$M:$S"));
}


void GUI_Bookmarks::currentIndexChanged(int cur_idx)
{
	ui->btn_tool->showAction(ContextMenu::EntryDelete, (cur_idx >= 0));

	int data = ui->cb_bookmarks->itemData(cur_idx).toInt();
	if(data < 0){
		return;
	}

	if(cur_idx >= 0)
	{
		m->bookmarks->jumpTo(cur_idx);
	}
}


void GUI_Bookmarks::nextClicked()
{
	m->bookmarks->jumpNext();
}


void GUI_Bookmarks::previousClicked()
{
	m->bookmarks->jumpPrevious();
}


void GUI_Bookmarks::loopToggled(bool b)
{
	bool success = m->bookmarks->setLoop(b);
	if(!success){
		ui->cb_loop->setChecked(success);
	}
}


void GUI_Bookmarks::newClicked()
{
	Bookmarks::CreationStatus status = m->bookmarks->create();
	if( status == Bookmarks::CreationStatus::NoDBTrack )
	{
		Message::warning(tr("Sorry, bookmarks can only be set for library tracks at the moment."),
						Lang::get(Lang::Bookmarks));
	}
}


void GUI_Bookmarks::deleteClicked()
{
	int idx = ui->cb_bookmarks->currentIndex();
	m->bookmarks->remove(idx);
}
