/***************************************************************************
    begin                : Feb 24 2007
    copyright            : 2007 by Holger Danielsson
    email                : holger.danielsson@versanet.de
***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "kileabbrevview.h"

#include <klistview.h>
#include <klocale.h>
#include <kmessagebox.h>
#include "kiledebug.h"

#include <tqheader.h>
#include <tqlayout.h>
#include <tqregexp.h>
#include <tqvalidator.h>
#include <tqfile.h>

KileAbbrevView::KileAbbrevView(TQWidget *parent, const char *name) 
	: KListView(parent, name), m_changes(false)
{

	addColumn(i18n("Short"));
	addColumn(TQString());
	addColumn(i18n("Expanded Text"));
	setAllColumnsShowFocus(true);
	setFullWidth(true);

	setItemsMovable(false);                 // default: true
	//setAcceptDrops(false);                // default: false
	//setDragEnabled(false);                // default: false
	//setShadeSortColumn(true);             // default: true
	header()->setMovingEnabled(false);      // default: true

	m_popup = new TQPopupMenu( this );

	connect(this, TQT_SIGNAL(mouseButtonClicked(int,TQListViewItem *,const TQPoint &,int)),
	        this, TQT_SLOT(slotMouseButtonClicked(int,TQListViewItem *,const TQPoint &,int)));

	connect(this, TQT_SIGNAL(contextMenu(KListView *,TQListViewItem *,const TQPoint &)),
	        this, TQT_SLOT(slotContextMenu(KListView *,TQListViewItem *,const TQPoint &)));
}

KileAbbrevView::~KileAbbrevView()
{
}
//////////////////// init abbreviation view with wordlists ////////////////////


void KileAbbrevView::init(const TQStringList *globallist, const TQStringList *locallist)
{
	setUpdatesEnabled(false);
	clear();
	addWordlist(globallist,true);
	addWordlist(locallist,false);
	setUpdatesEnabled(true);

	m_changes = false;
}

void KileAbbrevView::addWordlist(const TQStringList *wordlist, bool global)
{
	TQString type = ( global ) ? TQString() : "*";

	TQStringList::ConstIterator it;
	for ( it=wordlist->begin(); it!=wordlist->end(); ++it ) 
	{
		int index = (*it).find( '=' );
		if ( index >= 0 )
		{
			insertItem( new KListViewItem(this,(*it).left(index),type,(*it).right( (*it).length()-index-1 )) ); 
		}
	}
}

//////////////////// save local abbreviation list ////////////////////

void KileAbbrevView::saveLocalAbbreviation(const TQString &filename)
{
	if ( ! m_changes )
		return;

	KILE_DEBUG() << "=== KileAbbrevView::saveLocalAbbreviation ===================" << endl;
	// create the file 
	TQFile abbrevfile(filename);
	if ( ! abbrevfile.open( IO_WriteOnly ) ) 
		return;

	TQTextStream stream( &abbrevfile );
	stream << "# abbreviation mode: editable abbreviations\n";
	stream << "# dani/2007\n";

	//TQTextCodec *codec = TQTextCodec::codecForName(m_ki->activeTextDocument()->encoding().ascii());
	// stream.setCodec(codec); 

	TQListViewItemIterator it( this );
	while ( it.current() ) 
	{
		if ( it.current()->text(KileAbbrevView::ALVlocal) == "*" )
		{
			stream << it.current()->text(KileAbbrevView::ALVabbrev) 
			       << "=" 
			       << it.current()->text(KileAbbrevView::ALVexpansion)
			       << "\n";
		}
		++it;
	}
	abbrevfile.close();

	m_changes = false;
}

//////////////////// find abbreviation ////////////////////

bool KileAbbrevView::findAbbreviation(const TQString &abbrev)
{
	TQListViewItemIterator it( this );
	while ( it.current() ) 
	{
		if ( it.current()->text(KileAbbrevView::ALVabbrev) == abbrev )
			return true;
 
		++it;
	}
	return false;
}

//////////////////// item clicked ////////////////////

void KileAbbrevView::slotMouseButtonClicked(int button, TQListViewItem *item, const TQPoint &, int)
{
	if ( button==1 && item )
	{
		emit( sendText( item->text(KileAbbrevView::ALVexpansion) ) );
	}
}

//////////////////// context menu ////////////////////

void KileAbbrevView::slotContextMenu(KListView *, TQListViewItem *item, const TQPoint &pos)
{
	m_popup->clear();
	m_popup->disconnect();

	m_popup->insertItem(i18n("&Add"),ALVadd);
	if ( item && item->text(ALVlocal)== "*" )
	{
		m_popup->insertSeparator();
		m_popup->insertItem(i18n("&Edit"),ALVedit);
		m_popup->insertSeparator();
		m_popup->insertItem(i18n("&Delete"),ALVdelete);
	}
	
	connect(m_popup,  TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotPopupAbbreviation(int)));

	// show context menu
	m_popup->exec(pos);
}

void KileAbbrevView::addAbbreviation(const TQString &abbrev, const TQString &expansion)
{
	insertItem( new KListViewItem(this,abbrev,"*",expansion) ); 
	TQString newAbbrev = abbrev + '=' + expansion;

	emit( updateAbbrevList(TQString(),newAbbrev) );
	m_changes = true;
}

void KileAbbrevView::changeAbbreviation(KListViewItem *item, const TQString &abbrev, const TQString &expansion)
{
	if ( item )
	{
		TQString oldAbbrev = item->text(ALVabbrev) + '=' + item->text(ALVexpansion);
		TQString newAbbrev = abbrev + '=' + expansion;
		item->setText(ALVabbrev,abbrev);
		item->setText(ALVexpansion,expansion);

		emit( updateAbbrevList(oldAbbrev,newAbbrev) );
		m_changes = true;
	}
}

void KileAbbrevView::deleteAbbreviation(KListViewItem *item)
{
	TQString abbrev = item->text(ALVabbrev);
	TQString message = i18n("Delete the abbreviation '%1'?").arg(abbrev);
	if ( KMessageBox::questionYesNo( this,
		       "<center>" + message + "</center>",
		       i18n("Delete Abbreviation") ) == KMessageBox::Yes ) 
	{
		TQString s = item->text(ALVabbrev) + '=' + item->text(ALVexpansion);
		delete item;

		emit( updateAbbrevList(s,TQString()) );
		m_changes = true;
	}
}

void KileAbbrevView::slotPopupAbbreviation(int id)
{
	KListViewItem *item = (KListViewItem *)selectedItem();

	int mode = ALVnone;
	if ( id == ALVadd )
		mode = ALVadd;
	else if ( id==ALVedit && item )
		mode = ALVedit;
	else if ( id==ALVdelete && item ) 
		deleteAbbreviation(item);
	
	if ( mode != ALVnone )
	{
		KileAbbrevInputDialog *dialog = new KileAbbrevInputDialog(this,item,mode);
		if ( dialog->exec() == TQDialog::Accepted )
		{
			TQString abbrev,expansion;
			dialog->abbreviation(abbrev,expansion);
			if ( mode == ALVadd )
				addAbbreviation(abbrev,expansion);
			else
				changeAbbreviation(item,abbrev,expansion);
		}
		delete dialog;
	}
}

//////////////////// add/edit abbreviation ////////////////////

KileAbbrevInputDialog::KileAbbrevInputDialog(KileAbbrevView *listview, KListViewItem *item, int mode, const char *name )
	: KDialogBase(listview,name, true, i18n("Add Abbreviation"), KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true),
	  m_listview(listview), m_abbrevItem(item), m_mode(mode)
{
	TQWidget *page = new TQWidget(this);
	setMainWidget(page);
	TQVBoxLayout *vl = new TQVBoxLayout(page, 0, spacingHint());

	if ( m_mode == KileAbbrevView::ALVedit )
	{
		setCaption( i18n("Edit Abbreviation") );
		m_abbrev = m_abbrevItem->text(KileAbbrevView::ALVabbrev);
		m_expansion = m_abbrevItem->text(KileAbbrevView::ALVexpansion);
	}
	
	TQLabel *abbrev = new TQLabel(i18n("&Abbreviation:"),page);
	TQLabel *expansion = new TQLabel(i18n("&Expanded Text:"),page);
	m_leAbbrev = new KLineEdit(m_abbrev,page);
	m_leExpansion = new KLineEdit(m_expansion,page);

	vl->addWidget(abbrev);
	vl->addWidget(m_leAbbrev);
	vl->addWidget(expansion);
	vl->addWidget(m_leExpansion);
	vl->addSpacing(8);

	abbrev->setBuddy(m_leAbbrev);
	expansion->setBuddy(m_leExpansion);

	TQRegExp reg("[a-zA-Z0-9]+");
	TQRegExpValidator *abbrevValidator = new TQRegExpValidator(reg,TQT_TQOBJECT(this));
	m_leAbbrev->setValidator(abbrevValidator);

	connect(m_leAbbrev,TQT_SIGNAL(textChanged(const TQString &)),
	        this,TQT_SLOT(slotTextChanged(const TQString &)));
	connect(m_leExpansion,TQT_SIGNAL(textChanged(const TQString &)),
	        this,TQT_SLOT(slotTextChanged(const TQString &)));

	slotTextChanged(TQString());
	m_leAbbrev->setFocus();
	page->setMinimumWidth(350);
}

KileAbbrevInputDialog::~KileAbbrevInputDialog()
{
}

void KileAbbrevInputDialog::abbreviation(TQString &abbrev, TQString &expansion)
{
	abbrev = m_leAbbrev->text(); 
	expansion = m_leExpansion->text().stripWhiteSpace();
}

void KileAbbrevInputDialog::slotTextChanged(const TQString &)
{
	bool state = ( m_mode == KileAbbrevView::ALVadd )
	           ? ! m_listview->findAbbreviation( m_leAbbrev->text() ) : true;
 	state = state && !m_leAbbrev->text().isEmpty() && !m_leExpansion->text().isEmpty();

	enableButton(KDialogBase::Ok,state);
}

void KileAbbrevInputDialog::slotOk()
{
	TQString abbrev = m_leAbbrev->text();
	TQString expansion = m_leExpansion->text().stripWhiteSpace();

	if ( abbrev.isEmpty() || expansion.isEmpty() )
	{
		KMessageBox::error( this, i18n("Empty strings are not allowed.") );
		return;
	}

	if ( abbrev!=m_abbrev || expansion!=m_expansion )
		accept();
	else
		reject();
}


#include "kileabbrevview.moc"
