/*
 * input map code
 *
 * Copyright 2003 Jacob Robbins
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */





#ifndef INPUT_MAP_INCLUDES
#define INPUT_MAP_INCLUDES

#include <stddef.h>

#define EVENT_PARAMETER_DATA_TYPE_UCHAR 1
#define EVENT_PARAMETER_DATA_TYPE_CHAR  2
#define EVENT_PARAMETER_DATA_TYPE_INT   3
#define EVENT_PARAMETER_DATA_TYPE_FLOAT 4

#define SUBMAP_TEST_TYPE_EXACT 0x0
#define SUBMAP_TEST_TYPE_RANGE 0x1

#define EVENT_MAP_ACTION_TYPE_REMAP_EXTERN 1
#define EVENT_MAP_ACTION_TYPE_REMAP_LOCAL 2
#define EVENT_MAP_ACTION_TYPE_CALLBACK_FUNCTION 3

#define EVENT_TYPE_MY_MIDI_EVENT 1
typedef struct my_midi_event my_midi_event_t;
struct my_midi_event{unsigned char status; unsigned char data1; unsigned char data2;};
/*NOTE: the my_midi_event event type is used in this example, you should replace it with your own*/
/*NOTE: to replace the event type, create a struct describing your type*/
/*NOTE: the parameters you want to test must be data types from the EVENT_PARAMETER_DATA_TYPE... list above*/
/*NOTE: you must specify which parameter a submap is testing by using the parameter's offset in your C struct*/

typedef void (*input_map_callback_t)(void* target_object, int target_index, void* source_event, size_t source_offset);

typedef struct event_input_map event_input_map_t;
typedef struct event_submap event_submap_t;
typedef struct event_map_action event_map_action_t;



/*internal structs*/


struct event_input_map{
  void* owner_object;
  int event_type;

  generic_array_t* submap_array;

  /*int remap_array_size;*/
  /*event_input_map_t** remap_array;*/
  /*int callback_array_size;*/
  /*input_map_callback_t * callback_array;*/
};


struct event_submap{
  size_t event_parameter_offset; /*event parameter used in test*/
  char event_parameter_data_type; /*char, uchar, int, or float*/
  char event_parameter_test_type; /*exact or range*/
  
  generic_array_t* test_array;
  
  event_input_map_t* owner_input_map;
};



typedef struct pair_uc_i pair_uc_i_t;
struct pair_uc_i{unsigned char uc;ll_head action_list;};
typedef struct pair_c_i pair_c_i_t;
struct pair_c_i{char c;ll_head action_list;};
typedef struct pair_i_i pair_i_i_t;
struct pair_i_i{int i;ll_head action_list;};
typedef struct triplet_uc_uc_i triplet_uc_uc_i_t;
struct triplet_uc_uc_i{unsigned char min;unsigned char max;ll_head action_list;};
typedef struct triplet_c_c_i triplet_c_c_i_t;
struct triplet_c_c_i{char min;char max;ll_head action_list;};
typedef struct triplet_i_i_i triplet_i_i_i_t;
struct triplet_i_i_i{int min;int max;ll_head action_list;};
typedef struct triplet_f_f_i triplet_f_f_i_t;
struct triplet_f_f_i{float min;float max;ll_head action_list;};


struct event_map_action{
  char action_type; /*remap extern, remap local,or callback fxn*/
  int target_index; /*which control in target object to set*/
  size_t source_offset; /*which parameter in source event to use*/
  void* fixed_event; /*if present, fixed_event is sent to callback instead of triggering event*/
  int function_index; /*selects callback function from input_map->callback_array*/
  event_map_action_t* next;
};


/***************************************************************************/
/******************EVENT INPUT MAP FUNCTIONS********************************/
/***************************************************************************/



/* route_event.c functions */

void route_event(void* ev, event_input_map_t** maps, int mapcount, int whichmap, \
		 input_map_callback_t* callbacks, int callbackcount);





/* input_map.c functions */

event_input_map_t* event_input_map_create();
void event_input_map_destroy(event_input_map_t* inmap);

void* event_input_map_get_owner_object(event_input_map_t* inmap);
void event_input_map_set_owner_object(event_input_map_t* inmap, void* newobject);

int event_input_map_get_event_type(event_input_map_t* inmap);
void event_input_map_set_event_type(event_input_map_t* inmap, int newtype);

int event_input_map_get_submap_array_size(event_input_map_t* inmap);
event_submap_t* event_input_map_get_submap(event_input_map_t* inmap, int pos);

int event_input_map_insert_submap(event_input_map_t* inmap, int pos, char data_type, int test_type);
int event_input_map_remove_submap(event_input_map_t* inmap, int pos);
int event_input_map_append_submap(event_input_map_t* inmap, char data_type, int test_type);





/* submap.c fxns*/


/*SUBMAP ITSELF*/

event_submap_t* event_submap_create(char data_type, int test_type);
void event_submap_destroy(event_submap_t* sbmap);

size_t event_submap_get_parameter_offset(event_submap_t* sbmap);
void event_submap_set_parameter_offset(event_submap_t* sbmap, size_t newoffset);

char event_submap_get_parameter_data_type(event_submap_t* sbmap);
/*NOTE: parameter data type is set once on submap creation and can not be changed dynamically*/

int event_submap_get_parameter_test_type(event_submap_t* sbmap);
/*NOTE: parameter test type is set once on submap creation and can not be changed dynamically*/

/*SUBMAP TEST ARRAY*/

int event_submap_get_test_array_size(event_submap_t* sbmap);
int event_submap_set_test_array_size(event_submap_t* sbmap, int newsize);

int event_submap_insert_test(event_submap_t* sbmap, int pos, void* min, void* max);
int event_submap_remove_test(event_submap_t* sbmap, int pos);
int event_submap_append_test(event_submap_t* sbmap, void* min, void* max);

int event_submap_get_test_min(event_submap_t* sbmap, int pos, void* set);
int event_submap_set_test_min(event_submap_t* sbmap, int pos, void* set);

int event_submap_get_test_max(event_submap_t* sbmap, int pos, void* set);
int event_submap_set_test_max(event_submap_t* sbmap, int pos, void* set);

int event_submap_get_test_exact(event_submap_t* sbmap, int pos, void* set);
int event_submap_set_test_exact(event_submap_t* sbmap, int pos, void* set);

/*SUBMAP TEST ARRAY ACTIONS */

int event_submap_get_test_action_count(event_submap_t* sbmap, int pos);
event_map_action_t* event_submap_get_test_action(event_submap_t* sbmap, int pos, int actionpos);
/*NOTE: use get_action to get a pointer to particular action, then modify it with the event_action functions*/

int event_submap_get_action_index(event_submap_t* sbmap, event_map_action_t* act);
/*NOTE: use get_action_index to reverse lookup an action from a pointer to it*/

event_map_action_t* event_submap_append_test_action(event_submap_t* sbmap, int pos);
event_map_action_t* event_submap_prepend_test_action(event_submap_t* sbmap, int pos);

event_map_action_t* event_submap_insert_test_action(event_submap_t* sbmap, int pos, int actpos);
int event_submap_remove_test_action(event_submap_t* sbmap, int pos, int actpos);






/* event_map_action.c fxns*/

void event_map_action_zero(event_map_action_t* act); /*sets all fields to default*/

char event_map_action_get_type(event_map_action_t* act);
int event_map_action_set_type(event_map_action_t* act, char newtype);

int event_map_action_get_target_index(event_map_action_t* act);
void event_map_action_set_target_index(event_map_action_t* act, int newindex);

size_t event_map_action_get_source_offset(event_map_action_t* act);
void event_map_action_set_source_offset(event_map_action_t* act, size_t newoffset);

void* event_map_action_get_fixed_event(event_map_action_t* act);
void event_map_action_set_fixed_event(event_map_action_t* act, void* newfixed);
/*NOTE: set_action_fixed_event DOES NOT allocate memory, it just stores a pointer*/

int event_map_action_get_function_index(event_map_action_t* act);
void event_map_action_set_function_index(event_map_action_t* act, int new_func);



/* printout.c fxns  */

void print_action(event_map_action_t* act);
void print_submap(event_submap_t* sbmap);
void print_input_map(event_input_map_t* inmap);




#endif
