/***************************************************************************
 *            libmltrec/commands.c
 *
 *  Sat May  8 12:49:06 2004
 *  Copyright  2004  Stanislav Brabec
 *  utx@penguin.cz
 ****************************************************************************/

/*
 *  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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Generaversion.
 *
 *  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 Library 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.
 */

#include <stdio.h>

#include "commands.h"

/* FIXME: return what?, serial */

/**
 * mltrec_generic_command_12:
 * @mltdev: Pointer to camera device.
 * @command: Command.
 * @extcmd: Command extension.
 * @extval1: Command argument 1. For @size <= 0x0c unused.
 * @extval2: Command argument 2. For @size <= 0x0e unused.
 * @size: Command size.
 * @returns: Pointer to header of read buffer or @NULL if error.
 *
 * Skeleton for generic command. Generic command returns its
 * reply in @mltdev->ext.
 */

/* FIXME: strings should be dynamically allocated and freed after sending data to USB. It allows immediate detaching. */

/* MLTREC_OPEN 0x1001 */
int
mltrec_rec_open (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_OPEN\n");
  mltprot_submit_command (mltdev, hdr, MLTREC_OPEN, 12, mltrec_rec_open_c, NULL);
  return 0;
}
void
mltrec_rec_open_c (mltrec_device * mltdev, mltprot_header *hdr, void *user_data)
{
  char *id;
  DBG1 ("MLTREC_OPEN reply: status=%d, %d\n",
	mlthdr_get_extval1 (hdr), mlthdr_get_extval2 (hdr));
  id = mltusb_unicode_to_ascii (mlthdr_gendata (hdr), 0);
  DBG1 ("MLTREC_OPEN reply: camera_id=\"%s\"\n", id);
  free (id);
}

/* MLTREC_CLOSE_SLEEP 0x1002 */
int
mltrec_rec_close (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (16);
  if (!hdr)
    return 1;

  /* FIXME: Maybe this command is not needed. */
  //  mltrec_complete_all (mltdev);
  DBG1 ("Submitting MLTREC_CLOSE_SLEEP\n");
  mlthdr_set_extval1 (hdr, 0);
  mlthdr_set_extval2 (hdr, 0);
  mltprot_submit_command (mltdev, hdr, MLTREC_CLOSE_SLEEP, 16, NULL, NULL);
  /* FIXME: This command is not needed (move to device close). */
  //  mltrec_complete_all (mltdev);
  return 0;
}
int
mltrec_rec_sleep (mltrec_device * mltdev, uint16_t seconds)
{
uint8_t *hdr;
  hdr = malloc (16);
  if (!hdr)
    return 1;

  //  mltrec_complete_all (mltdev);
  DBG1 ("Submitting MLTREC_CLOSE_SLEEP\n");
  mlthdr_set_extval1 (hdr, 1);
  mlthdr_set_extval2 (hdr, seconds);
  mltprot_submit_command (mltdev, hdr, MLTREC_CLOSE_SLEEP, 16, NULL, NULL);
  //  mltrec_complete_all (mltdev);
  return 0;
}

/* MLTREC_SHUTDOWN 0x1003 */
/* BIG FIXME: This needs rewrite. Command does not reply! */
int
mltrec_shutdown (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (0x0c);
  if (!hdr)
    return 1;

  //  mltrec_complete_all (mltdev);
  DBG1 ("Submitting MLTREC_SHUTDOWN\n");
  mltprot_submit_command (mltdev, hdr, MLTREC_CLOSE_SLEEP, 16, NULL, NULL);
  /* FIXME: Maybe obsolete (closing device after. Camera does not reply to this command. */
  return 0;
}

/* MLTREC_UNKNOWN_1004 0x1004 */
/* FIXME: Unknown command size. */
/* Terminates communication in some way. Remote stop is accepted later, but live_get not.*/
int
mltrec_unknown1004 (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (16);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_UNKNOWN_1004\n");
  mlthdr_set_extval1 (hdr, 3);
  mlthdr_set_extval2 (hdr, 0);
  mltprot_submit_command (mltdev, hdr, MLTREC_UNKNOWN_1004, 16, NULL, NULL);
  return 0;
}

/* MLTREC_LOCK_AE_AF 0x1005 */
int
mltrec_lock_ae_af (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (14);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_LOCK_AE_AF (lock)\n");
  mlthdr_set_extval1 (hdr, 1);
  mltprot_submit_command (mltdev, hdr, MLTREC_LOCK_AE_AF, 14, mltrec_lock_ae_af_c, NULL);
  return 0;
}
int
mltrec_unlock_ae_af (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (14);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_LOCK_AE_AF (unlock)\n");
  mlthdr_set_extval1 (hdr, 0);
  mltprot_submit_command (mltdev, hdr, MLTREC_LOCK_AE_AF, 14, mltrec_lock_ae_af_c, NULL);
  return 0;
}
void
mltrec_lock_ae_af_c (mltrec_device * mltdev, mltprot_header *hdr, void *user_data)
{
  if (mlthdr_get_size (hdr) == 0x16)
    {
    DBG1 ("MLTREC_LOCK_AE_AF reply: status=%d, hpoint=%d, %d, vpoint=%d, %d\n",
	    mlthdr_get_extval1 (hdr),
	    mlthdr_get_extval2 (hdr),
	    mlthdr_get_ew0 (hdr), mlthdr_get_ew1 (hdr),
	  mlthdr_get_ew2 (hdr));
    }
  else
    {
    DBG0 ("Camera sends MLTREC_LOCK_AE_AF reply of unknown size %d\n",
	  mlthdr_get_size (hdr));
    }
}

/* MLTREC_CAPTURE_START 0x1006 */
/* How capture works: You need first set following callbacks:
mltrec_image_write_callback_set(), mltrec_image_close_callback_set().  */
/* quality, size, drive must be value from settings. */
/* FIXME: Unknown is image destination??? */
int
mltrec_capture_start (mltrec_device * mltdev, uint32_t drive,
		      uint32_t size, uint32_t quality, uint32_t unknown)
{
uint8_t *hdr;
  hdr = malloc (0x1c);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_CAPTURE_START\n");
  mlthdr_set_extval (hdr, drive);
  mlthdr_set_ext0 (hdr, size);
  mlthdr_set_ext1 (hdr, quality);
  mlthdr_set_ext2 (hdr, unknown);
  mltprot_submit_command (mltdev, hdr, MLTREC_CAPTURE_START, 0x1c, NULL, NULL);
  mltdev->capture_serial = mltdev->write_serial;
  return 0;
}

/* MLTREC_CAPTURE_STOP 0x1007 */
int
mltrec_capture_stop (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_CAPTURE_STOP\n");
  mltprot_submit_command (mltdev, hdr, MLTREC_CAPTURE_STOP, 12, NULL, NULL);
  return 0;
}

/* MLTREC_REMOTE_START 0x1008 */
int
mltrec_remote_start (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_REMOTE_START\n");
  mltprot_submit_command (mltdev, hdr, MLTREC_REMOTE_START, 12, NULL, NULL);
  return 0;
}

/* MLTREC_REMOTE_STOP 0x1009 */
int
mltrec_remote_stop (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  /* It seems, that before mltrec_remote_stop(), all commands must be
     completed. */
  //  mltrec_complete_all (mltdev);
  DBG1 ("Submitting MLTREC_REMOTE_STOP\n");
  mltprot_submit_command (mltdev, hdr, MLTREC_REMOTE_STOP, 12, NULL, NULL);
  return 0;
}

/* MLTREC_LIVE_GET 0x100a */
/* FIXME: We cannot get really read file size */
/* Returns image in hdr->data. */
/* FIXME: Ugly freeing */
/* FIXME: here atomic must cover also live image transfer */
int
mltrec_live_get (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_LIVE_GET\n");
  mltprot_submit_command (mltdev, hdr, MLTREC_LIVE_GET, 12, mltrec_live_get_c, NULL);
  return 0;
}
void
mltrec_live_get_c (mltrec_device * mltdev, mltprot_header *hdr, void *user_data)
{
  uint32_t size;
  uint8_t *data;

  size = mlthdr_get_live_size (hdr);
  data = hdr + 0x28;
  DBG1 ("MLTREC_LIVE_GET reply: image size=%d\n", size);
    /* FIXME: better test */
  if (data)
  {
  mltdev->live_callback (data, size, mltdev->live_user_data);
  free (hdr);
  }
}

/* MLTREC_UNKNOWN_100B 0x100b */

/* MLTREC_SETTINGS_SET 0x100c */

int
mltrec_settings_set (mltrec_device * mltdev, uint32_t val1, uint32_t val2)
{
uint8_t *hdr;
  hdr = malloc (0x1c);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_SETTINGS_SET\n");
  mlthdr_set_extval (hdr, 1);
  mlthdr_set_ext0 (hdr, val1);
  mlthdr_set_ext1 (hdr, 1);
  mlthdr_set_ext2 (hdr, val2);

  mltprot_submit_command (mltdev, hdr, MLTREC_SETTINGS_SET, 0x1c, NULL, NULL);
  return 0;
}



/* MLTREC_SETTINGS_GET 0x100e */
int
mltrec_settings_get (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_SETTINGS_GET\n");
  mltprot_submit_command (mltdev, hdr, MLTREC_SETTINGS_GET, 12, mltrec_settings_get_c, NULL);
  return 0;
}
void
mltrec_settings_get_c (mltrec_device * mltdev, mltprot_header *hdr, void *user_data)
{
  uint32_t i, offset;
  char *typename, *itemname;

  offset = 20;
  for (i = 0; i < mlthdr_get_esize (hdr); i++)
    {
      itemname = mltrec_settings_to_text (mltset_get_tag (hdr, i));
      switch (mltset_get_type (hdr, i))

	{
	case MLT_SET_MODE_RW:
	  typename = "read/write";
	  break;
	case MLT_SET_MODE_RO:
	  typename = "read only";
	  break;
	default:
	  typename = "unknown";
	  break;
	}
      DBG1 ("0x%x=%s: type=0x%x=%s, value=0x%x=%d, default=0x%x=%d, min=0x%x=%d, max=0x%x=%d\n",
	      mltset_get_tag (hdr, i), itemname,
	      mltset_get_type (hdr, i), typename,
	      mltset_get_value (hdr, i), mltset_get_value (hdr, i),
	      mltset_get_default (hdr, i), mltset_get_default (hdr, i),
	      mltset_get_min (hdr, i), mltset_get_min (hdr, i),
	    mltset_get_max (hdr, i), mltset_get_max (hdr, i));
    }
}

/* MLTREC_FLEXMAG_TOGGLE 0x101e */
/* FIXME: What it does? */
int
mltrec_flexmag_toggle (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_FLEXMAG_TOGGLE\n");
 mltprot_submit_command (mltdev, hdr, MLTREC_FLEXMAG_TOGGLE, 12, NULL, NULL);
  return 0;
}

/* MLTREC_FOCUS_SET 0x1020 */
int
mltrec_focus_set (mltrec_device * mltdev, int focus)
{
uint8_t *hdr;
  hdr = malloc (14);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_FOCUS_SET\n");
  mlthdr_set_extcmd (hdr, focus);
 mltprot_submit_command (mltdev, hdr, MLTREC_FOCUS_SET, 14, NULL, NULL);
  return 0;
}

/* MLTREC_INSTPLAY_CONFIRM 0x1021 */
/* FIXME: how to use it??? */
/* serial is corresponding mltrec_capture_start serial */
int
mltrec_instplay_confirm (mltrec_device * mltdev, uint16_t confirm,
		     uint16_t unknown)
{
uint8_t *hdr;
  hdr = malloc (0x14);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_INSTPLAY_CONFIRM\n");
  mlthdr_set_extcmd (hdr, 0);
  mlthdr_set_extval1 (hdr, confirm);
  mlthdr_set_extval2 (hdr, unknown);
  mlthdr_set_ext0 (hdr, mltdev->capture_serial);
  /* FIXME: clear capture_serial? */
  mltprot_submit_command (mltdev, hdr, MLTREC_INSTPLAY_CONFIRM, 0x14, NULL, NULL);
  return 0;
}

/* MLTREC_FLEXFOCUS_MODE 0x1025 */
/* 0=wide, 1=spot, FIXME: Where is Spot Follows FFP? */
int
mltrec_flexfocus_mode (mltrec_device * mltdev, int flexmode)
{
uint8_t *hdr;
  hdr = malloc (14);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_FLEXFOCUS_MODE\n");
  mlthdr_set_extval1 (hdr, flexmode);
  mltprot_submit_command (mltdev, hdr, MLTREC_FLEXFOCUS_MODE, 14, NULL, NULL);
  return 0;
}

/* MLTREC_FLEXFOCUS_POS 0x1026 */
int
mltrec_flexfocus_pos (mltrec_device * mltdev, uint16_t pos1, uint16_t pos2,
		      uint16_t pos3, uint16_t pos4)
{
uint8_t *hdr;
  hdr = malloc (0x14);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_FLEXFOCUS_POS\n");
  mlthdr_set_extval1 (hdr, pos1);
  mlthdr_set_extval2 (hdr, pos2);
  mlthdr_set_ew0 (hdr, pos3);
  mlthdr_set_ew1 (hdr, pos4);
  mltprot_submit_command (mltdev, hdr, MLTREC_FLEXFOCUS_POS, 14, mltrec_flexfocus_pos_c, NULL);
  return 0;
}
void
mltrec_flexfocus_pos_c (mltrec_device * mltdev, mltprot_header *hdr, void *user_data)
{
  if (mlthdr_get_size (hdr) == 0x16)
    {
    DBG1 ("MLTREC_FLEXFOCUS_POS reply: status=%d, %d, %d, %d, %d\n",
	    mlthdr_get_extval1 (hdr),
	    mlthdr_get_extval2 (hdr),
	    mlthdr_get_ew0 (hdr), mlthdr_get_ew1 (hdr),
	  mlthdr_get_ew2 (hdr));
    }
  else
    {
    DBG0 ("Camera sends MLTREC_FLEXFOCUS_POS reply of unknown size %d\n",
	  mlthdr_get_size (hdr));
    }
}

/* MLTREC_FLEX_AESPOT 0x1027 */
int
mltrec_flex_aespot (mltrec_device * mltdev, uint16_t unknown)
{
uint8_t *hdr;
  hdr = malloc (14);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_FLEX_AESPOT\n");
  mlthdr_set_extval1 (hdr, unknown);
  mltprot_submit_command (mltdev, hdr, MLTREC_FLEX_AESPOT, 14, NULL, NULL);
  return 0;
}

/* MLTREC_CLOCK_SET 0x1028 */
/* FIXME: verify second and tick */
int
mltrec_clock_set (mltrec_device * mltdev, uint16_t year, uint8_t month,
		  uint8_t day, uint8_t hour, uint8_t minute,
		  uint8_t second, uint8_t tick)
{
uint8_t *hdr;
  hdr = malloc (0x14);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_CLOCK_SET\n");
  mlthdr_set_year (hdr, year);
  mlthdr_set_month (hdr, month);
  mlthdr_set_day (hdr, day);
  mlthdr_set_hour (hdr, day);
  mlthdr_set_minute (hdr, minute);
  mlthdr_set_second (hdr, second);
  mlthdr_set_tick (hdr, tick);
  mltprot_submit_command (mltdev, hdr, MLTREC_CLOCK_SET, 0x14, NULL, NULL);
  return 0;
}

/* MLTREC_REMOTE_START2 0x1029 */
int
mltrec_remote_start2 (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_REMOTE_START2\n");
 mltprot_submit_command (mltdev, hdr, MLTREC_REMOTE_START2, 12, mltrec_remote_start2_c, NULL);
  return 0;
}
void
mltrec_remote_start2_c (mltrec_device * mltdev, mltprot_header *hdr, void *user_data)
  {
    if (mlthdr_get_size (hdr) == 0x16)
      {
    DBG1 ("MLTREC_REMOTE_START2 reply: status=%d, %d, %d, %d, %d\n",
	    mlthdr_get_extval1 (hdr),
	    mlthdr_get_extval2 (hdr),
	    mlthdr_get_ew0 (hdr), mlthdr_get_ew1 (hdr),
	  mlthdr_get_ew2 (hdr));
      }
  else
    {
    DBG0 ("Camera sends MLTREC_REMOTE_START2 reply of unknown size %d\n",
	  mlthdr_get_size (hdr));
    }
}

/* MLTREC_WB_MODE 0x102a */
int
mltrec_wb_mode (mltrec_device * mltdev, uint16_t unknown1, uint16_t unknown2)
{
uint8_t *hdr;
  hdr = malloc (16);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_WB_MODE\n");
  mlthdr_set_extval1 (hdr, unknown1);
  mlthdr_set_extval2 (hdr, unknown2);
 mltprot_submit_command (mltdev, hdr, MLTREC_WB_MODE, 16, NULL, NULL);
  return 0;
}

/* MLTREC_PREVIEW_GET 0x102b */
/* For getting preview in instant playback mode. */
int
mltrec_preview_get (mltrec_device * mltdev)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_PREVIEW_GET\n");
 mltprot_submit_command (mltdev, hdr, MLTREC_PREVIEW_GET, 16, mltrec_preview_get_c, NULL);
  return 0;
}
void
mltrec_preview_get_c (mltrec_device * mltdev, mltprot_header *hdr, void *user_data)
{
  uint32_t size;
  DBG1
    ("MLTREC_PREVIEW_GET reply: status=%d, %d, width: %d, height: %d\n",
     mlthdr_get_extval1 (hdr),
     mlthdr_get_extval2 (hdr), mlthdr_get_ew0 (hdr),
     mlthdr_get_ew1 (hdr));

  size = mlthdr_get_preview_size (hdr);
  DBG1 ("MLTREC_PREVIEW_GET image size: %d\n", size);
  /* FIXME: define special callback for preview? Probably useful. */
  mltdev->preview_callback(mlthdr_imgdata (hdr), size, mltdev->live_user_data);
}

/* MLTREC_WB_POINT 0x102c */
int
mltrec_wb_point (mltrec_device * mltdev, uint16_t unknown1,
		 uint16_t unknown2, uint16_t unknown3, uint16_t unknown4)
{
uint8_t *hdr;
  hdr = malloc (0x14);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_WB_POINT\n");
  mlthdr_set_extval1 (hdr, unknown1);
  mlthdr_set_extval2 (hdr, unknown2);
  mlthdr_set_ew0 (hdr, unknown3);
  mlthdr_set_ew1 (hdr, unknown4);
 mltprot_submit_command (mltdev, hdr, MLTREC_WB_POINT, 0x14, mltrec_wb_point_c, NULL);
  return 0;
}
void
mltrec_wb_point_c (mltrec_device * mltdev, mltprot_header *hdr, void *user_data)
{
  if (mlthdr_get_size (hdr) == 0x14)
    {
    DBG1
      ("MLTREC_WB_POINT reply: %d, %d, %d, %d\n",
       mlthdr_get_extval1 (hdr),
       mlthdr_get_extval2 (hdr), mlthdr_get_ew0 (hdr),
       mlthdr_get_ew1 (hdr));
    }
  else
    {
    DBG0 ("Camera sends MLTREC_WB_POINT reply of unknown size %d\n",
	  mlthdr_get_size (hdr));
    }
}

/* MLTREC_FLEXMAG_POS 0x102d */
int
mltrec_flexmag_pos (mltrec_device * mltdev, uint16_t unknown1,
		    uint16_t unknown2, uint16_t unknown3, uint16_t unknown4)
{
uint8_t *hdr;
  hdr = malloc (0x14);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_FLEXMAG_POS\n");
  mlthdr_set_extval1 (hdr, unknown1);
  mlthdr_set_extval2 (hdr, unknown2);
  mlthdr_set_ew0 (hdr, unknown3);
  mlthdr_set_ew1 (hdr, unknown4);
  mltprot_submit_command (mltdev, hdr, MLTREC_FLEXMAG_POS, 0x14, mltrec_flexmag_pos_c, NULL);
  return 0;
}
void
mltrec_flexmag_pos_c (mltrec_device * mltdev, mltprot_header *hdr, void *user_data)
{
  if (mlthdr_get_size (hdr) == 0x16)
    {
    DBG1 ("MLTREC_FLEXMAG_POS reply: %d, %d, %d, %d, %d\n",
	    mlthdr_get_extval1 (hdr),
	    mlthdr_get_extval2 (hdr),
	    mlthdr_get_ew0 (hdr), mlthdr_get_ew1 (hdr),
	  mlthdr_get_ew2 (hdr));
    }
  else
    {
    DBG0 ("Camera sends MLTREC_FLEXMAG_POS reply of unknown size %d\n",
	  mlthdr_get_size (hdr));
    }
}

/* MLTREC_INTERVAL_CTL 0x102e */
/* FIXME: where to place 1 */
int
mltrec_interval_start (mltrec_device * mltdev, uint16_t unknown)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_INTERVAL_CTL (start)\n");
 mlthdr_set_extval1 (hdr, 1);
 mlthdr_set_extval2 (hdr, unknown);
 mltprot_submit_command (mltdev, hdr, MLTREC_INTERVAL_CTL, 16, NULL, NULL);
 /* FIXME: set capture_serial, too? */
  return 0;
}
/* FIXME: where to place 0 */
int
mltrec_interval_stop (mltrec_device * mltdev, uint16_t unknown)
{
uint8_t *hdr;
  hdr = malloc (12);
  if (!hdr)
    return 1;

  DBG1 ("Submitting MLTREC_INTERVAL_CTL (stop)\n");
 mlthdr_set_extval1 (hdr, 0);
 mlthdr_set_extval2 (hdr, unknown);
 mltprot_submit_command (mltdev, hdr, MLTREC_INTERVAL_CTL, 16, NULL, NULL);
  return 0;
}

/* MLTREC_UNKNOWN_1100 0x1100 */

/* FIXME: Write it better, different file. */
char *
mltrec_settings_to_text (uint32_t setting)
{
  char *itemname;
      switch (setting)
	{
	case 0x00000000:
	  itemname = "Exposure Mode";
	  break;
	case 0x00000001:
	  itemname = "Flash Mode";
	  break;
	case 0x00000002:
	  itemname = "WB Mode";
	  break;
	case 0x00000003:
	  itemname = "Size";
	  break;
	case 0x00000004:
	  itemname = "Quality";
	  break;
	case 0x00000005:
	  itemname = "Drive";
	  break;
	case 0x00000006:
	  itemname = "Metering Mode";
	  break;
	case 0x00000007:
	  itemname = "Film Speed";
	  break;
	case 0x00000008:
	  itemname = "Shutter Speed";
	  break;
	case 0x00000009:
	  itemname = "Aperture Value";
	  break;
	case 0x0000000a:
	  itemname = "Focus Mode";
	  break;
	case 0x0000000b:
	  itemname = "Macro Mode";
	  break;
	case 0x0000000f:
	  itemname = "Exposure Compensatin";
	  break;
	case 0x00000010:
	  itemname = "Instant Playback Mode";
	  break;
	case 0x00000011:
	  itemname = "Bracketing Step";
	  break;
	case 0x00000015:
	  itemname = "Folder Serial Number";
	  break;
	case 0x00000016:
	  itemname = "File # Memory";
	  break;
	case 0x00000019:
	  itemname = "Subject Program";
	  break;
	case 0x0000001b:
	  itemname = "Focal Distance";
	  break;
	case 0x0000001d:
	  itemname = "Color Mode";
	  break;
	case 0x0000001f:
	  itemname = "Flash Compensation";
	  break;
	case 0x00000024:
	  itemname = "??? after or before settings get";
	  break;
	case 0x00000025:
	  itemname = "Battery Status";
	  break;
	case 0x00000026:
	  itemname = "3D Focus Mode";
	  break;
	case 0x00000027:
	  itemname = "Flex Focus Point X";
	  break;
	case 0x00000028:
	  itemname = "Flex Focus Point Y";
	  break;
	case 0x0000002d:
	  itemname = "???8 after focus lock, 0 after close";
	  break;
	case 0x0000002e:
	  itemname = "Saturation";
	  break;
	case 0x0000002f:
	  itemname = "Contrast";
	  break;
	case 0x00000030:
	  itemname = "Maximal Aperture";
	  break;
	case 0x00000034:
	  itemname = "Flash is Up";
	  break;
	case 0x00000035:
	  itemname = "Images to Capture";
	  break;
	case 0x00000036:
	  itemname = "??? 1 after focus lock, 0 after close";
	  break;
	case 0x00000037:
	  itemname = "Flash Metering Mode";
	  break;
	case 0x00000038:
	  itemname = "Sharpness";
	  break;
	case 0x00000039:
	  itemname = "??? 272 or 16 after mltrec capture";
	  break;
	case 0x0000003f:
	  itemname = "Focus ??? (notify?)";
	  break;
	case 0x00000040:
	  itemname = "Single Time Focus";
	  break;
	case 0x00000044:
	  itemname = "File Number";
	  break;
	case 0x00000046:
	  itemname = "Flash Charge";
	  break;
	case 0x0000004c:
	  itemname = "Folder Name Date";
	  break;
	case 0x0000004d:
	  itemname = "Color Filter";
	  break;
	case 0x0000004e:
	  itemname = "BW Color Filter";
	  break;
	case 0x00000053:
	  itemname = "WB ???";
	  break;
	case 0x00000055:
	  itemname = "Flex Spot in Center Point";
	  break;
	default:
	  itemname = "UNKNOWN";
	  break;
	}
      return itemname;
}

