/*****************************************************************
 * gmerlin - a general purpose multimedia framework and applications
 *
 * Copyright (c) 2001 - 2012 Members of the Gmerlin project
 * gmerlin-general@lists.sourceforge.net
 * http://gmerlin.sourceforge.net
 *
 * 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, see <http://www.gnu.org/licenses/>.
 * *****************************************************************/

#include <gtk/gtk.h>

#include <config.h>

#include <gmerlin/player.h>
#include <gmerlin/playermsg.h>
#include <gmerlin/cfg_registry.h>
#include <gmerlin/pluginregistry.h>
#include <gui_gtk/infowindow.h>
#include <gui_gtk/logwindow.h>
#include <gui_gtk/mdb.h>
//#include <gmerlin/lcdproc.h>
#include <gmerlin/bgsocket.h>
#include <gmerlin/websocket.h>
#include <gmerlin/mdb.h>

#include <gmerlin/cfg_dialog.h>

#include <gmerlin/upnp/ssdp.h>

#ifdef HAVE_DBUS
#include <gmerlin/bgdbus.h>
#endif


// #include <gmerlin/remote.h>

typedef struct gmerlin_s gmerlin_t;

#include "display.h"
#include "playerwindow.h"

/* Class hints */

#define WINDOW_NAME  "Gmerlin"
#define WINDOW_CLASS "gmerlin"
#define WINDOW_ICON  "player_icon.png"

/* Accelerators */

#define ACCEL_QUIT                   (BG_PLAYER_ACCEL_PRIV+1)
#define ACCEL_OPTIONS                (BG_PLAYER_ACCEL_PRIV+2)
#define ACCEL_GOTO_CURRENT           (BG_PLAYER_ACCEL_PRIV+3)
#define ACCEL_CURRENT_TO_FAVOURITES  (BG_PLAYER_ACCEL_PRIV+4)

typedef struct
  {
  char * directory;
  
  player_window_skin_t playerwindow;
  } gmerlin_skin_t;

void gmerlin_skin_destroy(gmerlin_skin_t * s);

typedef struct gmerlin_skin_browser_s gmerlin_skin_browser_t;

#define PLAYBACK_SKIP_ERROR (1<<0)

struct gmerlin_s
  {
  int playback_flags;

  /* Core stuff */
  
  bg_player_t          * player;
  
  bg_controllable_t    * player_ctrl;
  bg_controllable_t    * mdb_ctrl;
  
  bg_mdb_t * mdb;
  
  bg_control_t ctrl;
  
  /* GUI */
  
  bg_dialog_t * cfg_dialog;
  
  bg_gtk_mdb_tree_t * mdb_tree;
  GtkWidget * mdb_window;
  
  player_window_t * player_window;
  bg_gtk_info_window_t * info_window;
  bg_gtk_log_window_t * log_window;
  
  gmerlin_skin_t skin;
  char * skin_dir;
  
  gmerlin_skin_browser_t * skin_browser;
  bg_cfg_ctx_t * cfg_player;
  bg_cfg_ctx_t * cfg_mdb;
  
  int tree_error;

  /* Configuration stuff */
  
  bg_cfg_section_t * display_section;
  bg_cfg_section_t * tree_section;
  bg_cfg_section_t * general_section;
  bg_cfg_section_t * lcdproc_section;
  bg_cfg_section_t * remote_section;
  bg_cfg_section_t * logwindow_section;
  bg_cfg_section_t * infowindow_section;

  bg_parameter_info_t * input_plugin_parameters;
  bg_parameter_info_t * image_reader_parameters;
  
  //  bg_lcdproc_t * lcdproc;

  /* Remote control */
  bg_http_server_t   * srv;

  bg_server_storage_t * client_config;
  
  int player_state;

  /* For all windows */
  GtkAccelGroup *accel_group;

  gavl_dictionary_t state;

  bg_backend_handle_t * player_backend;
  bg_backend_handle_t * mdb_backend;

#ifdef HAVE_DBUS
  bg_frontend_t * dbus_frontend;
#endif

  /* Upnp stuff */
  bg_frontend_t * upnp_renderer_frontend;
  bg_frontend_t * upnp_server_frontend;

  bg_frontend_t * gmerlin_renderer_frontend;
  bg_frontend_t * gmerlin_server_frontend;
  
  bg_ssdp_t * renderer_ssdp;

  gavl_dictionary_t renderer_ssdp_dev;

  int stop;
  int frontend_thread_running;
  pthread_mutex_t stop_mutex;
  pthread_t frontend_thread;
  
  };

gmerlin_t * gmerlin_create(const gavl_dictionary_t * saved_state, const char * db_path);

/* Right after creating, urls can be added */

void gmerlin_add_locations(gmerlin_t * g, const char ** locations);
void gmerlin_play_locations(gmerlin_t * g, const char ** locations);

void gmerlin_open_device(gmerlin_t * g, const char * device);
void gmerlin_play_device(gmerlin_t * g, const char * device);

void gmerlin_destroy(gmerlin_t*);

void gmerlin_run(gmerlin_t*, const char ** locations);

// void gmerlin_set_next_track(gmerlin_t * g);

void gmerlin_connect_player(gmerlin_t * gmerlin);
void gmerlin_disconnect_player(gmerlin_t * gmerlin);

void gmerlin_connect_mdb(gmerlin_t * gmerlin);
void gmerlin_disconnect_mdb(gmerlin_t * gmerlin);


/* Skin stuff */

/* Load a skin from directory. Return the default dierectory if the
   skin could not be found */

char * gmerlin_skin_load(gmerlin_skin_t *, char * directory);

void gmerlin_skin_set(gmerlin_t*);
void gmerlin_skin_free(gmerlin_skin_t*);

/* Skin browser */

gmerlin_skin_browser_t * gmerlin_skin_browser_create(gmerlin_t *);
void gmerlin_skin_browser_destroy(gmerlin_skin_browser_t *);
void gmerlin_skin_browser_show(gmerlin_skin_browser_t *);

/* Run the main config dialog */

void gmerlin_create_dialog(gmerlin_t * g);

void gmerlin_configure(gmerlin_t * g);

void gmerlin_pause(gmerlin_t * g);

int gmerlin_handle_message(void * data, gavl_msg_t * msg);

/* This is called when the player signals that it wants a new
   track */

// void gmerlin_next_track(gmerlin_t * g);

const bg_parameter_info_t * gmerlin_get_parameters(gmerlin_t * g);

void gmerlin_set_parameter(void * data, const char * name,
                           const gavl_value_t * val);

int gmerlin_get_parameter(void * data, const char * name,
                          gavl_value_t * val);


/* Handle remote command */

void gmerlin_handle_remote(gmerlin_t * g, gavl_msg_t * msg);
