//==============================================
//  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 <qlayout.h>
#include <qlabel.h>
#include <qfont.h>
#include <qiconset.h>
#include <qpixmap.h>
#include <qtabwidget.h>
#include <qtextbrowser.h>
#include <qpushbutton.h>
#include <qstringlist.h>
#include <qdatetime.h>
#include <qfile.h>
#include <qdir.h>
#include <qdom.h>
#include <qstringlist.h>
#include <qmovie.h>
#include <qapplication.h>
#include <qframe.h>

//Projectwide includes
#include "about.h"
#include "../titleWidget.h"
#include "../window.h"
#include "../../config.h"
#include "../../configuration/configuration.h"

#define DEFAULT_WIDTH 600
#define DEFAULT_HEIGHT 500

#define UNSET 0
#define GET_RELEASES 1
#define GET_NEW_IMPROVEMENTS 2
#define GET_UPCOMING_FEATURES 3

//==============================================
About::About( int mode, QWidget* parent,  const char* name ) :  QDialog(parent,name)
{
  displayMode = mode;
  //--------------------------------------------------------------
  QColor white(255, 255, 255);
  QColor darkBlue(35, 75, 139);
  QColor black(0, 0, 0);
  //--------------------------------------------------------------
  //by default not getting anything
  getMode = UNSET;
  //--
  //set window title
  setCaption( tr("About Album Shaper"));
  //--
  //application logo
  QFrame* logoFrame = new QFrame( this );
  logoFrame->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
  albumShaperLogo = new QLabel( logoFrame );
  albumShaperLogo->setPixmap( QPixmap( QString(IMAGE_PATH)+"miscImages/albumShaper.png" ) );
  //--
  //if user chooses to get product updates information
  releases = NULL;
  if(((Window*)(qApp->mainWidget()))->getConfig()->getBool( "alerts", "showSoftwareUpdateAlerts"))
  {
    //set http host
    http.setHost( "albumshaper.sourceforge.net" );
    connect( &http, SIGNAL(done(bool)), this, SLOT(fileFetched(bool)) );
    //--
    //attempt to get releases list from website. this lets us find out if this
    //copy of Album Shaper is outdated, and also allows us to know what
    //changelogs to get.
    getMode = GET_RELEASES;
    http.get( "/webService/releases.xml");
  }
  //--
  //text labels
  QDate currentDate = QDate::currentDate();
  int copyYearFirst = QMIN( currentDate.year(), 2003 );
  int copyYearLast = QMAX( currentDate.year(), 2004 );
   

  progDesc = new QLabel( QString("Album Shaper " + 
                                 QString(ALBUMSHAPER_VERSION) + 
                                 ", © %1-%2 Will Stokes").arg(copyYearFirst).arg(copyYearLast), 
                         logoFrame );

  progURL = new QLabel( "http://albumshaper.sourceforge.net", logoFrame );

  
  QFont textFont = progDesc->font();
  textFont.setWeight(QFont::Bold);
  progDesc->setFont( textFont );
  progURL->setFont( textFont );
  //--
  //tab widget which contains credits, changelog, etc
  tabWidget = new QTabWidget( this );
  //--
  //create credits tab
  credits = new QTextBrowser( this );
  credits->setFrameStyle( QFrame::Panel | QFrame::Sunken );
  credits->mimeSourceFactory()->setFilePath( QStringList(TEXT_PATH) );
  credits->setSource( "about.html");
  tabWidget->addTab(credits, 
                    QIconSet( QPixmap(QString(IMAGE_PATH)+"tabIcons/credits.png") ), 
                    tr("Credits") );
   //--
  //create history tab
  history = new QTextBrowser(this);
  history->setFrameStyle( QFrame::Panel | QFrame::Sunken );
  history->mimeSourceFactory()->setFilePath( QStringList(TEXT_PATH) );
  history->setSource( "history.html");
  tabWidget->addTab(history, 
                    QIconSet( QPixmap(QString(IMAGE_PATH)+"tabIcons/history.png") ), 
                    tr("History") );
  //--
  //create close button
  closeButton = new QPushButton(
  //PLATFORM_SPECIFIC_CODE
  #ifndef Q_OS_MACX
  QPixmap(QString(IMAGE_PATH)+"buttonIcons/button_ok.png"),
  #endif
                              tr("Close"),
                              this );
  closeButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
  closeButton->setDefault(true);
  connect( closeButton, SIGNAL(clicked()), SLOT(close()) );
  //--
  logoFrame->setPaletteBackgroundColor( darkBlue );
  progDesc->setPaletteForegroundColor( white );
  progDesc->setPaletteBackgroundColor( darkBlue );
  progURL->setPaletteForegroundColor( white );
  progURL->setPaletteBackgroundColor( darkBlue );
  tabWidget->setPaletteForegroundColor( black );
  //--
  QGridLayout* logoGrid = new QGridLayout( logoFrame, 4, 3, 0);
  logoGrid->setSpacing(WIDGET_SPACING);
  logoGrid->addWidget( albumShaperLogo,  0, 1, Qt::AlignCenter );
  logoGrid->addWidget( progDesc,  2, 1, Qt::AlignCenter );
  logoGrid->addWidget( progURL,  3, 1, Qt::AlignCenter );

  grid = new QGridLayout( this, 3, 1, 0);
  grid->setSpacing(WIDGET_SPACING);
  grid->addWidget( logoFrame,  0, 0 );
  grid->addWidget( tabWidget, 1, 0 );
  grid->addWidget( closeButton, 2, 0, Qt::AlignCenter );
  resize( DEFAULT_WIDTH, DEFAULT_HEIGHT );
  //--
  //show secret images around Album Shaper's birthday (first release date - 4/3/2003)
  if( currentDate.year() > 2003 && currentDate.month() == 4 && currentDate.day() <= 3)
  {
    QLabel* cakeLogo = new QLabel(logoFrame);
    cakeLogo->setPixmap( QPixmap( QString(IMAGE_PATH)+"miscImages/birthdayL.png" ) );
    QLabel* cakeLogo2 = new QLabel(logoFrame);
    cakeLogo2->setPixmap( QPixmap( QString(IMAGE_PATH)+"miscImages/birthdayR.png" ) );
    QLabel* cakeMessage = new QLabel( QString( tr("Happy Birthday Album Shaper!") +
                                               QString(" %1 ").arg(currentDate.year() - 2003) +
                                               ( currentDate.year()-2003 == 1 ? tr("Year Old!") : tr("Years Old!")) ), logoFrame );
    cakeMessage->setFont(textFont);
    cakeMessage->setPaletteForegroundColor( white );
    //--
    logoGrid->addWidget( cakeLogo, 0, 0, Qt::AlignCenter );
    logoGrid->addWidget( cakeLogo2, 0, 2, Qt::AlignCenter );
    logoGrid->addMultiCellWidget( cakeMessage, 1, 1, 0, 2, Qt::AlignCenter );
  }
  //-------------------------------
  //set window to not be resizeable
  this->show();
  setFixedSize(size());
  //-------------------------------
}
//==============================================
About::~About()
{
  delete releases;
  releases = NULL;
}
//==============================================
void About::fileFetched(bool error)
{
  //------------------------------------------------------------
  //if unable to get file bail
  if(error)
  {
    getMode = UNSET;
    return;
  }
  //------------------------------------------------------------
  //getting releases?
  if(getMode == GET_RELEASES)
  {
    //write releases to temp file
    QFile fetchedDoc( TEMP_DIR + QString("/releases.xml") );
    if(fetchedDoc.open(IO_WriteOnly))
    {
      //----------------------------
      //write to file
      QTextStream stream( &fetchedDoc );
      stream.setEncoding( QTextStream::UnicodeUTF8 );
      stream << QString( http.readAll() );
      fetchedDoc.close();
      //----------------------------
      //parse xml file, construct string list of releases
      //open file, bail if unable to
      if( !fetchedDoc.open( IO_ReadOnly ) )
      {
        getMode = UNSET;
        return;
      }

      //parse dom
      QDomDocument xmlDom;
      if( !xmlDom.setContent( &fetchedDoc ) )
      {
        fetchedDoc.close();
        getMode = UNSET;
        return;
      }

      //close file
      fetchedDoc.close();

      //construct stringlist of releases
      releases = new QStringList();
      QDomElement root = xmlDom.documentElement();
      QDomNode node = root.firstChild();
      QDomText val;
      bool thisVersionFound = false;
      while( !node.isNull() )
      {
        if( node.isElement() && node.nodeName() == "release" )
        {
          val = node.firstChild().toText();
          if(!val.isNull())
          {
            //append release #
            releases->append( QString(val.nodeValue()) );

            //is release this version?
            if( QString(val.nodeValue()).compare( QString(ALBUMSHAPER_VERSION) ) == 0 )
              thisVersionFound = true;

          }
        }
        node = node.nextSibling();
      }

      //else if this version is not first on list but it was found in list then newer releases exist
      if(thisVersionFound && releases->first().compare( QString(ALBUMSHAPER_VERSION) ) != 0 )
      {
        //create new improvements file with beginning html and body tags
        QFile fetchedDoc( TEMP_DIR  + QString("/newImprovements.html") );
        if(fetchedDoc.open(IO_WriteOnly))
        {
          QTextStream stream( &fetchedDoc );          stream.setEncoding( QTextStream::UnicodeUTF8 );
          stream << "<html><body bgcolor=\"white\" text=\"black\">\n";
          stream << "<b><font size=\"+1\">" << tr("New improvements to Album Shaper are available in a new release!") << "<br><hr></font></b>";
          fetchedDoc.close();
        }

        getMode = GET_NEW_IMPROVEMENTS;
        http.get( "/webService/" + releases->first() + "_changelog.html");
      }
      //else we're up to date! move on to checking for new features in cvs!
      else
      {
        newImprovements = new QTextBrowser( this );
        newImprovements->setFrameStyle( QFrame::Panel | QFrame::Sunken );
        newImprovements->mimeSourceFactory()->setFilePath( QStringList(TEXT_PATH) );

        //bleeding edge message
        if(!thisVersionFound)
        {
          newImprovements->setSource( "bleedingEdge.html");
        }
        else
        {
          newImprovements->setSource( "noUpdates.html");
        }

        tabWidget->addTab(newImprovements, 
                          QIconSet( QPixmap(QString(IMAGE_PATH)+"tabIcons/newImprovements.png") ),
                          tr("Software Updates") );

        if(displayMode == UPDATES)
          tabWidget->setCurrentPage( tabWidget->indexOf( newImprovements ) );

        getMode = GET_UPCOMING_FEATURES;
        http.get( "/webService/upcomingFeatures.html");
      }
      //----------------------------
      //delete file
      QDir rootDir( TEMP_DIR );
      rootDir.remove("releases.xml");
      //----------------------------
    }
    else
    {
      getMode = UNSET;
    }
  }
  //------------------------------------------------------------
  else if(getMode == GET_NEW_IMPROVEMENTS)
  {
    //write additional changelog information to disk
    QFile fetchedDoc( TEMP_DIR + QString("/newImprovements.html") );
    if(fetchedDoc.open(IO_WriteOnly | IO_Append))
    {
      //write to file
      QTextStream stream( &fetchedDoc );
      stream.setEncoding( QTextStream::UnicodeUTF8 );
      stream << QString( http.readAll() );
      fetchedDoc.close();

      //pop of release from stack
      releases->pop_front();

      //if stack empty then or we've goten up to this version add new tab with changes
      if(releases->isEmpty() ||
         releases->first().compare( QString(ALBUMSHAPER_VERSION) ) == 0 )
      {
        //tack on the end body and html tags
        if(fetchedDoc.open(IO_WriteOnly | IO_Append))
        {
          //write to file
          QTextStream stream( &fetchedDoc );
          stream.setEncoding( QTextStream::UnicodeUTF8 );
          stream << "</body></html>";
          fetchedDoc.close();
        
          newImprovements = new QTextBrowser(this);
          newImprovements->setFrameStyle( QFrame::Panel | QFrame::Sunken );
          newImprovements->mimeSourceFactory()->setFilePath( TEMP_DIR );
          newImprovements->setSource( "newImprovements.html" );
          tabWidget->addTab(newImprovements, 
                            QIconSet( QPixmap(QString(IMAGE_PATH)+"tabIcons/newImprovements.png") ),
                            tr("Software Updates") );
          tabWidget->setCurrentPage( tabWidget->indexOf( newImprovements ) );;

          //move on to checking for upcoming features
          getMode = GET_UPCOMING_FEATURES;
          http.get( "/webService/upcomingFeatures.html");
        }
        else
        {
          getMode = UNSET;
        }
      }
      //if not empty then get even more new features!
      else
      {
        http.get( "/webService/" + releases->first() + "_changelog.html");
      }
    }
    else
    {
      getMode = UNSET;
    }
  }
  //------------------------------------------------------------
  //getting upcoming features?
  else if(getMode == GET_UPCOMING_FEATURES)
  {
    //write upcoming features to temp file
    QFile fetchedDoc( TEMP_DIR + QString("/upcomingFeatures.html") );
    if(fetchedDoc.open(IO_WriteOnly))
    {
      //write to file
      QTextStream stream( &fetchedDoc );
      stream.setEncoding( QTextStream::UnicodeUTF8 );
      stream << QString( http.readAll() );
      fetchedDoc.close();

      //add tab
      upcomingFeatures = new QTextBrowser(this);
      upcomingFeatures->setFrameStyle( QFrame::Panel | QFrame::Sunken );
      upcomingFeatures->mimeSourceFactory()->setFilePath( TEMP_DIR );
      upcomingFeatures->setSource( "upcomingFeatures.html" );
      tabWidget->addTab(upcomingFeatures, 
                        QIconSet( QPixmap(QString(IMAGE_PATH)+"tabIcons/upcomingFeatures.png") ),
                        tr("Upcoming Features") );

      if(displayMode == UPCOMING)
        tabWidget->setCurrentPage( tabWidget->indexOf( upcomingFeatures ) );

      //delete file
      QDir rootDir( TEMP_DIR );
      rootDir.remove("upcomingFeatures.html");
    }

    getMode = UNSET;
  }
  //------------------------------------------------------------
}
//==============================================
void About::closeEvent( QCloseEvent* e)
{
  QWidget::closeEvent( e );
  emit closed();
}
//==============================================
void About::reject()
{
  QDialog::reject();
  emit closed();
}
//==============================================
