/*! @file

    @id $Id$
*/
//       1         2         3         4         5         6         7         8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890

#ifndef __SWISSWEBWIDGET_HXX__
#define __SWISSWEBWIDGET_HXX__

#include <qbrowserlib/ui_swisswebwidget.hxx>
#include <qbrowserlib/downloadmanager.hxx>
#include <qbrowserlib/errorlog.hxx>

#include <QMainWindow>
#include <QToolBar>
#include <QStatusBar>

#include <QtDebug>

#ifndef CREATE_QT_PROPERTY
#define CREATE_QT_PROPERTY(type, name)                           \
  Q_PROPERTY(type _##name READ name WRITE name USER true)        \
  public:                                                        \
    void name(const type& v) {                                   \
      _##name = v;                                               \
    }                                                            \
    type name() {                                                \
      return _##name;                                            \
    }                                                            \
  private:                                                       \
    type _##name
#endif

//! @addtogroup qbrowserlib
//! @{

namespace qbrowserlib {

  //! Window Widget for complete page witghin a webbrowser.
  /*! Contains a toolbar, a status bar and @refs
      SwissWebView. Instanciate this and you have a complete
      browser. To be used inside a QTabBar, as main window or as
      docking widget. */
  class SwissWebWidget: public QWidget, private Ui::SwissWebWidget {
      
      Q_OBJECT;

      //..............................................................properties
      CREATE_QT_PROPERTY(QUrl, homeUrl);

      //................................................................methods
    public:
      
      SwissWebWidget(QWidget* p=0): QWidget(p) {
        setupUi(this);
        /*! Within a QMainWindow, the widget automatically reparents
            the top buttons to the toolbar and the bottom status
            line to the window's status bar. */
        moveToMain(qobject_cast<QMainWindow*>(p?p->parentWidget():p));
        connects();
      }

      //! Moves status widgets to status bar, tool widgets to toolbar
      /*! You can use this method to reparent the tools and the status
          part of the widget into the toolbar and statusbar of your
          main window.

          @note If used as central widget of a QMainWindow, status and
          tools are automatically reparented in the constructor. */
      void moveToMain(QMainWindow* w) {
        if (!w || !_statusbar || !_tools) return;
        QToolBar* t(w->addToolBar(trUtf8("Browser Tools",
                                         "name of the browser's toolbar")));
        while (_tools->count())
          t->addWidget(_tools->itemAt(0)->widget());
        delete _tools; _tools=0;
        _statusbar->removeWidget(_status); delete _status; _status=0;
        while (_statusbar->count())
          w->statusBar()->addWidget(_statusbar->itemAt(0)->widget());
        delete _statusbar; _statusbar=0;
      }

    public Q_SLOTS:

      void load() {
        _webview->load(_url->text());
      }

      void goHome() {
        _webview->load(_homeUrl);
      }
      
      void progress(qint64 total, qint64 done) {
        TRC;
        _progress->setMaximum(total);
        _progress->setValue(done);
      }
      
      void started() {
        TRC;
        _abort->setVisible(true);
        _reload->setVisible(false);
        _progress->setRange(0, 0);
        _progress->setValue(0);
        _progress->setEnabled(true);
        _progress->show();
      }
      
      void finished() {
        TRC;
        _abort->setVisible(false);
        _reload->setVisible(true);
        _progress->setRange(0, 1);
        _progress->setValue(1);
        _progress->setEnabled(false);
      }
      
      void finished(QNetworkReply *r) {
        TRC;
        if (r->error()!=QNetworkReply::NoError &&
            r->error()!=QNetworkReply::OperationCanceledError) {
          // statusBar()->showMessage
          //   (qbrowserlib::DownloadManager::networkError(r->error()));
          // badUrl();
          // if (!_showErrorLog) {
          //   statusBar()->addPermanentWidget
          //     ((_showErrorLog = new QPushButton(QIcon(":/icons/error"),
          //                                       tr("errors", "show error log"))));
          //   assert(connect(_showErrorLog, SIGNAL(clicked(bool)),
          //                  actionErrorLog, SLOT(trigger())));
          // }
          // _showErrorLog->show();
        }
      }

      void metaDataChanged(QNetworkReply* reply) {
        TRC;
        QString filename
          (QString::fromUtf8(reply->rawHeader("Content-Disposition")));
        if (filename.contains
            (QRegExp("^\\s*attachment\\s*;\\s*filename\\s*=\\s*\"[^\"]+\""))) {
          LOG<<"From Content-Disposition";
          filename = filename.replace
            (QRegExp("^\\s*attachment\\s*;\\s*filename\\s*=\\s*\"([^\"]+)\".*"),
             "\\1");
        } else {
          LOG<<"From path";
          filename =
            QFileInfo(!reply->url().toLocalFile().isEmpty()
                      ?reply->url().toLocalFile()
                      :reply->url().path()).fileName();
        }
        LOG<<"Filename:"<<filename;
        QStringList type
          (qbrowserlib::Settings::instance().mimetype
           (reply->header(QNetworkRequest::ContentTypeHeader).toString(),
            filename));
      }
      
    protected:
      
      void connects() {
        _downloadmanager+=_webview->page()->networkAccessManager();
        assert(connect(_webview->page()->networkAccessManager(),
                       SIGNAL(finished(QNetworkReply*)),
                       SLOT(finished(QNetworkReply*))));
        assert(connect(_url, SIGNAL(returnPressed()), SLOT(load())));
        assert(connect(_home, SIGNAL(pressed()), SLOT(goHome())));
        assert(connect(_abort, SIGNAL(pressed()),
                       &_downloadmanager, SLOT(abort())));
        assert(connect(&_downloadmanager, SIGNAL(progress(qint64, qint64)),
                       SLOT(progress(qint64, qint64))));
        assert(connect(&_downloadmanager, SIGNAL(started()),
                       SLOT(started())));
        assert(connect(&_downloadmanager, SIGNAL(finished()),
                       SLOT(finished())));
        assert(connect(&_downloadmanager, SIGNAL(error(QString)),
                       &qbrowserlib::ErrorLog::instance(),
                       SLOT(append(QString))));
        assert(connect(&_downloadmanager,
                       SIGNAL(metaDataChanged(QNetworkReply*)),
                       SLOT(metaDataChanged(QNetworkReply*))));
      }

      //..............................................................variables
    protected:

      qbrowserlib::DownloadManager _downloadmanager;
      QPushButton _showErrorLog;

  };
  
}

//! @}

#endif
