/***************************************************************************
 *   Copyright (C) 2004 by Jens Dagerbo                                    *
 *   jens.dagerbo@swipnet.se                                               *
 *                                                                         *
 *   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 <tqtimer.h>
#include <tqlabel.h>
#include <tqfileinfo.h>
#include <tqdatetime.h>
#include <tqfocusdata.h>

#include <klineedit.h>
#include <tdelistview.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <kurl.h>
#include <tdeapplication.h>

#include <kdevproject.h>
#include <kdevpartcontroller.h>

#include "ctags2_widget.h"
#include "tags.h"

class TagItem : public TQListViewItem
{
public:
    TagItem(TQListView * lv, TQString const & tag, TQString const & type, TQString const & file, TQString const & pattern );

	TQString tag;
	TQString type;
	TQString file;
	TQString pattern;
};

TagItem::TagItem( TQListView * lv, TQString const & tag, TQString const & type, TQString const & file, TQString const & pattern )
	: TQListViewItem( lv, tag, type, file ), tag(tag), type(type), file(file), pattern(pattern)
{
}

CTags2Widget::CTags2Widget( CTags2Part * part, const char* name, WFlags fl)
: CTags2WidgetBase(0,name,fl), _part(part)
{
    output_view->setColumnWidthMode(0,TQListView::Maximum);
	output_view->setColumnWidthMode(1,TQListView::Maximum);
	output_view->setColumnWidthMode(2,TQListView::Maximum);

	_typeTimeout = new TQTimer( this );
	connect( _typeTimeout, TQ_SIGNAL(timeout()), this, TQ_SLOT(line_edit_changed()) );

	connect( output_view, TQ_SIGNAL(executed(TQListViewItem*)), this, TQ_SLOT(itemExecuted(TQListViewItem*)) );
	connect( output_view, TQ_SIGNAL(returnPressed(TQListViewItem*)), this, TQ_SLOT(itemExecuted(TQListViewItem*)) );

	updateDBDateLabel();
}

CTags2Widget::~CTags2Widget()
{
}

void CTags2Widget::displayHits( Tags::TagList const & list )
{
	output_view->clear();
	showHitCount( list.count() );

	Tags::TagList::ConstIterator it = list.begin();
	while( it != list.end() )
	{
		new TagItem( output_view, (*it).tag, (*it).type, (*it).file, (*it).pattern );
		++it;
	}

	output_view->adjustColumn(0);
	output_view->adjustColumn(1);
	output_view->adjustColumn(2);

}

void CTags2Widget::displayHitsAndClear( Tags::TagList const & list )
{
	input_edit->blockSignals( true );
	input_edit->clear();
	input_edit->blockSignals( false );

	displayHits( list );
}

void CTags2Widget::line_edit_changed( )
{
	displayHits( Tags::getPartialMatches( input_edit->text() ) );
}

void CTags2Widget::line_edit_changed_delayed( )
{
	showHitCount( calculateHitCount() );
	_typeTimeout->start( 500, true );
}

void CTags2Widget::showHitCount( int n )
{
	hitcount_label->setText( i18n("Hits: %1").arg( n ) );
}

int CTags2Widget::calculateHitCount( )
{
	return Tags::numberOfPartialMatches( input_edit->text() ) ;
}

void CTags2Widget::itemExecuted( TQListViewItem * item )
{
	TagItem * tagItem = static_cast<TagItem*>( item );

	KURL url;
	TQString fileWithTagInside;
	// assume relative path to project directory if path does not start with slash
	if (tagItem->file[0] != '/') {
		fileWithTagInside = _part->project()->projectDirectory() + "/" + tagItem->file;
	}
	else {
		fileWithTagInside = tagItem->file;
	}

	url.setPath(fileWithTagInside);

	_part->partController()->editDocument( url, _part->getFileLineFromPattern( url, tagItem->pattern ) );
}

void CTags2Widget::regeneratebutton_clicked()
{
	TQApplication::setOverrideCursor(TQt::waitCursor);

	_part->createTagsFile();

	TQApplication::restoreOverrideCursor();

	updateDBDateLabel();
}

void CTags2Widget::updateDBDateLabel( )
{
	TQStringList tagFiles = Tags::getTagFiles();
	TQFileInfo tagsdb(tagFiles[0]);
	if ( tagsdb.exists() )
	{
		datetime_label->setText( tagsdb.created().date().toString( TQt::ISODate ) );
	}
	else
	{
		datetime_label->setText( i18n("No CTags database found") );
	}
}

void CTags2Widget::focusInEvent( TQFocusEvent* )
{
	updateDBDateLabel();
	input_edit->setFocus();
}

void CTags2Widget::goToNext( )
{
	TQListViewItem * item = output_view->firstChild();
	while( item )
	{
		if ( item->isSelected() )
		{
			// found the current, take the next
			item->setSelected( false );
			if ( (item = item->nextSibling()) != NULL )
			{
				item->setSelected( true );
				output_view->repaint( true );
				itemExecuted( item );
				return;
			}
			else
			{
				break;
			}
		}
		item = item->nextSibling();
	}
	// use the first
	if ( (item = output_view->firstChild()) != NULL )
	{
		item->setSelected( true );
		itemExecuted( item );
	}
}

#include "ctags2_widget.moc"
