/**
 * \file QBibtex.C
 * This file is part of LyX, the document processor.
 * Licence details can be found in the file COPYING.
 *
 * \author John Levon
 * \author Herbert Voß
 * \author Jürgen Spitzmüller
 *
 * Full author contact details are available in file CREDITS.
 */

#include <config.h>

#include "QBibtex.h"
#include "QBibtexDialog.h"
#include "ui/QBibtexAddDialogBase.h"
#include "Qt2BC.h"
#include "qt_helpers.h"
#include "validators.h"

#include "lyxrc.h"

#include "controllers/ControlBibtex.h"

#include "support/filetools.h" // ChangeExtension
#include "support/lstrings.h"

#include <qcombobox.h>
#include <qpushbutton.h>
#include <qlistbox.h>
#include <qcheckbox.h>


using lyx::support::ChangeExtension;
using lyx::support::split;
using lyx::support::trim;

using std::vector;
using std::string;

namespace lyx {
namespace frontend {

typedef QController<ControlBibtex, QView<QBibtexDialog> > base_class;

QBibtex::QBibtex(Dialog & parent)
	: base_class(parent, _("BibTeX Bibliography"))
{
}


void QBibtex::build_dialog()
{
	dialog_.reset(new QBibtexDialog(this));

	bcview().setOK(dialog_->okPB);
	bcview().setCancel(dialog_->closePB);
	bcview().addReadOnly(dialog_->databaseLB);
	bcview().addReadOnly(dialog_->stylePB);
	bcview().addReadOnly(dialog_->styleCB);
	bcview().addReadOnly(dialog_->bibtocCB);
	bcview().addReadOnly(dialog_->addBibPB);
	bcview().addReadOnly(dialog_->deletePB);
}


void QBibtex::update_contents()
{
	PathValidator * path_validator =
		getPathValidator(dialog_->add_->bibED);
	if (path_validator)
		path_validator->setChecker(kernel().docType(), lyxrc);

	bool bibtopic = controller().usingBibtopic();

	dialog_->databaseLB->clear();

	string bibs(controller().params().getContents());
	string bib;

	while (!bibs.empty()) {
		bibs = split(bibs, bib, ',');
		bib = trim(bib);
		if (!bib.empty())
			dialog_->databaseLB->insertItem(toqstr(bib));
	}

	dialog_->add_->bibLB->clear();

	vector<string> bib_str;
	controller().getBibFiles(bib_str);
	for (vector<string>::const_iterator it = bib_str.begin();
		it != bib_str.end(); ++it) {
		string bibItem(ChangeExtension(*it, ""));
		dialog_->add_->bibLB->insertItem(toqstr(bibItem));
	}

	dialog_->bibtocCB->setChecked(controller().bibtotoc() && !bibtopic);
	dialog_->bibtocCB->setEnabled(!bibtopic);

	string btprint(controller().params().getSecOptions());
	int btp = 0;
	if (btprint == "btPrintNotCited")
		btp = 1;
	else if (btprint == "btPrintAll")
		btp = 2;

	dialog_->btPrintCO->setCurrentItem(btp);
	dialog_->btPrintCO->setEnabled(bibtopic);

	dialog_->styleCB->clear();

	int item_nr(-1);
	string bibstyle(controller().getStylefile());

	vector<string> str;
	controller().getBibStyles(str);
	for (vector<string>::const_iterator it = str.begin();
		it != str.end(); ++it) {
		string item(ChangeExtension(*it, ""));
		if (item == bibstyle)
			item_nr = int(it - str.begin());
		dialog_->styleCB->insertItem(toqstr(item));
	}

	if (item_nr == -1 && !bibstyle.empty()) {
		dialog_->styleCB->insertItem(toqstr(bibstyle));
		item_nr = dialog_->styleCB->count() - 1;
	}

	if (item_nr != -1)
		dialog_->styleCB->setCurrentItem(item_nr);
	else
		dialog_->styleCB->clearEdit();
}


void QBibtex::apply()
{
	string dbs(fromqstr(dialog_->databaseLB->text(0)));

	unsigned int maxCount = dialog_->databaseLB->count();
	for (unsigned int i = 1; i < maxCount; i++) {
		dbs += ',';
		dbs += fromqstr(dialog_->databaseLB->text(i));
	}

	controller().params().setContents(dbs);

	string const bibstyle(fromqstr(dialog_->styleCB->currentText()));
	bool const bibtotoc(dialog_->bibtocCB->isChecked());

	if (bibtotoc && (!bibstyle.empty())) {
		// both bibtotoc and style
		controller().params().setOptions("bibtotoc," + bibstyle);
	} else if (bibtotoc) {
		// bibtotoc and no style
		controller().params().setOptions("bibtotoc");
	} else {
		// only style. An empty one is valid, because some
		// documentclasses have an own \bibliographystyle{}
		// command!
		controller().params().setOptions(bibstyle);
	}

	// bibtopic allows three kinds of sections:
	// 1. sections that include all cited references of the database(s)
	// 2. sections that include all uncited references of the database(s)
	// 3. sections that include all references of the database(s), cited or not
	int btp = dialog_->btPrintCO->currentItem();

	switch (btp) {
	case 0:
		controller().params().setSecOptions("btPrintCited");
		break;
	case 1:
		controller().params().setSecOptions("btPrintNotCited");
		break;
	case 2:
		controller().params().setSecOptions("btPrintAll");
		break;
	}

	if (!controller().usingBibtopic())
		controller().params().setSecOptions("");
}


bool QBibtex::isValid()
{
	return dialog_->databaseLB->count() != 0;
}

} // namespace frontend
} // namespace lyx
