//
// C++ Implementation: referencefieldsdialog
//
// Description:
//
//
// Author: Thach Nguyen <thach.nguyen@rmit.edu.au>, (C) 2007
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "referencefieldsdialog.h"

#include <klocale.h>
#include <kcombobox.h>
#include <klineedit.h>
#include <kiconloader.h>
#include <kmessagebox.h>
#include <kpushbutton.h>
#include <kaccelmanager.h>

#include <qgroupbox.h>
#include <qlayout.h>
#include <qhbox.h>
#include <qvbox.h>
#include <qlabel.h>
#include <qbuttongroup.h>
#include <qcheckbox.h>
#include <qwhatsthis.h>

ReferenceFieldsDialog::ReferenceFieldsDialog (QWidget *parent, const char *name )
		: KDialogBase ( parent, name, false, i18n ( "Reference Fields" ), Ok|Cancel, Ok, false )
{
	QWidget* page = new QWidget ( this );
	setMainWidget ( page );
	QHBoxLayout* topLayout = new QHBoxLayout ( page, 0, KDialog::spacingHint() );

	QGroupBox* fieldsGroup = new QGroupBox ( 1, Qt::Horizontal, i18n ( "Existing Fields" ), page );
	topLayout->addWidget ( fieldsGroup, 1 );
	m_fieldsBox = new QListBox ( fieldsGroup );
	m_fieldsBox->setMinimumWidth ( 150 );

	connect(m_fieldsBox, SIGNAL(highlighted(int)), SLOT(slotHighlightedChanged(int)));
	
	QHBox* hb1 = new QHBox ( fieldsGroup );
	hb1->setSpacing ( KDialog::spacingHint() );
	KPushButton *m_btnNew = new KPushButton ( i18n ( "New Field", "&New" ), hb1 );
	m_btnNew->setIconSet ( BarIcon ( QString::fromLatin1 ( "filenew" ), KIcon::SizeSmall ) );
	QWhatsThis::add ( m_btnNew, i18n ( "Add a new field" ) );
	m_btnDelete = new KPushButton ( i18n ( "Delete Field", "&Delete" ), hb1 );
	m_btnDelete->setIconSet ( BarIconSet ( QString::fromLatin1 ( "editdelete" ), KIcon::SizeSmall ) );
	QWhatsThis::add ( m_btnDelete, i18n ( "Remove the selected field" ) );
	m_btnDelete->setEnabled(false);
	connect(m_btnNew, SIGNAL(clicked()), SLOT(slotNewField()) );
	connect(m_btnDelete, SIGNAL(clicked()), SLOT(slotDeleteField()) );
	
	QGroupBox* propertiesGroup = new QGroupBox ( 1, Qt::Horizontal, i18n ( "Field Properties" ), page );
	topLayout->addWidget ( propertiesGroup, 1 );
	
	QHBox* hb2 = new QHBox ( propertiesGroup );
	hb2->setSpacing ( KDialog::spacingHint() );
	
	QLabel* label = new QLabel(i18n("Name:"), hb2);
	m_nameEdit = new KLineEdit(hb2);
	label->setBuddy(m_nameEdit);
 	QString st = i18n("The title of the field");
    QWhatsThis::add(label, st);
	QWhatsThis::add(m_nameEdit, st);
	
	QHBox* hb3 = new QHBox ( propertiesGroup );
	hb3->setSpacing ( KDialog::spacingHint() );
	label = new QLabel(i18n("Type:"), hb3);
	m_typeCombo = new KComboBox(hb3);
	label->setBuddy(m_typeCombo);
 	st = i18n("The type of the field");
    QWhatsThis::add(label, st);
	QWhatsThis::add(m_typeCombo, st);
	
	connect(m_typeCombo, SIGNAL(activated(int)), SLOT(slotTypeChanged(int)) );

	m_typeCombo->insertItem (QString::fromLatin1("Simple Text"));
	m_typeCombo->insertItem (QString::fromLatin1("Paragraph"));
	m_typeCombo->insertItem (QString::fromLatin1("Multiple Value"));
	m_typeCombo->insertItem (QString::fromLatin1("Number"));
	m_typeCombo->insertItem (QString::fromLatin1("URL"));
	m_typeCombo->insertItem (QString::fromLatin1("Month"));
	m_typeCombo->setCurrentItem(0);	
	
	QHBox* hb4 = new QHBox ( propertiesGroup );
	hb4->setSpacing ( KDialog::spacingHint() );
	m_multipleEditLabel = new QLabel(i18n("Connecting string:"), hb4);
	m_multipleEdit = new KLineEdit(hb4);
	m_multipleEditLabel->setBuddy(m_multipleEdit);
	st = i18n("The string used to connect values of a multiple value field into a complete field value, e.g., the author field uses the string \"and\" to connect multiple authors.");
	
	QWhatsThis::add(m_multipleEditLabel, st);
	QWhatsThis::add(m_multipleEdit, st);
	
	m_autoCompletion = new QCheckBox(i18n("Allow field auto-completion"), propertiesGroup);
	QWhatsThis::add(m_autoCompletion, i18n("If checked, KDE auto-completion will be enabled in the text edit box for this field."));
	m_allowGrouping = new QCheckBox(i18n("Allow grouping"), propertiesGroup);
	QWhatsThis::add(m_allowGrouping, i18n("If checked, this field may be used to group the entries in the group view."));
	
	KAcceleratorManager::manage(page);
	
	//Add field name to table and make a copy of the field table
	refFieldTab.setAutoDelete(true);
	refFieldTab.clear();
	
	RefField *field;
	
	QStringList fieldNameTab = BibEntryDefTable::self()->getFieldNames();
	for (QStringList::Iterator it = fieldNameTab.begin(); it != fieldNameTab.end(); ++it){
		field = BibEntryDefTable::self()->getRefField(*it);
		
		RefField *thisField = new RefField;
		thisField->name = field->name;
		thisField->type = field->type;
		thisField->connectingString = field->connectingString;
		thisField->autoCompletion = field->autoCompletion;
		thisField->allowGrouping = field->allowGrouping;
		
		m_fieldsBox->insertItem(thisField->name);
		refFieldTab.insert(thisField->name, thisField);
		
	}
	slotTypeChanged(m_typeCombo->currentItem());
	newFieldCnt = 1;
	prevIndex = -1;
}


ReferenceFieldsDialog::~ReferenceFieldsDialog()
{
	refFieldTab.setAutoDelete(true);
	refFieldTab.clear();
}


void ReferenceFieldsDialog::slotHighlightedChanged(int index){
	//Update the current field
	if (!updateField() )
		return;
	m_fieldsBox->blockSignals(true);
	m_fieldsBox->setSelected(index, true);
	m_fieldsBox->blockSignals(false);
	
	RefField *field;
	if (index >= 0 && index < m_fieldsBox->count() ){
		field = refFieldTab[m_fieldsBox->text(index)];
		m_nameEdit->setText(field->name);
		m_typeCombo->setCurrentItem(field->type);
		m_multipleEdit->setText(field->connectingString);
		m_autoCompletion->setChecked(field->autoCompletion);
		m_allowGrouping->setChecked(field->allowGrouping);
		prevIndex = index;
		prevName = field->name;
		m_btnDelete->setEnabled(true);
	}
	else{
		m_nameEdit->clear();
		m_typeCombo->setCurrentItem(0);
		m_multipleEdit->clear();
		m_autoCompletion->setChecked(false);
		m_allowGrouping->setChecked(false);
		m_btnDelete->setEnabled(false);
	}
	slotTypeChanged(m_typeCombo->currentItem());
}


void ReferenceFieldsDialog::slotTypeChanged(int type){
	if (type == MULTIPLE){
		m_multipleEditLabel->setEnabled(true);
		m_multipleEdit->setEnabled(true);
	}
	else {
		m_multipleEditLabel->setEnabled(false);
		m_multipleEdit->setEnabled(false);	
	}
	
	if (type == URL || type == PARAGRAPH || type == NUMBER || type == MONTH){
		m_autoCompletion->setEnabled(false);	
	}
	else
		m_autoCompletion->setEnabled(true);	
	
	
}
		
void ReferenceFieldsDialog::slotNewField(){
	if (!updateField())
		return;
	RefField *thisField = new RefField;
	QString name=i18n("NewField") + QString::fromLatin1("%1").arg(newFieldCnt);
	
	while(refFieldTab[name]){
		newFieldCnt++;	
		name = i18n("NewField") + QString::fromLatin1("%1").arg(newFieldCnt);
	}
	
	
	
	
	thisField->name = name;
	thisField->type = TEXT;
	thisField->connectingString = QString::fromLatin1("");
	thisField->autoCompletion =false;
	thisField->allowGrouping = false;
	
	refFieldTab.insert(thisField->name, thisField);
	m_fieldsBox->insertItem(thisField->name);

  
	m_fieldsBox->setSelected(m_fieldsBox->count()-1, true);
	newFieldCnt++;
	
	m_fieldsBox->ensureCurrentVisible();
  	m_nameEdit->setFocus();
  	m_nameEdit->selectAll();
	
}

void ReferenceFieldsDialog::slotDeleteField(){
	int index = m_fieldsBox->currentItem();
	if (index < 0)
		return;
	m_fieldsBox->blockSignals(true);
	m_fieldsBox->removeItem(index);
	refFieldTab.remove(m_fieldsBox->text(index));
	prevIndex = -1;
	prevName = QString();
	m_fieldsBox->blockSignals(false);
	slotHighlightedChanged(-1);
}
		
bool ReferenceFieldsDialog::checkField(){

	
	//Check for empty name
	QString name = m_nameEdit->text().stripWhiteSpace();
	if (name.isEmpty()){
		KMessageBox::sorry(this, i18n("The field name cannot be empty."));
			return false;	
	}
	
	RefField *field;
	int index = 0;
    for (int i = 0; i < m_fieldsBox->count(); i++ ){
		QString xname = 	m_fieldsBox->text(i);
		if (name.lower() == xname.lower() && index != prevIndex){
			KMessageBox::sorry(this, i18n("A field with name \"%1\" already exists. Please enter a different name.").arg(name));
			return false;
		}
		index++;
	}
	//Check for valid name
	QChar c = name.at(0);
	if (!c.isLetter()){
		KMessageBox::sorry(this, i18n("The field name must start with a letter."));
			return false;		
	}
	
	if (name.contains(' ') ){
		KMessageBox::sorry(this, i18n("The field name cannot contain white spaces."));
			return false;		 
	}
	
	
	
	return true;
}

bool ReferenceFieldsDialog::updateField(){
	//Update the current field
	RefField *field;
	if (prevIndex >= 0 && prevIndex < m_fieldsBox->count()){
		//Check for existing name
		if (!checkField()){
			m_fieldsBox->blockSignals(true);
			m_fieldsBox->setSelected(prevIndex, true);
			m_fieldsBox->blockSignals(false);
			return false;
		}
		else{
			if ( refFieldTab.find( prevName ) )
            	refFieldTab.remove( prevName );
			field = new RefField;
			field->name = (m_nameEdit->text()).stripWhiteSpace();
			field->type = m_typeCombo->currentItem();
			field->connectingString = m_multipleEdit->text();
			field->autoCompletion = m_autoCompletion->isChecked();
			field->allowGrouping = m_allowGrouping->isChecked();
			
			refFieldTab.insert(field->name, field);
			
			m_fieldsBox->blockSignals(true);
			m_fieldsBox->changeItem(m_nameEdit->text(), prevIndex);
			m_fieldsBox->blockSignals(false);
			return true;
		}
			
	}
	return true;
}

void ReferenceFieldsDialog::slotOk(){
	if (!updateField())
		return;
	
	BibEntryDefTable::self()->clearRefFields();
	QString name;
	RefField *field;
	for (int i = 0; i < m_fieldsBox->count(); i++){
		name = m_fieldsBox->text(i);
		field = refFieldTab[name];
		BibEntryDefTable::self()->newRefField(name,field->type, field->connectingString, field->autoCompletion, field->allowGrouping, true);
	}
		
	accept();
}

#include "referencefieldsdialog.moc"
