/*
 * choices.c
 * ---------
 * Reads and saves the choices file. Not all settings can be changed
 * whilst playing. The saving facility is mainly for the following settings,
 *
 * lock aspect
 * lock size
 * control panel on/off
 * brightness
 * contrast
 * colour
 * volume
 * non multitasking initial zoom
 *
 * The following settings retain their initial values when saved. i.e. they
 * are unaffected by changes made whilst playing.
 *
 * play audio
 * save audio
 * multitasking initial zoom
 *
 * The Play and Save audio settings can be automatically changed during
 * initialisation due to prevailing conditions. i.e. A video only file,
 * or problems with starting AMPlayer, or inability to open a sountrack
 * file. This is why the current play settings are not saved.
 *
 * The internal zoom setting is fixed at 100% when multitasking
 * to allow variable scale factors. For this reason, when multitasking,
 * the current zoom setting is not saved.
 *
 * The multitask on/off setting is saved unchanged because it is switched
 * off before play automatically if using a full screen mode.
 *
 * note. The debug setting is not loaded here as it makes more sense to
 * let the config program append it to the command line along with any
 * redirection. Any debug and comment strings are saved unchanged.
 * However, bit 0 of debug is loaded here (all frames).
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "kernel.h"
#include "swis.h"
#include "inttypes.h"
#include "config.h"
#include "choices.h"
#include "player.h"

extern ka_config_t config;

static char
  *choices = NULL;

static int
  play_audio = 1,
  save_audio = 0;

/**
 * Initializes config structure.
 */
void choices_init(void)
{
  config_init(&config);
  config.control = cfg_ctrl_scroll_bars | cfg_ctrl_autoexit;
  config.audio.cfg = cfg_audio_play;
  config.audio.volume = -1;
  config.video.mode = KA_MODE_DESKTOP;
}

/**
 * Checks choices values against invalid values or combinations.
 */
void choices_validate(void)
{
  config_validate(&config);
}

/**
 * Set playing options from the choices file.
 *
 * @param  filename  Name of the file to read options from.
 */
void choices_read(char* filename)
{
  choices = filename; // so we know where to save later

  config_read(&config, filename);

  config_validate(&config);

  // remember these values so we can save them later
  play_audio = config.audio.cfg & cfg_audio_play;
  save_audio = config.audio.cfg & cfg_audio_save;
}

/**
 * Saves the Choices configuration file from the last read one.
 * Checks if the Config setup task is running. If it is then a message
 * is sent to it so it knows the Choices file has changed.
 */
void choices_save(const player_t* player)
{
  _kernel_swi_regs regs;
  int blk[5], handle;

  player = player; // avoid compiler warning

  if (!choices) // can only save if a -f<file> option was passed to us
    return;

/*
note, we touch:
config.audio.volume
config.audio.stream
config.audio.cfg (mute, save, play, sync)
config.control (controls, scroll_bars, random, loop, auto_exit, no_check)
config.debug
config.video (bright, contrast, colour, pos_x, pos_y, stream, demux_ps, mode, zoom)
config.video.cfg (mono, lock_aspect, lock_size, dither)

    fprintf(f, "play audio    = %c\n", (play_audio) ? 'Y' : 'N'); // leave unchanged
    fprintf(f, "save audio    = %c\n", (save_audio) ? 'Y' : 'N'); // leave unchanged
    fprintf(f, "current volume= N\n"); // so we will use the new value next time
    fprintf(f, "video defaults= N\n"); // so we will use the new values next time

    fprintf(f, "x resolution  = %d\n", player->screen.width);
    fprintf(f, "y resolution  = %d\n", player->screen.height);
*/

  config_save(&config, choices);

  // find out if the config task is running
  regs.r[0] = 0;
  handle = 0;
  while ((regs.r[0] >= 0) && !handle)
  {
    regs.r[1] = (int) blk;
    regs.r[2] = sizeof(blk);
    _kernel_swi(TaskManager_EnumerateTasks, &regs, &regs);
    if (strcmp((char*) blk[1], "KinoAMP Configuration") == 0)
      handle = blk[0];
  }
  if (!handle)
    return;

  // tell the config task that the choices have changed
  regs.r[0] = 17; // User message
  regs.r[1] = (int) blk;
  regs.r[2] = handle;
  blk[0] = sizeof(blk);
  blk[3] = 0;
  blk[4] = 12345; // action !
  _kernel_swi(Wimp_SendMessage, &regs, &regs);
}
