bool HistogramTablesFormatter::hasOneEntry(unsigned typeIndex)
{
	casacore::Table &casaTable = getTable(HistogramCountTable, false);
	casacore::ROScalarColumn<int> typeColumn(casaTable, ColumnNameType);
	
	const unsigned nrRow = casaTable.nrow();
	
	for(unsigned i=0;i<nrRow;++i)
	{
		if(typeColumn(i) == (int) typeIndex)
			return true;
	}
	return false;
}
unsigned HistogramTablesFormatter::findFreeTypeIndex(casacore::Table &typeTable)
{
	int maxIndex = 0;
	
	casacore::ROScalarColumn<int> typeColumn(typeTable, ColumnNameType);
	
	const unsigned nrRow = typeTable.nrow();
	
	for(unsigned i=0;i<nrRow;++i)
	{
		if(typeColumn(i) > maxIndex)
			maxIndex = typeColumn(i);
	}
	return maxIndex + 1;
}
bool HistogramTablesFormatter::QueryTypeIndex(enum HistogramType type, unsigned polarizationIndex, unsigned &destTypeIndex)
{
	openTypeTable(false);
	casacore::ROScalarColumn<int> typeColumn(*_typeTable, ColumnNameType);
	casacore::ROScalarColumn<int> polarizationColumn(*_typeTable, ColumnNamePolarization);
	casacore::ROScalarColumn<casacore::String> nameColumn(*_typeTable, ColumnNameName);
	const casacore::String nameToFind(TypeToName(type));
	
	const unsigned nrRow = _typeTable->nrow();
	
	for(unsigned i=0;i<nrRow;++i)
	{
		if((unsigned) polarizationColumn(i) == polarizationIndex && nameColumn(i) == nameToFind)
		{
			destTypeIndex = typeColumn(i);
			return true;
		}
	}
	return false;
}
void HistogramTablesFormatter::QueryHistogram(unsigned typeIndex, std::vector<HistogramItem> &histogram)
{
	casacore::Table &table(getTable(HistogramCountTable, false));
	const unsigned nrRow = table.nrow();
	
	casacore::ROScalarColumn<int> typeColumn(table, ColumnNameType);
	casacore::ROScalarColumn<double> binStartColumn(table, ColumnNameBinStart);
	casacore::ROScalarColumn<double> binEndColumn(table, ColumnNameBinEnd);
	casacore::ROScalarColumn<double> countColumn(table, ColumnNameCount);
	
	for(unsigned i=0;i<nrRow;++i)
	{
		if(typeColumn(i) == (int) typeIndex)
		{
			HistogramItem item;
			item.binStart = binStartColumn(i);
			item.binEnd = binEndColumn(i);
			item.count = countColumn(i);
			histogram.push_back(item);
		}
	}
}
unsigned HistogramTablesFormatter::StoreType(enum HistogramType type, unsigned polarizationIndex)
{
	openTypeTable(true);
	
	unsigned typeIndex = findFreeTypeIndex(*_typeTable);
	
	unsigned newRow = _typeTable->nrow();
	_typeTable->addRow();
	casacore::ScalarColumn<int> typeColumn(*_typeTable, ColumnNameType);
	casacore::ScalarColumn<int> polarizationColumn(*_typeTable, ColumnNamePolarization);
	casacore::ScalarColumn<casacore::String> nameColumn(*_typeTable, ColumnNameName);
	typeColumn.put(newRow, typeIndex);
	polarizationColumn.put(newRow, polarizationIndex);
	nameColumn.put(newRow, TypeToName(type));
	return typeIndex;
}
void HistogramTablesFormatter::StoreValue(unsigned typeIndex, double binStart, double binEnd, double count)
{
	openCountTable(true);
	
	unsigned newRow = _countTable->nrow();
	_countTable->addRow();
	
	casacore::ScalarColumn<int> typeColumn(*_countTable, ColumnNameType);
	casacore::ScalarColumn<double> binStartColumn(*_countTable, ColumnNameBinStart);
	casacore::ScalarColumn<double> binEndColumn(*_countTable, ColumnNameBinEnd);
	casacore::ScalarColumn<double> countColumn(*_countTable, ColumnNameCount);
	
	typeColumn.put(newRow, typeIndex);
	binStartColumn.put(newRow, binStart);
	binEndColumn.put(newRow, binEnd);
	countColumn.put(newRow, count);
}
//-----------------------------------------------------------------------------
// Function: AbstractParameterModel::setData()
//-----------------------------------------------------------------------------
bool AbstractParameterModel::setData(QModelIndex const& index, const QVariant& value, int role /*= Qt::EditRole */) 
{
	if (!index.isValid() || index.row() < 0 || index.row() >= rowCount())
    {
		return false;
    }

    if (role == Qt::EditRole)
    {
        QSharedPointer<Parameter> parameter = getParameterOnRow(index.row());

        if (index.column() == nameColumn())
        {
            parameter->setName(value.toString());
        }
        else if (index.column() == displayNameColumn())
        {
            parameter->setDisplayName(value.toString());
        }
        else if (index.column() == typeColumn())
        {
            parameter->setType(value.toString());
        }
        else if (index.column() == bitWidthLeftColumn())
        {
            if (!value.isValid())
            {
                removeReferencesFromSingleExpression(parameter->getBitWidthLeft());

                emit dataChanged(QAbstractTableModel::index(0, usageCountColumn()),
                    QAbstractTableModel::index(rowCount() - 1, usageCountColumn()));
            }

            parameter->setBitWidthLeft(value.toString());

            if (value.isValid() && parameter->getBitWidthRight().isEmpty() && !value.toString().isEmpty())
            {
                parameter->setBitWidthRight(QString::number(0));
            }
        }
        else if (index.column() == bitWidthRightColumn())
        {
            if (!value.isValid())
            {
                removeReferencesFromSingleExpression(parameter->getBitWidthRight());

                emit dataChanged(QAbstractTableModel::index(0, usageCountColumn()),
                    QAbstractTableModel::index(rowCount() - 1, usageCountColumn()));
            }

            parameter->setBitWidthRight(value.toString());

            if (value.isValid() && parameter->getBitWidthLeft().isEmpty() && !value.toString().isEmpty())
            {
                parameter->setBitWidthLeft(QString::number(0));
            }
        }
        else if (index.column() == minimumColumn())
        {
            parameter->setMinimumValue(value.toString());
        }
        else if (index.column() == maximumColumn())
        {
            parameter->setMaximumValue(value.toString());
        }
        else if (index.column() == choiceColumn())
        {
            parameter->setChoiceRef(value.toString());
        }
        else if (index.column() == valueColumn())
        {
            if (!value.isValid())
            {
                removeReferencesFromSingleExpression(parameter->getValue());

                emit dataChanged(QAbstractTableModel::index(0, usageCountColumn()),
                    QAbstractTableModel::index(rowCount() - 1, usageCountColumn()));
            }

            parameter->setValue(value.toString());
        }
        else if (index.column() == resolveColumn())
        {
            parameter->setValueResolve(value.toString());
        }
        else if (index.column() == arrayLeftColumn())
        {
            if (!value.isValid())
            {
                removeReferencesFromSingleExpression(parameter->getAttribute("kactus2:arrayLeft"));

                emit dataChanged(QAbstractTableModel::index(0, usageCountColumn()),
                    QAbstractTableModel::index(rowCount() - 1, usageCountColumn()));
            }

            parameter->setAttribute("kactus2:arrayLeft", value.toString());

            if (value.isValid() && parameter->getAttribute("kactus2:arrayRight").isEmpty() &&
                !parameter->getAttribute("kactus2:arrayLeft").isEmpty())
            {
                parameter->setAttribute("kactus2:arrayRight", QString::number(0));
            }
        }
        else if (index.column() == arrayRightColumn())
        {
            if (!value.isValid())
            {
                removeReferencesFromSingleExpression(parameter->getAttribute("kactus2:arrayRight"));

                emit dataChanged(QAbstractTableModel::index(0, usageCountColumn()),
                    QAbstractTableModel::index(rowCount() - 1, usageCountColumn()));
            }

            parameter->setAttribute("kactus2:arrayRight", value.toString());

            if (value.isValid() && parameter->getAttribute("kactus2:arrayLeft").isEmpty() &&
                !parameter->getAttribute("kactus2:arrayRight").isEmpty())
            {
                parameter->setAttribute("kactus2:arrayLeft", QString::number(0));
            }
        }
        else if (index.column() == descriptionColumn())
        {
            parameter->setDescription(value.toString());
        }
        else if (index.column() == idColumn())
        {
            return false;
        }
        else
        {
            return false;
        }

        emit dataChanged(index, index);
        emit contentChanged();
        return true;
    }
    else // is unsupported role
    {
        return false;
    }
}
//-----------------------------------------------------------------------------
// Function: AbstractParameterModel::headerData()
//-----------------------------------------------------------------------------
QVariant AbstractParameterModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole) 
    {
        if (section == nameColumn())
        {
            return tr("Name");
        }
        else if (section == displayNameColumn())
        {
            return tr("Display\nname");
        }
        else if (section == typeColumn())
        {
            return tr("Type");   
        }
        else if (section == bitWidthLeftColumn())
        {
            QString bitWidthLeft = tr("Bit vector\nleft") + getExpressionSymbol();
            return bitWidthLeft;
        }
        else if (section == bitWidthRightColumn())
        {
            QString bitWidthRight = tr("Bit vector\nright") + getExpressionSymbol();
            return bitWidthRight;
        }
        else if (section == minimumColumn())
        {
            return tr("Min");
        }
        else if (section == maximumColumn())
        {
            return tr("Max");
        }
        else if (section == choiceColumn())
        {
            return tr("Choice");
        }     
        else if (section == valueColumn())
        {
            QString valueHeader = tr("Value") + getExpressionSymbol();
            return valueHeader;
        }  
        else if (section == resolveColumn())
        {     
            return tr("Resolve");
        }  
        else if (section == arrayLeftColumn())
        {
            QString arrayLeftHeader = tr("Array\nleft") + getExpressionSymbol();
            return arrayLeftHeader;
        }  
        else if (section == arrayRightColumn())
        {
            QString arrayRightHeader = tr("Array\nright") + getExpressionSymbol();
            return arrayRightHeader;
        } 
        else if (section == descriptionColumn())
        { 
            return tr("Description");
        }
        else if (section == idColumn())
        {
            return tr("Parameter id");
        }
        else if (section == usageCountColumn())
        {
            return tr("Usage\ncount");
        }

        else
        {
            return QVariant();
        }
    }
    else if (orientation == Qt::Vertical && role == Qt::DisplayRole) 
    {
        return QString(" ");
    }
    // if unsupported role
    else 
    {
        return QVariant();
    }
}