//==============================================
//  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 <qframe.h>
#include <qlayout.h>
#include <qpixmap.h>
#include <qtooltip.h>
#include <qdir.h>
#include <qapplication.h>
#include <qiconview.h>

//PLATFORM_SPECIFIC_CODE
#if defined(Q_OS_MACX)
#include "/Developer/Headers/FlatCarbon/Carbon.h"
#endif

//Projectwide includes
#include "window.h"
#include "titleWidget.h"
#include "layoutWidget.h"
#include "statusWidget.h"
#include "subalbumsWidget.h"
#include "subalbumWidget.h"
#include "dialogs/questionDialog.h"
#include "dialogs/alertDialog.h"

//#include "presentation/presentationWidget.h"
#include "../config.h"
#include "../backend/album.h"
#include "../backend/subalbum.h"
#include "../backend/photo.h"
#include "../backend/recentAlbums.h"
#include "../configuration/configuration.h"
#include "../configuration/loadingSavingWidget.h"
#include "../configuration/layoutSettingsWidget.h"
#include "../configuration/alertsWidget.h"
#include "../configuration/miscSettings.h"

//==============================================
Window::Window( QWidget* parent, const char* name ) : QWidget(parent,name)
{
  //don't clear pixmap area before painting, prevents flicker
  setWFlags(WRepaintNoErase);

  //load shadow pixmaps
  shadowBL = new QPixmap( QString(IMAGE_PATH)+"miscImages/photoGradientBottomLeft.png" );
  shadowB = new QPixmap( QString(IMAGE_PATH)+"miscImages/photoGradientBottom.png" );
  shadowBR = new QPixmap( QString(IMAGE_PATH)+"miscImages/photoGradientBottomRight.png" );
  shadowR = new QPixmap( QString(IMAGE_PATH)+"miscImages/photoGradientRight.png" );
  shadowTR = new QPixmap( QString(IMAGE_PATH)+"miscImages/photoGradientTopRight.png" );

  //load photo info pixmap
  photoInfo = new QPixmap( QString(IMAGE_PATH)+"buttonIcons/photoInfo.png");

  //------------------------------------------------
  //create configuration object with default settings
  config = new Configuration();
  LoadingSavingWidget::setDefaults(config);
  LayoutSettingsWidget::setDefaults(config);
  AlertsWidget::setDefaults(config);
  MiscSettings::setDefaults(config);
  //------------------------------------------------
  //load user settings
  config->loadSettings();

  //if temorary image directory does not exist create it
  QDir homeDir;
  bool configDirMade = true;
  if(!homeDir.exists( config->getString( "loadSave", "tempImageDirectory")) )
  { configDirMade = homeDir.mkdir( config->getString( "loadSave", "tempImageDirectory")); }
  //if directory could not be made attempt to revert to default directory
  if(!configDirMade)
  {
    AlertDialog alert( "unable to create temp dir", QString("unable to make temporary directory! (" + config->getString( "loadSave", "tempImageDirectory") ),
  "alertIcons/warning.png", this );
  alert.exec();


    config->resetSetting( "loadSave", "tempImageDirectory" );
    configDirMade = true;
    if(!homeDir.exists( config->getString( "loadSave", "tempImageDirectory")) )
    { configDirMade = homeDir.mkdir( config->getString( "loadSave", "tempImageDirectory")); }
  }

  //if we are still unable to create the temporary image directory then immediately abort
  if(!configDirMade)
  {
      AlertDialog alert( "unable to create temp dir", QString("unable to make temporary directory! (" + config->getString( "loadSave", "tempImageDirectory") ),
  "alertIcons/warning.png", this );
  alert.exec();

close();
  }

  //------------------------------------------------
  //create top level widgets
  title  = new TitleWidget (this, "title");
  layout = new LayoutWidget(this, "layout");
  status = new StatusWidget(this, "status");

  ///refresh title annotations when collections are selected
  connect( layout, SIGNAL(collectionSelected(Subalbum*)),
           title,  SLOT(refreshCollectionAnnotations(Subalbum*)) );

  ///refresh collection icons when collection names are edited
  connect( title,  SIGNAL(subalbumNameChanged()),
           layout, SLOT(refreshSelectedCollectionIconName()) );
  
//  slideshow = new SlideshowWidget(this, "slideshow", WResizeNoErase);
//  slideshow->hide();
//  connect( slideshow, SIGNAL(endSlideshow()), this, SLOT(endSlideshow()) );
    
  //refresh subalbums listing
  layout->refresh();

  //place widgets in main frame
  grid = new QGridLayout( this, 3, 2, 0);                
  grid->addWidget( title,     0, 0 );
  grid->addWidget( layout,    1, 0 );
  grid->setRowStretch( 1, 1 );
  grid->addWidget( status,    2, 0 );
  grid->setRowSpacing( 2, 24 );
//  grid->addMultiCellWidget( slideshow, 0, 2, 1, 1 );
  grid->setColStretch(0, 1 );  
  
  //PLATFORM_SPECIFIC_CODE
  //create and set application icon
  #if( !defined(Q_OS_MACX) && !defined(Q_OS_WIN) )
  setIcon( QPixmap(QString(IMAGE_PATH)+"miscImages/as32.png") );
  #endif

  setCaption( 
#ifdef CVS_CODE
      "(CVS BUILD) " +        
#endif              
              tr("Album Shaper"));
  //------------------------------------------------
  //apply settings
  QToolTip::setGloballyEnabled( config->getBool( "layout", "showTooltips" ) );
  title->useAnimation( config->getBool( "layout", "animation" ) );
  //------------------------------------------------
}
//==============================================
Window::~Window()
{
  //flush and reinsert recent albums listing
  config->removeGroup( "recentAlbums" );
  RecentAlbums* recentAlbums = title->getRecentAlbums();
  int num = recentAlbums->numEntries();
  int i;
  QString albumName, albumLocation, albumPhotoCount;
  for(i=0; i<num; i++)
  {
    recentAlbums->getEntry( i, albumName, albumLocation, albumPhotoCount );
    config->setString( "recentAlbums", QString("%1_name").arg(i),     albumName );
    config->setString( "recentAlbums", QString("%1_location").arg(i), albumLocation );    
    config->setString( "recentAlbums", QString("%1_photoCount").arg(i), albumPhotoCount );    
  }  
  
  //store window size and placement in config object
  config->setInt( "layout", "windowPosX", pos().x() );
  config->setInt( "layout", "windowPosY", pos().y() );
  config->setInt( "layout", "windowWidth", size().width() );
  config->setInt( "layout", "windowHeight", size().height() );

  //save user settings
  config->saveSettings();

  //delete non-qt objects
  delete config;
  config = NULL;
}
//==============================================
TitleWidget* Window::getTitle()
{
  return title;
}
//==============================================
LayoutWidget* Window::getLayout()
{
  return layout;
}
//==============================================
StatusWidget* Window::getStatus()
{
  return status;
}
//==============================================
void Window::refresh()
{
  layout->refresh();
}
//==============================================
void Window::closeEvent( QCloseEvent* e)
{
  //check if unsaved modifications exist, warn user they
  //will lose these if they quit now
  if(title->getAlbum()->albumModified() )
  {
    //if user has chosen to not receive destructive action warnings, or agrees to the action then quit
    bool proceed = (!config->getBool( "alerts", "showDestructiveAlerts" ));
    if(!proceed)
    {
      QuestionDialog sure( tr("Quit without saving?"),
                                       tr("You have unsaved work. Are you sure you want to quit without saving?"),
                                       "alertIcons/warning.png",
                                       this );
      proceed = sure.exec();
    }
    if(proceed)
      e->accept();
    else
      e->ignore();
  }
  else
  {
    e->accept();
  }
}
//==============================================
Configuration* Window::getConfig()
{
  return config;
}
//==============================================
/*
 void Window::startSlideshowAtBeginning()
{
  startSlideshow(true);
}  
//==============================================
void Window::startSlideshowWithSelectedPhoto()
{
  startSlideshow(false);  
}
//==============================================
 void Window::startSlideshow( bool startAtBeginning )
{ 
  //setup presentation
  if( startAtBeginning ) 
  {
    //start the slideshow
    slideshow->beginSlideshow(title->getAlbum());
  }
  else
  {
    //get selected collection
    Subalbum* startCollection = layout->getSubalbums()->getSelectedSubalbum();
  
    //get selected photo.if no photos selected in collection then we'll start with first photo in collection
    Photo* startPhoto = layout->getSubalbum()->getFirstSelectedPhoto();
    if(startPhoto == NULL) startPhoto = startCollection->getFirst();

    //start the slideshow
    slideshow->beginSlideshow( title->getAlbum(), 
                               startCollection, startPhoto );
  }

  //hide title, layout, and status widgets
  //show slideshow region fullscreen
  grid->setColStretch(0, 0 );  
  grid->setColStretch(1, 1 );  
  title->hide();
  layout->hide();
  status->hide();
  slideshow->show();
  slideshow->setFocus(); 
  
  //PLATFORM_SPECIFIC_CODE
  #if defined(Q_OS_MACX)
  SetSystemUIMode(kUIModeAllHidden, NULL);
  #endif

  showFullScreen();
}
//==============================================
void Window::endSlideshow()
{
  //exit from fullscreen mode
  showNormal();

  //PLATFORM_SPECIFIC_CODE
  #if defined(Q_OS_MACX)
  SetSystemUIMode(kUIModeNormal, NULL);
  #endif
    
  //give collection contents keyboard focus and select
  //and ensure visibility of last shown photo during presentation
  layout->getSubalbum()->getPhotos()->setFocus();
 
  Subalbum* tmpCollection = slideshow->getCurCollection();
  Photo* tmpPhoto = slideshow->getCurPhoto();

  if(tmpCollection != NULL)
  {
    layout->getSubalbums()->setSelectedSubalbum( tmpCollection );      
    if(tmpPhoto != NULL) 
    { 
      layout->getSubalbum()->setSelectedPhoto( tmpPhoto ); 
    }    
  }
  
  //hide slideshow and bring title, layout, and status back up
  title->show();
  layout->show();
  status->show();
  slideshow->hide();
  grid->setColStretch(1, 0 );  
  grid->setColStretch(0, 1 );  
  
}
*/
//==============================================
bool Window::event( QEvent *e )
{
  //if base class handles event return immediately
  if (QWidget::event( e ) )
    return true;
  
  //handle showMinimized events
  if ( e->type() == QEvent::ShowMinimized )
  {
    //update menu entries as per window state change
    title->windowStateChanged( false );
    return true;
  }
  
  return false;
}
//==============================================
void Window::hideEvent( QHideEvent *)
{
  //update menu entries as per window state change
  title->windowStateChanged( false );
}
//==============================================
void Window::showEvent ( QShowEvent * )
{
  //update menu entries as per window state change
  title->windowStateChanged( true );
}
//==============================================
