/*
    Copyright (C) 2000 - 2001 Kai Heitkamp, kai@kde.org

    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., 675 Mass Ave, Cambridge, MA 02139, USA.

 */

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

#include <qfile.h>
#include <qlabel.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qradiobutton.h>
#include <qpushbutton.h>
#include <qlineedit.h>
#include <qmultilineedit.h>
#include <qprogressbar.h>

#include <kdirlister.h>
#include <kurl.h>
#include <kapplication.h>
#include <kconfig.h>
#include <kmessagebox.h>
#include <kfiledialog.h>
#include <kglobal.h>
#include <klocale.h>
#include <kdebug.h>

#include "ripcd.h"
#include "ripcd.moc"
#include "tracklistviewitem.h"

RipCD::RipCD(QWidget *parent, const char *name ) : RipCD_GUI(parent, name, true) {
	// Read config
	KConfig *config = kapp->config();
	KConfig *configAudio = new KConfig( "kcmaudiocdrc" );

	configAudio->setGroup( "CDDB" );
	CDDBInfos = configAudio->readBoolEntry( "enable_cddb" );

	config->setGroup( "Config - ripcd" );
	QLineEdit_targetDir->setText( config->readEntry( "QLineEdit_targetDir" ) );
	QComboBox_fileFormat->setCurrentItem( config->readNumEntry( "QComboBox_fileFormat" ) );

	// Initializes the KListView
	KListView_tracklist->setSelectionMode( QListView::Extended );
	KListView_tracklist->setSorting( 0, true );
}

RipCD::~RipCD(){

}

// 'Start-Button' clicked
void RipCD::slot_start(){
	if ( KListView_tracklist->currentItem() == 0 ) {
		KMessageBox::error( 0, i18n("You need to select at least one track!"), i18n("KOnCD - Rip CD - Error") );
		return;
	}

	if ( QLineEdit_targetDir->text() == "" ) {
		KMessageBox::error( 0, i18n("You need to specify a target directory!"), i18n("KOnCD - Rip CD - Error") );
		return;
	}

	startJob = true;
	QPushButton_Start->setEnabled( false );
	slot_fileFormatChanged( QComboBox_fileFormat->currentItem() );
}

void RipCD::slot_startJob(){
	KURL::List urlList;
	KConfig *config = kapp->config();
	config->setGroup("CD-Reader");

	QList<QListViewItem> list = KListView_tracklist->selectedItems();

	QListViewItem *lvi;
	QValueList<TrackList>::Iterator it;
	for ( lvi = list.first(); lvi != 0; lvi = list.next() ){
		for( it = tlist.begin(); it != tlist.end(); ++it ){
			if ( lvi->text(0) == (*it).Count() ){
				urlList.append( "audiocd:" + (*it).Name() + "?device=" + config->readEntry("Device") );
				kdDebug() << "Copy \"audiocd:" << (*it).Name() << "?device=" << config->readEntry("Device") << "\" to \"" << QLineEdit_targetDir->text() << "\"" << endl;
			}
		}
	}

	KIO::CopyJob *job	= KIO::copy( urlList, "file:" + QLineEdit_targetDir->text(), true );
	connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slot_CopyingResult( KIO::Job * ) ) );
}

void RipCD::slot_CopyingResult( KIO::Job * ){
	QPushButton_Start->setEnabled( true );
	startJob = false;
}

// Get Tracks from CD
void RipCD::slot_getTracks(){
	KConfig *config = kapp->config();
	KDirLister *dirLister = new KDirLister();
	KLocale slave("kio_audiocd");
	
	config->setGroup("CD-Reader");

	connect( dirLister, SIGNAL( completed() ), SLOT( slot_completed() ) );
	connect( dirLister, SIGNAL( canceled() ), SLOT( slot_completed() ) );
	connect( dirLister, SIGNAL( newItems( const KFileItemList& ) ), SLOT( slot_NewItemsData( const KFileItemList& ) ) );

	if ( CDDBInfos ) {
		dirLister->openURL( "audiocd:/" + slave.translate( "By Name" ) + "?device=" + config->readEntry("Device"), false, true );
	}
	else {
		dirLister->openURL( "audiocd:/?device=" + config->readEntry("Device"), false, true );
	}

	KListView_tracklist->clear();
	QPushButton_getTracks->setEnabled( false );
}

void RipCD::slot_NewItemsData( const KFileItemList& list ){
	int count, tmp;
	QString name, size;
	KFileItemListIterator it( list );

	if( CDDBInfos ){
		for( ; it.current(); ++it ){
			name =  it.current()->text();
			count = name.left( 2 ).toInt( 0 );
			tmp = it.current()->size() / 1024;
			size = size.setNum( tmp );
			size = size.append( " KB" );
			name = name.mid( 3, name.length() );
			name = name.left( name.length() - 4 );
			new TrackListViewItem ( KListView_tracklist, count, name, size, 0 );
		}
	}
	else{
		for( ; it.current(); ++it ){
			if ( ! it.current()->isDir() ){
				count = it.current()->text().mid( 5, 2 ).toInt( 0 );
				tmp = it.current()->size() / 1024;
				size = size.setNum( tmp );
				size = size.append( " KB" );
				name = ( "Track " + name.setNum( count ) );
				new TrackListViewItem ( KListView_tracklist, count, name, size, 0 );
			}
		}
	}

	KListView_tracklist->setSorting( 0, true );
}

void RipCD::slot_completed(){
	int count = 0;
	int trackcounter = 0;
	QString tmp, tmp2;

	if ( KListView_tracklist->childCount() == 0 ){
		QPushButton_getTracks->setEnabled( true );
		return;
	}

	do{
		tmp = KListView_tracklist->itemAtIndex( count )->text( 2 );
		tmp = tmp.mid( 0, tmp.length() - 3 );
		trackcounter += tmp.toInt( 0 );
		count++;
	}
	while( count < KListView_tracklist->childCount() );

	tmp = tmp.setNum( trackcounter );
	tmp = tmp.append( " KB" );
	tmp2 = tmp2.setNum( KListView_tracklist->childCount() );

	QTextLabel_size->setText( tmp );
	QTextLabel_tracks->setText( tmp2 );
	QPushButton_getTracks->setEnabled( true );
}

// Select Directory as target for files
void RipCD::slot_selectDirectory(){
	QString dir = KFileDialog::getExistingDirectory();
	if ( dir == "" ) return;
	QLineEdit_targetDir->setText( dir );
}

// File format changed
void RipCD::slot_fileFormatChanged( int index ){
	if ( KListView_tracklist->childCount() == 0 ) return;

	KConfig *config = kapp->config();
	KDirLister *dirLister = new KDirLister();
	KLocale slave("kio_audiocd");

	config->setGroup("CD-Reader");

	formatChanged = true;
	connect( dirLister, SIGNAL( completed() ), SLOT( slot_DataCompleted() ) );
	connect( dirLister, SIGNAL( canceled() ), SLOT( slot_DataCompleted() ) );

	switch( index )
	{
		// Raw mode (.cda)
	 	case 0:	connect( dirLister, SIGNAL( newItems( const KFileItemList& ) ), SLOT( slot_Data( const KFileItemList& ) ) );
						dirLister->openURL( "audiocd:/?device=" + config->readEntry("Device"), false, true );
						break;

		// Wave mode (.wav)
	 	case 1:	connect( dirLister, SIGNAL( newItems( const KFileItemList& ) ), SLOT( slot_Data( const KFileItemList& ) ) );
						if( CDDBInfos ){
							dirLister->openURL( "audiocd:/" + slave.translate( "By Name" ) + "?device=" + config->readEntry("Device"), false, true );
						}
						else {
							dirLister->openURL( "audiocd:/" + slave.translate( "By Track" ) + "?device=" + config->readEntry("Device"), false, true );
						}
						break;

		// MP3 mode (.mp3)
	 	case 2:	connect( dirLister, SIGNAL( newItems( const KFileItemList& ) ), SLOT( slot_Data( const KFileItemList& ) ) );
						dirLister->openURL( "audiocd:/MP3?device=" + config->readEntry("Device"), false, true );
						break;

		// Ogg-Vorbis mode (.ogg)
	 	case 3:	connect( dirLister, SIGNAL( newItems( const KFileItemList& ) ), SLOT( slot_Data( const KFileItemList& ) ) );
						dirLister->openURL( "audiocd:/Ogg Vorbis?device=" + config->readEntry("Device"), false, true );
						break;
	}

	tlist.clear();
	QPushButton_Start->setEnabled( false );
}

void RipCD::slot_Data( const KFileItemList& list ){
	tlist.clear();
	QString counter;
  KFileItemListIterator it( list );

	for( ; it.current(); ++it ){
		if ( ! it.current()->isDir() ){
			switch( QComboBox_fileFormat->currentItem() )
			{
				// Raw mode (.cda)
			 	case 0:	counter = it.current()->url().fileName().mid( 5, 2 );
								break;

				// Wave mode (.wav)
			 	case 1:
								if( CDDBInfos ){
									counter = it.current()->url().fileName().mid( 0, 2 );
								}
								else {
									counter = it.current()->url().fileName().mid( it.current()->url().fileName().length() - 6, 2 );
								}
								break;

				// MP3 mode (.mp3)
			 	case 2:
								if( CDDBInfos ){
									counter = it.current()->url().fileName().mid( 0, 2 );
								}
								else {
									counter = it.current()->url().fileName().mid( it.current()->url().fileName().length() - 6, 2 );
								}
								break;

				// Ogg-Vorbis mode (.ogg)
			 	case 3:
								if( CDDBInfos ){
									counter = it.current()->url().fileName().mid( 0, 2 );
								}
								else {
									counter = it.current()->url().fileName().mid( it.current()->url().fileName().length() - 6, 2 );
								}
								break;
			}
			tlist.append( TrackList( counter, it.current()->url().path(), it.current()->size() ) );
		}
	}

	if ( startJob == true && formatChanged == true ) slot_startJob();
}

void RipCD::slot_DataCompleted(){
	QPushButton_Start->setEnabled( true );
}

//'Quit-Button' clicked
void RipCD::slot_exit(){
	//Write config
	KConfig *config = kapp->config();
	config->setGroup( "Config - ripcd" );
	config->writeEntry( "QLineEdit_targetDir", QLineEdit_targetDir->text() );
	config->writeEntry( "QComboBox_fileFormat", QComboBox_fileFormat->currentItem() );

	close();
}
