#ifndef ITOMODEL_H_INCLUDED
#define ITOMODEL_H_INCLUDED

#include "u_typedef.hpp"

//      ==================================================================
//        Об организации внешних модулей - библиотек с планами.
//      Каждый внешний модуль должен в обязательном порядке экспортировать
//      функцию 'GetModuleVersionInfo'. Экспорт функций перечисления  сла-
//      гаемых, моделей и генераторов не  обязателен.  Основная  программа
//      последовательно проверяет все модули на наличие функций перечисле-
//      ния, и если они обнаружены - добавляет поддерживаемые интерфейсы в
//      общий список.
//        Об организации интерфейсов.
//      Модуль может поддерживать три типа интерфейсов: "Слагамое модели",
//      "Модель" и "Генератор плана". Все эти интерфейсы могут  возвращать
//      свое описание. Интерфейс "Слагамое модели" содержит скалярную фун-
//      кцию векторного аргумента. Аналогичную функцию содержит  интерфейс
//      "Модель"; здесь предполагается, что она есть  линейная  комбинация
//      некоторых функций, и обеспечивается возможность  получения  интер-
//      фейсов на отдельные слагаемые. Наконец, интерфейс "Генератор  пла-
//      на" предназначен для заполнения матрицы - спектра плана. Он  также
//      может указывать модель, традиционно использующуюся с этим планом.
//      23.11.99 - передалка для компиляции MS C++
//      ==================================================================

//       =================================================================
//          ***  ОБЪЯВЛЕНИЯ ИНТЕРФЕЙСОВ И ФУНКЦИЙ - ПРОИЗВОДИТЕЛЕЙ  ***
//       =================================================================
//       Интерфейс - слагаемое экспериментально - статистической модели
class    IAdden
{
public:
  // Возвращает описание
  virtual pchar __stdcall      Description(void)=0;
  // Возвращает текстовую запись формулы
  virtual pchar __stdcall      StdName(void)=0;
  // Возвращает текстовую запись имени коэффициента
  virtual pchar __stdcall      StdBName(void)=0;
  // Возвращает минимально необходимую размерность факторного пространства,
  // в котором находятся точки - агрументы функции GetValue.
  virtual int   __stdcall      RequiredDimension(void)=0;
  // Возвращает значение в точке M
  virtual void  __stdcall      Value(double *M,double *Res)=0;
};

typedef  IAdden *pIAdden;

//       Интерфейс - экспериментально - статистическая модель
class    IModel
{
public:
  virtual pchar __stdcall      Description()=0;
  // Возвращает минимально необходимую размерность факторного пространства,
  // в котором находятся точки - агрументы функции GetValue.
  virtual int   __stdcall      RequiredDimension(void)=0;
  // Возвращает число слагаемых
  virtual int   __stdcall      AddenCount()=0;
  // Возвращает интерфейс на указанное слагаемое
  virtual pIAdden __stdcall    Addens(int Index)=0;
  // Возвращает значение в точке M для коэффициентов B
  virtual void  __stdcall      Value(double *M,double *B,double *Res)=0;
};

typedef  IModel *pIModel;

//       Интерфейс - генератор плана
class    IGenerator
{
public:
  virtual pchar __stdcall      Description()=0;
  // Возвращает размеры матрицы, в которую записывается план. Число
  // строк - количество опытов, число столбцов - количество фактров.
  virtual void  __stdcall      RequiredDimensions(int *nRows,int *nCols)=0;
  // Генерация плана.
  virtual void  __stdcall      Generate(double **Rows)=0;
  // Используемая по умолчанию модель.
  virtual pIModel __stdcall    DefaultModel()=0;
};

typedef IGenerator *pIGenerator;

//       Функции обратного вызова для перечислителей
typedef  int (__stdcall *GenericEnumProc)(pvoid lpObject);

#define ADENUM_OK       1
#define ADENUM_CANCEL   0
#define MODENUM_OK      1
#define MODENUM_CANCEL  0
#define PLENUM_OK       1
#define PLENUM_CANCEL   0

#pragma pack(push)
#pragma pack(2)
struct  ModuleVersionInfo
{
  word  wMinor,wMajor;
  char  *pszDescription;
};
#pragma pack(pop)

//       =================================================================
extern "C"
{
    //       Описание внешнего модуля
    int UEXPORT GetModuleVersionInfo(ModuleVersionInfo *lpVersionInfo);
    //       Перечислители объектов, поддерживающих указанные интерфейсы
    int UEXPORT AddensEnumerate(GenericEnumProc EnumProc);
    int UEXPORT ModelsEnumerate(GenericEnumProc EnumProc);
    int UEXPORT GensEnumerate(GenericEnumProc EnumProc);
};

#endif  // ITOMODEL_H_INCLUDED
