#include "logiccopyimage.h"
#include "src/frame/logger.h"
#include "src/data/datacdrom.h"
#include "src/model/logicmain.h"
#include "src/view/modaldialog.h"
#include "src/process/processgetiso.h"
#include "src/process/processcopydisk.h"
#include "src/view/execdialog.h"
#include "src/po/translation.h"
#include <QDebug>
LogicCopyImage *LogicCopyImage::m_oInstance = nullptr;
QMutex     LogicCopyImage::m_oMutex;

LogicCopyImage::LogicCopyImage(QObject *parent) :
    QObject(parent),
    m_iSource(-1),
    m_iDestination(-1)
{
    m_oSources.clear();
    m_oDestinations.clear();
    connect(MAIN, SIGNAL(createCopyImage(void*)), this, SLOT(slotsDestination(void*)));
    connect(MAIN, SIGNAL(emptyMedium(void*)), this, SLOT(slotsDestination(void*)));
    connect(MAIN, SIGNAL(appendableMedium(void*)), this, SLOT(slotsSource(void*)));
    connect(MAIN, SIGNAL(finishedMedium(void*)), this, SLOT(slotsSource(void*)));
    connect(MAIN, SIGNAL(noMedium(void*)), this, SLOT(slotsNoMedium(void*)));
    connect(MAIN, SIGNAL(burnCopySetting()), this, SLOT(slotsSetting()));
    connect(MAIN, SIGNAL(getISO()), this, SLOT(slotsCopyImage()));
    connect(MAIN, SIGNAL(copyData()), this, SLOT(slotsCopyData()));
    connect(this, SIGNAL(setting(void*)), BUSNESSSETTING, SLOT(load(void *)));
}

LogicCopyImage *LogicCopyImage::instance()
{
    if (nullptr == m_oInstance)
    {
        QMutexLocker locker(&m_oMutex);

        if (nullptr == m_oInstance)
        {
            m_oInstance = new LogicCopyImage();
        }
    }
    return m_oInstance;
}

bool LogicCopyImage::capacity()
{
    DataCDROM *src;
    DataCDROM *des;

    if (m_iDestination == 0) return true;
    if (m_iSource < 0 || m_iDestination < 0) return false;


    src = static_cast<DataCDROM *>(m_oSources.at(m_iSource));
    des = static_cast<DataCDROM *>(m_oDestinations.at(m_iDestination));

    return des->mediumFreeSize() >= src->mediumUsedSize();
}

void LogicCopyImage::updateISOPath(QString path)
{
    DataCDROM *cdrom;

    cdrom = static_cast<DataCDROM *>(m_oDestinations.at(0));
    cdrom->updateDisplay(path);
}

void LogicCopyImage::slotsDestination(void *d)
{
    if (-1 == m_oDestinations.indexOf(d)) m_oDestinations << d;
    destination(d);
}

void LogicCopyImage::slotsSource(void *d)
{
    m_oSources.clear();
    m_oSources << d;
    source(d);
}

void LogicCopyImage::slotsNoMedium(void *d)
{
    int idx;

    idx = m_oDestinations.indexOf(d);
    if (-1 != idx)
    {
        m_oDestinations.takeAt(idx);
        destination(idx);
    }

    idx = m_oSources.indexOf(d);
    if (-1 != idx)
    {
        m_oSources.takeAt(idx);
        source(idx);
    }
}

void LogicCopyImage::slotsSetting()
{
    DataCDROM *src;
    DataCDROM *des;
    BUSNESSSETTING;
    MODAL->show();
    src = static_cast<DataCDROM *>(m_oSources.at(m_iSource));
    des = static_cast<DataCDROM *>(m_oDestinations.at(m_iDestination));
    des->volumnID(src->settingVolumnID());
    des->preparer(src->settingPreparer());
    des->publisher(src->settingPublisher());
    des->copyright(src->settingCopyright());
    if (0 == m_iDestination)
    {
        des->clean(false);
        des->setOpen(false);
    }
    else
    {
        des->closeSession(src->mediumStatus() == DataMedium::MEDIUM_FINALIZED);
        des->createISO(false);
    }
    setting(des);
}

void LogicCopyImage::slotsCopyImage()
{
    ProcessGetISO *getISO;

    getISO = new ProcessGetISO(m_oSources.at(m_iSource), m_oDestinations.at(0), this);
    getISO->exec();
    delete getISO;
}

void LogicCopyImage::slotsCopyData()
{
    ProcessCopyDisk *copyDisk;
    DataCDROM *src;
    DataCDROM *des;

//    if (m_iDestination == 0) return true;
//    if (m_iSource < 0 || m_iDestination < 0) return false;


    src = static_cast<DataCDROM *>(m_oSources.at(m_iSource));
    des = static_cast<DataCDROM *>(m_oDestinations.at(m_iDestination));
    if(src->mediumType().contains("CD")&&des->mediumType().contains("DVD")){
        EXEC->information("",_("This disc is a CD, and copying to DVD is not supported"),true);
        return;

    }else if(src->mediumType().contains("DVD")&&des->mediumType().contains("CD")){
        EXEC->information("",_("This disc is a DVD, and copying to CD is not supported"),true);
        return;

    }else{
    copyDisk = new ProcessCopyDisk(m_oSources.at(m_iSource), m_oDestinations.at(m_iDestination), this);
    copyDisk->exec();
    delete copyDisk;
    }
}

LogicCopyImage::~LogicCopyImage()
{
}
