/* -*- mode: c++; indent-tabs-mode: nil; -*-
 *
 * This file is part of the Mango recipe management distribution.
 * Copyright (c) 2000-2003, Roland Jesse
 * All rights reserved.
 *
 * For license and copyright information see the file COPYRIGHT or 
 * <http://www.opensource.org/licenses/bsd-license.html>.
 *
 * $Id: PrintPreviewForm.ui.h,v 1.9 2003/05/11 16:13:06 rjesse Exp $
 */

#ifdef NO_KDE2
# include <qstatusbar.h>
#else
# include <kstatusbar.h>
#endif

void
PrintPreviewForm::init()
{
   setMDICaption( caption());
   textBrowser->clear();
}

void
PrintPreviewForm::destroy()
{
}

void
PrintPreviewForm::setRecipes( RecipeModel* recipes)
{
   m_recipes = recipes;
   slotRender();
}

/*!
  Print the currently displayed contents of the text browser.
*/
void
PrintPreviewForm::slotPrint()
{
   QPrinter printer;
   printer.setFullPage( true);
   if (! printer.setup( this)) return; // abort by user
   QPainter painter( &printer);
   if (! painter.device()) return;  // no valid device available
   QString footerString;
   QTextOStream( &footerString)
      << "<i>"
      << tr( "Printed using Mango %1", 
             "The argument is substituted by Mango's version number.")
      .arg( MANGO_VERSION_STRING)
      << "</i>";
   QFont font = QApplication::font();
   painter.setFont( font);
   QFontMetrics fm = painter.fontMetrics();
   // get resolution
   QPaintDeviceMetrics metrics( painter.device());
   int dpiX = metrics.logicalDpiX();
   int dpiY = metrics.logicalDpiY();
   const int screenRes = 72;
   // Use 42pt margin for now. FIXME: Could possibly be set by the user.
   const int margin = 42;
   QRect page( margin * dpiX & screenRes, margin * dpiY / screenRes,
               metrics.width() - margin * dpiX / screenRes * 2,
               metrics.height() - margin * dpiY / screenRes * 2);
   QSimpleRichText srt( textBrowser->text(), font, textBrowser->context(),
                        textBrowser->styleSheet(), textBrowser->mimeSourceFactory(),
                        page.height());
   QRect clip( page);
   Mango* mango = Mango::getInstance();
   int pageNr = 1;
   bool doPrint = true;
   while (doPrint) {
      mango->statusBar()->message( tr( "Printing page %1.", 
                                       "The argument is substituted by the current page number.")
                                   .arg( QString::number( pageNr)));
      qApp->processEvents();
      srt.draw( &painter, page.left(), page.top(), clip, colorGroup());
      clip.moveBy( 0, page.height());
      painter.translate( 0, -page.height());
      // footer
      int fromBottom = (int) floor( fm.ascent() * 1.3);
      painter.drawText( clip.left(), clip.bottom() + fromBottom, footerString);
      painter.drawText( clip.right() - fm.width( QString::number( pageNr)),
                        clip.bottom() + fromBottom,
                        QString::number( pageNr));
      // eventually, next page
      if (clip.top() >= srt.height()) {
         doPrint = false;
         break;
      }
      printer.newPage();
      pageNr++;
   }
   mango->statusBar()->message( STATUS_DEFAULT);
} // slotPrint()

void
PrintPreviewForm::slotRender()
{
   QString content;
   content += getDocumentTitle();
   content += createRecipeListOverview();
   content += createRecipeList();
   textBrowser->setText( content);
}

QString
PrintPreviewForm::getDocumentTitle()
{
   QString ret( m_recipes->getName());
   if (! ret.isEmpty()) {
      ret.prepend( "<title>");
      ret.append( "</title");
   }
   return ret;
}

/*!
  Return a string containing a list of all recipes in richtext format.
  If there is only one recipe, the string is empty.
*/
QString
PrintPreviewForm::createRecipeListOverview()
{
   QString ret;
   RecipeModel::RecipeList rlist = m_recipes->getRecipeList();
   if (rlist.size() > 1) {
      QTextOStream( &ret)
         << "<h1>" 
         << tr( "Overview of recipes", "Headline used for the recipe listing"
                " at the beginning. Only used if there is more than one recipe.")
         << "</h1>"
         << "<ul>";
      RecipeModel::RecipeList::const_iterator it;
      for (it = rlist.begin(); it != rlist.end(); it++) {
         QTextOStream( &ret) 
            << "<li><a href=\"#" 
            << (*it).title() << "\">" << (*it).title()
            << "</li>";
      }
      QTextOStream( &ret) << "</ul>";
   }
   return ret;
} // createRecipeListOverview()

/*!
  Return a string containing all recipes in richtext format.
*/
QString
PrintPreviewForm::createRecipeList()
{
   QString ret;

   RecipeModel::RecipeList rlist = m_recipes->getRecipeList();
   if (rlist.size() > 1) {
      QTextStream( &ret, IO_WriteOnly|IO_Append)
         << "<h1>" 
         << tr( "The recipes", "Headline used in case multiple recipes are shown.")
         << "</h1";
   }
   RecipeModel::RecipeList::const_iterator it;
   for (it = rlist.begin(); it != rlist.end(); it++) {
      Recipe r( *it);
      QString categories( r.categories().join( ", "));
      QString yieldsString( QString::number( r.yieldQty()));
      yieldsString.append( " ");
      yieldsString.append( r.yieldUnit());
      QTextStream( &ret, IO_WriteOnly|IO_Append)
         << "<a name=\"" << r.title() << "\">"
         << "<h2>" << r.title() << "</h2></a>"
         << "<table><tr>"
         << "<td>"
         << tr( "Categories: %1") .arg( categories) << "<br />"
         << tr( "Yields: %1") .arg( yieldsString) << "<br />"
         << "<h3>" 
         << tr( "Ingredients", "Caption used for the ingredients section.")
         << "</h3>";

      // Handle a group with an eventually empty name first
      Recipe::Ingredients ings = r.ingredients();
      QString emptyString;
      Recipe::Ingredients::iterator aListIt = ings.find( emptyString);
      Recipe::IngredientList aList = aListIt.data();
      if (aList.count() > 0) ingredientList2Richtext( aList, ret);

      Recipe::Ingredients::const_iterator ing;
      for (ing = ings.begin(); ing != ings.end(); ing++) {
         QString groupName( ing.key());
         if (groupName.isEmpty()) {
            continue;           // next group, empty name already handled
         } else {
            QTextStream( &ret, IO_WriteOnly|IO_Append)
               << "<h4>" << groupName << "</h4>";
         }
         ret.append( "<ul>");
         Recipe::IngredientList ingList = ing.data();
         ingredientList2Richtext( ingList, ret);
         ret.append( "</ul>");
      } // iterate ingredients
      QTextStream( &ret, IO_WriteOnly|IO_Append)
         << "</td><td><img source=\"" << r.title() << "\" /></td></tr></table>"
         << "<h3>"
         << tr( "Directions", "Caption used for the directions section.")
         << "</h3>"
         << r.directions();
   } // iterate recipes
   return ret;
} // createRecipeList()

/*!
  Adds the ingredients in \a lst to the string \str as list items,
  i.e. "<li>42 g blurb</li>".
*/
void
PrintPreviewForm::ingredientList2Richtext( const Recipe::IngredientList& lst, 
                                           QString& str)
{
   QTextStream( &str, IO_WriteOnly|IO_Append) << "<ul>\n";
   Recipe::IngredientList::const_iterator it;
   for (it = lst.begin(); it != lst.end(); it++) {
      QTextStream( &str, IO_WriteOnly|IO_Append)
         << "<li>" << (*it).amountQty() << " " << (*it).measurement().description()
         << " " << (*it).name() << "</li>";
   }
   QTextStream( &str, IO_WriteOnly|IO_Append) << "</ul>\n";
}

void
PrintPreviewForm::slotExport()
{
   Mango* mango = Mango::getInstance();
   ExportDialog* dlg = new ExportDialog( mango);
   RecipeModel::RecipeList rlist = m_recipes->getRecipeList();
   if (rlist.size() > 1) {
      dlg->setMarkedRecipes( m_recipes);
   } else {
      RecipeModel::RecipeList::const_iterator it = rlist.begin();
      dlg->setCurrentRecipe( *it);
   }
   dlg->show();
}
