//This file is part of AcetoneISO. Copyright 2006,2007,2008,2009 Fabrizio Di Marco and Marco Di Antonio  (acetoneiso@gmail.com)
//Copyright 2010/2011 Marco Di Antonio

//    AcetoneISO 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 3 of the License, or
//    (at your option) any later version.
//
//    AcetoneISO 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 AcetoneISO.  If not, see <http://www.gnu.org/licenses/>.

#include <QtGui>
#include <QCoreApplication>
#include <QByteArray>
#include <QProcess>
#include <QList>
#include <fcntl.h>
#include <iostream>
#include <QDebug>
#include "erase_cd.h"

/*
cancellare cd completo: wodim -verbose dev=/dev/sr0  blank=all
cancellare cd rapido: wodim -verbose dev=/dev/sr0  blank=fast
dice il tipo di media inserito: hal-get-property "--key volume.disc.type --udi $udi
*/

//
erasecd::erasecd( QWidget * parent, Qt::WFlags f) 
	: QDialog(parent, f)
{

    setupUi(this);
    is_erasing = false;
    loaded_success = false;
    QCoreApplication::setApplicationName("AcetoneISO");
    connect( start, SIGNAL( clicked() ), this, SLOT( start_erase() ) );
    start->setEnabled(false);
    textBrowser->clear();    
    device_scan();

}

//scannerizza periferiche e ritorna array stringa di tutte le periferiche trovate
void erasecd::scan_devices_burn() {
  scan_devices_process = new QProcess();
  scan_devices_process->setReadChannel(QProcess::StandardOutput);
  scan_devices_process->setProcessChannelMode(QProcess::MergedChannels);		
  //connection to update the display
  connect(scan_devices_process, SIGNAL(readyReadStandardOutput()), SLOT(updateScanDevices() )); 
  QDir bin("/usr/bin");
  QDir::setCurrent( bin.absolutePath() );
  Devices_Burn = "";
  scan_devices_process->start("xorriso -devices" );
  scan_devices_process->waitForFinished();
  QString stream_Devices_Burn = Devices_Burn;
  Devices_Burn.clear();
  QTextStream stream(&stream_Devices_Burn);
  QString line;
  while (!stream.atEnd()) {
    line = stream.readLine();
    if (line.contains("---------------") ) {
      line = stream.readLine();
      if (!line.contains("---------------") && (line != "") ) {
	Devices_Burn = Devices_Burn.prepend("~" + line) ;
      }
    }
  }
}

void erasecd::updateScanDevices() {
  QByteArray process_output = scan_devices_process->readAllStandardOutput();
  QString temp = process_output;
  Devices_Burn.append(" " + temp);
}

void erasecd::updateScanDevicesProperties() {
  QByteArray process_output = scan_device_properties_process->readAllStandardOutput();
  Properties_Device = Properties_Device.append(process_output);
}

void erasecd::device_scan() {

   scan_devices_burn();

   //qDebug() << Devices_Burn;
  //disabilita tutto se non viene trovato almeno 1 periferica
  if (Devices_Burn == "") {
    QMessageBox::warning(this, "AcetoneISO::warning", tr("No CD/DVD device found.\nIf you think this is a bug please report it."));
    disable_buttons();
    devices_combo->addItem( tr("No CD/DVD device found") );
    return;
  }
  QIcon icon_optical_drive( ":/images/drive-optical.png" );

  //Devices_Burn = "~ 0  -dev '/dev/sr0' rwrw-- :  'TSSTcorp' 'CDDVDW SE-S084F' ~ 1  -dev '/dev/sr1' rwrw-- :  'ASUS' 'CDDVDW' ";
  
  QStringList split_devices = Devices_Burn.split("~",QString::SkipEmptyParts);
  int count = split_devices.count();
  //qDebug() << count;
  int cc = 0;
  int success = -1;
  
  while (cc < count) {
    Properties_Device = "";
    //controllare se device supporta masterizzare su cd-r cd-rw, in caso contrario ripartire ciclo:  xorriso -outdev /dev/sr0 -list_profiles
    QString device_current = split_devices[cc].split("'", QString::SkipEmptyParts)[1];
    scan_device_properties_process = new QProcess();
    scan_device_properties_process->setReadChannel(QProcess::StandardOutput);
    scan_device_properties_process->setProcessChannelMode(QProcess::MergedChannels);		
    //connection to update the display
    connect(scan_device_properties_process, SIGNAL(readyReadStandardOutput()), SLOT(updateScanDevicesProperties() )); 
    QDir bin("/usr/bin");
    QDir::setCurrent( bin.absolutePath() );
    scan_device_properties_process->start("xorriso -outdev " + device_current + " -list_profiles" );
    scan_device_properties_process->waitForFinished(); 
    if (!Properties_Device.contains("cd-rw", Qt::CaseInsensitive) ) {
      qDebug() << "Removed:" << Properties_Device;
      cc = cc + 1;
      continue;
    }
    
    //success si ricorda sempre la posizione in cui aggiungere all'array indipendentemente dal cc del ciclo while 
    success = success + 1;
    //aggiungo id nell'array
    id_device.insert(success, split_devices[cc]);		  
    devices_combo->insertItem(success,icon_optical_drive, " " + split_devices[cc] );
    cc = cc + 1;
   }

  //media_available();
//if < 1 significa che sebbene ci sono 1 o piu periferiche cdrom, nessuna e' capace di scrivere su cd-rw
  if (devices_combo->count() < 1) {
    disable_buttons();
    QMessageBox::warning(this, "AcetoneISO::warning", tr("No CD/DVD device found capable of writing to CD-RW discs.\nIf you think this is a bug please report it."));
    return; 
  }
  else { //c'e' almeno 1 periferica cdrom in grado di scrivere su dischi cd-rw
    loaded_success = true;
    //crea un timer cosi aggiorna automaticamente la label_info
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(media_available()));
    timer->start(6500);
    connect( devices_combo, SIGNAL(currentIndexChanged(int) ), this , SLOT( combo_changed(int) ) ); 
  }

  
}


void erasecd::media_available() {
  //qDebug() << "media_available()";
  //se sto masterizzando deve uscire da qui
  if (is_erasing) {
    start->setEnabled(false);
    label_info->setText(tr("The CD-RW is getting blanked..."));
    return;
  }

  //if < 1 it means there are no devices capaci di scrivere su dischi cd-rw
  if (devices_combo->count() < 1) {
    return; 
  }

  //se non e' visibile deve disconnettere le connessioni
  if (loaded_success) {
    if (!devices_combo->isVisible()) {
      disconnect(devices_combo, 0, 0, 0);
      disconnect(timer, 0, 0, 0);
      loaded_success = false;
    }
  }

  //prendo indice corrente della combobox cosi so chi l'id della periferica selezionata
  int current_index = devices_combo->currentIndex();
  QString id = id_device[current_index];
  //qDebug() << id;

  Properties_Device = "";
  //controllo se ce un cd inserito ed è di tipo CD-RW :  xorriso -outdev /dev/sr0 -list_profiles
  QString device_current = id.split("'", QString::SkipEmptyParts)[1];
  //qDebug() << device_current;
  scan_device_properties_process = new QProcess();
  scan_device_properties_process->setReadChannel(QProcess::StandardOutput);
  scan_device_properties_process->setProcessChannelMode(QProcess::MergedChannels);		
  //connection to update the display
  connect(scan_device_properties_process, SIGNAL(readyReadStandardOutput()), SLOT(updateScanDevicesProperties() ));
  connect( scan_device_properties_process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(scan_device_properties_process_Finished(int, QProcess::ExitStatus)));
  QDir bin("/usr/bin");
  QDir::setCurrent( bin.absolutePath() );
  scan_device_properties_process->start("xorriso -outdev " + device_current + " -list_profiles" );
  //qDebug() << Properties_Device;
}


//gestisce quando l'utente cambia periferica nella combobox
void erasecd::combo_changed(int n) {
  int a;
  a = n;
  media_available();
}


void erasecd::start_erase() {
 QMessageBox msgBox;
 msgBox.setText(tr("You decided to blank the CD-RW.\nAre you sure?"));
 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
 switch (msgBox.exec()) {
 case QMessageBox::Yes:
    {
      //continue below
     }
     break;
 case QMessageBox::No:
 {
  return; //exit
 }
     break;
 default:
     // should never be reached
     break;
 }

  QString erase_type;
  if (radioButton->isChecked()) {
    erase_type = "blank=all";
  }
  else {
    erase_type = "blank=fast";
  }


  disable_buttons();
  QString dev = device_path.at(devices_combo->currentIndex());
  dev = dev.prepend("dev=");
  textBrowser->clear(); 
  erase = new QProcess();
  erase->setReadChannel(QProcess::StandardOutput);
  erase->setProcessChannelMode(QProcess::MergedChannels);		
  //connection to update the display
  connect(erase, SIGNAL(readyReadStandardOutput()), SLOT(updateEraseDisplay() )); 
  connect(erase, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(printOutErase(int, QProcess::ExitStatus)));
  QDir bin("/usr/bin");
  QDir::setCurrent( bin.absolutePath() );
  is_erasing = true;
  if (eject->isChecked()) {
    erase->start("wodim",QStringList()  << "-verbose" << dev <<  erase_type << "-eject" );
  }
  else {
    erase->start("wodim",QStringList()  << "-verbose" << dev <<  erase_type );
  }

}

//fa loutput nel display del processo wodim
void erasecd::updateEraseDisplay() {
  erase_output = erase->readAllStandardOutput(); 
  textBrowser->setPlainText(erase_output);   
}

//gestisce quando il processo wodim finisce

void erasecd::scan_device_properties_process_Finished(int, QProcess::ExitStatus) {
  if (Properties_Device.contains("Media current: is not recognizable", Qt::CaseInsensitive) ) {
    label_info->setText(tr("Insert a CD-RW disc."));
    start->setEnabled(false);
    //devices_combo->setItemText(cc,tr("No Media Inserted, insert a media and click on refresh button."));
    return;
  }
//ferma in caso che il disco inserito non sia un disco CD-RW
  if (!Properties_Device.contains("Media current: CD-RW", Qt::CaseInsensitive) ) {
    label_info->setText(tr("The disc isn't a CD-RW. Please insert a CD-RW disc."));
    start->setEnabled(false); 
    return;
  }

  label_info->setText(tr("CD-RW succesfully found in device."));
  start->setEnabled(true);
}

//gestisce quando il processo wodim finisce
void erasecd::printOutErase(int, QProcess::ExitStatus) {
  enable_buttons();
  is_erasing = false;
  int valore_uscita = erase->exitCode();
  if(valore_uscita == 0) {
    QMessageBox::information(this, "AcetoneISO",tr("Process Succesfully Finished!"));
  }
  else {
  QMessageBox::critical(this, "AcetoneISO","Process Error Code: " + QString::number(valore_uscita) );
  }
}

//abilita i bottoni
void erasecd::enable_buttons() { 
  start->setEnabled(true);
  devices_combo->setEnabled(true);
  eject->setEnabled(true);
  radioButton->setEnabled(true);
  radioButton_2->setEnabled(true);
}
//disabilita i bottoni
void erasecd::disable_buttons() {
  start->setEnabled(false);
  devices_combo->setEnabled(false);
  eject->setEnabled(false);
  radioButton->setEnabled(false);
  radioButton_2->setEnabled(false); 
}


void erasecd::play_success() {
  /*
Phonon::MediaObject *mediaObject;	
Phonon::AudioOutput *audioOutput; 
Phonon::Path path;
mediaObject = new Phonon::MediaObject();
audioOutput = new Phonon::AudioOutput(Phonon::NoCategory);
path = Phonon::createPath(mediaObject, audioOutput);
QString file(":/audio/success.ogg");
mediaObject->setCurrentSource(Phonon::MediaSource(file));
mediaObject->play();
*/
}

void erasecd::play_error() {
/*
Phonon::MediaObject *mediaObject;	
Phonon::AudioOutput *audioOutput; 
Phonon::Path path;
mediaObject = new Phonon::MediaObject();
audioOutput = new Phonon::AudioOutput(Phonon::NoCategory);
path = Phonon::createPath(mediaObject, audioOutput);
QString file(":/audio/error.ogg");
mediaObject->setCurrentSource(Phonon::MediaSource(file));
mediaObject->play();
*/
}



