/***************************************************************************
 *   Copyright (C) 2005 - 2007 by                                          *
 *      Christian Muehlhaeuser, Last.fm Ltd <chris@last.fm>                *
 *      Erik Jaelevik, Last.fm Ltd <erik@last.fm>                          *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA  02110-1301, USA.          *
 ***************************************************************************/

#include "MediaDeviceConfirmDialog.h"

#include "container.h"
#include "MooseCommon.h"
#include "logger.h"
#include "Scrobbler-1.2.h"
#include "User.h"

#include <QString>
#include <QDebug>
#include <QDesktopWidget>


MediaDeviceConfirmDialog::MediaDeviceConfirmDialog( const QString& username, QWidget *parent )
        : QDialog( parent, Qt::Sheet ),
          m_username( username )
{
    m_tracks = ScrobbleCache::mediaDeviceCache( m_username ).tracks();
}


void
MediaDeviceConfirmDialog::setupUi()
{
    ui.setupUi( this );

    addTracksToView();
    
    QPixmap p( MooseUtils::dataPath( "app_55.png" ) );
//     p = p.scaled( 32, 32, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
    ui.iconLabel->setPixmap( p );

////// This section sizes the dialog as best as possible, it is a shame but
    // Qt sizeHints usually ignore the view contents size, so we do it manually.
 
    //this magnificent hack bought to you by teh mxcl
    // @short allow access to this protected function so we can determine the
    // ideal width for the confirm dialog
    struct NoProtection : QAbstractItemView
    {
        using QAbstractItemView::sizeHintForColumn;
    };

    int w = 0, desiredwidth = 0;
    for (int x = 0; x < ui.tracksWidget->columnCount(); ++x) {
        desiredwidth = reinterpret_cast<NoProtection*>(ui.tracksWidget)->sizeHintForColumn( x );
        w += desiredwidth;
    }
    
    ui.tracksWidget->setMinimumWidth( w );
    if (m_tracks.count() > 10 )
        ui.tracksWidget->setMinimumHeight( ui.tracksWidget->sizeHint().height() * 2 );

    //make us always the right size
    layout()->setSizeConstraint( QLayout::SetMinimumSize );
    
    int const W = QDesktopWidget().availableGeometry().width();
    if (sizeHint().width() > W)
        ui.tracksWidget->setMinimumWidth( W
                                          - (sizeHint().width() - ui.tracksWidget->width()) 
                                          - 10 /*small aesthetic gap*/ );

///////
    connect( ui.scrobble, SIGNAL(clicked()), SLOT(accept()) );
    connect( ui.cancel,   SIGNAL(clicked()), SLOT(reject()) );
    connect( ui.toggle,   SIGNAL(clicked()), SLOT(toggleChecked()) );
    
///////
    activateWindow();
}


void
MediaDeviceConfirmDialog::addTracksToView()
{
    QList<QTreeWidgetItem*> items;
    int index = 0;
    foreach (TrackInfo t, m_tracks)
    {
        QDateTime dt = QDateTime::fromTime_t( t.timeStamp() );
        QTreeWidgetItem* widget = new QTreeWidgetItem;
        widget->setData( 0, Qt::DisplayRole, t.artist() );
        widget->setData( 1, Qt::DisplayRole, t.track() );
        widget->setData( 2, Qt::DisplayRole, dt );
        widget->setData( 3, Qt::DisplayRole, QString::number(t.playCount()) );

        widget->setFlags( widget->flags() | Qt::ItemIsUserCheckable );
        widget->setCheckState( 0, Qt::Checked );

        widget->setData( 0, Qt::UserRole, index++ );

        items += widget;
    }

    ui.tracksWidget->insertTopLevelItems( 0, items );
    ui.tracksWidget->resizeColumnToContents( 0 );
    ui.tracksWidget->resizeColumnToContents( 1 );
    ui.tracksWidget->resizeColumnToContents( 2 );
    ui.tracksWidget->resizeColumnToContents( 4 );

    ui.tracksWidget->setSortingEnabled( true );
    ui.tracksWidget->sortByColumn( 2, Qt::DescendingOrder );

    QString text = tr( "<p>Last.fm found %n new track(s) since the last time you synced your iPod.<br/>"
                       "Please select the tracks that you want to be scrobbled from your iPod.",
                       "", items.count() );

    // avoid lawsuits
    if (The::user().name() != m_username)
        text += "<p><b>" + tr("This iPod scrobbles to %1's profile!").arg( m_username );
    
    ui.messageLabel->setText( text );
}


void
MediaDeviceConfirmDialog::toggleChecked()
{
    for (int x = 0; x < ui.tracksWidget->topLevelItemCount(); ++x) 
    {
        QTreeWidgetItem* i = ui.tracksWidget->topLevelItem( x );
        i->setCheckState( 0, i->checkState( 0 ) == Qt::Checked ? Qt::Unchecked : Qt::Checked );
    }
}


int
MediaDeviceConfirmDialog::exec()
{
    if (m_tracks.count())
    {
        setupUi();
        return QDialog::exec();
    }
    else
        return QDialog::Rejected;
}


QList<TrackInfo>
MediaDeviceConfirmDialog::tracks() const
{
    QList<TrackInfo> tracks;
    for (int x = 0; x < ui.tracksWidget->topLevelItemCount(); ++x)
    {
        QTreeWidgetItem* item = ui.tracksWidget->topLevelItem( x );
        if (item->checkState( 0 ) == Qt::Checked)
        {
            int const index = item->data( 0, Qt::UserRole ).toInt();
            tracks += m_tracks[index];
        }
    }
    return tracks;
}
