//---------------------------------------------------------------------------


#pragma hdrstop

#include "LTR11_ProcessThread.h"

// Время, за которое будет отображаться среднее значение (в мс)
#define RECV_BLOCK_TIME          500
// Дополнительный  постоянный таймаут на прием данных (в мс)
#define RECV_TOUT                4000


//---------------------------------------------------------------------------

#pragma package(smart_init)

 __fastcall TLTR11_ProcessThread::TLTR11_ProcessThread(bool CreateSuspended)
    : TThread(CreateSuspended), stop(false), err (LTR_OK) {

}

/* обновление индикаторов формы результатами последнего измерения.
   Метод должен выполняться только через Syncronize, который нужен
   для доступа к элементам VCL не из основного потока */
void __fastcall TLTR11_ProcessThread::updateData() {
    for (int ch=0; ch < phltr11->LChQnt; ch++) {
        edtChAvg[ch]->Text = FloatToStrF(ChAvg[ch], ffFixed, 4, 8);
    }
}


void __fastcall TLTR11_ProcessThread::Execute() {
    DWORD *rcv_buf=0;
    double *data=0;
    // номера разрешенных каналов
    INT recv_wrd_cnt;  //количество принимаемых сырых слов за раз
    INT recv_data_cnt; //количество обработанных слов, которые должны принять за раз

    err = LTR_OK;

    /* Определяем, сколко преобразований будет выполненно за заданное время
      => будем принимать данные блоками такого размера */
    recv_data_cnt =  (INT)(phltr11->ChRate*RECV_BLOCK_TIME) * phltr11->LChQnt;
    if (recv_data_cnt < phltr11->LChQnt)
        recv_data_cnt = phltr11->LChQnt;
    recv_wrd_cnt = recv_data_cnt;

    //выделяем массивы для приема данных
    rcv_buf = new DWORD[recv_wrd_cnt];
    data = new double[recv_data_cnt];

    err = LTR11_Start(phltr11);
    if (err==LTR_OK) {
        while (!stop && (err==LTR_OK)) {
            /* Принимаем данные */
            INT recv_size = LTR11_Recv(phltr11, rcv_buf, 0, recv_wrd_cnt, RECV_TOUT + RECV_BLOCK_TIME);
            //Значение меньше нуля соответствуют коду ошибки
            if (recv_size < 0) {
                err=recv_size;
            } else if (recv_size < recv_wrd_cnt) {
                err=LTR_ERROR_RECV_INSUFFICIENT_DATA;
            } else {
                double ch_avg[LTR11_MAX_CHANNEL];

                err=LTR11_ProcessData(phltr11, rcv_buf, data, &recv_size,
                                      TRUE, TRUE);
                if (err==LTR_OK) {
                    for (INT ch=0; ch < phltr11->LChQnt; ch++) {
                        ch_avg[ch] =  0;
                    }

                    // получаем кол-во отсчетов на канал
                    recv_size = (INT) (recv_size/phltr11->LChQnt);

                    // рассчет среднего
                    for (INT i=0; i < recv_size; i++) {
                        for (INT ch=0; ch < phltr11->LChQnt; ch++) {
                            ch_avg[ch] +=  data[phltr11->LChQnt*i + ch];
                        }
                    }

                    for (INT ch=0; ch < phltr11->LChQnt; ch++) {
                        ChAvg[ch]=ch_avg[ch]/recv_size;
                        ChValidData[ch] = true;
                    }
                    // обновляем значения элементов управления
                    Synchronize(updateData);
                }
            }
        } // while (!stop && (err==LTR_OK))

        /* По выходу из цикла отсанавливаем сбор данных.
            Чтобы не сбросить код ошибки (если вышли по ошибке)
            результат останова сохраняем в отдельную переменную */
        INT stoperr= LTR11_Stop(phltr11);
        if (err == LTR_OK)
            err= stoperr;
    }

    delete []rcv_buf;
    delete []data;
}
