/***************************************************************************
                          RippAudioDialog.cpp  -  description
                             -------------------
    begin                : Mon Feb 4 2002
    copyright            : (C) 2002 by Alex Podolsky
    email                : alexpod@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/


#include <qcheckbox.h>
#include <qstringlist.h>
#include <qlistview.h>
#include <qevent.h>
#include <qdatetime.h>
#include <qtooltip.h>

#include <kiconloader.h>
#include <kprocess.h>
#include <kmessagebox.h>
//#include <kapplication.h>
#include <kfiledialog.h>
#include <klocale.h>
#include <kconfig.h>
#include <kurl.h>
#include <kprocess.h>
#include <kdebug.h>

#include "RippAudioDialogBase.h"
#include "RippAudioDialog.h"
#include "RippAudioDialog.moc"
#include "../audio/CdboCddaView.h"
#include "../audio/CdboAudioActionFactory.h"

//---------------------------------------------------------------------------------------------
RippAudioDialog::RippAudioDialog(QWidget *parent, const char *name ) :
	RippAudioDialogBase(parent,name,true),
	CdboDialogBase(CdboDialogBase::RippAudioCdDialogType){
	//////////////
	
	//factory = new CdboAudioActionFactory(this, "audioFactory");
	
	config = 0;
	stillRipping = false;

	/////////////////////////////////////////////////
	srcDevicePnl->setType(DriveInfoPnl::Source);
	srcDevicePnl->setUsrBtnTitle(i18n("Scan &Tracks"));
	////////////////////////////////////////////////
	dialogCntPnl->setStartBtnTitle(i18n("&Rip!"));
	QToolTip::add(dialogCntPnl->getStartBtn(), i18n( "Start ripping!" ) );
	dialogCntPnl->resizeOutputViewColomns(80,508);

	/////////////////////////////////////////////////

	imageBrowseBtn->setPixmap( SmallIcon("fileopen") );
	
	readOptions();
	initBtns();

	trackView->setUser(this);
	factory = trackView->getFactory();
	trackView->resizeTrackViewColomns(55,55,290);
	trackView->setHeaderClickEnabled(true);
	trackView->setRenameable();
	trackView->showLongTitle();
	
	// connecting to the Src Drive Info Panel
	connect( srcDevicePnl->getDetectBtn(), SIGNAL( clicked() ), this, SLOT( detectDestSlot() ) );
	connect( srcDevicePnl->getUsrBtn(), SIGNAL( clicked() ), this, SLOT( scanSlot() ) );
	connect( srcDevicePnl, SIGNAL( trayEjected() ), trackView, SLOT( invalidate() ) );
	
	// connecting to the Dialog Control Panel
	connect( dialogCntPnl->getStartBtn(), SIGNAL( clicked() ), this, SLOT( startBtnSlot() ) );
	connect( dialogCntPnl->getCancelBtn(), SIGNAL( clicked() ), this, SLOT( cancelSlot() ) );
	connect( dialogCntPnl->getSettingsBtn(), SIGNAL( clicked() ), this, SLOT( settingsSlot() ) );
	connect( dialogCntPnl->getQuitBtn(), SIGNAL( clicked() ), this, SLOT( quitSlot() ) );
	
	// connecting to the factory
	connect( factory, SIGNAL( processDone(bool) ), this, SLOT( taskDone(bool) ) );
	connect( factory, SIGNAL( failedToLunchProcess() ), this, SLOT( taskFailedToStart() ) );

}
//---------------------------------------------------------------------------------------------
RippAudioDialog::~RippAudioDialog(){
	//delete factory;
	if(config)
		delete config;
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::readOptions(){
	saveOptions();
	if(config)
		delete config;
	config = new KConfig("cdbakeovenrc");
	////////////////////////////////////////////////		
	config->setGroup("Rip Options");
	
	tempDir = config->readEntry("Output Dir","");
	if(tempDir.isNull() || tempDir.isEmpty()){
		config->setGroup("Default Settings");
		tempDir = config->readEntry("Tmp Dir", "");
		config->setGroup("Rip Options");
	}
	outputDirLbl->setText(tempDir);
	QToolTip::add(outputDirLbl, i18n("Using %1 as output directory").arg(tempDir));
	
	fileFormatCmb->setCurrentItem(config->readNumEntry("Type of Output", 0));
	
	srcDevicePnl->readOptions();
	trackView->readOptions();
	trackView->setDevice(srcDevicePnl->getDriveName());
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::saveOptions(){
	if(!config)
		return;
	//////////////////////////////////////////////////////////
	config->setGroup("Rip Options");
	config->writeEntry("Type of Output", fileFormatCmb->currentItem());

 	srcDevicePnl->saveOptions();
 	trackView->saveOptions();
 	config->sync();
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::initBtns(){
	if(srcDevicePnl->isReady()){
		
		srcDevicePnl->closeTray();
		blockBtns(false);
		dialogCntPnl->status(i18n("Ready"));
	}
	else{
		blockBtns(true);
		dialogCntPnl->getCancelBtn()->setEnabled(false);
		dialogCntPnl->status(i18n("No reading device configured."));
	}
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::blockBtns(bool yes) const{
	dialogCntPnl->getStartBtn()->setEnabled(!yes);
	dialogCntPnl->getCancelBtn()->setEnabled(yes);
	trackView->setEnabled(!yes);
	detailsPnl->setEnabled(!yes);
	srcDevicePnl->blockBtns(yes);
	if(stillRipping){
		srcDevicePnl->getDetectBtn()->setEnabled(false);
		dialogCntPnl->getSettingsBtn()->setEnabled(false);
		dialogCntPnl->getDumpBtn()->setEnabled(false);
	}
	else{
		srcDevicePnl->getDetectBtn()->setEnabled(true);
		dialogCntPnl->getSettingsBtn()->setEnabled(true);
		dialogCntPnl->getDumpBtn()->setEnabled(true);
	}
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::detectDestSlot(){
	KShellProcess *cdboProc = new KShellProcess();
	*cdboProc << "kcmshell cdbocdromdevices kcmdf";
	connect(cdboProc, SIGNAL(processExited(KProcess*)), this, SLOT(kcmshellDone(KProcess*)));
	if(!cdboProc->start(KProcess::NotifyOnExit))
		kdDebug() << "Failed to start" << endl;
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::settingsSlot(){
	KShellProcess *cdboProc = new KShellProcess();
	*cdboProc << "kcmshell audiocd cdboaudioopt cdbodefaultopt";
	connect(cdboProc, SIGNAL(processExited(KProcess*)), this, SLOT(kcmshellDone(KProcess*)));
	if(!cdboProc->start(KProcess::NotifyOnExit))
		kdDebug() << "Failed to start" << endl;
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::kcmshellDone(KProcess *proc){
	delete proc;
	readOptions();
	if(!stillRipping)
		initBtns();
}
//------------------------------------------------------------------------------------------
void RippAudioDialog::isoBrowseSlot(){
	QString tempDir = outputDirLbl->text();
	if(!tempDir || tempDir == ""){
    		tempDir = KFileDialog::getExistingDirectory(QDir::homeDirPath(),
    			this,
    			i18n("Choose Temporary Directory."));
	}
	else{
		tempDir = KFileDialog::getExistingDirectory(tempDir,
    			this,
    			i18n("Choose Temporary Directory."));
	}
	tempDir = tempDir.stripWhiteSpace();
	if(!tempDir || tempDir == "") return;

	//if(!factory->checkTmp(tempDir, minTmpSize)) return;

	outputDirLbl->setText(tempDir);
	QToolTip::add(outputDirLbl, i18n("Using %1 as output directory").arg(tempDir));

	config->setGroup("Rip Options");
	config->writeEntry("Output Dir",outputDirLbl->text());
}
//------------------------------------------------------------------------------------------
void RippAudioDialog::scanSlot(){
	dialogCntPnl->clearOutput();
	trackView->invalidate();
	trackView->loadAndUncheck(srcDevicePnl->getDriveName());
}
//---------------------------------------------------------------------------------------------
QString RippAudioDialog::getActionType() const{
	if(fileFormatCmb->currentText()  == i18n("Ogg-Vorbis (.ogg)"))
		return "ogg";
	
	if(fileFormatCmb->currentText()  == i18n("MP3 (.mp3)"))
		return "mp3";
	
	if(fileFormatCmb->currentText()  == i18n("Wave (.wav)"))
		return "wav";
	
	if(fileFormatCmb->currentText()  == i18n("Raw (headerless) (.cda)"))
		return "cda";
	
	/*if(fileFormatCmb->currentText()  == "Apple/SGI (.aiff)")
		return "aiff";*/
	return "wav";
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::output(int type, QString message) const {
	dialogCntPnl->output(type, message);
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::startBtnSlot(){
	saveOptions();
	trackView->stop();
	dialogCntPnl->clearOutput();
	
	
	QStringList* tracks = trackView->getPickedTracks();
	if(!tracks){
		output(CdboDialogBase::StatusNotOkMessage,
  			i18n("You must scan the device."));
		output(CdboDialogBase::StatusNotOkMessage,
  			i18n("Pick the individual tracks you want to rip (read)!"));
		return;
	}
	if(tracks->count() == 0){
		output(CdboDialogBase::ErrorMessage, i18n("No tracks chosen! There is nothing to rip."));
		return;
	}
	stillRipping = true;
	dialogCntPnl->startForwardTimer();
	factory->ripp(srcDevicePnl->getDriveName(), tracks, tempDir, getActionType(), this);

}

//---------------------------------------------------------------------------------------------
void RippAudioDialog::taskDone(bool){
	//if(!success)
		//output(CdboDialogBase::StatusNotOkMessage, "Rip process failed!");
	
	dialogCntPnl->stopForwardTimer();
	stillRipping = false;
	//status("Ready.");
	blockBtns(false);
	return;

}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::taskFailedToStart(){
	dialogCntPnl->stopForwardTimer();
	stillRipping = false;
	//status("Ready.");
	blockBtns(false);
}

//---------------------------------------------------------------------------------------------
void RippAudioDialog::cancelSlot(){
	if(stillRipping && confermExit()){
		factory->killCurrentTask();
		/*if(stillCopying){
			output(CdboDialogBase::StatusNotOkMessage, "Copy process canceled!");
			if(getCopyType() != ON_THE_FLY_COPY && removeTempBtn->isChecked()){
				int result = KMessageBox::warningContinueCancel(this,
	   				"Do you still want to remove temporary image(s)?",
        				"Confirm your action",
        				QString("Yes"));
       			if(result == KMessageBox::Continue)
					factory->removeTmpImage(imageAddr, tempDir);
			}
		}
		else if(stillReading){
			output(CdboDialogBase::StatusNotOkMessage, "Read process canceled!");
			factory->removeTmpImage(imageAddr, tempDir);
		}*/
		dialogCntPnl->stopForwardTimer();
		stillRipping = false;
		//status("Ready.");
		blockBtns(false);	
	}
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::quitSlot(){
	if(stillRipping){
		if(!confermExit())
			return;
		else{
			factory->killCurrentTask();
   			trackView->invalidate();
			/*if(stillReading)
				factory->removeTmpImage(imageAddr, tempDir);
			
			if(stillCopying && getCopyType() != ON_THE_FLY_COPY && removeTempBtn->isChecked()){
				int result = KMessageBox::warningContinueCancel(this,
	   				"Do you still want to remove temporary image(s)?",
        				"Confirm your action",
        				QString("Yes"));
       			if(result == KMessageBox::Continue)
					factory->removeTmpImage(imageAddr, tempDir);
			}*/
			saveOptions();
			accept();
		}
	}
	else{	
		saveOptions();
		accept();
	}
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::closeEvent(QCloseEvent *e){
	
	if(stillRipping){
		if(!confermExit())
			e->ignore();
		else{
			factory->killCurrentTask();
   			trackView->invalidate();
			/*if(stillReading)
				factory->removeTmpImage(imageAddr,tempDir);
			
			if(stillCopying && getCopyType() != ON_THE_FLY_COPY && removeTempBtn->isChecked()){
				int result = KMessageBox::warningContinueCancel(this,
	   				"Do you still want to remove temporary image(s)?",
        				"Confirm your action",
        				QString("Yes"));
       			if(result == KMessageBox::Continue)
					factory->removeTmpImage(imageAddr,tempDir);
			}*/
			e->accept();
		}
	}
	else
		e->accept();
}
//---------------------------------------------------------------------------------------------
void RippAudioDialog::keyPressEvent(QKeyEvent *e){
	if(e->key() == Key_Escape){
		if(!stillRipping){
			trackView->invalidate();
			accept();
			return;
		}
		if(!confermExit())
			return;
		else{
			if(stillRipping)
				factory->killCurrentTask();
		}
		trackView->invalidate();
		accept();
	}
	if(e->key() == Key_F2){
		settingsSlot();
	}
}
//---------------------------------------------------------------------------------------------
bool RippAudioDialog::confermExit(){
	//if(stillChecking) return true;
	QString message = i18n("This will abort the rip process.");
	int result = KMessageBox::warningContinueCancel(this,
						message,
						i18n("Confirm abort!"),
						i18n("&Quit"));
	switch(result) {
		case KMessageBox::Continue:
			return true;
		case KMessageBox::Cancel:
			return false;
	}
	return false;
}
