#ifndef TESTFUNCPLUGIN_H
#define TESTFUNCPLUGIN_H

#include "testfuncplugin_global.h"
#include "drawableDataInterface.h"

/** 
	 * Пример плагина, демонстрирующего последовательность выполнения определённых им функций.
	 * Запуск анализа вызовов функций происходит по кнопке визуализатора Start session.
	 * При этом запускается проход программы до следующей точки останова, при котором на каждом вызове 
	 * одной из заданных плагином функций вызывается метод плагина setFunctionParams. На момент вызова setFunctionParams 
	 * отлаживаемая программа находится на начале одной из заданных функций - в этот момент из поставщика данных
	 * можно получить все необходимые сведения о параметрах, переданных в функцию.
	 * Когда программа снова останавливается на точке останова, вызывается метод updateGraphicsItem,
	 * в котором плагин должен обновит графическое представление в соответствии с прошедшими вызовами.

	 * Данный плагин анализирует вызовы функции testFunction (в примере ниже) и на каждый вызов её показывает
	 * строчку <значение первого параметра> + <значение по указателю - второму параметру>.
 */

/* Тестовая программа (при запуске Start session, когда программа стоит на первой точке останова,
будут проанализированы три вызова функций, и при остановке на второй точке останова,
плагин покажет эти три вызова).

int testFunction(int param1, int* param2)
{
	(*param2)++;
	return param1 + *param2;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int* p = new int;
	*p = 3; // Первая точка останова стоит здесь
	testFunction(1, p); 
	testFunction(2, p);
	testFunction(3, p);

	return 0; // Вторая точка останова здесь
}

*/
class TESTFUNCPLUGIN_EXPORT TestFuncPlugin : public QObject, DrawableDataInterface
{
	Q_OBJECT
	Q_INTERFACES(DrawableDataInterface)

private:
	QString representedFunction; /*!< Список имён функций, вызовы которых обрабатываются плагином */
	QList<QList<Variable*>> arguments; /*!< Список аргументов, переданных в функцию при каждом её вызове
									   Внешний контейнер - для каждого вызова, внутренний - для каждого аргумента */
	QGraphicsRectItem* item; /*!< Графическое представление плагина */
public:
	TestFuncPlugin();
	~TestFuncPlugin();

    /**
    *  @brief Расчёт всех внутренних координат. Вызывается после setData().
	* В результате должен быть посчитан размер (size).
	*/
	void calcGeometry();

	/**
    * @brief Расчёт координат по умолчанию. В случае, если укладка может меняться в процессе трассировки, приводит её в стандартный вид.
	* Обычно может просто вызывать calcGeometry().
	* \param provider поставщик данных (на всякий случай).
	*/
	void calcDefaultGeometry(DataProvider* provider);

	/** 
	 * Инициализация данными о переменных
	 * \param provider поставщик данных
	 * \param result результат получения данных из отладчика
	 * \param variables контейнер с переменными (если нужен особый набор)
	 */
	bool setData(TraceDataProvider* provider, GET_VARIABLES_RESULT result, QList<Variable*> & variables);

	/** 
	 * Получение имени объекта
	 * \return имя
	 */
	QString getName() const;

	/** 
	 * Требует ли особый набор данных
	 * \return требует ли особый набор данных
	 */
	bool isRequiredCustomVariables() const;

	/** 
     * @brief Требует ли особый набор данных - в этом случае точно указываются требуемые переменные, используемые плагином.
	 * В этом случае - не требует.
	 * иначе - плагин будет анализировать целиком контейнер всех данных в программе.
	 * \return требует ли особый набор данных.
	 */
	QStringList requiredCustomVariables() const;

	/** 
     * @brief Получение списка необходимых данных. Порядок описания переменных должен соответствовать их ожидаемому порядку в параметре variables в setData()
	 * \return каждый элемент контейнера - словесное описание нужной переменной
	 */
	QGraphicsItem* createGraphicsItem();

	/**
	* @brief Обновление графического представления (будет вызвано после setData() в случае, если вызов не первый)
	*/
	void updateGraphicsItem();

	/** 
	 * Действия при нажатии на область объекта
	 * \param [in] id идентификатор элемента, который был нажат
	 * \return идентификатор элемента, который должен быть подсвечен в графах и других представлениях
	 */
	int onElementClicked(int id);

	/** 
	 * Сворачивает или разворачивает все вершины
	 * \param minimized свернуть или развернуть
	 */
	void setAllMinimized(bool minimized);

	/**
	* Подсветка объекта, представляющего переменную с заданным id
	* \param id идентификатор переменной
	* \param primitives примитивы
	*/
	void markItem(int id);

	bool isPlugin() const { return true; };

	/** 
     * @brief Представляет ли плагин результат выполнения некоторых функций
	 */
	bool isRepresentsFunctionResult() const { return true; };

	/** 
     * @brief Получение имён функций, результат которых представляет плагин
	 * \return список имён функций
	 */
	QStringList getRepresentedFunctionNames() const;

	/** 
     * @brief Получение необходимых параметров представляемой функции из поставщика данных.
	 * Вызывается, когда программа остановлена на первой строчке функции functionName.
	 * Используя provider можно получить:
	 *		- аргументы, переданные в функцию: provider->getFunctionArguments(functionName).last();
	 *		- любые данные по их адресу: provider->readVariableByPointer.
	 * \param functionName имя функции
	 * \param provider поставщик данных
	 */
	void setFunctionParams(QString & functionName, TraceDataProvider* provider);

	/**
	* @brief Получение анимации, которую надо выполнить после последнего обновления данных.
	*/
	QAnimationGroup* getAnimationAfterStep();
};

#endif // TESTFUNCPLUGIN_H
