#include "WimaController.h"

const char* WimaController::wimaFileExtension   = "wima";
const char* WimaController::areaItemsName       = "AreaItems";
const char* WimaController::missionItemsName    = "MissionItems";

WimaController::WimaController(QObject *parent)
    : QObject               (parent)
    , _container            (nullptr)
    , _joinedArea           (this)
    , _measurementArea      (this)
    , _serviceArea          (this)
    , _corridor             (this)
    , _localPlanDataValid   (false)
{

}

QmlObjectListModel* WimaController::visualItems()
{
    return &_visualItems;
}

QStringList WimaController::loadNameFilters() const
{
    QStringList filters;

    filters << tr("Supported types (*.%1 *.%2)").arg(wimaFileExtension).arg(AppSettings::planFileExtension) <<
               tr("All Files (*.*)");
    return filters;
}

QStringList WimaController::saveNameFilters() const
{
    QStringList filters;

    filters << tr("Supported types (*.%1 *.%2)").arg(wimaFileExtension).arg(AppSettings::planFileExtension);
    return filters;
}

WimaDataContainer *WimaController::dataContainer() const
{
    return _container;
}

QmlObjectListModel *WimaController::missionItems()
{
    return &_missionItems;
}

void WimaController::setMasterController(PlanMasterController *masterC)
{
    _masterController = masterC;
    emit masterControllerChanged();
}

void WimaController::setMissionController(MissionController *missionC)
{
    _missionController = missionC;
    emit missionControllerChanged();
}

/*!
 * \fn void WimaController::setDataContainer(WimaDataContainer *container)
 * Sets the pointer to the \c WimaDataContainer, which is meant to exchange data between the \c WimaController and the \c WimaPlaner.
 *
 * \sa WimaPlaner, WimaDataContainer, WimaPlanData
 */
void WimaController::setDataContainer(WimaDataContainer *container)
{
    if (container != nullptr) {
        if (_container != nullptr) {
           disconnect(_container, &WimaDataContainer::dataValidChanged, this, &WimaController::containerDataValidChanged);
        }

        _container = container;
        connect(_container, &WimaDataContainer::dataValidChanged, this, &WimaController::containerDataValidChanged);

        emit dataContainerChanged();
    }
}

void WimaController::startMission()
{

}

void WimaController::abortMission()
{

}

void WimaController::pauseMission()
{

}

void WimaController::resumeMission()
{

}

bool WimaController::updateMission()
{
    return true;
}

void WimaController::saveToCurrent()
{
}

void WimaController::saveToFile(const QString& filename)
{
    QString file = filename;
}

bool WimaController::loadFromCurrent()
{
    return true;
}

bool WimaController::loadFromFile(const QString &filename)
{
    QString file = filename;
    return true;
}



QJsonDocument WimaController::saveToJson(FileType fileType)
{
    if(fileType)
    {

    }
    return QJsonDocument();
}

/*!
 * \fn void WimaController::containerDataValidChanged(bool valid)
 * Pulls plan data generated by \c WimaPlaner from the \c _container if the data is valid (\a valid equals true).
 * Is connected to the dataValidChanged() signal of the \c WimaDataContainer.
 *
 * \sa WimaDataContainer, WimaPlaner, WimaPlanData
 */
void WimaController::containerDataValidChanged(bool valid)
{
    if ( valid ) {
        if (_container == nullptr) {
            qWarning("WimaController::containerDataValidChanged(): No container assigned!");
        }
        _localPlanDataValid = false;
        _visualItems.clear();
        _missionItems.clear();
        WimaPlanData planData = _container->pull();

        // extract list with WimaAreas
        QList<const WimaAreaData*> areaList = planData.areaList();

        int areaCounter = 0;
        int numAreas = 4; // extract only numAreas Areas, if there are more they are invalid and ignored
        qWarning() << QString("List Size: %1").arg(areaList.size());
        for (int i = 0; i < areaList.size(); i++) {
            const WimaAreaData *areaData = areaList[i];

            qWarning() << areaData->type();
            if (areaData->type() == WimaServiceAreaData::typeString) { // is it a service area?
                _serviceArea = *qobject_cast<const WimaServiceAreaData*>(areaData);
//                qWarning("Service area, wuhuuu!");
                areaCounter++;
                _visualItems.append(&_serviceArea);

                continue;
            }

            if (areaData->type() == WimaMeasurementAreaData::typeString) { // is it a measurement area?
                _measurementArea =  *qobject_cast<const WimaMeasurementAreaData*>(areaData);
//                qWarning("Measurement area, wuhuuu!");
                areaCounter++;
                _visualItems.append(&_measurementArea);

                continue;
            }

            if (areaData->type() == WimaCorridorData::typeString) { // is it a corridor?
                _corridor =  *qobject_cast<const WimaCorridorData*>(areaData);
//                qWarning("WimaCorridorData, wuhuuu!");
                areaCounter++;
                //_visualItems.append(&_corridor); // not needed

                continue;
            }

            if (areaData->type() == WimaJoinedAreaData::typeString) { // is it a corridor?
                _joinedArea =  *qobject_cast<const WimaJoinedAreaData*>(areaData);
//                qWarning("WimaJoinedAreaData, wuhuuu!");
                areaCounter++;
                _visualItems.append(&_joinedArea);

                continue;
            }

            if (areaCounter >= numAreas)
                break;
        }

#ifdef QT_DEBUG
        //qWarning("containerDataValidChanged(): count:");
        //qWarning() << planData.missionItems().count();
#endif

        QList<const MissionItem*> tempMissionItems = planData.missionItems();

        for (auto missionItem : tempMissionItems)
            _missionItems.append(const_cast<MissionItem *>(missionItem)); // losing const qualifier here

        if (areaCounter == numAreas)
            _localPlanDataValid = true;

    } else {
        _localPlanDataValid = false;
        _visualItems.clear();
        _missionItems.clear();
    }

    emit visualItemsChanged();
    emit missionItemsChanged();

#ifdef QT_DEBUG
    //qWarning("Mission Items count: ");
    //qWarning() << _missionItems.count();
#endif
}







