// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void PhaseTypeSelectionWidget::populateAttributeMatrixList()
{
  QString dcName = dataContainerCombo->currentText();

  // Clear the AttributeMatrix List
  attributeMatrixCombo->blockSignals(true);
  attributeMatrixCombo->clear();

  // Loop over the data containers until we find the proper data container
  QList<DataContainerProxy> containers = m_DcaProxy.dataContainers.values();
  QListIterator<DataContainerProxy> containerIter(containers);
  while(containerIter.hasNext())
  {
    DataContainerProxy dc = containerIter.next();

    if(dc.name.compare(dcName) == 0 )
    {
      // We found the proper Data Container, now populate the AttributeMatrix List
      QMap<QString, AttributeMatrixProxy> attrMats = dc.attributeMatricies;
      QMapIterator<QString, AttributeMatrixProxy> attrMatsIter(attrMats);
      while(attrMatsIter.hasNext() )
      {
        attrMatsIter.next();
        QString amName = attrMatsIter.key();
        attributeMatrixCombo->addItem(amName);
      }
    }
  }

  attributeMatrixCombo->blockSignals(false);
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void DataContainerArrayProxyWidget::updateModelFromProxy(DataContainerArrayProxy& proxy)
{
  QStandardItemModel* model = qobject_cast<QStandardItemModel*>(dcaProxyView->model());
  if(!model)
  {
    Q_ASSERT_X(model, "Model was not a QStandardItemModel in QColumnView", "");
    return;
  }
  QStandardItem* rootItem = model->invisibleRootItem();

  // Loop over the data containers until we find the proper data container
  QList<DataContainerProxy> containers = proxy.dataContainers.values();
  QListIterator<DataContainerProxy> containerIter(containers);
  QStringList dcList;
  while(containerIter.hasNext())
  {
    DataContainerProxy dcProxy = containerIter.next();
    dcList.push_back(dcProxy.name);
    QStandardItem* dcItem = getColumnItem<DataContainerProxy>(rootItem, dcProxy.name, dcProxy);
    assert(dcItem != NULL);
    //    qDebug() << "**  " << dcProxy.name;
    // We found the proper Data Container, now populate the AttributeMatrix List
    QMap<QString, AttributeMatrixProxy>& attrMats = dcProxy.attributeMatricies;
    QMutableMapIterator<QString, AttributeMatrixProxy> attrMatsIter(attrMats);
    while(attrMatsIter.hasNext() )
    {
      attrMatsIter.next();
      QString amName = attrMatsIter.key();
      AttributeMatrixProxy& attrProxy = attrMatsIter.value();
      QStandardItem* amItem = getColumnItem<AttributeMatrixProxy>(dcItem, amName, attrProxy);
      assert(amItem != NULL);

      //   qDebug() << "@@@ " << amName;
      // We found the selected AttributeMatrix, so loop over this attribute matrix arrays and populate the list widget
      QMap<QString, DataArrayProxy>& dataArrays = attrProxy.dataArrays;
      QMutableMapIterator<QString, DataArrayProxy> dataArraysIter(dataArrays);
      while(dataArraysIter.hasNext() )
      {
        dataArraysIter.next();
        DataArrayProxy& daProxy = dataArraysIter.value();
        QString daName = dataArraysIter.key();
        //    qDebug() << "#### " << daName;
        QStandardItem* daItem = getColumnItem<DataArrayProxy>(amItem, daName, daProxy);
        if (NULL == daItem)
        {
          Q_ASSERT_X(daItem != NULL, "daItem was NULL. This can not happen", "");
        }
      }

      // Now remove those items that are still in the model but NOT the proxy. This can happen if a filter upstream
      // renames something
      removeNonExistantChildren(amItem, dataArrays.keys() );
    }
    // Now remove any nonexistant AttributeMatrix objects
    removeNonExistantChildren(dcItem, attrMats.keys() );
  }
  // Remove any Data Containers from the model
  removeNonExistantChildren(rootItem, dcList);
}
    static void PopulateAttributeMatrixComboBox(AbstractFilter* filter, FilterParameter* filterParameter,
                                            QComboBox* dcCombo, QComboBox* amCombo,
                                            DataContainerArrayProxy& dcaProxy)
    {
      FilterParameterType* fp = dynamic_cast<FilterParameterType*>(filterParameter);
      assert(fp != NULL);
      DataContainerArray::Pointer dca = filter->getDataContainerArray();
      if (NULL == dca.get()) { return; }

      QString dcName = dcCombo->currentText();

      // Clear the AttributeMatrix List
      bool alreadyBlocked = false;
      if(amCombo->signalsBlocked()) { alreadyBlocked = true; }
      amCombo->blockSignals(true);
      amCombo->clear();

      // Loop over the data containers until we find the proper data container
      QList<DataContainerProxy> containers = dcaProxy.dataContainers.values();
      QListIterator<DataContainerProxy> containerIter(containers);
      QVector<unsigned int> defVec = fp->getDefaultAttributeMatrixTypes();
      while(containerIter.hasNext())
      {
        DataContainerProxy dc = containerIter.next();

        if(dc.name.compare(dcName) == 0 )
        {
          // We found the proper Data Container, now populate the AttributeMatrix List
          QMap<QString, AttributeMatrixProxy> attrMats = dc.attributeMatricies;
          QMapIterator<QString, AttributeMatrixProxy> attrMatsIter(attrMats);
          while(attrMatsIter.hasNext() )
          {
            attrMatsIter.next();
            QString amName = attrMatsIter.key();
            AttributeMatrix::Pointer am = dca->getAttributeMatrix(DataArrayPath(dc.name, amName, ""));
            amCombo->addItem(amName);

            if (NULL != am.get() && defVec.isEmpty() == false && defVec.contains(am->getType()) == false)
            {
              QStandardItemModel* model = qobject_cast<QStandardItemModel*>(amCombo->model());
              if (NULL != model)
              {
                QStandardItem* item = model->item(amCombo->findText(amName));
                if (NULL != item)
                {
                  item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
                }
              }
            }
          }
        }
      }

      if(!alreadyBlocked) { // Only unblock if this function blocked the signals.
        amCombo->blockSignals(false);
      }
    }
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void DataArraySelectionWidget::populateAttributeArrayList()
{
  attributeArrayCombo->blockSignals(true);
  attributeArrayCombo->clear();

  // Get the selected Data Container Name from the DataContainerList Widget
  QString currentDCName = dataContainerCombo->currentText();
  QString currentAttrMatName = attributeMatrixCombo->currentText();

  // Loop over the data containers until we find the proper data container
  QList<DataContainerProxy> containers = m_DcaProxy.dataContainers.values();
  QListIterator<DataContainerProxy> containerIter(containers);
  while(containerIter.hasNext())
  {
    DataContainerProxy dc = containerIter.next();
    if(dc.name.compare(currentDCName) == 0 )
    {
      // We found the proper Data Container, now populate the AttributeMatrix List
      QMap<QString, AttributeMatrixProxy> attrMats = dc.attributeMatricies;
      QMapIterator<QString, AttributeMatrixProxy> attrMatsIter(attrMats);
      while(attrMatsIter.hasNext() )
      {
        attrMatsIter.next();
        QString amName = attrMatsIter.key();
        if(amName.compare(currentAttrMatName) == 0 )
        {
          // Clear the list of arrays from the QListWidget
          attributeArrayCombo->clear();
          // We found the selected AttributeMatrix, so loop over this attribute matrix arrays and populate the list widget
          AttributeMatrixProxy amProxy = attrMatsIter.value();
          QMap<QString, DataArrayProxy> dataArrays = amProxy.dataArrays;
          QMapIterator<QString, DataArrayProxy> dataArraysIter(dataArrays);
          while(dataArraysIter.hasNext() )
          {
            dataArraysIter.next();
            //DataArrayProxy daProxy = dataArraysIter.value();
            QString daName = dataArraysIter.key();
            attributeArrayCombo->addItem(daName);
          }
        }
      }
    }
  }

  attributeArrayCombo->setCurrentIndex(-1);
  attributeArrayCombo->blockSignals(false);
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void DataContainerReaderWidget::updateProxyFromProxy(DataContainerArrayProxy& current, DataContainerArrayProxy& incoming)
{
  //  qDebug() << getFilter()->getNameOfClass() << " DataContainerReaderWidget::mergeProxies";

  // Loop over the current model and only worry about getting the flag for each proxy from the current and transfering
  // that flag to the incoming. This allows us to save the selections but also update the model later on with this new
  // proxy which will have selection flags set appropriately.

  QList<DataContainerProxy> containers = current.dataContainers.values();
  QListIterator<DataContainerProxy> containerIter(containers);
  //  QStringList dcList;
  while(containerIter.hasNext())
  {
    DataContainerProxy dcProxy = containerIter.next();

    // We have a DataContainer from the DataContainerArrayProxy, transfer any flags from this DataContainerProxy to
    // the same one in the incoming DataContainerArrayProxy
    Detail::transferDataContainFlags(dcProxy, incoming);

    QMap<QString, AttributeMatrixProxy>& attrMats = dcProxy.attributeMatricies;
    QMapIterator<QString, AttributeMatrixProxy> attrMatsIter(attrMats);
    while(attrMatsIter.hasNext() )
    {
      attrMatsIter.next();
      QString amName = attrMatsIter.key();
      const AttributeMatrixProxy attrProxy = attrMatsIter.value();

      Detail::transferAttributeMatrixFlags(dcProxy.name, attrProxy, incoming);

      //   qDebug() << "@@@ " << amName;
      // Loop over the current AttributeMatrixProxy and see if we need to transfer any flags.
      const QMap<QString, DataArrayProxy> dataArrays = attrProxy.dataArrays;
      QMapIterator<QString, DataArrayProxy> dataArraysIter(dataArrays);
      while(dataArraysIter.hasNext() )
      {
        dataArraysIter.next();
        DataArrayProxy daProxy = dataArraysIter.value();

        Detail::transferDataArrayFlags(dcProxy.name, attrProxy.name, daProxy, incoming);
      }
    }
  }

}
    static void PopulateAttributeArrayList(AbstractFilter* filter, FilterParameter* filterParameter,
                                           QComboBox* dcCombo, QComboBox* amCombo, WidgetType* attributeArraysWidget,
                                           DataContainerArrayProxy& dcaProxy,
                                           QVector<DataArrayPath> selectedPaths)
    {
      FilterParameterType* fp = dynamic_cast<FilterParameterType*>(filterParameter);
      assert(fp != NULL);

      DataContainerArray::Pointer dca = filter->getDataContainerArray();
      if (NULL == dca.get()) { return; }

      attributeArraysWidget->blockSignals(true);
      attributeArraysWidget->clear();

      // Get the selected Data Container Name from the DataContainerList Widget
      QString currentDCName = dcCombo->currentText();
      QString currentAttrMatName = amCombo->currentText();

      // Loop over the data containers until we find the proper data container
      QList<DataContainerProxy> containers = dcaProxy.dataContainers.values();
      QListIterator<DataContainerProxy> containerIter(containers);
      QVector<QString> daTypes = fp->getDefaultAttributeArrayTypes();
      QVector< QVector<size_t> > cDims = fp->getDefaultComponentDimensions();
      while (containerIter.hasNext())
      {
        DataContainerProxy dc = containerIter.next();
        if (dc.name.compare(currentDCName) == 0)
        {
          // We found the proper Data Container, now populate the AttributeMatrix List
          QMap<QString, AttributeMatrixProxy> attrMats = dc.attributeMatricies;
          QMapIterator<QString, AttributeMatrixProxy> attrMatsIter(attrMats);
          while (attrMatsIter.hasNext())
          {
            attrMatsIter.next();
            QString amName = attrMatsIter.key();
            if (amName.compare(currentAttrMatName) == 0)
            {
              // Clear the list of arrays from the QListWidget
              attributeArraysWidget->clear();
              // We found the selected AttributeMatrix, so loop over this attribute matrix arrays and populate the list widget
              AttributeMatrixProxy amProxy = attrMatsIter.value();
              QMap<QString, DataArrayProxy> dataArrays = amProxy.dataArrays;
              QMapIterator<QString, DataArrayProxy> dataArraysIter(dataArrays);
              while (dataArraysIter.hasNext())
              {
                dataArraysIter.next();
                QString daName = dataArraysIter.key();
                QListWidgetItem* daItem = new QListWidgetItem(daName);
                daItem->setCheckState(Qt::Unchecked);

                for (int i = 0; i < selectedPaths.size(); i++)
                {
                  if (selectedPaths.at(i).getDataArrayName() == daName)
                  {
                    daItem->setCheckState(Qt::Checked);
                  }
                }

                IDataArray::Pointer da = dca->getPrereqIDataArrayFromPath<IDataArray, AbstractFilter>(NULL, DataArrayPath(dc.name, amProxy.name, daName));
                attributeArraysWidget->addItem(daItem);

                if (NULL != da.get() && ((daTypes.isEmpty() == false && daTypes.contains(da->getTypeAsString()) == false) || (cDims.isEmpty() == false && cDims.contains(da->getComponentDimensions()) == false)))
                {
                  QList<QListWidgetItem*> rejectList = attributeArraysWidget->findItems(daName, Qt::MatchRecursive);
                  for (int i = 0; i < rejectList.size(); i++)
                  {
                    QListWidgetItem* item = rejectList[i];
                    item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
                  }
                }
              }
            }
          }
        }
      }

      attributeArraysWidget->blockSignals(false);
    }
    static void PopulateAttributeArrayComboBox(AbstractFilter* filter, FilterParameter* filterParameter,
                                      QComboBox* dcCombo, QComboBox* amCombo, QComboBox* aaCombo,
                                      DataContainerArrayProxy& dcaProxy)
    {
      FilterParameterType* fp = dynamic_cast<FilterParameterType*>(filterParameter);
      assert(fp != NULL);

      DataContainerArray::Pointer dca = filter->getDataContainerArray();
      if (NULL == dca.get()) { return; }
      bool alreadyBlocked = false;
      if(aaCombo->signalsBlocked()) { alreadyBlocked = true; }
      aaCombo->blockSignals(true);
      aaCombo->clear();

      // Get the selected Data Container Name from the DataContainerList Widget
      QString currentDCName = dcCombo->currentText();
      QString currentAttrMatName = amCombo->currentText();

      // Loop over the data containers until we find the proper data container
      QList<DataContainerProxy> containers = dcaProxy.dataContainers.values();
      QListIterator<DataContainerProxy> containerIter(containers);
      QVector<QString> daTypes = fp->getDefaultAttributeArrayTypes();
      QVector< QVector<size_t> > cDims = fp->getDefaultComponentDimensions();
      while (containerIter.hasNext())
      {
        DataContainerProxy dc = containerIter.next();
        if (dc.name.compare(currentDCName) == 0)
        {
          // We found the proper Data Container, now populate the AttributeMatrix List
          QMap<QString, AttributeMatrixProxy> attrMats = dc.attributeMatricies;
          QMapIterator<QString, AttributeMatrixProxy> attrMatsIter(attrMats);
          while (attrMatsIter.hasNext())
          {
            attrMatsIter.next();
            QString amName = attrMatsIter.key();
            if (amName.compare(currentAttrMatName) == 0)
            {
              // Clear the list of arrays from the QListWidget
              aaCombo->clear();
              // We found the selected AttributeMatrix, so loop over this attribute matrix arrays and populate the list widget
              AttributeMatrixProxy amProxy = attrMatsIter.value();
              QMap<QString, DataArrayProxy> dataArrays = amProxy.dataArrays;
              QMapIterator<QString, DataArrayProxy> dataArraysIter(dataArrays);
              while (dataArraysIter.hasNext())
              {
                dataArraysIter.next();
                //DataArrayProxy daProxy = dataArraysIter.value();
                QString daName = dataArraysIter.key();
                IDataArray::Pointer da = dca->getPrereqIDataArrayFromPath<IDataArray, AbstractFilter>(NULL, DataArrayPath(dc.name, amProxy.name, daName));
                aaCombo->addItem(daName);

                if (NULL != da.get() && ((daTypes.isEmpty() == false && daTypes.contains(da->getTypeAsString()) == false) || (cDims.isEmpty() == false && cDims.contains(da->getComponentDimensions()) == false)))
                {
                  QStandardItemModel* model = qobject_cast<QStandardItemModel*>(aaCombo->model());
                  if (NULL != model)
                  {
                    QStandardItem* item = model->item(aaCombo->findText(daName));
                    if (NULL != item)
                    {
                      item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
                    }
                  }
                }
              }
            }
          }
        }

        aaCombo->setCurrentIndex(-1);
        if(alreadyBlocked == false)
        {
          aaCombo->blockSignals(false);
        }
      }
    }