/*
 *  libMirage: B6T image
 *  Copyright (C) 2007-2026 Rok Mandeljc
 *
 *  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, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#pragma once

#include "mirage/config.h"
#include <mirage/mirage.h>

#include <glib/gi18n-lib.h>

#include "parser.h"

G_BEGIN_DECLS


typedef enum
{
    UNKNOWN = 0x0000, /* No Media */
    NRDISC = 0x0001, /* Non removable disc */
    RMDISC = 0x0002, /* Removable Disc */
    MOE = 0x0003, /* Magneto Optical Erasable */
    OPTICWO = 0x0004, /* Optical Write Once */
    ASMO = 0x0005, /* Advanced Storage - Magneto Optical */
    CDROM = 0x0008, /* CD-ROM (not writable) */
    CDR = 0x0009, /* CD-R (Write once) */
    CDRW = 0x000A, /* CD-RW (R/W) */
    DVDROM = 0x0010, /* DVD-ROM (not writable) */
    DVDR = 0x0011, /* DVD-R */
    DVDRAM = 0x0012, /* DVD-RAM */
    DVDRW = 0x0013, /* DVD-RW Restricted overwrite */
    DVDRWSEQ = 0x0014, /* DVD-RW Sequential Recording */
    DLDVDR = 0x0015,  /* Dual Layer DVD-R */
    DLDVDRJMP = 0x0016, /* Dual Layer DVD-R Jump Recording */
    DVDPLUSRW = 0x001A, /* DVD+RW */
    DVDPLUSR = 0x001B, /* DVD+R */
    DDCDROM = 0x0020, /* Double Density CD-ROM */
    DDCDR = 0x0021, /* Double Density CD-R (Write once) */
    DDCDRW = 0x0022, /* Double Density CD-RW */
    DLDVDPLUSRW = 0x002A, /* Dual Layer DVD+RW */
    DLDVDPLUSR = 0x002B, /* Dual Layer DVD+R */
    BDROM = 0x0040, /* BluRay Disc ROM (not writable) */
    BDR = 0x0041, /* BluRay Disc Sequential Recording */
    BDRE = 0x0042, /* BluRay Disc Random Recording */

    HDBURNCDROM = 0x0080, /* HDBurn CD-R */
    HDBURNCDR = 0x0081, /* HDBurn CD-R */
    HDBURNCDRW = 0x0082, /* HDBurn CD-RW */

    NODEVICE = 0xFFFE,
    CUSTOM = 0xFFFF /* doesn't conform to any standard media */
} B6T_MediaType;



#pragma pack(1)

/* This is the first chunk of data that follows the signature; it consists of
 * 112 bytes that are more or less undeciphered, but it seems to contain lengths
 * of other blocks at the end */
typedef struct
{
    guint32 __dummy1__; /* Default value: 0x00000002 */
    guint32 __dummy2__; /* Default value: 0x00000002 */
    guint32 __dummy3__; /* Default value: 0x00000006 */
    guint32 __dummy4__; /* Default value: 0x00000000 */

    guint32 __dummy5__; /* Default value: 0x00000000 */
    guint32 __dummy6__; /* Default value: 0x00000000 */
    guint32 __dummy7__; /* Default value: 0x00000000 */
    guint32 __dummy8__; /* Default value: 0x00000000 */

    guint16 disc_type; /* 0x08 is CD-ROM, 0x10 is DVD-ROM; it seems to be
                        * equivalent to current profile from GET CONFIGURATION */
    guint16 num_sessions; /* Number of sessions */
    guint32 __dummy9__; /* Default value: 0x00000002 */
    guint32 __dummy10__; /* Default value: 0x00000000 */
    guint32 __dummy11__; /* Default value: 0x00000000 */

    guint8 mcn_valid;
    gchar mcn[13];
    guint8 __dummy12__;
    guint8 __dummy13__;

    guint32 __dummy14__; /* Default value: 0x00000000 */
    guint32 __dummy15__; /* Default value: 0x00000000 */
    guint32 __dummy16__; /* Default value: 0x00000000 */
    guint32 __dummy17__; /* Default value: 0x00000000 */

    guint16 pma_data_length; /* PMA data length, as read by READ TOC/PMA/ATIP, format 3 */
    guint16 atip_data_length; /* ATIP data length, as read by READ TOC/PMA/ATIP, format 4 */
    guint16 cdtext_data_length; /* CD-TEXT data length; read by READ TOC/PMA/ATIP, format 5 */
    guint16 cdrom_info_length; /* Length of block which seemingly contains additional info about disc (CD-ROM) */
    guint32 dvdrom_bca_length; /* BCA length for DVD-ROM */
    guint32 __dummy19__; /* Default value: 0x00000000 */

    guint32 __dummy20__; /* Default value: 0x00000000 */
    guint32 __dummy21__; /* Default value: 0x00000000 */
    guint32 dvdrom_structures_length; /* Disc structures data length for DVD-ROM */
    guint32 dvdrom_info_length; /* Same as cdrom_info_length above, but for DVD-ROM */
} B6T_DiscBlock_1;

/* This is chunk of bytes that represents lengths of blocks that follow... */
typedef struct
{
    guint32 mode_page_2a_length; /* Length of Mode Page 0x2A */
    guint32 unknown1_length; /* Unknown; seems to be always 4 bytes? */
    guint32 datablocks_length; /* Length of data-blocks data */
    guint32 sessions_length; /* Length of sessions data */
    guint32 dpm_data_length; /* Length of internal DPM data */
} B6T_DiscBlock_2;


/* Drive identifiers, taken from INQUIRY data */
typedef struct
{
    gchar vendor[8];
    gchar product[16];
    gchar revision[4];
    guint8 vendor_specific[20]; /* note: may not be a valid string */
} B6T_DriveIdentifiers;

/* Structure that represents data block... I think the idea behind them is similar
 * to the idea behind fragments in libMirage... */
typedef struct
{
    guint32 type; /* In one way or another; different values here mean different type of data... */
    guint32 length_bytes; /* Length of data block, in bytes */
    guint32 __dummy1__;
    guint32 __dummy2__;
    guint32 __dummy3__;
    guint32 __dummy4__;
    guint32 offset; /* Offset in image file */
    guint32 __dummy5__;
    guint32 __dummy6__;
    guint32 __dummy7__;
    gint32 start_sector; /* First sector for which the block holds data (signed integer!) */
    gint32 length_sectors; /* Length of data block, in sectors (also signed due to arithmetics!) */
    guint32 filename_length; /* Filename length */

    /* Fields below will have to be read separately */
    gchar *filename; /* Original filename is UTF-16, but we'll convert it... */
    guint32 __dummy8__;
} B6T_DataBlock;

/* Session descriptor; 16 bytes, more or less figured out */
typedef struct
{
    guint16 number; /* Session number */
    guint8 num_entries; /* Number of entries */
    guint8 __dummy1__; /* Not sure... seems to be fixed at 3... */

    gint32 session_start; /* Session start address */

    gint32 session_end; /* Session end address */

    guint16 first_track; /* First track in session */
    guint16 last_track; /* Last track in session */
} B6T_Session;

/* Generic track descriptor; this is 64-byte version, so in case this is 'real'
 * track descriptor, additional 8 bytes will have to be read manually */
typedef struct
{
    guint8 type; /* Track descriptor type */
    guint8 __dummy1__; /* Unknown; seems to be set to 1 for data and 0 to audio tracks */
    guint8 __dummy2__; /* Unknown; seems to be set to 1 for data and 0 to audio tracks */
    guint8 __dummy3__; /* Unknown; seems to be set to 1 for data and 0 to audio tracks */

    guint32 __dummy4__;

    guint8 subchannel; /* If set to 4, it means subchannel is present */
    guint8 __dummy5__;
    guint8 ctl;
    guint8 adr;

    guint8 point; /* Point */
    guint8 __dummy6__;
    guint8 min;
    guint8 sec;

    guint8 frame;
    guint8 zero;
    guint8 pmin;
    guint8 psec;

    guint8 pframe;
    guint8 __dummy7__;

    guint32 pregap; /* Pregap length */

    guint32 __dummy8__;
    guint32 __dummy9__;
    guint32 __dummy10__;
    guint32 __dummy11__;

    gint32 start_sector;
    gint32 length;

    guint32 __dummy12__;
    guint32 __dummy13__;
    guint32 session_number;

    guint16 __dummy14__;
} B6T_Track;

#pragma pack()


G_END_DECLS
