/* -*- mode: c++; indent-tabs-mode: nil; -*-
 *
 * This file is part of the Mango recipe management distribution.
 * Copyright (c) 2001-2002, Roland Jesse
 * All rights reserved.
 *
 * For license and copyright information see the file COPYRIGHT or 
 * <http://www.opensource.org/licenses/bsd-license.html>.
 *
 * $Id: ManageCookbooksForm.ui.h,v 1.13 2003/03/17 22:34:39 rjesse Exp $
 */

#include "ExportDialog.h"
#include "Importer.h"
#include "Mango.h"
#include "RecipeListDialog.h"
#include "RecipeModel.h"
#include "Repository.h"
#include <qfiledialog.h>
#include <qinputdialog.h>
#include <qmessagebox.h>

void ManageCookbooksForm::
init()
{
   setMDICaption( caption());
   initContextMenu();
   populateListBox();

   // set up observer pattern
   Repository* repo = Repository::getInstance();
   connect( repo, SIGNAL( cookbookAdded( const QString&)), this, SLOT( addCookbook( const QString&)));
}

void ManageCookbooksForm::
destroy()
{
}

/*!
  Populate cookbook list box.
*/
void ManageCookbooksForm::
populateListBox()
{
   CookbooksListBox->clear();
   QStringList cbNames = Repository::getInstance()->getCookbookNames();
   CookbooksListBox->insertStringList( cbNames);
}

/*!
  Initialise the context menu.
*/
void ManageCookbooksForm::
initContextMenu()
{
   m_contextMenu = new QPopupMenu( this);
   m_contextMenu->insertItem( tr( "&View / Edit", "Item in the context menu"),
                              this, SLOT( slotViewCurrentCookbook()),
                              tr( "Ctrl+V", "Context menu|View"));
   m_contextMenu->insertItem( tr( "&Rename", "Item in the context menu"),
                              this, SLOT( slotRename()),
                              tr( "Ctrl+R", "Context menu|Rename"));
   m_contextMenu->insertItem( tr( "&Delete", "Item in the context menu"),
                              this, SLOT( slotDeleteSelected()),
                              tr( "Ctrl+D", "Context menu|Delete"));
   m_contextMenu->insertItem( tr( "E&xport", "Item in the context menu"),
                              this, SLOT( slotExportSelected()),
                              tr( "Ctrl+x", "Context menu|Export"));
}

/*!
  Opens up the context menu. The menu is placed at \a pos.
*/
void ManageCookbooksForm::
slotContextMenu( QListBoxItem*, const QPoint& pos)
{
   m_contextMenu->exec( pos);
}

void
ManageCookbooksForm::slotDeleteSelected()
{
   Repository* repo = Repository::getInstance();
   for (uint a = 0; a < CookbooksListBox->count(); a++) {
      if (CookbooksListBox->isSelected( a)) {
         repo->removeCookbook( CookbooksListBox->text( a));
         CookbooksListBox->removeItem( a);
      }
   }
}

void
ManageCookbooksForm::slotLoad()
{
   QString startDir = Repository::getInstance()->defaultPath( "LoadDirectory");
   QString filter = Importer::getSupportedFileExtensions();
   QString fn = QFileDialog::getOpenFileName( startDir, tr(filter));
   if (fn.isNull()) return;
   
   RecipeModel rm;
   try {
      rm = Repository::getInstance()->addCookbookFromFile( fn);
   }
   catch (Error& e) {
	  QString msg( tr( "Error reading file: %1", "The argument is the error message from the importer class.")
                       .arg( e.what()));
	  QMessageBox::warning( 0,
                                tr( "Reading cookbook from file...", "Caption of the error message dialog"),
                                msg);
	  return;
   }
   //CookbooksListBox->insertItem( rm.getName());
}

/*!
  In case more than one cookbook is selected, all of them get concatenated
  and will be exported into a new cookbook.
*/
void
ManageCookbooksForm::slotExportSelected()
{
   ExportDialog* dlg = new ExportDialog( this);
   Repository* repo = Repository::getInstance();
   int selectionCount = 0;

   for (uint a = 0; a < CookbooksListBox->count(); a++)
      if (CookbooksListBox->isSelected( a)) selectionCount++;

   if (selectionCount == 0) {
      QMessageBox::information( this,
                                tr( "Export cookbook(s)"),
                                tr( "Please make a selection first."));
   }
   else if (selectionCount == 1) {
      RecipeModel* rm = repo->getCookbook( CookbooksListBox->currentText());
      dlg->setCurrentCookbook( rm);
   }
   else {                       // more than one cookbook selected
      QDict<RecipeModel> markedCB( 9973); // 9973 is a prime, see QDict documentation for more details.
      for (uint b = 0; b < CookbooksListBox->count(); b++) {
         if (CookbooksListBox->isSelected( b)) {
            RecipeModel* rm = repo->getCookbook( CookbooksListBox->text( b));
            markedCB.insert( rm->getName(), rm);
         }
      }
      dlg->setMarkedCookbooks( markedCB);
      RecipeModel* cur = repo->getCookbook( CookbooksListBox->currentText());
      dlg->setCurrentCookbook( cur);
   }
   dlg->show();
} // slotExportSelected()

/*! Open dialog to examine one selected cookbook. 

  Good for double click action.
  
  \param idx index of selection cookbook list box.
*/
void ManageCookbooksForm::
slotViewCookbook( int idx)
{
   RecipeModel* model = Repository::getInstance()->getCookbook( CookbooksListBox->text( idx));
   RecipeListDialog* rld = new RecipeListDialog( model);
   Mango* mango = Mango::getInstance();
   mango->addWindow( rld);
}

/*!
  This is a convienient function that behaves exactly like the above.
  The index of the cookbook to view is the current one.
*/
void ManageCookbooksForm::
slotViewCurrentCookbook()
{
   int cur = CookbooksListBox->currentItem();
   slotViewCookbook( cur);
}


/*! Open dialog to examine all selected cookbooks.

  Good for actions working on the whole list box and not only the currently
  selected item in it.

  A new (virtual) cookbook is created based on the sum of all recipes
  contained in all selected cookbooks.
*/
void
ManageCookbooksForm::slotViewCookbooks()
{
   bool noneSelected = true;
   RecipeModel model;
   for (uint a = 0; a < CookbooksListBox->count(); a++) {
      if (CookbooksListBox->isSelected( a)) {
         noneSelected = false;
	 RecipeModel cb( Repository::getInstance()->getCookbook( CookbooksListBox->text( a)));
         model += cb;
      }
   }
   if (noneSelected) {
      QMessageBox::warning( this, 
			    tr( "Examine cookbook(s)"), 
			    tr( "Please make a selection first."));
      return;
   }
   
   RecipeListDialog* rld = new RecipeListDialog( &model);
   rld->show();
}

void
ManageCookbooksForm::addCookbook( const QString & name)
{
   if (! CookbooksListBox->findItem( name)) {
      CookbooksListBox->insertItem( name);
      CookbooksListBox->sort();
   }
}

/*!
  Allows user to rename the current cookbook.
  Note: Renaming of multiple cookbooks is not possible as the user can
  only edit one cookbook's name anyway.
*/
void ManageCookbooksForm::
slotRename()
{
   QString curStr = CookbooksListBox->currentText();
   Repository* repo = Repository::getInstance();
   RecipeModel* cb = repo->getCookbook( curStr);
   QString oldName( cb->getName());
   bool ok = false;
   QString newName = QInputDialog::getText(
      tr( "Mango"),
      tr( "Please enter the new name for the Cookbook:"),
      QLineEdit::Normal, oldName, &ok, this);
   if (ok && !newName.isEmpty()) {
      repo->removeCookbook( oldName, false);
      cb->setName( newName);
      repo->insertCookbook( cb);
      populateListBox();
   }
}
