/*  XMPS - X Movie Player System
 *  Copyright (C) 1999 Damien Chavarria
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public Licensse 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

/*
 * libxmps.h : global types and definitions.
 *
 */

#ifndef _LIBXMPS_H
#define _LIBXMPS_H

/**********************************************************************
 *                                INCLUDES                            *
 **********************************************************************/

/*
 * includes : local
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "libxmps_config.h"

/*
 * includes : system
 *
 */

#include <time.h>
#include <pthread.h>
#include <glib.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/time.h>

/*
 * EVENTS
 */

#define XMPS_EVENT_NO_EVENT            -1
#define XMPS_EVENT_TOGGLE_PLAY          0
#define XMPS_EVENT_TOGGLE_PAUSE         1
#define XMPS_EVENT_GO_FORWARD_ONE       2
#define XMPS_EVENT_GO_BACKWARD_ONE      3
#define XMPS_EVENT_TOGGLE_STOP          4
#define XMPS_EVENT_STOP_RENDERER        5
#define XMPS_EVENT_BACK_FROM_FULLSCREEN 6
#define XMPS_EVENT_EXIT                 7

void push_xmps_event(gint event);
/*
 * adds an event to the queue.
 *
 */

gint pop_xmps_event(void);
/*
 * removes and returns oldest event.
 *
 */


/**********************************************************************
 *                           CONSTANTS & ENUMS                        *
 **********************************************************************/

#ifdef XMPS_DEBUG_ENABLED

#define XMPS_DEBUG(X, args...) \
 { \
   fprintf (stderr, "xmps->%s->", __FUNCTION__); \
   fprintf (stderr, X, ##args); \
   fprintf (stderr, "\n"); \
 }

#else

#define XMPS_DEBUG(X, args...) \
 { \
 }

#endif


typedef enum {

  XMPS_PLUGIN_NONE,
  XMPS_PLUGIN_GUI,
  XMPS_PLUGIN_MEDIA,
  XMPS_PLUGIN_SYSTEM,
  XMPS_PLUGIN_VIDEO_DECODER,
  XMPS_PLUGIN_AUDIO_DECODER,
  XMPS_PLUGIN_AUDIO_FILTER,
  XMPS_PLUGIN_VIDEO_FILTER,
  XMPS_PLUGIN_VIDEO_RENDERER,
  XMPS_PLUGIN_AUDIO_RENDERER,
  XMPS_PLUGIN_VIDEO_ADDON,

} xmps_plugin_types_t;



typedef enum {

  XMPS_FLAG_NONE,
  XMPS_FLAG_PLUGIN_TYPE,
  XMPS_FLAG_INPUT_LIST,
  XMPS_FLAG_OUTPUT_LIST,
  XMPS_FLAG_INPUT,
  XMPS_FLAG_OUTPUT,
  XMPS_FLAG_VIDEO_FORMAT_LIST,
  XMPS_FLAG_VIDEO_FORMAT,
  XMPS_FLAG_VIDEO_INFO,
  XMPS_FLAG_AUDIO_FORMAT_LIST,
  XMPS_FLAG_AUDIO_FORMAT,
  XMPS_FLAG_AUDIO_INFO,
  XMPS_FLAG_AUDIO_CALLBACK,
  XMPS_FLAG_VIDEO_BUFFER,
  XMPS_FLAG_VIDEO_BUFFER_SIZE,
  XMPS_FLAG_RAW_BUFFER,
  XMPS_FLAG_FRAMERATE,
  XMPS_FLAG_LOCK,
  XMPS_FLAG_UNLOCK,
  XMPS_FLAG_VIDEO_RESIZE,
  XMPS_FLAG_FULLSCREEN_SET,
  XMPS_FLAG_FULLSCREEN_UNSET,
  XMPS_FLAG_LOOP_SET,
  XMPS_FLAG_LOOP_UNSET,
  XMPS_FLAG_USER_DATA,
  XMPS_FLAG_DROPFRAME,
  XMPS_FLAG_AUDIO_VOLUME,
  XMPS_FLAG_XML_MENU,
  XMPS_FLAG_XML_CONFIG,
  XMPS_FLAG_SAVE_CONFIG,
  XMPS_FLAG_TIME,
  XMPS_FLAG_TIME_INFO,
  XMPS_FLAG_EMPTY_BUFFERS,
  
} xmps_flag_t;



typedef enum {

  XMPS_DATA_RAW,
  XMPS_DATA_VIDEO_COMP,
  XMPS_DATA_VIDEO_DECOMP,
  XMPS_DATA_AUDIO_COMP,
  XMPS_DATA_AUDIO_DECOMP,
  XMPS_DATA_SUBTITLES

} xmps_data_types_t;



typedef enum {

  XMPS_VIDEO_FORMAT_RGB8,
  XMPS_VIDEO_FORMAT_RGB15,
  XMPS_VIDEO_FORMAT_RGB16,
  XMPS_VIDEO_FORMAT_RGB24,
  XMPS_VIDEO_FORMAT_RGB32,
  XMPS_VIDEO_FORMAT_YUV12
  
} xmps_video_format_types_t;



typedef enum {

  XMPS_AUDIO_FORMAT_U8,
  XMPS_AUDIO_FORMAT_S8,
  XMPS_AUDIO_FORMAT_U16,
  XMPS_AUDIO_FORMAT_S16

} xmps_audio_format_types_t;

typedef enum {

  XMPS_SEEK_SET,
  XMPS_SEEK_CUR,
  XMPS_SEEK_END,
  XMPS_SEEK_PERCENT

} xmps_seeking_method_t;

/**********************************************************************
 *                               STRUCTURES                           *
 **********************************************************************/


typedef struct {
  
  unsigned int              bpp;
  xmps_video_format_types_t type;

} xmps_video_format_t;


typedef struct {

  unsigned int              bit_count;
  xmps_audio_format_types_t type;

} xmps_audio_format_t;

typedef struct {

  unsigned char r;
  unsigned char g;
  unsigned char b;

} xmps_rgb_color_t;

typedef struct {

  unsigned int         windowid;
  unsigned int         width;
  unsigned int         height;
  unsigned int         x;
  unsigned int         y;
  xmps_video_format_t  format;
  xmps_rgb_color_t    *palette;  

} xmps_video_info_t;

typedef struct {

  unsigned int        frequency;
  unsigned int        channels;
  unsigned int        sample_size;
  
  xmps_audio_format_t format;

} xmps_audio_info_t;

typedef struct {

  long current_time;
  long total_time;

} xmps_time_t;

typedef struct {

  unsigned int         id;
  xmps_data_types_t    type;

  void                *user_data;

  char                *video_compression;
  char                *audio_compression;
  
  unsigned int         total_subtitles;

  xmps_video_info_t    video_info;
  xmps_audio_info_t    audio_info;

  xmps_plugin_types_t  plugin_type;
  void                *plugin;

} xmps_data_t;


/**********************************************************************
 *                             PLUGIN TYPES                           *
 **********************************************************************/

typedef struct _xmps_media_plugin_t {

  unsigned int     id;
  char            *name;
  void            *data;
  char            *path;

  unsigned int    (*open) (struct _xmps_media_plugin_t *media, char *full_path);
  void*           (*get)  (struct _xmps_media_plugin_t *media, xmps_flag_t flag, void *args);
  unsigned int    (*set)  (struct _xmps_media_plugin_t *media, xmps_flag_t flag, void *args);
  unsigned int    (*read) (struct _xmps_media_plugin_t *media, void *buffer, unsigned int size);
  unsigned int    (*seek) (struct _xmps_media_plugin_t *media, long pos, xmps_seeking_method_t seek_method);
  unsigned int    (*write)(struct _xmps_media_plugin_t *media, const void *buffer, unsigned int size);
  unsigned int    (*close)(struct _xmps_media_plugin_t *media);

} xmps_media_plugin_t;



typedef struct _xmps_system_plugin_t {

  unsigned int     id;
  char            *name;
  void            *data;

  unsigned int    (*open) (struct _xmps_system_plugin_t *system);
  void*           (*get)  (struct _xmps_system_plugin_t *system, xmps_flag_t  flag,    void *args);
  unsigned int    (*set)  (struct _xmps_system_plugin_t *system, xmps_flag_t  flag,    void *args);
  int             (*read) (struct _xmps_system_plugin_t *system, unsigned int data_id, void *buffer,       long wanted_size);
  unsigned int    (*seek) (struct _xmps_system_plugin_t *system, unsigned int data_id, unsigned int pos,   xmps_seeking_method_t seek_method);
  unsigned int    (*write)(struct _xmps_system_plugin_t *system, unsigned int data_id, const void *buffer, unsigned int size);
  unsigned int    (*close)(struct _xmps_system_plugin_t *system);

} xmps_system_plugin_t;



typedef struct _xmps_video_decoder_plugin_t {

  unsigned int     id;
  char            *name;
  void            *data;

  unsigned int    (*open)      (struct _xmps_video_decoder_plugin_t *video_decoder);
  void*           (*get)       (struct _xmps_video_decoder_plugin_t *video_decoder, xmps_flag_t flag, void *args);
  unsigned int    (*set)       (struct _xmps_video_decoder_plugin_t *video_decoder, xmps_flag_t flag, void *args);
  unsigned int    (*decompress)(struct _xmps_video_decoder_plugin_t *video_decoder, void *in_buffer, void *out_buffer, unsigned int data_size);
  unsigned int    (*close)     (struct _xmps_video_decoder_plugin_t *video_decoder);

} xmps_video_decoder_plugin_t;


typedef struct _xmps_audio_decoder_plugin_t {

  unsigned int     id;
  char            *name;
  void            *data;

  unsigned int    (*open)      (struct _xmps_audio_decoder_plugin_t *audio_decoder);
  void*           (*get)       (struct _xmps_audio_decoder_plugin_t *audio_decoder, xmps_flag_t flag, void *args);
  unsigned int    (*set)       (struct _xmps_audio_decoder_plugin_t *audio_decoder, xmps_flag_t flag, void *args);
  unsigned int    (*decompress)(struct _xmps_audio_decoder_plugin_t *audio_decoder, void *in_buffer, void *out_buffer, unsigned int data_size);
  unsigned int    (*close)     (struct _xmps_audio_decoder_plugin_t *audio_decoder);

} xmps_audio_decoder_plugin_t;



typedef struct _xmps_video_addon_plugin_t {

  unsigned int     id;
  char            *name;
  void            *data;
  
  unsigned int    (*open) (struct _xmps_video_addon_plugin_t *video_addon);
  void*           (*get)  (struct _xmps_video_addon_plugin_t *video_addon, xmps_flag_t flag, void *args);
  unsigned int    (*set)  (struct _xmps_video_addon_plugin_t *video_addon, xmps_flag_t flag, void *args);
  unsigned int    (*apply)(struct _xmps_video_addon_plugin_t *video_addon, void *video_buffer, xmps_video_info_t *info, unsigned int time);
  unsigned int    (*close)(struct _xmps_video_addon_plugin_t *video_addon);
  
} xmps_video_addon_plugin_t;

typedef struct _xmps_video_renderer_plugin_t {

  unsigned int     id;
  char            *name;
  void            *data;

  unsigned int    (*open) (struct _xmps_video_renderer_plugin_t *video_renderer);
  void*           (*get)  (struct _xmps_video_renderer_plugin_t *video_renderer, xmps_flag_t flag, void *args);
  unsigned int    (*set)  (struct _xmps_video_renderer_plugin_t *video_renderer, xmps_flag_t flag, void *args);
  unsigned int    (*draw) (struct _xmps_video_renderer_plugin_t *video_renderer, void *image);
  unsigned int    (*close)(struct _xmps_video_renderer_plugin_t *video_renderer);

} xmps_video_renderer_plugin_t;



typedef struct _xmps_audio_renderer_plugin_t {

  unsigned int     id;
  char            *name;
  void            *data;

  unsigned int    (*open) (struct _xmps_audio_renderer_plugin_t *audio_renderer);
  void*           (*get)  (struct _xmps_audio_renderer_plugin_t *audio_renderer, xmps_flag_t flag, void *args);
  unsigned int    (*set)  (struct _xmps_audio_renderer_plugin_t *audio_renderer, xmps_flag_t flag, void *args);
  unsigned int    (*start)(struct _xmps_audio_renderer_plugin_t *audio_renderer);
  unsigned int    (*close)(struct _xmps_audio_renderer_plugin_t *audio_renderer);

} xmps_audio_renderer_plugin_t;



/*****************************************************************************
 *                                GLOBAL TYPES                               *
 *****************************************************************************/

typedef void (*xmps_audio_callback)(void *user_data, void *buffer, int length);

typedef struct _xmps_plugin_center_t {

  xmps_config_file_t         *config_file;

  GList                      *gui_plugins_list;
  GList                      *media_plugins_list;
  GList                      *system_plugins_list;
  GList                      *video_decoder_plugins_list;
  GList                      *video_renderer_plugins_list;
  GList                      *video_filter_plugins_list;
  GList                      *audio_decoder_plugins_list;
  GList                      *audio_renderer_plugins_list;
  GList                      *audio_filter_plugins_list;
  GList                      *video_addon_plugins_list;

} xmps_plugin_center_t;

typedef struct _xmps_plugin_graph_node_t {

  xmps_plugin_types_t plugin_type;
  void               *plugin;

} xmps_plugin_graph_node_t;

typedef struct _xmps_plugin_graph_link_t {

  void *plugin_source;
  void *plugin_dest;

} xmps_plugin_graph_link_t;

typedef struct _xmps_plugin_graph_t {
  
  GList *nodes;
  GList *links;
  
} xmps_plugin_graph_t;

typedef struct _xmps_session_t {

  xmps_plugin_center_t *plugin_center;
  xmps_plugin_graph_t  *plugin_graph;
  void                 *user_data;
  
} xmps_session_t;

typedef struct _xmps_gui_plugin_t {

  int   id;
  char *name;
  void *data;

  int  (*init) (struct _xmps_gui_plugin_t *gui, void *gui_data);
  int  (*main) (struct _xmps_gui_plugin_t *gui);
  int  (*close)(struct _xmps_gui_plugin_t *gui);
  
} xmps_gui_plugin_t;

typedef struct _xmps_playback_t {

  char                         *media_name;

  pthread_t                     main_thread;

  unsigned int                  loop;
  unsigned int                  playing;

  unsigned long long            audio_bytes;
  unsigned long long            current_frame;

  unsigned int                  video_setup_ok;
  unsigned int                  audio_setup_ok;

  unsigned int                  use_video;
  unsigned int                  use_audio;

  xmps_video_info_t            *video_info;
  xmps_audio_info_t            *audio_info;

  xmps_video_format_t          *video_decoder_format;
  xmps_video_format_t          *video_renderer_format;

  xmps_data_t                  *video_data;
  xmps_data_t                  *audio_data;

  xmps_media_plugin_t          *media;
  xmps_system_plugin_t         *system;
  xmps_video_decoder_plugin_t  *video_decoder;
  xmps_video_renderer_plugin_t *video_renderer;
  xmps_audio_decoder_plugin_t  *audio_decoder;
  xmps_audio_renderer_plugin_t *audio_renderer;
  xmps_video_addon_plugin_t    *subtitles;

  void                         *audio_buffer;
  void                         *video_buffer;
  void                         *video_surface;
  void                         *conversion_surface;

} xmps_playback_t;

/*****************************************************************************
 *                              LIBRARY_FUNCTIONS                            *
 *****************************************************************************/

/*
 * graph functions
 *
 */

unsigned int xmps_plugin_graph_add_node(xmps_plugin_graph_t *plugin_graph,
                                        xmps_plugin_types_t type,
                                        void *plugin);

unsigned int xmps_plugin_graph_add_link(xmps_plugin_graph_t *plugin_graph,
                                        void *plugin1, void *plugin2);

/*
 * pseudo-xml functions
 *
 */

char *xmps_xml_get_value(char *xml_data, char *tag);
char *xmps_xml_config_entry_int_new(char *name, int value, char *control, char *label);
char *xmps_xml_config_entry_string_new(char *name, char *value, char *control, char *label);

/*
 * video conversion functions
 *
 */

void libxmps_color_init();

void xmps_video_conversion(xmps_video_format_t *src_format, 
			   xmps_video_format_t *dest_format,
			   xmps_video_info_t  *video_info,
			   void *src, 
			   void *dest);

/*
 * library functions
 *
 */

xmps_session_t *xmps_init(int argc, char **argv, xmps_config_file_t *config_file);
/*
 * initialize the library;
 *
 */

unsigned int    xmps_load_all(xmps_session_t *xmps_session);
/*
 * loads all available plugins;
 *
 */

unsigned int    xmps_load_plugin(xmps_session_t *xmps_session, 
				 char *plugin_path);
/*
 * loads a particular plugin so that it'll be available;
 *
 */

xmps_plugin_types_t  xmps_get_plugin_type_from_id(xmps_session_t *session, unsigned int id);
void                *xmps_get_plugin_from_id(xmps_session_t *session, unsigned int id);

unsigned int    xmps_playback_init(xmps_session_t *xmps_session);

unsigned int    xmps_playback_setup_video(xmps_session_t *xmps_session, 
					  unsigned int use_it, 
					  unsigned int x_decal,
					  unsigned int y_decal,
					  unsigned int windowid,
					  char        *video_renderer);

unsigned int    xmps_playback_setup_audio(xmps_session_t *xmps_session, 
					  unsigned int    use_it,
					  char           *audio_renderer);
unsigned int    xmps_playback_open(xmps_session_t *xmps_session, 
				   char *video_path);

unsigned int    xmps_playback_play(xmps_session_t *xmps_session);

unsigned int    xmps_playback_pause(xmps_session_t *xmps_session);

unsigned int    xmps_playback_stop(xmps_session_t *xmps_session);

unsigned int    xmps_playback_seek(xmps_session_t *xmps_session, unsigned short percent);

unsigned int    xmps_playback_set_volume(xmps_session_t *xmps_session, unsigned int volume);

unsigned int    xmps_playback_set_loop(xmps_session_t *session, unsigned int on);

unsigned int    xmps_playback_video_resize(xmps_session_t *xmps_session, 
					   unsigned int new_width, 
					   unsigned int new_height);

unsigned int    xmps_playback_video_fullscreen(xmps_session_t *xmps_session, unsigned int on);

xmps_video_info_t *xmps_playback_get_video_info(xmps_session_t *xmps_session);

xmps_audio_info_t *xmps_playback_get_audio_info(xmps_session_t *xmps_session);

xmps_time_t       *xmps_playback_get_time_info(xmps_session_t *xmps_session);

unsigned int    xmps_playback_is_playing(xmps_session_t *xmps_session);

unsigned int    xmps_playback_has_audio(xmps_session_t *xmps_session);

unsigned int    xmps_playback_has_video(xmps_session_t *xmps_session);

unsigned int    xmps_playback_close(xmps_session_t *xmps_session);

void           xmps_quit();
/*
 * unloads all plugins and performs cleanup;
 *
 */


#endif
