// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
FilterPipeline::Pointer JsonFilterParametersReader::ReadPipelineFromFile(QString filePath, IObserver* obs)
{
    QFileInfo fInfo(filePath);

    if (filePath.isEmpty() == true)
    {
        return FilterPipeline::NullPointer();
    }
    QFileInfo fi(filePath);
    if (fi.exists() == false)
    {
        return FilterPipeline::NullPointer();
    }

    FilterManager* filtManager = FilterManager::Instance();
    FilterFactory<EmptyFilter>::Pointer emptyFilterFactory = FilterFactory<EmptyFilter>::New();
    filtManager->addFilterFactory("EmptyFilter", emptyFilterFactory);

    JsonFilterParametersReader::Pointer reader = JsonFilterParametersReader::New();
    int err = reader->openFile(filePath);

    if (err < 0)
    {
        if (NULL != obs)
        {
            PipelineMessage pm(JsonFilterParametersReader::ClassName(), "File '" + fInfo.fileName() + "' could not be opened for reading.", -1, PipelineMessage::Error);
            obs->processPipelineMessage(pm);
        }
        return FilterPipeline::NullPointer();
    }

    reader->openGroup(DREAM3D::Settings::PipelineBuilderGroup);
    int filterCount = reader->readValue(DREAM3D::Settings::NumFilters, 0);
    reader->closeGroup();

    FilterPipeline::Pointer pipeline = FilterPipeline::New();

    for (int i = 0; i < filterCount; ++i)
    {
        // Open the group to get the name of the filter then close again.
        reader->openFilterGroup(NULL, i);
        QString filterName = reader->readString(DREAM3D::Settings::FilterName, "");
        reader->closeFilterGroup();
        //qDebug() << "Group: " << gName << " FilterName: " << filterName;
        if (filterName.isEmpty() == false)
        {
            IFilterFactory::Pointer factory = filtManager->getFactoryForFilter(filterName);
            if (factory.get() != NULL)
            {
                AbstractFilter::Pointer filter = factory->create();

                if (NULL != filter.get())
                {
                    filter->readFilterParameters(reader.get(), i);
                    pipeline->pushBack(filter);
                }
            }
            else // Could not find the filter because the specific name has not been registered. This could
                // be due to a name change for the filter.
            {
                EmptyFilter::Pointer filter = EmptyFilter::New();
                QString humanLabel = QString("UNKNOWN FILTER: ") + filterName;
                filter->setHumanLabel(humanLabel);
                filter->setOriginalFilterName(filterName);
                pipeline->pushBack(filter);

                if (NULL != obs)
                {
                    QString ss = QObject::tr("An implementation for filter '%1' could not be located. Possible reasons include a name change of the filter, plugin not loading or a simple spelling mistake? A blank filter has been inserted in its place.").arg(filterName);
                    PipelineMessage pm(filterName, ss, -66066, PipelineMessage::Error);
                    pm.setPrefix("JsonFilterParametersReader::ReadPipelineFromFile()");
                    obs->processPipelineMessage(pm);
                }
            }
        }
        else
        {
            EmptyFilter::Pointer filter = EmptyFilter::New();
            QString humanLabel = QString("MISSING FILTER: ") + filterName;
            filter->setHumanLabel(humanLabel);
            filter->setOriginalFilterName(filterName);
            pipeline->pushBack(filter);

            if (NULL != obs)
            {
                QString gName = QString::number(i);
                QString ss = QObject::tr("A filter for index '%1' is missing in the file. Is the numbering of the filters correct in the pipeline file?").arg(gName);
                PipelineMessage pm(filterName, ss, -66067, PipelineMessage::Error);
                pm.setPrefix("JsonFilterParametersReader::ReadPipelineFromFile()");
                obs->processPipelineMessage(pm);
            }
        }
    }
    return pipeline;
}