/*********
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
* Copyright 1999-2006 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/



//BibleTime includes
#include "cmainindex.h"
#include "cindexitem.h"

#include "backend/creferencemanager.h"
#include "backend/cswordmoduleinfo.h"

#include "frontend/searchdialog/csearchdialog.h"
#include "frontend/cbtconfig.h"
#include "frontend/cdragdropmgr.h"
#include "frontend/cinfodisplay.h"

#include "frontend/cprinter.h"

#include "util/cresmgr.h"
#include "util/scoped_resource.h"

//TQt includes
#include <tqheader.h>
#include <tqlistview.h>
#include <tqdragobject.h>
#include <tqinputdialog.h>
#include <tqregexp.h>

//TDE includes
#include <tdelocale.h>
#include <kstandarddirs.h>
#include <tdepopupmenu.h>
#include <tdemessagebox.h>
#include <tdeglobalsettings.h>

using namespace Printing;

CMainIndex::ToolTip::ToolTip(CMainIndex* parent) : TQToolTip(parent->viewport()), m_mainIndex(parent) {}

void CMainIndex::ToolTip::maybeTip(const TQPoint& p) {
	CItemBase* i = dynamic_cast<CItemBase*>(m_mainIndex->itemAt(p));
	Q_ASSERT(i);
	if ( !i ) {
		return;
	}

	TQRect r = m_mainIndex->itemRect(i);
	if (!r.isValid()) {
		return;
	}

	//get type of item and display correct text
	const TQString text = i->toolTip();
	if (!text.isEmpty()) {
		CBookmarkItem* bookmark = dynamic_cast<CBookmarkItem*>(i);
		if (bookmark) {
			(CPointers::infoDisplay())->setInfo(
				InfoDisplay::CInfoDisplay::CrossReference,
				bookmark->module()->name() + ":" + bookmark->key()
			);
		}
		else {
			CPointers::infoDisplay()->clearInfo();
		}

		tip(r, text);
	}
	else {
		CPointers::infoDisplay()->clearInfo();
	}
}

CMainIndex::CMainIndex(TQWidget *parent) : TDEListView(parent),
m_searchDialog(0), m_toolTip(0), m_itemsMovable(false), m_autoOpenFolder(0), m_autoOpenTimer(this) {
	initView();
	initConnections();
	//initTree() is called in polish()
}

CMainIndex::~CMainIndex() {
	saveSettings();
	saveBookmarks();

	m_toolTip->remove(this);
	delete m_toolTip;
}

/** Reimplementation. Adds the given group to the tree. */
void CMainIndex::addGroup(const CItemBase::Type type, const TQString language) {
	CTreeFolder *i = 0;
	switch (type) {
		case CItemBase::BookmarkFolder:
			i = new CBookmarkFolder(this);
			break;
		case CItemBase::GlossaryModuleFolder:
			//we have no second language
			i = new CGlossaryFolder(this, type, language, TQString()); 
			break;
		default:
			i = new CTreeFolder(this, type, language);
			break;
	}
	
	if (i) {
		i->init();
		if (i->childCount() == 0 && type != CItemBase::BookmarkFolder) {
			delete i;
		}
	}
}


/** Initializes the view. */
void CMainIndex::initView() {
	addColumn(TQString());
	header()->hide();

	m_toolTip = new ToolTip(this);
	setTooltipColumn(-1);
	//to disable TQt's tooltips
	setShowToolTips(false);

	setBackgroundMode(PaletteBase);
	setFullWidth(true);
	setFocusPolicy(TQWidget::WheelFocus);

	setAcceptDrops( true );
	setDragEnabled( true );
	setDropVisualizer( true );
	setDropHighlighter( true );
	setAutoOpen(true);
	viewport()->setAcceptDrops(true);
	setRootIsDecorated(false);
	setAllColumnsShowFocus(true);
	setItemsMovable(false);
	setSelectionModeExt(Extended);

	//setup the popup menu
	m_popup = new TDEPopupMenu(viewport());
	m_popup->insertTitle(i18n("Bookshelf"));

	m_actions.newFolder = new TDEAction(i18n("Create a new folder"), CResMgr::mainIndex::newFolder::icon, 0, this, TQ_SLOT(createNewFolder()), this);
	m_actions.changeFolder = new TDEAction(i18n("Change this folder"),CResMgr::mainIndex::changeFolder::icon, 0, this, TQ_SLOT(changeFolder()), this);

	m_actions.changeBookmark = new TDEAction(i18n("Change bookmark description"),CResMgr::mainIndex::changeBookmark::icon, 0, this, TQ_SLOT(changeBookmark()), this);
	m_actions.importBookmarks = new TDEAction(i18n("Import bookmarks"),CResMgr::mainIndex::importBookmarks::icon, 0, this, TQ_SLOT(importBookmarks()), this);
	m_actions.exportBookmarks = new TDEAction(i18n("Export bookmarks"),CResMgr::mainIndex::exportBookmarks::icon, 0, this, TQ_SLOT(exportBookmarks()), this);
	m_actions.printBookmarks = new TDEAction(i18n("Print bookmarks"),CResMgr::mainIndex::printBookmarks::icon, 0, this, TQ_SLOT(printBookmarks()), this);

	m_actions.deleteEntries = new TDEAction(i18n("Remove selected item(s)"),CResMgr::mainIndex::deleteItems::icon, 0, this, TQ_SLOT(deleteEntries()), this);

	m_actions.editModuleMenu = new TDEActionMenu(i18n("Edit this work"),CResMgr::mainIndex::editModuleMenu::icon, this);
	m_actions.editModuleMenu->setDelayed(false);
	m_actions.editModulePlain = new TDEAction(i18n("Plain text"),CResMgr::mainIndex::editModulePlain::icon, 0, this, TQ_SLOT(editModulePlain()), this);
	m_actions.editModuleHTML = new TDEAction(i18n("HTML"),CResMgr::mainIndex::editModuleHTML::icon, 0, this, TQ_SLOT(editModuleHTML()), this);
	
	m_actions.searchInModules = new TDEAction(i18n("Search in selected work(s)"),CResMgr::mainIndex::search::icon, 0, this, TQ_SLOT(searchInModules()), this);
	m_actions.unlockModule = new TDEAction(i18n("Unlock this work"),CResMgr::mainIndex::unlockModule::icon, 0, this, TQ_SLOT(unlockModule()), this);
	m_actions.aboutModule = new TDEAction(i18n("About this work"),CResMgr::mainIndex::aboutModule::icon, 0, this, TQ_SLOT(aboutModule()), this);


	//fill the popup menu itself
	m_actions.newFolder->plug(m_popup);
	m_actions.changeFolder->plug(m_popup);
	(new TDEActionSeparator(this))->plug(m_popup);
	m_actions.changeBookmark->plug(m_popup);
	m_actions.importBookmarks->plug(m_popup);
	m_actions.exportBookmarks->plug(m_popup);
	m_actions.printBookmarks->plug(m_popup);
	(new TDEActionSeparator(this))->plug(m_popup);
	m_actions.deleteEntries->plug(m_popup);
	(new TDEActionSeparator(this))->plug(m_popup);
	m_actions.editModuleMenu->plug(m_popup);
	//sub item of edit module menu
	m_actions.editModuleMenu->insert(m_actions.editModulePlain); 
	//sub item of edit module menu
	m_actions.editModuleMenu->insert(m_actions.editModuleHTML);  

	m_actions.searchInModules->plug(m_popup);
	m_actions.unlockModule->plug(m_popup);
	m_actions.aboutModule->plug(m_popup);
}

/** Initialize the signal<->slot connections */
void CMainIndex::initConnections() {
	connect(this, TQ_SIGNAL(executed(TQListViewItem*)),
			TQ_SLOT(slotExecuted(TQListViewItem*)));
	connect(this, TQ_SIGNAL(dropped(TQDropEvent*, TQListViewItem*, TQListViewItem*)),
			TQ_SLOT(dropped(TQDropEvent*, TQListViewItem*, TQListViewItem*)));
	connect(this, TQ_SIGNAL(contextMenu(TDEListView*, TQListViewItem*, const TQPoint&)),
			TQ_SLOT(contextMenu(TDEListView*, TQListViewItem*, const TQPoint&)));
	connect(&m_autoOpenTimer, TQ_SIGNAL(timeout()),
			this, TQ_SLOT(autoOpenTimeout()));
}

/** Is called when an item was clicked/double clicked. */
void CMainIndex::slotExecuted( TQListViewItem* i ) {
	CItemBase* ci = dynamic_cast<CItemBase*>(i);
	if (!ci) {
		return;
	}

	if (ci->isFolder()) {
		i->setOpen(!i->isOpen());
	}
	else if (CModuleItem* m = dynamic_cast<CModuleItem*>(i))  { //clicked on a module
		CSwordModuleInfo* mod = m->module();
		ListCSwordModuleInfo modules;
		modules.append(mod);
		emit createReadDisplayWindow(modules, TQString());
	}
	else if (CBookmarkItem* b = dynamic_cast<CBookmarkItem*>(i) ) { //clicked on a bookmark
		if (CSwordModuleInfo* mod = b->module()) {
			ListCSwordModuleInfo modules;
			modules.append(mod);
			emit createReadDisplayWindow(modules, b->key());
		}
	}
}

/** Reimplementation. Returns the drag object for the current selection. */
TQDragObject* CMainIndex::dragObject() {
	if (!m_itemsMovable) {
		return 0;
	}

	CDragDropMgr::ItemList dndItems;

	TQPtrList<TQListViewItem> items = selectedItems();
	for (items.first(); items.current(); items.next()) {
		if (CItemBase* i = dynamic_cast<CItemBase*>(items.current())) {
			//we can move this item!
			if (!i->isMovable()) { //we can only drag items which allow us to do it, e.g. which are movable
				continue;
			}

			if (CBookmarkItem* bookmark = dynamic_cast<CBookmarkItem*>( items.current() )) {
				//take care of bookmarks which have no valid module any more, e.g. if it was uninstalled
				const TQString moduleName = bookmark->module() ? bookmark->module()->name() : TQString();
				dndItems.append( CDragDropMgr::Item(moduleName, bookmark->key(), bookmark->description()) );
			}
		}
	}

	return CDragDropMgr::dragObject( dndItems, viewport() );
}

/** Reimplementation from TDEListView. Returns true if the drag is acceptable for the listview. */
bool CMainIndex::acceptDrag( TQDropEvent* event ) const {
	const TQPoint pos = contentsToViewport(event->pos());

	CItemBase* i = dynamic_cast<CItemBase*>(itemAt(pos));
	return i ? (i->acceptDrop(event) || i->isMovable()) : false;
}

/** No descriptions */
void CMainIndex::initTree() {
	addGroup(CItemBase::BookmarkFolder, TQString("*"));
	addGroup(CItemBase::BibleModuleFolder, TQString("*"));
	addGroup(CItemBase::BookModuleFolder, TQString("*"));
	addGroup(CItemBase::CommentaryModuleFolder, TQString("*"));
	addGroup(CItemBase::DevotionalModuleFolder, TQString("*"));
	addGroup(CItemBase::GlossaryModuleFolder, TQString("*"));
	addGroup(CItemBase::LexiconModuleFolder, TQString("*"));
}

/** No descriptions */
void CMainIndex::dropped( TQDropEvent* e, TQListViewItem* parent, TQListViewItem* after) {
	Q_ASSERT(after);
	Q_ASSERT(parent);

	//the drop was started in this main index widget
	if (m_itemsMovable && ((e->source()) == (viewport()))) {
		/*
		* If the drag was started from the main index and should move items and if the destination is the bookmark
		* folder or one of its subfolders
		* we remove the current items because the new ones will be inserted soon.
		*/
		if (dynamic_cast<CBookmarkFolder*>(parent) || dynamic_cast<Bookmarks::SubFolder*>(parent)) { 
			// we drop onto the bookmark folder or one of it's subfolders
			//       TQPtrList<TQListViewItem> items = selectedItems();
			//       items.setAutoDelete(true);
			//       items.clear(); //delete the selected items we dragged
		}
	}

	//finally do the drop, either with external drop data or with the moved items' data
	CItemBase* const parentItem = dynamic_cast<CItemBase*>(parent);
	CItemBase* const afterItem  = dynamic_cast<CItemBase*>(after);

	bool removeSelectedItems = true;
	bool moveSelectedItems = false;

	if (afterItem && afterItem->isFolder()) {
		moveSelectedItems = false;
		removeSelectedItems = false;

		afterItem->setOpen(true);
		afterItem->dropped(e); //inserts new items, moving only works on the same level
	}
	else if (afterItem && !afterItem->isFolder() && parentItem) {
		const bool justMoveSelected =
			(e->source() == viewport())
			&& m_itemsMovable
			&& parentItem->acceptDrop(e)
			&& !afterItem->acceptDrop(e);

		if (justMoveSelected) {
			moveSelectedItems = true;
			removeSelectedItems = false;
		}
		else {
			moveSelectedItems = false;
			removeSelectedItems = false;

			if (afterItem->acceptDrop(e)) {
				afterItem->dropped(e, after);
			}
			else { //insert in the parent folder and then move the inserted items
				parentItem->dropped(e, after);
			}
		}

		parentItem->setOpen(true);
	}
	else if (parentItem) { //no after item present, but a parent is there
		moveSelectedItems = false;
		removeSelectedItems = false;

		parentItem->setOpen(true);
		parentItem->dropped(e);
	}

	if (moveSelectedItems) {
		//move all selected items after the afterItem
		if (m_itemsMovable) {
			TQPtrList<TQListViewItem> items = selectedItems();
			TQListViewItem* i = items.first();
			TQListViewItem* after = afterItem;
			while (i && afterItem) {
				i->moveItem(after);
				after = i;

				i = items.next();
			}
		}
	}

	if (removeSelectedItems) {
		TQPtrList<TQListViewItem> items = selectedItems();
		items.setAutoDelete(true);
		items.clear(); //delete the selected items we dragged
	}
}

/** No descriptions */
void CMainIndex::emitModulesChosen( ListCSwordModuleInfo modules, TQString key ) {
	emit createReadDisplayWindow(modules, key);
}

/** Returns the correct TDEAction object for the given type of action. */
TDEAction* const CMainIndex::action( const CItemBase::MenuAction type ) const {
	switch (type) {
	case CItemBase::NewFolder:
		return m_actions.newFolder;
	case CItemBase::ChangeFolder:
		return m_actions.changeFolder;

	case CItemBase::ChangeBookmark:
		return m_actions.changeBookmark;
	case CItemBase::ImportBookmarks:
		return m_actions.importBookmarks;
	case CItemBase::ExportBookmarks:
		return m_actions.exportBookmarks;
	case CItemBase::PrintBookmarks:
		return m_actions.printBookmarks;

	case CItemBase::DeleteEntries:
		return m_actions.deleteEntries;

	case CItemBase::EditModule:
		return m_actions.editModuleMenu;
	case CItemBase::SearchInModules:
		return m_actions.searchInModules;
	case CItemBase::UnlockModule:
		return m_actions.unlockModule;
	case CItemBase::AboutModule:
		return m_actions.aboutModule;
	default:
		return 0;
	}
}

/** Shows the context menu at the given position. */
void CMainIndex::contextMenu(TDEListView* /*list*/, TQListViewItem* i, const TQPoint& p) {
	//setup menu entries depending on current selection
	TQPtrList<TQListViewItem> items = selectedItems();

	if (items.count() == 0) { 
		//special handling for no selection
	}
	else if (items.count() == 1) { 
		//special handling for one selected item
		
		CItemBase* item = dynamic_cast<CItemBase*>(i);
		CItemBase::MenuAction actionType;
		for (int index = CItemBase::ActionBegin; index <= CItemBase::ActionEnd; ++index) {
			actionType = static_cast<CItemBase::MenuAction>(index);
			if (TDEAction* a = action(actionType))
				a->setEnabled( item->enableAction(actionType) );
		}
	}
	else {
		//first disable all actions
		CItemBase::MenuAction actionType;
		for (int index = CItemBase::ActionBegin; index <= CItemBase::ActionEnd; ++index) {
			actionType = static_cast<CItemBase::MenuAction>(index);
			if (TDEAction* a = action(actionType))
				a->setEnabled(false);
		}

		//enable the menu items depending on the types of the selected items.
		for (int index = CItemBase::ActionBegin; index <= CItemBase::ActionEnd; ++index) {
			actionType = static_cast<CItemBase::MenuAction>(index);
			bool enableAction = isMultiAction(actionType);
			for (items.first(); items.current(); items.next()) {
				CItemBase* i = dynamic_cast<CItemBase*>(items.current());
				enableAction = enableAction && i->enableAction(actionType);
			}
			if (enableAction) {
				TDEAction* a = action(actionType) ;
				if (i && a)
					a->setEnabled(enableAction);
			}
		}
	}
	
	//finally, open the popup
	m_popup->exec(p);
}

/** Adds a new subfolder to the current item. */
void CMainIndex::createNewFolder() {
	CFolderBase* i = dynamic_cast<CFolderBase*>(currentItem());
	Q_ASSERT(i);
	
	if (i) {
		i->newSubFolder();
	}
}

/** Opens a dialog to change the current folder. */
void CMainIndex::changeFolder() {
	CFolderBase* i = dynamic_cast<CFolderBase*>(currentItem());
	Q_ASSERT(i);
	if (i) {
		i->rename();
	}
}

/** Changes the current bookmark. */
void CMainIndex::changeBookmark() {
	CBookmarkItem* i = dynamic_cast<CBookmarkItem*>(currentItem());
	Q_ASSERT(i);
	
	if (i) {
		i->rename();
	}
}

/** Exports the bookmarks being in the selected folder. */
void CMainIndex::exportBookmarks() {
	CBookmarkFolder* i = dynamic_cast<CBookmarkFolder*>(currentItem());
	Q_ASSERT(i);
	
	if (i) {
		i->exportBookmarks();
	}
}

/** Import bookmarks from a file and add them to the selected folder. */
void CMainIndex::importBookmarks() {
	CBookmarkFolder* i = dynamic_cast<CBookmarkFolder*>(currentItem());
	Q_ASSERT(i);
	
	if (i) {
		i->importBookmarks();
	}
}

/** Prints the selected bookmarks. */
void CMainIndex::printBookmarks() {
	CPrinter::KeyTree tree;
	CPrinter::KeyTreeItem::Settings settings;
	settings.keyRenderingFace = CPrinter::KeyTreeItem::Settings::CompleteShort;

	TQPtrList<TQListViewItem> items;
	CBookmarkFolder* bf = dynamic_cast<CBookmarkFolder*>(currentItem());

	if (bf) {
		items = bf->getChildList();
	}
	else {
		items = selectedItems();
	}

	//create a tree of keytreeitems using the bookmark hierarchy.
	for (items.first(); items.current(); items.next()) {
		CBookmarkItem* i = dynamic_cast<CBookmarkItem*>(items.current());
		if (i) {
			tree.append( new CPrinter::KeyTreeItem( i->key(), i->module(), settings ) );
		}
	}

	util::scoped_ptr<CPrinter> printer( 
		new CPrinter( this, CBTConfig::getDisplayOptionDefaults(), CBTConfig::getFilterOptionDefaults() ) 
	);
	printer->printKeyTree(tree);
}

/** Deletes the selected entries. */
void CMainIndex::deleteEntries() {
	TQPtrList<TQListViewItem> items = selectedItems();
	if (!items.count())
		return;

	if (KMessageBox::warningYesNo(this, i18n("Do you really want to delete the selected items and child-items?"), i18n("Delete Items")) != KMessageBox::Yes) {
		return;
	}

	// We have to go backwards because otherwise deleting folders would delete their childs => crash before we delete those
	for (items.last(); items.current(); items.prev()) {
		if (CItemBase* i = dynamic_cast<CItemBase*>(items.current())) {
			if (i->enableAction(CItemBase::DeleteEntries)) {
				delete i;
			}
		}
	}
}

/** Opens the searchdialog for the selected modules. */
void CMainIndex::searchInModules() {
	TQPtrList<TQListViewItem> items = selectedItems();
	ListCSwordModuleInfo modules;
	for (items.first(); items.current(); items.next()) {
		if (CModuleItem* i = dynamic_cast<CModuleItem*>(items.current())) {
			if (i->module()) {
				modules.append(i->module());
			}
		}
	}

	if (modules.isEmpty()) { //get a list of useful default modules for the search if no modules were selected
		CSwordModuleInfo* m = CBTConfig::get(CBTConfig::standardBible);
		if (m) {
			modules.append(m);
		}
	}

	Search::CSearchDialog::openDialog(modules, TQString());
}

/** Unlocks the current module. */
void CMainIndex::unlockModule() {
	if (CModuleItem* i = dynamic_cast<CModuleItem*>(currentItem())) {
		bool ok = false;
		const TQString unlockKey = TQInputDialog::getText(i18n("BibleTime - Unlock work"),
			i18n("Enter the unlock key for this work."),
			TQLineEdit::Normal, i->module()->config(CSwordModuleInfo::CipherKey), &ok);
		
		if (ok) {
			i->module()->unlock( unlockKey );
			emit signalSwordSetupChanged();
		}
	}
}

/** Shows information about the current module. */
void CMainIndex::aboutModule() {
	if (CModuleItem* i = dynamic_cast<CModuleItem*>(currentItem())) {
		KMessageBox::about(this, i->module()->aboutText(), i->module()->config(CSwordModuleInfo::Description), false);
	}
}

/** Reimplementation. Takes care of movable items. */
void CMainIndex::startDrag() {
	TQPtrList<TQListViewItem> items = selectedItems();
	m_itemsMovable = true;

	for (items.first(); items.current() && m_itemsMovable; items.next()) {
		if (CItemBase* i = dynamic_cast<CItemBase*>(items.current())) {
			m_itemsMovable = (m_itemsMovable && i->isMovable());
		}
		else {
			m_itemsMovable = false;
		}
	}

	TDEListView::startDrag();
}

/** Reimplementation to support the items dragEnter and dragLeave functions. */
void CMainIndex::contentsDragMoveEvent( TQDragMoveEvent* event ) {
	//  tqWarning("void CMainIndex:: drag move event ( TQDragLeaveEvent* e )");
	CItemBase* i = dynamic_cast<CItemBase*>( itemAt( contentsToViewport(event->pos())) );
	if (i) {
		if (i->allowAutoOpen(event) || (i->acceptDrop(event) && i->isFolder() && i->allowAutoOpen(event) && !i->isOpen() && autoOpen()) ) {
			if (m_autoOpenFolder != i)  {
				m_autoOpenTimer.stop();
			}
			
			m_autoOpenFolder = i;
			m_autoOpenTimer.start( 400, true );
		}
		else {
			m_autoOpenFolder = 0;
		}
	}
	else {
		m_autoOpenFolder = 0;
	}

	TDEListView::contentsDragMoveEvent(event);
}

TQRect CMainIndex::drawItemHighlighter(TQPainter* painter, TQListViewItem* item) {
	CBookmarkItem* bookmark = dynamic_cast<CBookmarkItem*>(item);
	if (bookmark) { 
		//no drops on bookmarks allowed, just moving items after it
		return TQRect();
	}

	return TDEListView::drawItemHighlighter(painter, item);
}


void CMainIndex::autoOpenTimeout() {
	m_autoOpenTimer.stop();
	if (m_autoOpenFolder && !m_autoOpenFolder->isOpen() && m_autoOpenFolder->childCount()) {
		m_autoOpenFolder->setOpen(true);
	}
}

/** No descriptions */
void CMainIndex::contentsDragLeaveEvent( TQDragLeaveEvent* e ) {
	m_autoOpenTimer.stop();
	TDEListView::contentsDragLeaveEvent(e);
}

/** Returns true if more than one netry is supported by this action type. Returns false for actions which support only one entry, e.g. about module etc. */
const bool CMainIndex::isMultiAction( const CItemBase::MenuAction type ) const {
	switch (type) {
	case CItemBase::NewFolder:
		return false;
	case CItemBase::ChangeFolder:
		return false;

	case CItemBase::ChangeBookmark:
		return false;
	case CItemBase::ImportBookmarks:
		return false;
	case CItemBase::ExportBookmarks:
		return false;
	case CItemBase::PrintBookmarks:
		return true;

	case CItemBase::DeleteEntries:
		return true;

	case CItemBase::EditModule:
		return false;
	case CItemBase::SearchInModules:
		return true;
	case CItemBase::UnlockModule:
		return false;
	case CItemBase::AboutModule:
		return false;
	}
	
	return false;
}

/** Is called when items should be moved. */
void CMainIndex::moved( TQPtrList<TQListViewItem>& /*items*/, TQPtrList<TQListViewItem>& /*afterFirst*/, TQPtrList<TQListViewItem>& /*afterNow*/) {
	tqDebug("move items");
}

/** Opens an editor window to edit the modules content. */
void CMainIndex::editModulePlain() {
	TQPtrList<TQListViewItem> items = selectedItems();
	ListCSwordModuleInfo modules;
	for (items.first(); items.current(); items.next()) {
		if (CModuleItem* i = dynamic_cast<CModuleItem*>(items.current())) {
			modules.append(i->module());
		}
	}
	if (modules.count() == 1) {
		emit createWriteDisplayWindow(modules.first(), TQString(), CDisplayWindow::PlainTextWindow);
	};
}

/** Opens an editor window to edit the modules content. */
void CMainIndex::editModuleHTML() {
	TQPtrList<TQListViewItem> items = selectedItems();
	ListCSwordModuleInfo modules;
	for (items.first(); items.current(); items.next()) {
		if (CModuleItem* i = dynamic_cast<CModuleItem*>(items.current())) {
			modules.append(i->module());
		}
	}
	
	if (modules.count() == 1) {
		emit createWriteDisplayWindow(modules.first(), TQString(), CDisplayWindow::HTMLWindow);
	}
}

/** Reloads the main index's Sword dependend things like modules */
void CMainIndex::reloadSword() {
	//reload the modules, save the open groups before removing the items
	saveSettings();
	clear();
	initTree();	
	readSettings();
}

/** Saves the bookmarks to disk */
void CMainIndex::saveBookmarks() {
	//find the bookmark folder
	CItemBase* i = 0;

	TQListViewItemIterator it( this );
	while ( it.current() ) {
		i = dynamic_cast<CItemBase*>( it.current() );

		if (i && (i->type() == CItemBase::BookmarkFolder)) { 
			//found the bookmark folder
			TDEStandardDirs stdDirs;

			const TQString path = stdDirs.saveLocation("data", "bibletime/");
			if (!path.isEmpty()) {
				//save the bookmarks to the right file
				if (CBookmarkFolder* f = dynamic_cast<CBookmarkFolder*>(i)) {
					f->saveBookmarks( path + "bookmarks.xml" );
				}
			}
			break;
		}

		++it;
	}
}

void CMainIndex::readSettings() {
 	tqDebug("CMainIndex::readSettings");
	
	TQStringList openGroups = CBTConfig::get(CBTConfig::bookshelfOpenGroups);
	for (TQStringList::Iterator it( openGroups.begin() ); it != openGroups.end(); ++it) {
		TQStringList path = TQStringList::split("/", (*it)); //e.g. with items parent, child
		TQListViewItem* item = firstChild(); //begin on the top for each item
		Q_ASSERT(item);
		unsigned int index = 1;

		for (TQStringList::Iterator p_it( path.begin() ); p_it != path.end(); ++p_it) {
			TQString itemName = (*p_it).replace("\\/", "/");

			while (item && (item->text(0) != itemName)) {
				item = item->nextSibling();
			}

			if (item && (item->text(0) == itemName)) {
				if (index < path.count()) { //don't call firstChild on the right, i.e. last item of the list
					item = item->firstChild();
				}

				++index;
			}
		}

		if (item) {
			item->setOpen(true);
		}
	}

	//restore the content position
// 	setContentsPos(
// 		CBTConfig::get(CBTConfig::bookshelfContentsX),
// 		CBTConfig::get(CBTConfig::bookshelfContentsY)
// 	);
// 	horizontalScrollBar()->setValue(CBTConfig::get(CBTConfig::bookshelfContentsX));
// 	verticalScrollBar()->setValue(CBTConfig::get(CBTConfig::bookshelfContentsY));


	//restore the selected item
	TQStringList path = TQStringList::split("/", CBTConfig::get(CBTConfig::bookshelfCurrentItem));
	TQListViewItem* item = firstChild();
	Q_ASSERT(item);
	unsigned int index = 1;
	for (TQStringList::iterator it( path.begin() ); it != path.end(); ++it) {
		//search for the current caption and go down to it's childs
		while (item && (item->text(0) != (*it)) ) {
			item = item->nextSibling();
		}

		if (item && ((*it) == item->text(0))) {
			if (index == path.count()) { //last item reached
				setCurrentItem( item );
				setSelected( item, true );
				break;//for loop
			}
			else {
				item = item->firstChild();
			}

			index++;
		}
	}
}

void CMainIndex::saveSettings() {
	//save the complete names of all open groups to the settings file (e.g. Bibles/German/,Bookmarks/Jeuss Christ
	TQStringList openGroups;

	TQListViewItemIterator it( this );
	while ( it.current() ) {
		if ( it.current()->isOpen() ) { //is a group and open
			//it.current()'s full name needs to be added to the list
			TQListViewItem* i = it.current();
			TQString fullName = i->text(0);
			while (i->parent()) {
				i = i->parent();
				fullName.prepend("/").prepend( i->text(0).replace("/", "\\/")); // parent / child
			}
			openGroups << fullName;
		}

		++it;
	}

	CBTConfig::set(CBTConfig::bookshelfOpenGroups, openGroups);

	//now save the position of the scrollbars
// 	CBTConfig::set(CBTConfig::bookshelfContentsX,
// 		horizontalScrollBar() ? horizontalScrollBar()->value() : 0);
// 	CBTConfig::set(CBTConfig::bookshelfContentsY,
// 		verticalScrollBar() ? verticalScrollBar()->value() : 0);

	//save the currently selected item
	TQListViewItem* item = currentItem();
	TQString path;
	while (item) {
		path.prepend( item->text(0) + "/" );
		item = item->parent();
	}
	CBTConfig::set(CBTConfig::bookshelfCurrentItem, path);
}

void CMainIndex::polish()
{
	TDEListView::polish();
	initTree();
	readSettings();
}

#include "cmainindex.moc"
