/*
	File                 : ROOTFilter.h
	Project              : LabPlot
	Description          : ROOT(CERN) I/O-filter
	--------------------------------------------------------------------
	SPDX-FileCopyrightText: 2018 Christoph Roick <chrisito@gmx.de>
	SPDX-FileCopyrightText: 2022 Stefan Gerlach <stefan.gerlach@uni.kn>
	SPDX-License-Identifier: GPL-2.0-or-later
*/

#ifndef ROOTFILTER_H
#define ROOTFILTER_H

#include "backend/datasources/filters/AbstractFileFilter.h"

class ROOTFilterPrivate;
class QStringList;
class QIODevice;

/// Manages the importing of histograms from ROOT files
class ROOTFilter : public AbstractFileFilter {
	Q_OBJECT

public:
	ROOTFilter();
	~ROOTFilter() override;

	// UNUSED enum class ColumnTypes {Center = 1, Low = 2, Content = 4, Error = 8};

	static QString fileInfoString(const QString&);

	/**
	 * @brief Read data from the currently selected histogram
	 *
	 * The ROOT file is kept open until the file name is changed
	 */
	void
	readDataFromFile(const QString& fileName, AbstractDataSource* = nullptr, AbstractFileFilter::ImportMode = AbstractFileFilter::ImportMode::Replace) override;
	/// Currently writing to ROOT files is not supported
	void write(const QString& fileName, AbstractDataSource*) override;

	void loadFilterSettings(const QString&) override;
	void saveFilterSettings(const QString&) const override;

	/// Internal directory structure in a ROOT file
	struct Directory {
		QString name;
		QVector<QPair<QString, quint64>> content;
		QVector<Directory> children;
	};

	/// List names of histograms contained in ROOT file
	Directory listHistograms(const QString& fileName) const;
	/// List names of trees contained in ROOT file
	Directory listTrees(const QString& fileName) const;
	/// List names of leaves contained in ROOT tree
	QVector<QStringList> listLeaves(const QString& fileName, qint64 pos) const;

	/// Set the current histograms, which is one out of listHistograms
	void setCurrentObject(const QString&);
	/// Get the name of the currently set object
	const QString currentObject() const;

	/// Get preview data of the currently set object
	QVector<QStringList> previewCurrentObject(const QString& fileName, int first, int last) const;

	/// Get the number of rows in the current object
	int rowsInCurrentObject(const QString& fileName) const;

	/**
	 * @brief Set the last bin of the object to be read
	 *
	 * -1 skips the underflow bin of histograms
	 */
	void setStartRow(const int bin);
	/// Get the index of the first row to be read
	int startRow() const;
	/**
	 * @brief Set the last row of the object to be read
	 *
	 * -1 skips the overflow bin of histograms
	 */
	void setEndRow(const int bin);
	/// Get the index of the last row to be read
	int endRow() const;

	/**
	 * @brief Set the columns of the object to be read
	 *
	 * For histograms the following are available: center, low, content, error
	 */
	void setColumns(const QVector<QStringList>& columns);
	/**
	 * @brief Get the columns to be read
	 *
	 * For histograms, the identifiers for location, content and error are given
	 * as the first part, the corresponding translation as the second part.
	 * For trees, the branch name and the leaf name are returned.
	 *
	 * @return A pair of strings with different content depending on the object type
	 */
	QVector<QStringList> columns() const;

	/// Save bin limitation settings
	void save(QXmlStreamWriter*) const override;
	/// Load bin limitation settings
	bool load(XmlStreamReader*) override;

private:
	std::unique_ptr<ROOTFilterPrivate> const d;
	friend class ROOTFilterPrivate;
};

#endif
