/******************************************************************************
*
* Copyright (C) 2006-2017  Brian Berlin
* 
* 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 3 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, see <http://www.gnu.org/licenses/>
*
******************************************************************************
*
* FILENAME: input.h
*
* DESCRIPTION:  This contains function declarations for input handling
*
* AUTHORS:  bberlin
*
* CHANGE LOG
*
*  VER     DATE     CHANGED BY   DESCRIPTION OF CHANGE
* ------  --------  ----------   ------------------------------------
* 0.5.0   01/10/06  bberlin      Creation, break out from config
* 0.8.0   11/13/17  bberlin      Add combo inputs
******************************************************************************/
#ifndef input_h
#define input_h

#include "katconfig.h"
#include "sdl_if.h"
#include "../core/console.h"

struct atari_list {
    char name[257];
    t_input_common *ctrl;
    struct atari_list *next;
}; 

typedef struct atari_list t_atari_input_list;

/*
 * Declare PC specific structs
 */
struct pc_common {
    int ( *pos_function ) ( void *,int,int,int );
    int ( *neg_function ) ( void *,int,int,int );
    int player;
    int atari_key;
    int direction;
    int engaged;
    int has_combo_mod;
    unsigned int modifier;
    struct pc_common *top;
    struct pc_common *combo;
    struct pc_common *next;
};

typedef struct pc_common t_pc_common;

typedef struct {
    t_pc_common common;
    int sa_high_threshold;
    int sa_low_threshold;
} t_pc_analog_axis;

typedef struct {
    t_pc_analog_axis x_axis;
    t_pc_analog_axis y_axis;
    int speed;
} t_pc_ball;

typedef struct {
    t_pc_common keyboard[MAX_PC_KEY];
    t_pc_common pov_hat[MAX_PC_DEVICE][MAX_PC_PART][MAX_DIR];
    t_pc_analog_axis analog_axis[2][MAX_PC_DEVICE][MAX_PC_PART];
    t_pc_ball trackball[MAX_PC_DEVICE][MAX_PC_PART];
    t_pc_ball mouse;
    t_pc_common button[2][MAX_PC_DEVICE][MAX_PC_PART];
    t_pc_common mouse_button[6];
    int ( *frame_x_function[MAX_CONTROLLER] ) ( void *,int,int );
    int ( *frame_y_function[MAX_CONTROLLER] ) ( void *,int,int );
} t_pc_input;

typedef struct {
    int axis_idle[2];
    int axis_value[2];
    float mouse_accum[2];
    int mouse_active[2];
    int mouse_axis_mode[2];
    int pot_center[2];
    int pot_low[2];
    int pot_high[2];
    int trackball_center[2];
    int trackball_dpot_min;
    int trackball_dpot_max;
    int uses_trackball;
    int sa_high_threshold[2];
    int sa_low_threshold[2];
    int pressed[MAX_DIR];
    int digital_pressed[MAX_DIR];
    unsigned char pot_values[2][0x10000];
} t_pc_stick_interface;

/*
 * Function Declarations
 */
int input_init ( void );
int input_set_controls ( void );
void input_mouse_accumulate ( int player, int dir, int mode, float magnitude );
void input_flush_mouse_motion ( void );
void input_auto_fire_frame ( void );
void input_auto_fire_reset ( void );
int input_mouse_axis (void *input, int player, int dir, int value);
int input_mouse_trackball_axis (void *input, int player, int dir, int value);
void input_exit ( void );
int input_set_gui_function ( int (*func) (int) );
int input_pc_common_is_mapped ( t_pc_common *p );
int input_find_common ( int id, t_input_common *ctrl );
int input_write_common ( char *statement, t_input_common *ctrl, int *id );
t_atari_input_list * input_check_conflicts ( t_game_input *p_input );
int input_convert_sdl_keycodes ();
void input_add_combo_function ( t_input_common *ctrl,
       int (**d_addr)(int,int,int), int (*d)(int,int,int),
       int *param1addr, int *param2addr, int *param3addr );
int input_set_combo_off_function ( int (**e_addr)(int,int,int), 
       int param1, int param2, int param3 );
int input_update_combo_off_function ( int (**e_addr)(int,int,int), 
       int param1, int param2, int param3 );
const char * input_get_type_string ( e_ctrlr_type type );
char * input_get_key_string ( int key, char *name );
char * input_get_keypad_string ( int key_index, char *name );
int input_get_key_value ( char *name );
int input_get_keypad_value ( const char *name );
int input_ui_back (void *input, int key, int temp, int temp1);
void input_combo_disengage_all ( void );

#endif
