#pragma once

#include <stdio.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_eigen.h>
#include <gsl/gsl_blas.h>
#include <gsl/gsl_complex.h>
#include <gsl/gsl_complex_math.h>
#include <gsl/gsl_linalg.h>
#include <gsl/gsl_randist.h>
#include <time.h>
#include "activ_function.h"

#include <direct.h>

#include "cv.h"
#include "highgui.h"

//#include <strings.h>
#include <string>
#include <sstream>

using namespace std;



#define PI 3.1415926535897932384626433832795

#define PART_HEAD 0
#define PART_TORSO 1
#define PART_LEFT_ARM 2 
#define PART_RIGHT_ARM 3

#define COLOR_RED 0
#define COLOR_GREEN 1
#define COLOR_BLUE 2

#define SHAPE_BOX 0
#define SHAPE_CYL 1
#define SHAPE_SPH 2

#define ACTION_POINT 0
#define ACTION_TOUCH 1
#define ACTION_PUSH 2

#define POSITION_LEFT 0
#define POSITION_MIDDLE 1
#define POSITION_RIGHT 2


typedef struct
{
    double x;
	double y;
	double z;
} position;

char *getPortName(int part);

gsl_matrix *pinv(gsl_matrix *m);
gsl_matrix *generate_sine(int fvz, int freq, double amplitude, int length);
void print_vector(gsl_vector *v);
void print_vector(gsl_vector_complex *v);
double getAbsMaxEig(gsl_matrix *m);
gsl_matrix *create_matrix(int rows, int cols, double scaling);
void print_matrix(gsl_matrix *m);
void print_matrix_to_file(gsl_matrix *m, const char *filename);
void print_vector_to_file(gsl_vector *v, const char *filename);
void print_vector_to_file_append(gsl_vector *v, const char *filename);
void print_vector_to_file(gsl_vector *v, FILE *f);
int factorial(int n);

void shuffleCols(gsl_matrix *m_in, gsl_matrix *m_des);

void splitDataset(gsl_matrix *m_in, gsl_matrix *m_des, gsl_matrix **train_in, gsl_matrix **train_des, gsl_matrix **test_in, gsl_matrix **test_des, double trainSize);

void maxOnehot(gsl_matrix *m);
double successfulness(gsl_matrix *desired, gsl_matrix *output);

IplImage *getTable(IplImage *image);
void setROIFromMask(IplImage *img, IplImage *mask);
IplImage *backProject(IplImage *image, char *file);
CvSeq* do_contours(IplImage *grey, float thresh = 10, float min_obsah = 500, int vypln = 0);
CvRect getBoundingBox(CvSeq* object_contours, float min_obsah = 500);
void getMoments(CvSeq* contours, float min_obsah = 500);
IplImage *getObjectImage(IplImage *img);
gsl_vector *createNeuronVector(int in, int hidden, int out);

double distance_euclidean(position x, position y);
gsl_vector *combineVectors(gsl_vector *v1, gsl_vector *v2);
gsl_vector *combineVectorsFreeFirst(gsl_vector *v1, gsl_vector *v2);
gsl_vector *addBias(gsl_vector *v);

gsl_vector *addBit(gsl_vector *v, double bit);
gsl_vector *createOneHotVector(int size, int active);
int getOneHotActive(gsl_vector *onehot);

gsl_vector *getPositionVector(position pos);

char *toStringPosition(int position);
char *toStringAction(int action);