#pragma once
#include "traceDataProvider.h"
#include <QtPlugin>
#include <qrect.h>
#include <qanimationgroup.h>

/**
* @brief Интерфейс объекта, отображающего некоторые отладочные данные графически.
* @detailed Может показывать изменения определённых данных после каждого шага или результат
* выполнения определённых функций. Реализуется плагинами.
* Плагин первого типа создаёт графическое представление, сответствующее некоторым данным
* программы и обновляет его на каждом шаге в соответствии с изменениями данных.
* Для плагина второго типа по нажатию кнопки Start session выставляются точки останова в начале
* каждой отслеживаемой им функции, и запускатся проход по ним до ближайшей точки останова,
* поставленной пользователем. Плагин отображает последовательность вызова этих функций,
* исходя из переданных им параметров.
* Порядок вызовов методов:
* - При инициализации:
*	-# setData()
*	-# calcGeometry()
*	-# createGraphicsItem()
* - После каждого шага:
*	-# setData()
*	-# calcGeometry()
*	-# updateGraphicsItem()
*	-# getAnimationAfterStep()
* - Для плагина, представляющего последовательность вызовов функций:
*	каждый раз, когда программа останавливается в начале одной из отслеживаемых функций,
*	вызывается метод setFunctionParams().
*/
class DrawableDataInterface : public QObject
{
private:
	QPointF coordinates;	/*!< Координаты */
protected:
	QSizeF size;			/*!< Размер */
public:

	/**
    * @brief Получение координат
	* \return координаты
	*/
	const QPointF & getCoordinates() const { return coordinates; }

	/**
    * @brief Получение размера
	* \return размер
	*/
	const QSizeF & getSize() const { return size; }

	/**
    * @brief Задание координат
	* \param coordinates координаты
	*/
	void setCoordinates(QPointF & coordinates) { this->coordinates = coordinates; }

	/**
    * @brief Задание X-координаты
	* \param x координата
	*/
    void setXCoordinate(float x) { coordinates.setX(x); }

	/**
    * @brief Задание Y-координаты
	* \param y координата
	*/
    void setYCoordinate(float y) { coordinates.setY(y); }

	/**
    * @brief Задание размера прямоугольника
	* \param size размер
	*/
	void setSize(QSizeF & size) { this->size = size; }

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

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

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

	/** 
     * @brief Создание графического представления (вызывается один раз при инициализации, после setData()).
	 * \return созданный графический объект.
	 */
	virtual QGraphicsItem* createGraphicsItem() = 0;

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

	/** 
     * @brief Получение имени объекта (плагина)
	 * \return имя.
	 */
	virtual QString getName() const = 0;

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

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

	/** 
     * @brief Сворачивает или разворачивает все элементы
	 * \param minimized свернуть или развернуть
	 */
	virtual void setAllMinimized(bool minimized) = 0;

	/**
    * @brief НЕ ИСПОЛЬЗУЕТСЯ! Подсветка объекта, представляющего переменную с заданным id
	* \param id идентификатор переменной
	*/
	virtual void markItem(int id) = 0;

	/** 
     * @brief Является ли плагином
	 * \return плагин или нет
	 */
	virtual bool isPlugin() const = 0;

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

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

	/** 
     * @brief Получение необходимых параметров представляемой функции из поставщика данных
	 * \param functionName имя функции
	 * \param provider поставщик данных
	 */
	virtual void setFunctionParams(QString & functionName, TraceDataProvider* provider) = 0;

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

};
QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(DrawableDataInterface, "com.trolltech.Plugin.DrawableInterface/1.0")
QT_END_NAMESPACE
