/************************************************************************************
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  Copyright (c) Renesas of America, Inc.  All rights reserved.
 *  Use and distribution are subject to applicable contract restrictions.
 * **********************************************************************************/
#ifndef REALITYAI_TYPES_H_
#define REALITYAI_TYPES_H_
#include <stdlib.h>
#include <stdint.h>
#include "RealityAI_Config.h"

#define RAI_MAX_MONITOR_SCORES 		10
#define RAI_MAX_MONITOR_BYTES 		(8+RAI_MAX_MONITOR_SCORES*4+1)
struct ai_monitor {
  uint8_t data[RAI_MAX_MONITOR_BYTES];
};

struct conversion_struct {
    const uint32_t* data;
    void (*const convert)(const void* usr, rai_data_t* out, int len, struct conversion_struct* conv);
};

struct feature_extraction_struct {
    int32_t num_channels;
    int32_t samples_per_channel;
    int32_t window_size;
    int32_t subwindow_size;
    int32_t windows_per_channel;
    int32_t step_size;
    int32_t feature_length;
    void (*const feature_extractor)(rai_data_t*, rai_data_t*, struct feature_extraction_struct*);
};

struct smoothing_struct {
    int32_t counter;
    int32_t pos;
    uint32_t state;
    int32_t len;
    int32_t threshold;
    const int32_t buffer_size;
    void *const buffer;
    float (*const smoother)(const void*, int32_t, struct smoothing_struct*);
};

typedef struct {
    uint8_t  sh, exp;
}std_params_t;

typedef struct {
    int32_t  a,b,c,d,e;
}svm_cal_params_t;

typedef struct {
    float    sf;
    int32_t  si, z;
}cal_data_t;

typedef struct {
    std_params_t     s;
    svm_cal_params_t p;
    cal_data_t       x, y;
}int8_cal_t;

struct rai_model_struct {
    struct conversion_struct* Conv;
    struct feature_extraction_struct* Fe;
    struct smoothing_struct* Smo;
    const int8_cal_t* Cal;
    const int32_t class_index;
    const uint32_t flags;
    float* Class_scores;
    int32_t num_classes;
    int32_t num_learners;
    int32_t subset_feature_length;
    void* network;
    float results[2];
    struct ai_monitor mon;
};

struct svm_network_struct {
    const void* Beta;
    const void* Bias;
    const void* Mu;
    const void* Sigma;
    const int8_t* coding_matrix;
    float* learner_scores;
};

struct neural_network_struct {
    const void* Mu;
    const void* Sigma;
    int32_t (*const predict)(rai_data_t*, struct rai_model_struct*);
};

#define RAI_CLZ_NO_RESULTS          0

#define RAI_CMD_SMO_CTRL            0x0U
#define RAI_CMD_SMO_LEN             0x1U
#define RAI_CMD_SMO_GRP             0x2U

#define RAI_VAL_SMO_DISABLE         0x0U
#define RAI_VAL_SMO_ENABLE          0x1U
#define RAI_VAL_SMO_GRP_START       0x1U
#define RAI_VAL_SMO_GRP_END         0x0U

#define RAI_FLAGS_TYPE_MASK         0x01U
#define RAI_FLAGS_TYPE_SHIFT        0U
#define RAI_FLAGS_TYPE_CLASSIFY     (0U << RAI_FLAGS_TYPE_SHIFT)
#define RAI_FLAGS_TYPE_REGRESSION   (1U << RAI_FLAGS_TYPE_SHIFT)

#define RAI_FLAGS_QUANT_MASK        0x02U
#define RAI_FLAGS_QUANT_SHIFT       1U
#define RAI_FLAGS_QUANT_DIS         (0U << RAI_FLAGS_QUANT_SHIFT)
#define RAI_FLAGS_QUANT_ENA         (1U << RAI_FLAGS_QUANT_SHIFT)

#define RAI_FLAGS_NET_MASK          0x04U
#define RAI_FLAGS_NET_SHIFT         2U
#define RAI_FLAGS_NET_SVM           (0U << RAI_FLAGS_NET_SHIFT)
#define RAI_FLAGS_NET_NN            (1U << RAI_FLAGS_NET_SHIFT)

#define RAI_FLAGS_GRP_SMO_MASK      0x08U
#define RAI_FLAGS_GRP_SMO_SHIFT     3U
#define RAI_FLAGS_GRP_SMO_DIS       (0U << RAI_FLAGS_GRP_SMO_SHIFT)
#define RAI_FLAGS_GRP_SMO_ENA       (1U << RAI_FLAGS_GRP_SMO_SHIFT)

#define RAI_FLAGS_SCORE_SMO_MASK    0x10U
#define RAI_FLAGS_SCORE_SMO_SHIFT   4U
#define RAI_FLAGS_SCORE_SMO_DIS     (0U << RAI_FLAGS_SCORE_SMO_SHIFT)
#define RAI_FLAGS_SCORE_SMO_ENA     (1U << RAI_FLAGS_SCORE_SMO_SHIFT)

#ifdef RAI_STACK_TRACE
extern void edsp_stack_init_(void);
extern void edsp_stack_check_(void);
extern int* edsp_start_ptr;
extern int* edsp_end_ptr;
#define edsp_stack_init()  edsp_stack_init_()
#define edsp_stack_check() edsp_stack_check_()
#else
#define edsp_stack_init()
#define edsp_stack_check()
#endif

#endif /* REALITYAI_TYPES_H_ */
