//==============================================
//  copyright            : (C) 2003-2005 by Will Stokes
//==============================================
//  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.
//==============================================

//Systemwide includes
#include <qwidget.h>
#include <qmenubar.h>
#include <qpopupmenu.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qfont.h>
#include <qpixmap.h>
#include <qmovie.h>
#include <qimage.h>
#include <qtoolbutton.h>
#include <qfileinfo.h>
#include <qlineedit.h>
#include <qapplication.h>
#include <qdir.h>
#include <qcursor.h>
#include <qfiledialog.h>
#include <qtooltip.h>
#include <qiconset.h>
#include <qdatetime.h>

#include <math.h>

//Projectwide includes
#include "window.h"
#include "titleWidget.h"
#include "layoutWidget.h"
#include "subalbumsWidget.h"
#include "subalbumWidget.h"
#include "statusWidget.h"
#include "ALabel.h"
#include "subalbumPreviewWidget.h"
#include "recentAlbumMenuItem.h"

#include "dialogs/albumStatistics.h"
#include "dialogs/about.h"
#include "help/helpWindow.h"
#include "dialogs/questionDialog.h"
#include "dialogs/alertDialog.h"
#include "dialogs/saveDialog.h"

#include "../config.h"
#include "../backend/album.h"
#include "../backend/subalbum.h"
#include "../backend/photo.h"
#include "../backend/tools/fileTools.h"
#include "../backend/tools/guiTools.h"
#include "../configuration/configurationWidget.h"
#include "../configuration/configuration.h"

//==============================================
TitleWidget::TitleWidget(QWidget *parent,
                                 const char* name ) : QFrame(parent,name)
{
  tmpDirErrorMessage = tr("Error! Unable to create temp directory!");
  tmpDirErrorDesc = tr("Album Shaper was unable to create the necessary temp directory required: ");
  //--------------------------------------------------------------
  QColor white(255, 255, 255);
  QColor lightBlue(193, 210, 238);
  QColor darkBlue(35, 75, 139);
  QColor black(0, 0, 0);
  //--------------------------------------------------------------
  ///Store parent pointer
  window = (Window*)parent;

  ///program not busy at first
  busy = false;

  //detect changes to text fields
  detectModifications = true;

  ///no windows open by default
  albumStats = NULL;
  settingsWindow = NULL;
  about = NULL;
  helpWindow = NULL;

  //create backend album object
  albm = new Album( createTmpDir() );
  if(albm->getTmpDir().isNull() )
  {
      AlertDialog alert( tmpDirErrorMessage, tmpDirErrorDesc + window->getConfig()->getString( "loadSave", "tempImageDirectory" ),
      "alertIcons/warning.png", this );
      alert.exec();
      quitApplication();
  }
  //-------------------------------------
  //initialize recent albums object
  int i;
  QString recentName, recentLocation, recentPhotoCount;
  for(i = 0; i<recentAlbums.getMaxItems(); i++)
  {
    //get album name and location
    recentName = window->getConfig()->getString(    "recentAlbums", QString("%1_name").arg(i)     );
    recentLocation = window->getConfig()->getString("recentAlbums", QString("%1_location").arg(i) );
    recentPhotoCount = window->getConfig()->getString("recentAlbums", QString("%1_photoCount").arg(i) );

    //no such listing? since listings are continious all listings must be loaded
    if(recentLocation.compare("-1") == 0)
      break;

    //insert item into list
    recentAlbums.insertEntry( recentName, recentLocation, recentPhotoCount ); 
  }      
  //--------------------------------------------------------------
  //create menus
  menu = new QMenuBar( this, "menuBar" );
  //---
  //File menu
  file = new QPopupMenu( this, "fileMenu" );
  NEW_ALBUM = file->insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/new.png") ),
                                tr("&New"), this, SLOT(newAlbum()), CTRL+Key_N );

  OPEN_ALBUM = file->insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/open.png") ),
                                 tr("&Open..."), this, SLOT(loadAlbum()), CTRL+Key_O );

  openRecent = new QPopupMenu( this, "openRecentMenu" );
  populateOpenRecentMenu();
  refreshOpenRecentMenu();
  file->insertItem( tr("Open Recent"), openRecent );
  //----------------------
  file->insertSeparator();
  //----------------------  
  SAVE_ALBUM = file->insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/save.png") ),
                                 tr("&Save"), this, SLOT(saveAlbum()), CTRL+Key_S );

  SAVEAS_ALBUM = file->insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/saveas.png") ),
                                   tr("&Save As..."), this, SLOT(saveAsAlbum()), CTRL+SHIFT+Key_S );

  REVERT_TO_SAVED_ALBUM = file->insertItem( tr("Revert to Saved"), this, SLOT(revertToSaved()) );
  file->setItemEnabled( REVERT_TO_SAVED_ALBUM, false );  
  //----------------------
  file->insertSeparator();
  //----------------------
  QPopupMenu* exportAs = new QPopupMenu( this, "exportAs" );
  EXPORT_SMALL_WEB_GALLERY = exportAs->insertItem( tr("Small Web Gallery..."), 
                                                   this, SLOT(exportSmallWebGallery()) );
  EXPORT_LARGE_IMAGES = exportAs->insertItem( tr("Images for Printing..."), 
                                              this, SLOT(exportLargeImages()) );
  
  file->insertItem( tr("Export"), exportAs );
  //----------------------  
  file->insertSeparator();
  //----------------------
  file->insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/quit.png") ),
                    tr("&Quit"), this, SLOT(quitApplication()), CTRL+Key_Q);

  
  menu->insertItem( tr("&File"), file );
  //---
  //Photo menu
  photoMenu = new QPopupMenu( this, "phooMenu" );
    
  REMOVE_DESCRIPTIONS = photoMenu->insertItem( tr("Remove Description"), this, SLOT(removeSelectedPhotoDesc()) );
  REVERT_PHOTOS = photoMenu->insertItem( tr("Revert to Original"), this, SLOT(revertPhotos()) );
  
  menu->insertItem( tr("&Photos"), photoMenu );
  //---
  //Tools menu
  tools = new QPopupMenu( this, "toolsMenu" );
/*
  BEGIN_PRESENTATION_AT = tools->insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/startPresentation.png") ),
                                          tr("Begin Presentation"), 
                                          window, SLOT(startSlideshowWithSelectedPhoto()), CTRL+Key_P );   
  BEGIN_PRESENTATION = tools->insertItem( tr("Begin Presentation at Beginning"), 
                                             window, SLOT(startSlideshowAtBeginning()), CTRL+SHIFT+Key_P ); 
  updateMenus();
 */

  tools->insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/albumStatistics.png") ),
                     tr("Album Statistics"), this, SLOT(albumStatistics()), CTRL+Key_I );

  tools->insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/settings.png") ),
                     tr("Settings"), this, SLOT(settings()) );

  menu->insertItem( tr("&Tools"), tools );
  //---
  //PLATFORM_SPECIFIC_CODE
  //Window menu
  #if defined(Q_OS_MACX)
  windowMenu = new QPopupMenu( this, "windoMenu" );
  WINDOW_MINIMIZE = windowMenu->insertItem( tr("&Minimize"), (QWidget*)window, SLOT(showMinimized()), CTRL+Key_M );
  menu->insertItem( tr("&Window"), windowMenu );
  #endif
  //---    
  //Help menu
  helpMenu = new QPopupMenu( this, "helpMenu" );
  helpMenu->insertItem( tr("Album Shaper Help"), this, SLOT(help()), CTRL+Key_Question );

  helpMenu->insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/about.png") ),
                    tr("About"), this, SLOT(aboutProgram()) );
  menu->insertSeparator();
  menu->insertItem( tr("&Help"), helpMenu );
  //--------------------------------------------------------------
  //create all widgets
  mainFrame = new QFrame( this, "mainFrame" );
  mainFrame->setPaletteBackgroundColor( darkBlue );
  //------
  //album annotations
  albumAnnotationFrame = new QFrame( mainFrame, "albumAnnotationFrame" );
  albumAnnotationFrame->setLineWidth(2);
  albumAnnotationFrame->setMidLineWidth(0);
  albumAnnotationFrame->setFrameStyle( QFrame::Panel | QFrame::Plain );
  albumAnnotationFrame->setPaletteForegroundColor( white );
  albumAnnotationFrame->setPaletteBackgroundColor( darkBlue );

  QFrame* albumImageFrame = new QFrame( albumAnnotationFrame, "albumImageFrame" );
  albumImage = new ALabel( albumImageFrame, "albumImage",
                                               new QPixmap( QString(IMAGE_PATH)+"buttonIcons/removeImage.png") );
  connect( albumImage, SIGNAL(mouseRelease()),
                this, SLOT(unsetAlbumImage()) );

  //allow drop events
  this->setAcceptDrops(true);

  albumName = new QLabel( tr("Album Name:"), albumAnnotationFrame, "albumName" );
  albumNameVal = new QLineEdit( albumAnnotationFrame, "albumNameVal" );
  connect( albumNameVal, SIGNAL(textChanged( const QString&)),
           SLOT( storeAnnotations()) );

  albumDescription = new QLabel( tr("Description:"), albumAnnotationFrame, "albumDescription" );
  albumDescriptionVal = new QLineEdit( albumAnnotationFrame, "albumDescriptionVal" );
  connect( albumDescriptionVal, SIGNAL(textChanged( const QString&)),
           SLOT( storeAnnotations()) );

  albumAuthor = new QLabel( tr("Author:"), albumAnnotationFrame, "albumAuthor" );
  albumAuthorVal = new QLineEdit( albumAnnotationFrame, "albumAuthorVal" );
  connect( albumAuthorVal, SIGNAL(textChanged( const QString&)),
           SLOT( storeAnnotations()) );
  //------
  //subalbum annotations
  subalbumAnnotationFrame = new QFrame( mainFrame, "subalbumAnnotationFrame" );
  subalbumAnnotationFrame->setLineWidth(2);
  subalbumAnnotationFrame->setMidLineWidth(0);
  subalbumAnnotationFrame->setFrameStyle( QFrame::Panel | QFrame::Plain );
  subalbumAnnotationFrame->setPaletteForegroundColor( white );
  subalbumAnnotationFrame->setPaletteBackgroundColor( darkBlue );

  QFrame* subalbumImageFrame = new QFrame( subalbumAnnotationFrame, "subalbumImageFrame" );
  subalbumImage = new ALabel( subalbumImageFrame, "subalbumImage",
                                                    new QPixmap( QString(IMAGE_PATH)+"buttonIcons/removeImage.png") );

  connect( subalbumImage, SIGNAL(mouseRelease()),
                 this, SLOT(unsetSubalbumImage()) );

  subalbumName = new QLabel( tr("Collection Name:"), subalbumAnnotationFrame );
  subalbumNameVal = new QLineEdit( subalbumAnnotationFrame );
  connect( subalbumNameVal, SIGNAL(textChanged( const QString&)),
           SLOT( storeAnnotations()) );

  subalbumDescription = new QLabel( tr("Description:"), subalbumAnnotationFrame );
  subalbumDescriptionVal = new QLineEdit( subalbumAnnotationFrame );
  connect( subalbumDescriptionVal, SIGNAL(textChanged( const QString&)),
           SLOT( storeAnnotations()) );
  //--------------------------------------------------------------
  //Set fonts + colors
  QFont labelFont = albumName->font();
  labelFont.setWeight(QFont::Bold);

  albumName->setFont( labelFont );
  albumName->setPaletteForegroundColor( white );
  albumName->setPaletteBackgroundColor( darkBlue );

  albumNameVal->setFont( labelFont );
  albumNameVal->setPaletteForegroundColor( black );
  albumNameVal->setPaletteBackgroundColor( lightBlue );
  albumNameVal->setFrameShape ( QFrame::NoFrame );

  albumDescription->setFont( labelFont );
  albumDescription->setPaletteForegroundColor( white );
  albumDescription->setPaletteBackgroundColor( darkBlue );

  albumDescriptionVal->setFont( labelFont );
  albumDescriptionVal->setPaletteForegroundColor( black );
  albumDescriptionVal->setPaletteBackgroundColor( lightBlue );
  albumDescriptionVal->setFrameShape ( QFrame::NoFrame );

  albumAuthor->setFont( labelFont );
  albumAuthor->setPaletteForegroundColor( white );
  albumAuthor->setPaletteBackgroundColor( darkBlue );

  albumAuthorVal->setFont( labelFont );
  albumAuthorVal->setPaletteForegroundColor( black );
  albumAuthorVal->setPaletteBackgroundColor( lightBlue );
  albumAuthorVal->setFrameShape ( QFrame::NoFrame );

  subalbumName->setFont( labelFont );
  subalbumName->setPaletteForegroundColor( white );
  subalbumName->setPaletteBackgroundColor( darkBlue );

  subalbumNameVal->setFont( labelFont );
  subalbumNameVal->setPaletteForegroundColor( black );
  subalbumNameVal->setPaletteBackgroundColor( lightBlue );
  subalbumNameVal->setFrameShape ( QFrame::NoFrame );

  subalbumDescription->setFont( labelFont );
  subalbumDescription->setPaletteForegroundColor( white );
  subalbumDescription->setPaletteBackgroundColor( darkBlue );

  subalbumDescriptionVal->setFont( labelFont );
  subalbumDescriptionVal->setPaletteForegroundColor( black );
  subalbumDescriptionVal->setPaletteBackgroundColor( lightBlue );
  subalbumDescriptionVal->setFrameShape ( QFrame::NoFrame );
  //--------------------------------------------------------------
  //place widgets in grids
  //------------------------
  //album annotations
  QGridLayout* albumImageGrid = new QGridLayout( albumImageFrame, 1, 1 );
  albumImageGrid->addWidget( albumImage, 0, 0 );
  albumImageGrid->setRowSpacing( 0, REP_IMAGE_HEIGHT );

  albumAnnotationGrid =      new QGridLayout( albumAnnotationFrame, 3, 3);
  albumAnnotationGrid->setMargin(WIDGET_SPACING);
  albumAnnotationGrid->setSpacing(WIDGET_SPACING);

  albumAnnotationGrid->addMultiCellWidget( albumImageFrame, 0, 2, 0, 0 );

  albumAnnotationGrid->addWidget          ( albumName, 0, 1, Qt::AlignLeft);
  albumAnnotationGrid->addWidget          ( albumDescription, 1, 1, Qt::AlignLeft);
  albumAnnotationGrid->addWidget          ( albumAuthor, 2, 1, Qt::AlignLeft);

  albumAnnotationGrid->setColStretch(2, 1);
  albumAnnotationGrid->addWidget( albumNameVal, 0, 2);
  albumAnnotationGrid->addWidget( albumDescriptionVal, 1, 2);
  albumAnnotationGrid->addWidget( albumAuthorVal, 2, 2);
  //------------------------
  //subalbum annotations
  QGridLayout* subalbumImageGrid = new QGridLayout( subalbumImageFrame, 1, 1 );
  subalbumImageGrid->addWidget( subalbumImage, 0, 0 );
  subalbumImageGrid->setRowSpacing( 0, REP_IMAGE_HEIGHT );

  subalbumAnnotationGrid = new QGridLayout( subalbumAnnotationFrame, 5, 5);
  subalbumAnnotationGrid->setMargin(WIDGET_SPACING);
  subalbumAnnotationGrid->setSpacing(WIDGET_SPACING);

  subalbumAnnotationGrid->addMultiCellWidget( subalbumImageFrame, 0, 2, 0, 0);

  subalbumAnnotationGrid->setRowStretch(2, 1);
  subalbumAnnotationGrid->addWidget          ( subalbumName, 0, 1, Qt::AlignLeft);
  subalbumAnnotationGrid->addWidget          ( subalbumDescription, 1, 1, Qt::AlignLeft);

  subalbumAnnotationGrid->setColStretch(2, 1);
  subalbumAnnotationGrid->addWidget( subalbumNameVal, 0, 2);
  subalbumAnnotationGrid->addWidget( subalbumDescriptionVal, 1, 2);
  //------------------------
  //place menu and album and subalbum annotations into main grid
  mainGrid =                       new QGridLayout( mainFrame, 1, 2);
  mainGrid->setMargin(WIDGET_SPACING);
  mainGrid->setSpacing(WIDGET_SPACING);

  mainGrid->addWidget          ( albumAnnotationFrame, 0, 0);
  mainGrid->setColStretch(0, 1);

  mainGrid->addWidget          ( subalbumAnnotationFrame, 0, 1);
  mainGrid->setColStretch(1, 1);

  QVBoxLayout* vb = new QVBoxLayout(this);
  this->layout()->setMenuBar( menu );
  vb->addWidget(mainFrame);
  //-----------------------------------------------
}
//==============================================
void TitleWidget::useAnimation(bool val)
{
  //enable animation
  if(val)
  {
    albumImage->setAnimationMethods( SLIDE_IN_LEFT, SLIDE_OUT_LEFT,
                                                                FADE_TRANSITION, FADE_TRANSITION);
    subalbumImage->setAnimationMethods( SLIDE_IN_LEFT, SLIDE_OUT_LEFT,
                                                                FADE_TRANSITION, FADE_TRANSITION);
  }
  //disable animation
  else
  {
    albumImage->setAnimationMethods();
    subalbumImage->setAnimationMethods();
  }
}
//==============================================
TitleWidget::~TitleWidget()
{
  //delete old album
  delete albm;
  albm = NULL;
}
//==============================================
void TitleWidget::storeAnnotations()
{
  //only sync backend album/collection data when detectModifications is enabled
  if( !detectModifications ) return;

  //set album annotations
  albm->setName        ( albumNameVal->text()        );
  albm->setDescription ( albumDescriptionVal->text() );
  albm->setAuthor      ( albumAuthorVal->text()      );

  //get subalbum pointer
  Subalbum* collection = window->getLayout()->getSubalbums()->getSelectedSubalbum();
  if(collection != NULL )
  {
    //store old subalbum name
    QString oldName =  collection->getName();

    //set name and description
    collection->setName(  subalbumNameVal->text()   );
    collection->setDescription(  subalbumDescriptionVal->text()   );

    //if subalbum name has changed emit signal
    if(oldName.compare( collection->getName() ) != 0)
      emit subalbumNameChanged();
  }
}
//==============================================
void TitleWidget::updateAlbumAnnotations()
{
  //disable modification detection while updating fields
  detectModifications = false;

  //set album annotations

  //if no image then remove pixmap
  if( albm->getRepresentativeImage(LARGE) != NULL)
    albumImage->setPixmap( *albm->getRepresentativeImage(SMALL) );
  else
    albumImage->removePixmap();

  albumNameVal->setText( albm->getName() );
  albumNameVal->setCursorPosition(0);
  albumDescriptionVal->setText( albm->getDescription() );
  albumDescriptionVal->setCursorPosition(0);
  albumAuthorVal->setText( albm->getAuthor() );
  albumAuthorVal->setCursorPosition(0);

  //enable modification detection
  detectModifications = true;
}
//==============================================
void TitleWidget::refreshCollectionAnnotations(Subalbum* collection)
{
  //disable modification detection while updating fields
  detectModifications = false;

  //get subalbum pointer
  if( collection == NULL )
  {
    subalbumAnnotationFrame->hide();
    subalbumImage->removePixmap(true);
  }
  else
  {
    subalbumAnnotationFrame->show();

    //if no image then remove pixmap
    if( collection->getRepresentativeImage(LARGE) != NULL)
      subalbumImage->setPixmap( *collection->getRepresentativeImage(SMALL) );
    else
      subalbumImage->removePixmap();

    subalbumNameVal->setText( collection->getName() );
    subalbumNameVal->setCursorPosition(0);
    subalbumDescriptionVal->setText( collection->getDescription() );
    subalbumDescriptionVal->setCursorPosition(0);
  }

  //enable modification detection
  detectModifications = true;
}
//==============================================
void TitleWidget::setAlbum( Album* val)
{
  //delete old album
  delete albm;
  albm = val;
}
//==============================================
Album* TitleWidget::getAlbum()
{
  return albm;
}
//==============================================
void TitleWidget::setAlbumImage()
{
  //---------------------------------------------------------
  //determine if a subalbum is even selected
  SubalbumWidget* sw = window->getLayout()->getSubalbum();
  if(sw == NULL)
    return;
  //---------------------------------------------------------
  //set image to photo
  setAlbumImage( sw->getSelectedPhoto() );
}
//==============================================
void TitleWidget::setAlbumImage(Photo* selectedPhoto)
{
  if(selectedPhoto == NULL)
    return;
  //---------------------------------------------------------
  //set album image
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  albm->setRepresentativeImages( selectedPhoto->getImageFilename() );
  //---------------------------------------------------------
  //update onscreen image
  albumImage->setPixmap( *albm->getRepresentativeImage(SMALL) );
  qApp->restoreOverrideCursor();
  //---------------------------------------------------------
}
//==============================================
void TitleWidget::unsetAlbumImage()
{
  albm->setRepresentativeImages( QString::null );
}
//==============================================
void TitleWidget::setSubalbumImage()
{
  //---------------------------------------------------------
  //determine if a subalbum is even selected
  SubalbumWidget* sw = window->getLayout()->getSubalbum();
  if(sw == NULL)
    return;
  //---------------------------------------------------------
  //set collection image to selected photo
  setSubalbumImage( sw->getSelectedPhoto() );
}
//==============================================
void TitleWidget::setSubalbumImage(Photo* selectedPhoto)
{
  if(selectedPhoto == NULL)
    return;

  //---------------------------------------------------------
  //set subalbum image
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  SubalbumWidget* sw = window->getLayout()->getSubalbum();
  sw->getSubalbum()->setRepresentativeImage( selectedPhoto->getThumbnailFilename() );  
  //---------------------------------------------------------
  //update onscreen image
  subalbumImage->setPixmap( *sw->getSubalbum()->getRepresentativeImage(SMALL) );
  SubalbumPreviewWidget* item = (SubalbumPreviewWidget*)window->getLayout()->getSubalbums()->getCurrentSelection();
  item->setPixmap( *sw->getSubalbum()->getRepresentativeImage(MEDIUM), false );
  qApp->restoreOverrideCursor();
  //---------------------------------------------------------
}
//==============================================
void TitleWidget::unsetSubalbumImage()
{
  SubalbumPreviewWidget* item = (SubalbumPreviewWidget*)window->getLayout()->getSubalbums()->getCurrentSelection();
  if(item != NULL && ((SubalbumPreviewWidget*)item)->getSubalbum() != NULL)
  {
    Subalbum* subalbm =  ((SubalbumPreviewWidget*)item)->getSubalbum();
    subalbm->setRepresentativeImage( QString::null );
    item->setPixmap( *subalbm->getRepresentativeImage(MEDIUM), false );
  }
}
//==============================================
void TitleWidget::refresh()
{
  //first refresh the subalbums listing. this is 
  //IMPERATIVE! Right now current subalbum selection contains a pointer
  //to dead memory where previous subalbum was deleted. 
  //AKA not refreshing the subalbums iconview first will cause a crash!
  window->refresh();

  //update the album annotations (name, desc, author, images)
  //subalbum auto updated since window refresh auto selected first item
  updateAlbumAnnotations();
}
//==============================================
void TitleWidget::newAlbum()
{
  //if modifications exist and user wants to receive destructive action warnings,
  //ask if they are sure before creating a new album
  if( albm->albumModified() && window->getConfig()->getBool( "alerts", "showDestructiveAlerts" ) )
  {
    QuestionDialog sure( tr("New album?"),
                                   tr("Warning, unsaved modifications to the current album exist. Creating a new album will result in lost work. Are you sure you want to do this?"),
                                   "alertIcons/warning.png",
                                   this );
    if(!sure.exec())
      return;
  }

  //delete old album
  delete albm;

  //create new one
  albm = new Album( createTmpDir() );
  
  if(albm->getTmpDir().isNull() )
  {
      AlertDialog alert( tmpDirErrorMessage, tmpDirErrorDesc + window->getConfig()->getString( "loadSave", "tempImageDirectory" ),
      "alertIcons/warning.png", this );
      alert.exec();
      quitApplication();
  }

  //refresh screen
  albumImage->removePixmap();
  subalbumImage->removePixmap(true);

  //disable revert menu option since there is no loaded album
  file->setItemEnabled( REVERT_TO_SAVED_ALBUM, false );  
  
  //reset editing interface since old pointers are invalid
  window->getLayout()->getSubalbum()->setSubalbum( NULL );
  refresh();

  albm->setModified(false);
}
//==============================================
void TitleWidget::loadAlbum()
{
  ///make sure we want to proceed
  if(!proceedWithLoad())
    return;

  QString path = window->getConfig()->getString( "loadSave", "loadSaveDir" );
  QDir testPath(path);
  if(!testPath.exists())
  {
    window->getConfig()->resetSetting( "loadSave", "loadSaveDir" );
    path = window->getConfig()->getString( "loadSave", "loadSaveDir" );
  }
  
  QString albumXML = QFileDialog::getOpenFileName( path,
                                                   tr("XML Files (*.xml)"),
                                                   this,
                                                   "open file dialog",
                                                   tr("Choose an album to load") );
  
  //if null bail
  if(albumXML.isNull()) return;
  
  //attempt to load album
  loadAlbum( albumXML );    
}  
//==============================================
void TitleWidget::loadRecentAlbum(int index)
{
  ///make sure we want to proceed
  if(!proceedWithLoad())
    return;
  //load album
  QString recentName, recentLocation, recentPhotoCount;
  recentAlbums.getEntry( index, recentName, recentLocation, recentPhotoCount );
  loadAlbum( QDir::convertSeparators( recentLocation + "/Album.xml") );             
}
//==============================================
bool TitleWidget::proceedWithLoad()
{
  //if modifications exist and user wants to receive destructive action warnings,
  //ask if they are sure before creating a new album
  if( albm->albumModified() && window->getConfig()->getBool( "alerts", "showDestructiveAlerts" ) )
  {
    QuestionDialog sure( tr("Load album?"),
                         tr("Warning, unsaved modifications to the current album exist. Loading a new album will result in lost work. Are you sure you want to do this?"),
                         "alertIcons/warning.png",
                         this );
    if(!sure.exec())
      return false;
  }  
  
  return true;
}
//==============================================
void TitleWidget::revertToSaved()
{
  //if there are no changed then immediately return since reverting will have no effect
  //TODO: disable "revert" menu entry when no modifications exist
  if( !albm->albumModified() )
    return;
  
  ///make sure we want to proceed
  //if modifications exist and user wants to receive destructive action warnings,
  //ask if they are sure before creating a new album
  if( window->getConfig()->getBool( "alerts", "showDestructiveAlerts" ) )
  {
    QuestionDialog sure( tr("Revert to Saved?"),
                         tr("Warning, unsaved modifications to the current album exist. These changes will be lost if you revert to the album's last saved form. Are you sure you want to do this?"),
                         "alertIcons/warning.png",
                         this );
    if(!sure.exec())
      return;
  }    
  
  //reload album
  loadAlbum( QDir::convertSeparators( albm->getSaveLocation() + "/Album.xml") );  
}
//==============================================
void TitleWidget::exportSmallWebGallery()
{
  //if the Album's theme is not currently available alert user and bail
  if(!SaveDialog::themeAvailable( getAlbum()->getTheme() ))
  {
    AlertDialog alert( tr("Previous theme not available!"),
                       QString(tr("Theme previously used to save this album not available on this machine. Before exporting the %1 theme must be installed, or the album must be resaved using a different theme.")).arg( getAlbum()->getTheme() ),
                        "alertIcons/warning.png", this );
    alert.exec();
    return;
  }
  
  
  //setup dialog title and default path
  QString dialogTitle = tr( "Export Small Web Gallery" );
  
  //new directory name in which all images will be contained
  QString newDir;
  if(getAlbum()->prevSave())
  { newDir = QDir( getAlbum()->getSaveLocation() ).dirName() + "_WEB"; }
  else
  { newDir = getAlbum()->getName() + "_WEB"; }
  newDir = fixFilename( newDir );
  
  //get filename from user
  QFileDialog* fd = new QFileDialog( this, "file dialog", TRUE );
  fd->setCaption( tr("Export Location") );
  fd->setMode( QFileDialog::DirectoryOnly );
  fd->setDir( window->getConfig()->getString( "loadSave", "loadSaveDir" ) );
  
  //user canceled operation
  if ( !fd->exec() == QDialog::Accepted ) { return; }
  
  //get export path
  QString exportPath = QDir::convertSeparators( fd->selectedFile() + "/" + newDir );
  
  //check to make sure the album is not in this location, if so raise red flag and abort!!
  if( getAlbum()->prevSave() && getAlbum()->getSaveLocation().compare( exportPath ) == 0 )
  {
    QString errorMessage = tr("Error! Cannot export to album location on disk!");
    QString errorDesc = tr("Exporting small web galleries to the same location the album is stored will corrupt it and is not allowed. Try using the default location when exporting images, or chose a different directory.");
    AlertDialog alert( errorMessage, errorDesc,
                       "alertIcons/warning.png", this );
    alert.exec();
    return;
  }
  
  //otherwise check if directory already exists, if so warn user and ask before proceeding
  QDir tmpDir;
  if(tmpDir.exists( exportPath ) )
  {
    QString warningMessage = 
    QString(tr("Warning! A directory named %1 already exists in %2. Continue with export?")).arg
    ( newDir ).arg( fd->selectedFile() );
    
    QuestionDialog sure( tr("Directory Exists!"),
                         warningMessage, "alertIcons/warning.png",
                         this );
    if(!sure.exec()) { return; }
  }    
  //else create directory
  else
  {
    if( !tmpDir.mkdir( exportPath ) )
    {
      AlertDialog alert( tr("Error creating directory!"),
                         tr("Unable to create directory to export images to. Perhaps you are running out of disk space or you don't have sufficient privileges?"),
                         "alertIcons/warning.png", this );
      alert.exec();
      return;
    }
  }
  
  //set busy flag and disable buttons
  setBusy(true);
  window->getLayout()->getSubalbums()->updateButtons(false);
  if(window->getLayout()->getSubalbum() != NULL)
    window->getLayout()->getSubalbum()->updateButtons(false);
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  
  //setup progress bar
  int numPhotos = getAlbum()->getNumPhotos();  
  QString exportMessage = tr( "Exporting %1 photos to web gallery" );
  window->getStatus()->showProgressBar( exportMessage.arg(numPhotos), numPhotos );
  qApp->processEvents();
  
  //export large images
  getAlbum()->exportCompressedWebAlbum(window->getStatus(), exportPath, exportMessage);  
  
  //remove progress bar
  window->getStatus()->setStatus( tr("Exporting photos complete.") );
  
  //nolonger busy
  setBusy(false);
  window->getLayout()->getSubalbums()->updateButtons(true);
  if(window->getLayout()->getSubalbum() != NULL)
    window->getLayout()->getSubalbum()->updateButtons(true);
  qApp->restoreOverrideCursor();
}
//==============================================
void TitleWidget::exportLargeImages()
{
  //setup dialog title and default path
  QString dialogTitle = tr( "Export Large Images" );

  //new directory name in which all images will be contained
  QString newDir;
  if(getAlbum()->prevSave())
  { newDir = QDir( getAlbum()->getSaveLocation() ).dirName() + "_IMAGES"; }
  else
  { newDir = getAlbum()->getName() + "_IMAGES"; }
  newDir = fixFilename( newDir );
  
  //get filename from user
  QFileDialog* fd = new QFileDialog( this, "file dialog", TRUE );
  fd->setCaption( tr("Export Location") );
  fd->setMode( QFileDialog::DirectoryOnly );
  fd->setDir( window->getConfig()->getString( "loadSave", "loadSaveDir" ) );
  
  //user canceled operation
  if ( !fd->exec() == QDialog::Accepted ) { return; }

  //get export path
  QString exportPath = QDir::convertSeparators( fd->selectedFile() + "/" + newDir );

  //check to make sure the album is not in this location, if so raise red flag and abort!!
  if( getAlbum()->prevSave() && getAlbum()->getSaveLocation().compare( exportPath ) == 0 )
  {
    QString errorMessage = tr("Error! Cannot export to album location on disk!");
    QString errorDesc = tr("Exporting large images to the same location the album is stored will corrupt it and is not allowed. Try using the default location when exporting images, or chose a different directory.");
    AlertDialog alert( errorMessage, errorDesc,
                       "alertIcons/warning.png", this );
    alert.exec();
    return;
  }

  //otherwise check if directory already exists, if so warn user and ask before proceeding
  QDir tmpDir;
  if(tmpDir.exists( exportPath ) )
  {
    QString warningMessage = 
    QString(tr("Warning! A directory named %1 already exists in %2. Continue with export?")).arg
    ( newDir ).arg( fd->selectedFile() );
    
    QuestionDialog sure( tr("Directory Exists!"),
                         warningMessage, "alertIcons/warning.png",
                         this );
    if(!sure.exec()) { return; }
  }    
  //else create directory
  else
  {
    if( !tmpDir.mkdir( exportPath ) )
    {
      AlertDialog alert( tr("Error creating directory!"),
                         tr("Unable to create directory to export images to.Perhaps you are running out of disk space or you don't have sufficient privileges?"),
                           "alertIcons/warning.png", this );
      alert.exec();
      return;
    }
  }

  //set busy flag and disable buttons
  setBusy(true);
  window->getLayout()->getSubalbums()->updateButtons(false);
  if(window->getLayout()->getSubalbum() != NULL)
    window->getLayout()->getSubalbum()->updateButtons(false);
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));

  //setup progress bar
  int numPhotos = getAlbum()->getNumPhotos();  
  QString exportMessage = tr( "Exporting %1 photos" );
  window->getStatus()->showProgressBar( exportMessage.arg(numPhotos), numPhotos );
  qApp->processEvents();
  
  //export large images
  getAlbum()->exportLargeImages(window->getStatus(), exportPath, exportMessage);  

  //remove progress bar
  window->getStatus()->setStatus( tr("Exporting photos complete.") );

  //nolonger busy
  setBusy(false);
  window->getLayout()->getSubalbums()->updateButtons(true);
  if(window->getLayout()->getSubalbum() != NULL)
    window->getLayout()->getSubalbum()->updateButtons(true);
  qApp->restoreOverrideCursor();
}
//==============================================
void TitleWidget::loadAlbum(QString albumXML)
{
  //disable user input
  window->getStatus()->grabInput();
  
  //enable busy cursor, set busy flag, and deactivate buttons
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));
  setBusy(true);
  window->getLayout()->getSubalbums()->updateButtons(false);
  if(window->getLayout()->getSubalbum() != NULL)
    window->getLayout()->getSubalbum()->updateButtons(false);

  //store load/save location
  QDir lastDir = QDir( QFileInfo(albumXML).dirPath() );
  lastDir.cdUp();
  window->getConfig()->setString( "loadSave", "loadSaveDir", lastDir.path() );
 
  //create a new album (with no subalbums, hense false)
  delete albm;

  albm = new Album( createTmpDir( QFileInfo(albumXML).dirPath() ), false );
  if(albm->getTmpDir().isNull() )
  {
      AlertDialog alert( tmpDirErrorMessage, tmpDirErrorDesc + window->getConfig()->getString( "loadSave", "tempImageDirectory" ),
      "alertIcons/warning.png", this );
      alert.exec();
      quitApplication();
  }

  //attempt to load xml file
  int errorCode = albm->importFromDisk(window->getStatus(), albumXML,
                                       window->getConfig()->getBool( "loadSave", "disableCheckPhotoMods" ) );

  //if no subalbums in album then hide subalbum annotations
  if(albm->getFirstSubalbum() == NULL)
  {
    subalbumAnnotationFrame->hide();
    subalbumImage->removePixmap(true);
  }
  
  //reset editing interface since old pointers are invalid
  window->getLayout()->getSubalbum()->setSubalbum( NULL );
  refresh();

  //set album as not modified
  albm->setModified(false);
    
  //update recent albums listing
  recentAlbums.insertEntry( albm->getName(), albm->getSaveLocation(), 
                           QString("%1").arg(albm->getNumPhotos()), false );
  refreshOpenRecentMenu();  
  
  //nolonger busy
  qApp->restoreOverrideCursor();
  setBusy(false);
  window->getLayout()->getSubalbums()->updateButtons(true);
  if(window->getLayout()->getSubalbum() != NULL)
    window->getLayout()->getSubalbum()->updateButtons(true);

  //enable user input
  window->getStatus()->releaseInput(); 
  
  //load successful
  if(errorCode == ALBUM_LOADED)
  {
    //enable "revert" menu option
    file->setItemEnabled( REVERT_TO_SAVED_ALBUM, true );    

    //update presentation command based on if there are photos in this album
    updateMenus();
  }
  //else display appropriate error message
  else
  {  
    QString errorMessage, errorDescription;
    if(errorCode == ALBUM_READ_ERROR)
    {
      errorMessage = tr("Unable to open file!");
      errorDescription = tr("An error was encountered attempting to load the XML file. Perhaps you do not have read access?");
    }
    else if(errorCode == ALBUM_XML_ERROR)
    {
      errorMessage = tr("Unable to construct DOM!");
      errorDescription = tr("The XML file you selected is not valid XML.");
    }
    else
    {
      errorMessage = tr("Unknown loading error!");
      errorDescription = tr("An unknown error was encountered loading the specified file.");
    }

    AlertDialog alert( errorMessage, errorDescription, "alertIcons/warning.png", this );
    alert.exec();
  }
}
//==============================================
void TitleWidget::saveAlbum()
{
  //if album not previously saved then
  //run saveas dialog
  if(!getAlbum()->prevSave())
  {
    saveAsAlbum();
    return;
  }

  //if previously used theme not available for use again alert user,
  //then run saveas dialog
  if(!SaveDialog::themeAvailable( getAlbum()->getTheme() ))
  {
    AlertDialog alert( tr("Previous theme not available!"),
                            tr("Theme previously used to save this album not available on this machine. Click ok to open the save-as dialog to save an alternative theme."),
                            "alertIcons/warning.png", this );
    alert.exec();
    saveAsAlbum();
    return;
  }

  //set busy flag and disable buttons
  setBusy(true);
  window->getLayout()->getSubalbums()->updateButtons(false);
  if(window->getLayout()->getSubalbum() != NULL)
    window->getLayout()->getSubalbum()->updateButtons(false);
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));

  getAlbum()->exportToDisk(window->getStatus());

  window->getConfig()->setString( "loadSave", "lastUsedTheme",  getAlbum()->getTheme() );

  //update recent albums listing
  recentAlbums.insertEntry( albm->getName(), albm->getSaveLocation(), 
                            QString("%1").arg(albm->getNumPhotos()), false );
  refreshOpenRecentMenu();  

  //enable revert command since saved album now exists
  file->setItemEnabled( REVERT_TO_SAVED_ALBUM, true );    
  
  //nolonger busy
  setBusy(false);
  window->getLayout()->getSubalbums()->updateButtons(true);
  if(window->getLayout()->getSubalbum() != NULL)
    window->getLayout()->getSubalbum()->updateButtons(true);
  qApp->restoreOverrideCursor();
}
//==============================================
void TitleWidget::saveAsAlbum()
{
  //setup dialog title and default path
  QString dialogTitle = tr( "Save As" );
  QString defaultPath;

  if(getAlbum()->prevSave())
    defaultPath = getAlbum()->getSaveLocation();
  else
  {
    defaultPath = getAlbum()->getName();
    defaultPath.replace( QChar(' '), "_" );
    defaultPath.replace( "<", "" );
    defaultPath.replace( ">", "" );
    defaultPath.replace( "&", "and" );
    defaultPath.replace( "\"", "" );
    defaultPath.replace( "\'", "" );
    defaultPath.replace( "?", "" );
    defaultPath = QDir::convertSeparators
       ( window->getConfig()->getString( "loadSave", "loadSaveDir" ) + "/" + defaultPath );
  }

  //get directory name in which album directory will be placed in
  QString theme, savePath;

  //if abum saved before then auto select last used theme
  if(getAlbum()->getTheme().compare("-1") != 0)
    theme = getAlbum()->getTheme();
  else
  {
    if(window->getConfig()->getString( "loadSave", "defaultTheme" ).compare( "Last Used" ) == 0)
      theme = window->getConfig()->getString( "loadSave", "lastUsedTheme" );
    else
      theme = window->getConfig()->getString( "loadSave", "defaultTheme" );
  }

  if( !SaveDialog::selectThemeAndPath( dialogTitle, defaultPath, theme, savePath ) )
    return;

  //check if directory already exists, if not attempt to create it
  QDir d(savePath);
  if(!d.exists())
  {
    if(!d.mkdir(savePath))
    {
      AlertDialog alert( tr("Error creating directory!"),
                              tr("Unable to create directory to save album in. Perhaps you are running out of disk space or you don't have sufficient privileges?"),
                              "alertIcons/warning.png", this );
      alert.exec();
      return;
    }
  }
  else
  {
    if(!d.isReadable())
    {
      AlertDialog alert( tr("Destination directory not readable!"),
                              tr("The destination directory is not readable. Perhaps you don't have sufficient privileges?"),
                              "alertIcons/warning.png", this );
      alert.exec();
      return;
    }
  }

  //store this load/Save location
  QDir lastDir = QDir( savePath );
  lastDir.cdUp();
  window->getConfig()->setString( "loadSave", "loadSaveDir", lastDir.path() );
  window->getConfig()->setString( "loadSave", "lastUsedTheme",  theme );

  //set busy flag and disable buttons
  setBusy(true);
  window->getLayout()->getSubalbums()->updateButtons(false);
  if(window->getLayout()->getSubalbum() != NULL)
    window->getLayout()->getSubalbum()->updateButtons(false);
  qApp->setOverrideCursor( QCursor(Qt::WaitCursor));

  //save
  getAlbum()->exportToDisk(window->getStatus(), savePath, theme);
  window->getConfig()->setString( "misc", "defaultAuthor", albumAuthorVal->text() );

  //update recent albums listing
  recentAlbums.insertEntry( albm->getName(), albm->getSaveLocation(), 
                            QString("%1").arg(albm->getNumPhotos()), false );
  refreshOpenRecentMenu();  
  
  //enable revert command since saved album now exists
  file->setItemEnabled( REVERT_TO_SAVED_ALBUM, true );    
  
  //nolonger busy
  setBusy(false);
  window->getLayout()->getSubalbums()->updateButtons(true);
  if(window->getLayout()->getSubalbum() != NULL)
    window->getLayout()->getSubalbum()->updateButtons(true);
  qApp->restoreOverrideCursor();
}
//==============================================
void TitleWidget::albumStatistics()
{
  //create window and center if not already present
  if(albumStats == NULL)
  {
    albumStats = new AlbumStatistics(albm);
    connect( albumStats, SIGNAL(closed()),
           this, SLOT(albumStatisticsClosed()));
    albumStats->show();
    centerWindow(albumStats);
  }

  albumStats->raise();
  albumStats->setActiveWindow();
}
//==============================================
void TitleWidget::removeSelectedPhotoDesc()
{
  //if no subalbum or photos selected ignore command
  if(window->getLayout()->getSubalbum() == NULL ||
     !window->getLayout()->getSubalbum()->anyPhotosSelected())
     return;

  //ask user if they are sure they want to remove selected photo descriptions
  if( window->getConfig()->getBool( "alerts", "showDestructiveAlerts" ) )
  {
    QuestionDialog sure( tr("Remove Selected Photo Descriptions?"),
                                   tr("This action cannot be undone. Are you sure you want to proceed?"),
                                   "alertIcons/warning.png",
                                   this );
    if(!sure.exec())
      return;
  }

  //proceed with stripping of photo descriptions
  window->getLayout()->getSubalbum()->stripDescriptionsFromSelectedPhotos();
}
//==============================================
void TitleWidget::revertPhotos()
{  
  window->getLayout()->revertPhotos();
}
//==============================================
void TitleWidget::settings()
{
  //create window and center if not already present
  if(settingsWindow == NULL)
  {
    settingsWindow = new ConfigurationWidget( window->getConfig() );
    connect( settingsWindow, SIGNAL(closed()),
                  this, SLOT(settingsWindowClosed()));
    settingsWindow->show();
    centerWindow(settingsWindow);
  }

  settingsWindow->raise();
  settingsWindow->setActiveWindow();
}
//==============================================
void TitleWidget::aboutProgram(int mode)
{
  //create window and center if not already present
  if(about == NULL)
  {
    about = new About(mode);
    connect( about, SIGNAL(closed()),
             this, SLOT(aboutClosed()));
    about->show();
    centerWindow(about);
  }

  about->raise();
  about->setActiveWindow();
}
//==============================================
void TitleWidget::help()
{
  //create window and center if not already present
  if(helpWindow == NULL)
  {
    helpWindow = new HelpWindow(0);
    connect( helpWindow, SIGNAL(closed()),
             this, SLOT(helpClosed()));
    helpWindow->show();
    centerWindow(helpWindow);
  }

  helpWindow->raise();
  helpWindow->setActiveWindow();
}
//==============================================
void TitleWidget::albumStatisticsClosed()
{
  delete albumStats;
  albumStats = NULL;
}
//==============================================
void TitleWidget::aboutClosed()
{
  delete about;
  about = NULL;
}
//==============================================
void TitleWidget::helpClosed()
{
  delete helpWindow;
  helpWindow = NULL;
}
//==============================================
void TitleWidget::settingsWindowClosed()
{
  delete settingsWindow;
  settingsWindow = NULL;
}
//==============================================
bool TitleWidget::getBusy()
{
  return busy;
}
//==============================================
void TitleWidget::setBusy(bool val)
{
  busy = val;

  //disable/enable file operations
  if(busy)
  {
    file->setItemEnabled(NEW_ALBUM, false);
    file->setItemEnabled(OPEN_ALBUM, false);
    file->setItemEnabled(SAVE_ALBUM, false);
    file->setItemEnabled(SAVEAS_ALBUM, false);
  }
  else
  {
    file->setItemEnabled(NEW_ALBUM, true);
    file->setItemEnabled(OPEN_ALBUM, true);
    file->setItemEnabled(SAVE_ALBUM, true);
    file->setItemEnabled(SAVEAS_ALBUM, true);
  }
}
//==============================================
void TitleWidget::quitApplication()
{
  window->close();
}
//==============================================
void TitleWidget::dragEnterEvent( QDragEnterEvent* e)
{
  e->accept(true);
}
//==============================================
void TitleWidget::dropEvent( QDropEvent* e )
{
  //force redraw so we don't see missing unpainted
  //region while we resize an image which takes a while.
  repaint(false);
  qApp->processEvents();

  //if the source is not the origanize icon view then ignore the event
  if(e->source() == NULL ||
     e->source()->parentWidget() != window->getLayout()->getSubalbum()->getPhotos())
    return;
  
  if( e->pos().x() < (width() / 2) )
    setAlbumImage();
  else
    setSubalbumImage();
}
//==============================================
QString TitleWidget::createTmpDir(QString albumPath)
{
  //if album path provided attempt to create tmp directory in there to
  //minimize cost of doing moves when saving album changes.
  //the other reasoning is that user will have hopefully provided enough
  //space for saving large files on directory where they previously saved,
  //so this minmizes the chance of running out of disk hopefully
  if(!albumPath.isNull())
  {
    QDir rootDir( albumPath );
    if(rootDir.exists( "tmp" ) || rootDir.mkdir( "tmp" ))
    return QDir::convertSeparators( albumPath + "/tmp" );
  }

  //otherwise create unique tmp dir under scratch dir user specified in preferences
  QDate date = QDate::currentDate();
  QTime time = QTime::currentTime();
  QString baseDir = window->getConfig()->getString( "loadSave", "tempImageDirectory" );

  QDir testPath(baseDir);
  if(!testPath.exists())
  {
    window->getConfig()->resetSetting( "loadSave", "tempImageDirectory" );
    baseDir = window->getConfig()->getString( "loadSave", "tempImageDirectory" );
  }

  QString tmpDir = QString("albumshaper_tmp%1%2%3%4%5%6%7").arg( date.year() ).arg( date.month() ).arg
                                  ( date.day() ).arg( time.hour() ).arg( time.minute() ).arg( time.second() ).arg( time.msec() );

  QDir rootDir( baseDir );
  if(rootDir.exists() && (rootDir.exists( tmpDir ) || rootDir.mkdir( tmpDir) ) )
  {
/*    AlertDialog alert( "tmpDir:", QDir::convertSeparators( QString("(" + baseDir + "/" + tmpDir ) ),
    "alertIcons/warning.png", this );
    alert.exec();
*/
    return QDir::convertSeparators( baseDir + "/" + tmpDir );
  }
  else
  {
//    cout << "ERROR!\n";
    return QString::null;
  }
}
//==============================================
//PLATFORM_SPECIFIC_CODE
#if defined(Q_OS_MACX)
void TitleWidget::windowStateChanged(bool state)
{
  //disable "Minimize" menu entry if window is minimized
  windowMenu->setItemEnabled(WINDOW_MINIMIZE, state);
}
#else
void TitleWidget::windowStateChanged(bool)
{ 
//Do nothing 
}
#endif
//==============================================
void TitleWidget::clearOpenRecentMenu()
{
  //clear recent list
  recentAlbums.clearList();
  
  //refresh menu
  refreshOpenRecentMenu();
}
//==============================================
void TitleWidget::populateOpenRecentMenu()
{
  int maxItems = recentAlbums.getMaxItems();
  numRecentMenuItems = maxItems + 2; //+2 for seperator and clear entry
  recentMenuItems = new int[numRecentMenuItems];
  customRecentMenuItems = new RecentAlbumMenuItem*[maxItems];
  
  //insert recent albums into menu
  int i;
  for(i = 0; i<maxItems; i++)
  {
    Key key;
    if(i == 0) key = Key_1;
    else if(i == 1) key = Key_2;
    else if(i == 2) key = Key_3;
    else if(i == 3) key = Key_4;
    else if(i == 4) key = Key_5;
    else if(i == 5) key = Key_6;
    else if(i == 6) key = Key_7;
    else if(i == 7) key = Key_8;
    else if(i == 8) key = Key_9;
    else key = Key_unknown;
    
    //get album name + location
    QString recentName = "recentName";
    QString recentLocation = "recentLocation";
    QString recentPhotoCount = "recentPhotoCount";
    
    //----------------------------------------------    
    //PLATFORM_SPECIFIC_CODE
#if defined(Q_OS_MACX)
    //Mac OS X does not support custom painted system menu entries. :(
    recentMenuItems[i] = openRecent->insertItem( "uninitialized recent album",
                                         this, SLOT(loadRecentAlbum(int)) );  
    //----------------------------------------------    
    //Under other operating systems (Windows, Linux, FreeBSD) use custom recent album menu item 
    //such that album image is larger and more detail is provided
#else  
    customRecentMenuItems[i] = new RecentAlbumMenuItem(key);
    recentMenuItems[i] = openRecent->insertItem( customRecentMenuItems[i] );
    openRecent->connectItem( recentMenuItems[i], this, SLOT(loadRecentAlbum(int)) );
#endif   
    //----------------------------------------------         
    //Set accelerator key sequence if valid    
    if( key != Key_unknown )
    {
      openRecent->setAccel( CTRL+key, recentMenuItems[i] ); 
      openRecent->setItemParameter( recentMenuItems[i], i );
    }

    //hide + disable entry
    openRecent->setItemVisible( recentMenuItems[i], false );    
    openRecent->setItemEnabled( recentMenuItems[i], false );      
    //----------------------------------------------         
  }
  
  //insert separator and "clear menu" entry.
  recentMenuItems[numRecentMenuItems-2] = openRecent->insertSeparator();
  recentMenuItems[numRecentMenuItems-1] = openRecent->insertItem( tr("Clear Menu"), 
                                                                  this, 
                                                                  SLOT(clearOpenRecentMenu()) );  
  
  //hide separtor, disable clear entry
  openRecent->setItemVisible( recentMenuItems[numRecentMenuItems-2], false );    
  openRecent->setItemEnabled( recentMenuItems[numRecentMenuItems-1], false );      
}
//==============================================
void TitleWidget::refreshOpenRecentMenu()
{
  //update text, visibility, and enabled bit for all items in list
  int i;

#ifndef Q_OS_MACX
  int maxWidth=0;
#endif

  for(i=0; i<numRecentMenuItems; i++)
  {
    //----------------------------------------------    
    //item - update fields, enable, and show
    QString recentName, recentLocation, recentPhotoCount;
    QDir tempDir;
    if( i < recentAlbums.numEntries())
    {
      //get album name + location
      recentAlbums.getEntry( i, recentName, recentLocation, recentPhotoCount );
      //----------------------------------------------    
      //PLATFORM_SPECIFIC_CODE
      //Mac OS X does not support custom painted system menu entries. :(
#if defined(Q_OS_MACX)
      QString albumImageLocation = QDir::convertSeparators( recentLocation + "/img/album.jpg" );
      
      //don't display photo count if not available (-1)
      if(recentPhotoCount.compare("-1") == 0)
        recentPhotoCount = "";
      else
        recentPhotoCount = " (" + recentPhotoCount + ")";
      
      //if album image exits resize it and use for menu item icon
      if( tempDir.exists( albumImageLocation ) )
      {
        //scale image
        QImage scaledAlbumImage;
        scaleImage( albumImageLocation, scaledAlbumImage, 32, 32 );
        
        //use text and pixmap
        QPixmap scaledAlbumImagePixmap;
        scaledAlbumImagePixmap.convertFromImage( scaledAlbumImage );
        
        openRecent->changeItem( recentMenuItems[i],
                                QIconSet( scaledAlbumImagePixmap ),
                                QString("%1%2").arg(recentName).arg(recentPhotoCount) );
      }      
      //otherwise simply display the album name and number of phots (if available)
      else
      {
        //using just text
        openRecent->changeItem( recentMenuItems[i],
                                QIconSet(NULL),
                                QString("%1%2").arg(recentName).arg(recentPhotoCount) );
      }
      //----------------------------------------------    
      //Under other operating systems (Windows, Linux, FreeBSD) use custom recent album menu item 
      //such that album image is larger and more detail is provided
#else  
      customRecentMenuItems[i]->changeItem( recentName, recentLocation, recentPhotoCount );                                           
      maxWidth = QMAX( maxWidth, customRecentMenuItems[i]->sizeHint().width() );
#endif   
      //----------------------------------------------         
      openRecent->setItemEnabled( recentMenuItems[i], true );      
      openRecent->setItemVisible( recentMenuItems[i], true );    
      
      //if the Album.xml file is unavailable then disable menu entry
      if( !tempDir.exists( QDir::convertSeparators(recentLocation + "/Album.xml") ) )
        openRecent->setItemEnabled( recentMenuItems[i], false );    
    }
    //----------------------------------------------         
    //hidden item - disable and hide
    else if( i >= recentAlbums.numEntries() &&
             i < numRecentMenuItems-2 )
    {
      openRecent->setItemEnabled( recentMenuItems[i], false );      
      openRecent->setItemVisible( recentMenuItems[i], false );    
    }
    //----------------------------------------------         
    //separtor - show if one or more items in list
    else if (i == numRecentMenuItems-2)
    {
      openRecent->setItemVisible( recentMenuItems[numRecentMenuItems-2], 
                                  recentAlbums.numEntries() > 0 );    
    }
    //----------------------------------------------         
    //clear items - enable if items in list
    else if (i == numRecentMenuItems-1)
    {
      openRecent->setItemEnabled( recentMenuItems[numRecentMenuItems-1], 
                                  recentAlbums.numEntries() > 0 );    
    }
    //----------------------------------------------         
  }


  //pass over custom menu items a second time letting them know the maximum item width
#ifndef Q_OS_MACX
  for(i=0; i<recentAlbums.numEntries(); i++)
  {
    customRecentMenuItems[i]->setMaxWidth( maxWidth );
  }
#endif

}
//==============================================
RecentAlbums* TitleWidget::getRecentAlbums()
{
  return &recentAlbums; 
}
//==============================================
void TitleWidget::updateMenus(bool anySelected, bool anyRevertable)
{
  //no photos? disable begin presentation command
//  tools->setItemEnabled( BEGIN_PRESENTATION, albm->getNumPhotos() != 0 );
//  tools->setItemEnabled( BEGIN_PRESENTATION_AT, albm->getNumPhotos() != 0 );  

  //none selected? disable removing photo descriptions
  photoMenu->setItemEnabled( REMOVE_DESCRIPTIONS, anySelected );

  //none revertable? disable revert photos
  photoMenu->setItemEnabled( REVERT_PHOTOS, anyRevertable );
}
//==============================================
