#include "logicburnimage.h"
#include "src/frame/logger.h"
#include "src/frame/configuration.h"
#include "src/po/translation.h"
#include "src/model/logicmain.h"
#include "src/data/datacdrom.h"
#include "src/process/processburnimage.h"
#include "src/view/modaldialog.h"

#include <QFileInfo>
#include <QDebug>
LogicBurnImage *LogicBurnImage::m_oInstance = nullptr;
QMutex          LogicBurnImage::m_oMutex;

LogicBurnImage::LogicBurnImage(QObject *parent) :
    QObject(parent),
    m_iBurner(-1)
{
    connect(this, SIGNAL(info(QString)), LOGGER, SLOT(info(QString)));
    connect(this, SIGNAL(warn(QString)), LOGGER, SLOT(warn(QString)));
    connect(this, SIGNAL(error(QString)), LOGGER, SLOT(error(QString)));
    connect(this, SIGNAL(debug(QString)), LOGGER, SLOT(debug(QString)));
    LOGGER->registerName(this, _("BURNIMAGE"));

    m_oISOPath.clear();
    m_oISOPaths.clear();
    m_oBurners.clear();
    connect(MAIN,SIGNAL(appendableMedium(void*)),this,SLOT(slotsNewBurner(void*)));
    connect(MAIN, SIGNAL(emptyMedium(void*)), this, SLOT(slotsNewBurner(void*)));
    connect(MAIN, SIGNAL(noMedium(void*)), this, SLOT(slotsDeleteBurner(void*)));
    connect(MAIN,SIGNAL(burnImage()), this, SLOT(slotsBurnImage()));
    connect(MAIN, SIGNAL(burnImageSetting()), this, SLOT(slotsSetting()));
    connect(this, SIGNAL(setting(void*)), BUSNESSSETTING, SLOT(load(void *)));
}

LogicBurnImage *LogicBurnImage::instance()
{
    if (nullptr == m_oInstance)
    {
        QMutexLocker locker(&m_oMutex);
        if (nullptr == m_oInstance)
        {
            m_oInstance = new LogicBurnImage();
        }
    }
    return m_oInstance;
}

void LogicBurnImage::init()
{
    QString isoPath;
    QFileInfo f;
    QVariantList vars;

//    if (m_oISOPath.isEmpty())
//    {
//        vars = CFG->gets("BurnImage", "Paths");
//        while (vars.size())
//        {
//            isoPath = vars.takeFirst().toString();
//            f.setFile(isoPath);
//            if (f.exists())
//            {
//                debug(_("Loaded iso path <%1>").arg(isoPath));
//                emit newISOPath(isoPath);
//            }
//        }
//    }
    if (0 == m_oBurners.size())
    {
        emit enableBurner(m_iBurner >= 0);
        emit enableBusness(check());
        emit burnerError(_("No valid burner,need burner which with empty meduim."));
    }
    if(m_oBurners.size() > 0){
        DataCDROM *cdrom;
       // qDebug() << QString("[%1] [%2] : 光盘设置的 m_iBurner = %3").arg(__func__).arg(__LINE__).arg(m_iBurner);
        cdrom = (DataCDROM *)(m_oBurners.at(m_iBurner));

      //  qDebug() <<__func__<<__LINE__<<cdrom;

        if(cdrom->mediumType().contains("RW")&&DataMedium::MEDIUM_EMPTY != cdrom->mediumStatus()){
            emit burnerError(_("This disc is a non-empty disc and needs to be erased!"));
            emit enableBurner(m_iBurner >= 0);
            emit enableBusness(check());
            return;
        }else if(DataMedium::MEDIUM_EMPTY != cdrom->mediumStatus()){
            emit burnerError(_("No valid burner,need burner which with empty meduim."));
            emit enableBurner(m_iBurner >= 0);
            emit enableBusness(check());
            return;
        }
        //if(DataMedium::MEDIUM_EMPTY == cdrom->mediumStatus()){
        emit enableBurner(m_iBurner >= 0);
        emit enableBusness(check());
        //}
    }
    //emit enableBurner(m_iBurner >= 0);
    //emit enableBusness(check());
}

QIcon LogicBurnImage::mediumIcon(int idx)
{
    DataCDROM *cdrom;
    if (idx < 0 || idx >= m_oBurners.size()) return QIcon();
    cdrom = (DataCDROM *)(m_oBurners.at(idx));
    return cdrom->mediumIcon();
}

QString LogicBurnImage::display(int idx)
{
    DataCDROM *cdrom;
    if (idx < 0 || idx >= m_oBurners.size()) return QString();
    cdrom = (DataCDROM *)(m_oBurners.at(idx));
    return cdrom->mDisplay();
}

QString LogicBurnImage::tooltip(int idx)
{
    DataCDROM *cdrom;
    if (idx < 0 || idx >= m_oBurners.size()) return QString();
    cdrom = (DataCDROM *)(m_oBurners.at(idx));
    return cdrom->display();
}

void LogicBurnImage::onNewISOPath(QString path)
{
    m_oISOPath = path;
    if (-1 == m_oISOPaths.indexOf(path))
    {
        m_oISOPaths << path;
        debug(_("Record new iso file path <%1>").arg(path));
    }
    init();
    debug(_("Ready to burn : %1").arg(m_oISOPath));
}

void LogicBurnImage::onNewBurner(int idx)
{
    m_iBurner = idx;
    init();
    debug(_("Current index for burning is %1").arg(m_iBurner));
}

bool LogicBurnImage::check()
{
    QFileInfo f;
    DataCDROM *cdrom;

    // ISO file cannot empty.
    if (m_oISOPath.isEmpty())
    {
        //emit isoError(_("No iso file."));
        return false;
    }
    // cannot have no burner to burn.
    if (m_iBurner < 0 || 0 == m_oBurners.size())
    {
        emit burnerError(_("No valid burner,need burner which with empty meduim."));
        return false;
    }
    if(m_oBurners.size() > 0){
        DataCDROM *cdrom;
       // qDebug() << QString("[%1] [%2] : 光盘设置的 m_iBurner = %3").arg(__func__).arg(__LINE__).arg(m_iBurner);
        cdrom = (DataCDROM *)(m_oBurners.at(m_iBurner));

       // qDebug() <<"LogicBurnImage"<<__func__<<__LINE__<<cdrom;

        if(cdrom->mediumType().contains("RW")&&DataMedium::MEDIUM_EMPTY != cdrom->mediumStatus()){
            emit burnerError(_("This disc is a non-empty disc and needs to be erased!"));
            return false;
        }else if(DataMedium::MEDIUM_EMPTY != cdrom->mediumStatus()){
            emit burnerError(_("No valid burner,need burner which with empty meduim."));
            return false;
        }
    }

    cdrom = (DataCDROM *)(m_oBurners.at(m_iBurner));
    f.setFile(m_oISOPath);
    if (f.size() > cdrom->mediumFreeSize())
    {
        emit isoError(_("Too long to burn to current medium."));
        emit burnerError(_("Current medium has not enough space for burning current iso file."));
        return false;
    }
    // iso file size cannot larger than disk free size.
    emit ready(_("Ready to burn,please click [BurnImage] button."));
    return true;
}

void LogicBurnImage::slotsNewBurner(void *d)
{
    int idx;
    DataCDROM *cdrom;

    cdrom = (DataCDROM *)d;

    idx = m_oBurners.indexOf(d);
    if (-1 == idx)
    {
        m_oBurners << d;
        emit newBurner(cdrom->mDisplay(), cdrom->display());
        debug(_("New empty medium burner %1, medium %2")
              .arg(cdrom->display()).arg(cdrom->mDisplay()));
        qDebug()<<__LINE__<<__func__<<cdrom->mDisplay();
    }
}

void LogicBurnImage::slotsDeleteBurner(void *d)
{
    int idx;

    idx = m_oBurners.indexOf(d);
    if (-1 != idx)
    {
        debug(_("Remove burner."));
        m_oBurners.takeAt(idx);
        deleteBurner(idx);
        if (m_iBurner == idx) {
           // qDebug()<<__LINE__<<__func__<<d;
          //  qDebug() << QString("[%1] [%2] : idx = %3 移除的光盘为m_iBurner = %4").arg(__func__).arg(__LINE__).arg(idx).arg(m_iBurner);
           // --m_iBurner;
           // qDebug()<<__LINE__<<__func__<<d;
           // qDebug() << QString("[%1] [%2] :  移除光盘后的m_iBurner = %4").arg(__func__).arg(__LINE__).arg(m_iBurner);
        }
    }
}

void LogicBurnImage::slotsBurnImage()
{
    DataCDROM *cdrom;

    cdrom = (DataCDROM *)m_oBurners.at(m_iBurner);
    debug(_("Begin to burn image, burn image<%1> to medium in <%2>")
          .arg(m_oISOPath).arg(cdrom->display()));
    ProcessBurnImage burnImage(m_oISOPath, cdrom);
    burnImage.exec();
}

void LogicBurnImage::slotsSetting()
{
    BUSNESSSETTING;
    MODAL->show();
    setting(m_oBurners.at(m_iBurner));
}

LogicBurnImage::~LogicBurnImage()
{
    QVariantList vars;

    vars.clear();
    while (m_oISOPaths.size())
        vars << m_oISOPaths.takeFirst();
    CFG->sets("BurnImage", "Paths", vars);
}
