/***************************************************************************
                          EraseDialog.cpp  -  description
                             -------------------
    begin                : Sat May 5 2001
    copyright            : (C) 2001 by Alexy 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 <iostream.h>

#include <qstring.h>
#include <qcombobox.h>
#include <qtooltip.h>
#include <qslider.h>
#include <qdir.h>
#include <qlabel.h>
#include <qcheckbox.h>
#include <qstringlist.h>
#include <qlistview.h>
#include <qevent.h>
#include <qdatetime.h>
#include <qlcdnumber.h>
#include <qimage.h>
#include <qpixmap.h>

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

#include "CdboDialogBase.h"
#include "CdboDialogActionFactory.h"

#include "EraseDialogBase.h"
#include "EraseDialog.h"
#include "EraseDialog.moc"
#include "PreviewDialog.h"
#include "dialogParts/DriveInfoPnl.h"
#include "dialogParts/SpeedPnl.h"
#include "dialogParts/DialogCntPnl.h"


EraseDialog::EraseDialog(QWidget *parent, const char *name ) :
	EraseDialogBase(parent,name,true),
	CdboDialogBase(CdboDialogBase::EraseDialogType){
	eraseMode = true;
	init();
}
//=============================================
EraseDialog::EraseDialog(bool eraseMode, QWidget *parent, const char *name ) :
	EraseDialogBase(eraseMode,parent,name,true),
	CdboDialogBase(CdboDialogBase::EraseDialogType){
	
	this->eraseMode = eraseMode;
	init();
}
//=======================================
void EraseDialog::init(){	
	factory = new CdboDialogActionFactory(this, "EraseDialogFactory");
	stillErasing = false;
	stillChecking = false;
	stillFixating = false;
	config = 0;

	///////////////////////////////////////////////////
	targetDevicePnl->setType(DriveInfoPnl::Target);
	targetDevicePnl->setUsrBtnTitle(i18n("&Preview"));
	/////////////////////////////////////////////////
	if(eraseMode)
		dialogCntPnl->setStartBtnTitle(i18n("&Erase!"));
	else
		dialogCntPnl->setStartBtnTitle(i18n("&Fixate!"));
	dialogCntPnl->resizeOutputViewColomns(80,462);
	/////////////////////////////////////////////////
	readOptions();
	initBtns();
	targetDevicePnl->closeTray();
	
	// connecting to the Drive Info Panel
	connect( targetDevicePnl->getDetectBtn(), SIGNAL( clicked() ), this, SLOT( detectDestSlot() ) );
	connect( targetDevicePnl->getUsrBtn(), SIGNAL( clicked() ), this, SLOT( previewSlot() ) );
	// 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() ) );
	
	connect( customBurnBtn, SIGNAL( clicked() ), this, SLOT( customBtnSlot() ) );
}
//---------------------------------------------------------------------------------------------
EraseDialog::~EraseDialog(){
	delete factory;
	if(config)
		delete config;
}
//---------------------------------------------------------------------------------------------
void EraseDialog::saveOptions(){	
	if(!config)
		return;
	if(eraseMode){
     		config->setGroup("Erase Options");
     		config->writeEntry("Force Blank", forceChk->isChecked());
    		config->writeEntry("Type of Blank", blankTypeCmb->currentItem());
     	}
     	else{
     		config->setGroup("Fixate options");
     		config->writeEntry("Type of Fixate", blankTypeCmb->currentItem());
     	}
    	speedPnl->saveOptions();
 	targetDevicePnl->saveOptions();
 	config->sync();
}

//---------------------------------------------------------------------------------------------
void EraseDialog::readOptions(){
    saveOptions();
	if(config)
		delete config;
	config = new KConfig("cdbakeovenrc");
    	if(eraseMode){
     		config->setGroup("Erase Options");
     		bool doForceChk = config->readBoolEntry("Force Blank", true);
     		forceChk->setChecked(doForceChk);
     		int iBuff = config->readNumEntry("Type of Blank", 0);
     		blankTypeCmb->setCurrentItem(iBuff);
	}
	else{
		config->setGroup("Fixate options");
     		int iBuff = config->readNumEntry("Type of Fixate", 0);
     		blankTypeCmb->setCurrentItem(iBuff);
	}
     	speedPnl->readOptions();
     	targetDevicePnl->readOptions();
}
//---------------------------------------------------------------------------------------------
void EraseDialog::initBtns(){
	if(targetDevicePnl->isReady()){
		
		blockBtns(false);
		dialogCntPnl->status(i18n("Ready"));
	}
	else{
		blockBtns(true);
		dialogCntPnl->getCancelBtn()->setEnabled(false);
		dialogCntPnl->status(i18n("No recording device!"));
	}
}
//---------------------------------------------------------------------------------------------
void EraseDialog::blockBtns(bool yes) const{
	dialogCntPnl->getStartBtn()->setEnabled(!yes);
	dialogCntPnl->getCancelBtn()->setEnabled(yes);
	detailsFrm->setEnabled(!yes);
	targetDevicePnl->blockBtns(yes);
	if(stillErasing || stillChecking || stillFixating){
		targetDevicePnl->getDetectBtn()->setEnabled(false);
		dialogCntPnl->getSettingsBtn()->setEnabled(false);
		dialogCntPnl->getDumpBtn()->setEnabled(false);
	}
	else{
		targetDevicePnl->getDetectBtn()->setEnabled(true);
		dialogCntPnl->getSettingsBtn()->setEnabled(true);
		dialogCntPnl->getDumpBtn()->setEnabled(true);
	}
}
//---------------------------------------------------------------------------------------------
QString EraseDialog::getActionType() const{
	int pos = blankTypeCmb->currentItem();
	if(eraseMode){
		switch(pos){
			case 0: return "fast";
			case 1: return "all";
       		case 2: return "track";
       		case 3: return "unreserve";
       		case 4: return "trtail";
       		case 5: return "unclose";
       		case 6: return "session";
       	}
       }
       else{
       	switch(pos){
			case 0: return "burn";
			case 1: return "dummy";
		}
       }
	return "";
}
//---------------------------------------------------------------------------------------------
void EraseDialog::customBtnSlot(){
	KShellProcess *cdboProc = new KShellProcess();
	*cdboProc << "kcmshell cdboburnopt";
	connect(cdboProc, SIGNAL(processExited(KProcess*)), this, SLOT(kcmshellDone(KProcess*)));
	if(!cdboProc->start(KProcess::NotifyOnExit))
		cerr << "Failed to start\n\n";
}
//---------------------------------------------------------------------------------------------
void EraseDialog::detectDestSlot(){
	KShellProcess *cdboProc = new KShellProcess();
	*cdboProc << "kcmshell cdbocdromdevices kcmdf";
	connect(cdboProc, SIGNAL(processExited(KProcess*)), this, SLOT(kcmshellDone(KProcess*)));
	if(!cdboProc->start(KProcess::NotifyOnExit))
		cerr << "Failed to start\n\n";
}
//---------------------------------------------------------------------------------------------
void EraseDialog::settingsSlot(){
	KShellProcess *cdboProc = new KShellProcess();
	*cdboProc << "kcmshell cdboburnopt cdbodefaultopt";
	connect(cdboProc, SIGNAL(processExited(KProcess*)), this, SLOT(kcmshellDone(KProcess*)));
	if(!cdboProc->start(KProcess::NotifyOnExit))
		cerr << "Failed to start\n\n";
}
//---------------------------------------------------------------------------------------------
void EraseDialog::kcmshellDone(KProcess *proc){
	delete proc;
	readOptions();
	if(!(stillErasing || stillFixating || stillChecking))
		initBtns();
}
//---------------------------------------------------------------------------------------------
void EraseDialog::cancelSlot(){
	if((stillErasing || stillFixating) && confermExit()){
		if(stillErasing || stillFixating)
			factory->killCurrentTask();
		
		if(stillErasing)
			output(CdboDialogBase::StatusNotOkMessage, i18n("Erase canceled!"));
		else
			output(CdboDialogBase::StatusNotOkMessage, i18n("Fixate CD canceled!"));
		dialogCntPnl->stopForwardTimer();
		stillErasing = false;
		stillChecking = false;
		stillFixating = false;
		blockBtns(false);
		status(i18n("Ready"));
	}
}
//---------------------------------------------------------------------------------------------
void EraseDialog::closeEvent(QCloseEvent *e){
	if(stillErasing || stillFixating){
		if(!confermExit())
			e->ignore();
		else{
			//if(stillErasing)
			factory->killCurrentTask();
			e->accept();
		}
	}
	else
		e->accept();
}
//---------------------------------------------------------------------------------------------
void EraseDialog::quitSlot(){
	if(stillErasing || stillFixating){
		if(!confermExit()) return;
		else{
			//if(stillErasing)
			factory->killCurrentTask();
			saveOptions();
			accept();
		}
	}
	else{
		saveOptions();
		accept();
	}
}
//---------------------------------------------------------------------------------------------
void EraseDialog::keyPressEvent(QKeyEvent *e){
	if(e->key() == Key_Escape){
        	if(stillErasing || stillFixating){
			if(!confermExit())
				return;
			else
				factory->killCurrentTask();
		}
		accept();
	}
	if(e->key() == Key_F2){
		if(!stillErasing && !stillFixating && !stillChecking)
			settingsSlot();
	}
}
//---------------------------------------------------------------------------------------------
void EraseDialog::startBtnSlot(){
	saveOptions();
	targetDevicePnl->closeTray();
	dialogCntPnl->clearOutput();
	dialogCntPnl->startForwardTimer();
	
	if(eraseMode){
		stillErasing = true;
		/////////////////////////////////////////			
        	config->setGroup("Erase Options");
        	stillChecking = config->readBoolEntry("Check Drive First", false);
        	
        	if(stillChecking)
        		factory->checkDrive();
        	else factory->erase();
	}
	else{
        	stillFixating = true;
        	config->setGroup("Recording Options");
		stillChecking = config->readBoolEntry("Check Drive First", false);
		if(stillChecking)
			factory->checkDrive();	
		else
			factory->fixate();	
        }
}
//---------------------------------------------------------------------------------------------
void EraseDialog::taskDone(bool success){
	if(success && stillChecking){
     		stillChecking = false;
     	
     	/////////////////////////////////////////	
     		if(eraseMode){		
			config->setGroup("Erase Options");
     			if(config->readBoolEntry("Eject After Erase", true))
     				targetDevicePnl->setEjected();  	
     			factory->erase();
     		}
     		else{
     			config->setGroup("Recording Options");
			if(config->readBoolEntry("Eject Media At End", true))
				targetDevicePnl->setEjected();
     			factory->fixate();	
     		}
	}
	else{
		dialogCntPnl->stopForwardTimer();
		stillErasing = false;
		stillChecking = false;
		stillFixating = false;
		blockBtns(false);
	}
}
//---------------------------------------------------------------------------------------------
void EraseDialog::taskFailedToStart(){
	dialogCntPnl->stopForwardTimer();
	stillErasing = false;
	stillFixating = false;
}
//---------------------------------------------------------------------------------------------
bool EraseDialog::confermExit(){
	if(stillChecking)
		return true;
	int result = KMessageBox::warningContinueCancel(this,
        i18n("Aborting now may damage the CD-RW media, "\
        "and/or even hang your system! Click \"Quit\" to abort."),
        i18n("This may hang your system!"),
        QString(i18n("&Quit")));
    	switch(result) {
    		case KMessageBox::Continue:{
    			/*KMessageBox::error(this,
					"You've been WARNED!");*/
			return true;
		}
		case KMessageBox::Cancel:
        		return false;
    	}
    	return false;
}
//------------------------------------------------------------------------------------------
void EraseDialog::previewSlot(){
	PreviewDialog *pd = new PreviewDialog((QWidget *)parent(), "pd");
	if(!pd->open(targetDevicePnl->getDriveName())){
		KMessageBox::error(this,
                i18n("Failed to mount %1. Make sure you have enough privileges to perform this action.").arg(targetDevicePnl->getDriveName()));
		return;
	}
	pd->exec();
}
