/******************************************************************************
*
* Copyright (C) 2004-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: sdl_if.h
*
* DESCRIPTION:  This contains function declartions for SDL interface functions
*
* AUTHORS:  bberlin
*
* CHANGE LOG
*
*  VER     DATE     CHANGED BY   DESCRIPTION OF CHANGE
* ------  --------  ----------   ------------------------------------
* 0.1     07/18/04  bberlin      Creation
* 0.2     03/09/05  bberlin      Added function declaration for debugger and
*                                  GUI video functions
* 0.4.0   05/31/06  bberlin      Added 'pc_toggle_fullscreen' function
******************************************************************************/
#ifndef sdl_if_h
#define sdl_if_h

#ifdef __APPLE__
#include <SDL3/SDL.h>
#else
#include <SDL3/SDL.h>
#endif
#include <SDL3/SDL_gpu.h>
#include "atari_ntsc.h"
#include "../core/boom6502.h"
#include "katconfig.h"
#include "shader_gpu.h"

#define VID_STYLE

#define KAT_WINDOW_MIN_WIDTH  640
#define KAT_WINDOW_MIN_HEIGHT 480

#define MAX_PC_DEVICE 8
#define MAX_PC_PART 32
#define MAX_PC_KEY SDL_SCANCODE_COUNT

typedef struct {
    SDL_Window *screen;
    SDL_Renderer *renderer;
    SDL_Texture *screen_texture;
    SDL_Surface *surface;
    SDL_Surface *ntsc_surface;
    SDL_Surface *output_surface;
    SDL_Rect valid_video_rect;
    unsigned char *draw_pixel_start;
    int draw_pitch;
    int draw_bpp;
    SDL_Rect draw_video_rect;
    SDL_AudioSpec audio_d;
    SDL_AudioSpec audio_o;
    SDL_Color color_palette[256];
    SDL_AudioStream *audio_stream;
    atari_ntsc_t *ntsc_emu;
    unsigned int color_rgb[256];
    unsigned int output_rgb[256];
    int use_shader;
    int ntsc_start_x;
    int audio_samples;
    int shaders_supported;
    SDL_GPUDevice *gpu_device;
    SDL_GPUShaderFormat gpu_shader_formats;
    t_shader_bundle shader_bundle;
    t_shader_gpu_graph shader_graph;
} t_sdl_if;

typedef struct {
    SDL_GUID guid;
    char serial[64];
} t_sdl_joy_info;

typedef struct {
    SDL_Joystick *joy_ptr;
    SDL_Gamepad *ctlr_ptr;
    SDL_JoystickID joy_id;
    t_sdl_joy_info info;
} t_sdl_joy_conv;

typedef struct {
    int size;
    int fill_size;
    int curr_fill_size;
    int play_pos;
    int write_pos;
    int adj_rate_high;
    int adj_rate_med;
    int adj_rate_low;
    int adj_threshold[5];
    int freq;
    unsigned int frame_cnt;
    unsigned int samp_cnt;
    unsigned int avg_queue;
    unsigned char *buf;
    unsigned char *extra_buf;
} t_sdl_aud_buf;

int pc_init (void);
int pc_exit (void);
int pc_get_exit(void);
int pc_is_android_tv(void);
int pc_get_android_content_insets(int *left, int *top, int *right, int *bottom);
int pc_debugger_available(void);
char * pc_get_compiled_version ( char *v_string );
char * pc_get_linked_version ( char *v_string );
char * pc_get_image_compiled_version ( char *v_string );
char * pc_get_image_linked_version ( char *v_string );
int pc_game_init (void);
void pc_flush_input_events (void);
int pc_get_shaders_supported (void);
SDL_GPUDevice * pc_get_gpu_device (void);
SDL_GPUShaderFormat pc_get_gpu_shader_formats (void);
void pc_set_shader ( t_video *p_video );
void pc_get_shader_live_status ( char *status, size_t status_size );
int pc_resolve_shader_bundle ( const char *shader_name, char *bundle_dir,
        size_t bundle_dir_size );
int pc_enumerate_shader_bundles ( char **ids, int max );
SDL_Texture * pc_shader_preview_update ( t_shader_bundle *bundle,
        char *err, size_t err_size );
void pc_shader_preview_free ( void );
int pc_open_joystick (int index);
unsigned int * pc_check_for_and_open_joysticks(void);
int pc_detect_and_open_joysticks (void);
int pc_detect_joysticks (void);
int pc_get_num_joysticks(void);
int pc_get_valid_joy_count(void);
unsigned int pc_get_valid_joy_id(int n);
unsigned int pc_get_joy_generation(void);
int pc_check_ctrl_joystick_use(int joy_num, t_input_common *ctrl);
int pc_get_joy_slot_name(int slot, char *buf, int buf_size);
void pc_get_joy_slot_device_types(e_dev_type *types, int max_types);
void pc_get_joy_guid_string(unsigned int joy_id, char *buf, int buf_size);
void pc_get_joy_serial(unsigned int joy_id, char *buf, int buf_size);
void pc_get_player_joy_name(const char *guid_str, char *buf, int buf_size);
const char * pc_get_joystick_name ( int index );
int pc_get_joystick_index_from_id (int instance_id);
int pc_get_bytes_per_pixel (void);
//UINT8 * pc_get_scanline_ptr (void);
void pc_set_scanline_ptr ( void *ptr );
void * pc_get_current_line_ptr (void);
int pc_calculate_first_use_window_geometry ( const SDL_Rect *bounds,
        int *w, int *h, int *x, int *y );
int pc_render_frame_video_sound(void);
int pc_render_frame_sound(void);
float pc_get_auto_sound_buffer_size ( void );
void pc_set_sound_gain ( int gain );
int pc_poll_events (void);
int pc_poll_input_events (SDL_Event *event);
int pc_handle_unmapped_gui_button (SDL_Event *event, int *status);
int pc_poll_debug (void);
void pc_delay (int ms);
void pc_delay_precise_ns (Uint64 ns);
unsigned int pc_get_ticks (void);
Uint64 pc_get_ticks_us (void);
int pc_get_modes (int bpp, int monitor, SDL_DisplayMode ***p_modes);
//int pc_lock_audio (void);
//int pc_unlock_audio (void);
int pc_set_palette ( t_video *p_video, SDL_Color *palette, unsigned int *rgb );
SDL_Window * pc_set_window ( t_video *p_video, int w, int h );
SDL_Renderer * pc_get_renderer ( int vsync );
int pc_get_render_drivers ( const char **names, int max );
void pc_reinit_video_surfaces ( t_video *p_video, int tv_standard );
SDL_Window * pc_set_game_video ( t_video *p_video, int tv_standard );
void pc_blit_ntsc_filtered_screen_32(void);
void pc_blit_palette_screen_32(void);
void pc_refresh_video_output(void);
SDL_ScaleMode pc_texture_scale_mode ( int texture_scaling );
SDL_Window * pc_set_debugger_video (void);
SDL_Window * pc_toggle_fullscreen ( t_video *p_video );
void pc_apply_fullscreen ( t_video *p_video );
void pc_apply_window ( t_video *p_video );
void pc_native_video_size ( t_video *p_video, int tv_standard, int *w, int *h );
void pc_get_window_size_limits ( t_config *cfg, int *min_w, int *min_h,
                                 int *max_w, int *max_h );
int pc_save_screenshot (char *file);
int pc_convert_bitmap ( char *old_file, char *new_file );
int pc_window_position_in_bounds ( int x, int y );
void pc_set_ui_defaults ( void );
void pc_set_controller_defaults ( void );
void pc_set_keyboard_defaults ( void );
int pc_check_for_lr_keys ( int key_value );
int pc_adjust_key_value ( int key_value );
int pc_interpret_controller_button ( const char *string );
char * pc_interpret_controller_button_value ( int value, char *string );
int pc_interpret_controller_axis ( const char *string );
char * pc_interpret_controller_axis_value ( int value, char *string );
int pc_interpret_key ( const char *string );
char * pc_interpret_key_value ( int value, char *string );
int pc_interpret_mod_key ( const char *string );
char * pc_interpret_mod_key_value ( int value, char *string );
int pc_get_joystick_index_from_id ( int id );
void pc_set_joystick_id ( int index, unsigned int instance_id );
const char * pc_get_internal_app_storage ( void );
char * pc_get_external_sdcard_path ( char *dir );

/* Android storage roots (see sdl_if.c).  Root count is 0 off Android, which
 * leaves the desktop file browser behaving exactly as before. */
int pc_storage_has_full_access ( void );
int pc_storage_request_full_access ( void );
int pc_get_storage_root_count ( void );
const char * pc_get_storage_root_path ( int index );
const char * pc_get_storage_root_label ( int index );

void * pc_start_thread ( void *fn, const char *name, void *data);
void pc_set_thread_data ( void *value );
void * pc_get_thread_data ( void );
void pc_wait_semaphore (void);
void pc_signal_semaphore (void);

void pc_blit_ntsc_filtered_screen_with_inputs(atari_ntsc_t *ntsc_emu,SDL_Surface *surface, SDL_Rect surface_rect, SDL_Surface *screen, SDL_Rect screen_rect);
void pc_blit_ntsc_filtered_screen_with_inputs_32(atari_ntsc_t *ntsc_emu,SDL_Surface *surface, SDL_Rect surface_rect, SDL_Surface *screen, SDL_Rect screen_rect);
void pc_reset_sound_adj ( void );

struct fb_dir_entries;
void *pc_malloc(size_t size);
void pc_free_memory(void *memory);
char *pc_get_current_directory(void);
char **pc_glob_directory(char *dir, char *pattern, int *count);
int pc_get_entry_type(int type);
char **pc_enumerate_directory(struct fb_dir_entries *fb_cfg);

#endif
