// ----------------------------------------------------------------------------
//
//  Copyright (C) 2003-2013 Fons Adriaensen <fons@linuxaudio.org>
//    
//  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 3 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/>.
//
// ----------------------------------------------------------------------------


#ifndef __IMPDATA_H
#define __IMPDATA_H


#include <stdio.h>
#include <sndfile.h>
#include "itypes.h"


class Impdata
{
public:

    enum
    {
        TYPE_RAW     = 0x00010000,
	TYPE_SWEEP   = 0x00020002,
	TYPE_LR      = 0x00030002,
	TYPE_MS      = 0x00040002,
        TYPE_AMB_A   = 0x00050004,
        TYPE_AMB_B3  = 0x00060003,
        TYPE_AMB_B4  = 0x00070004,
	TYPE__CHAN   = 0x0000ffff,
	TYPE__TYPE   = 0xffff0000
    };

    enum
    {
        ERR_NONE    = 0,
	ERR_MODE    = -1,
	ERR_DATA    = -2,
	ERR_OPEN    = -3,
	ERR_FORM    = -4,
	ERR_SEEK    = -5,
	ERR_READ    = -6,
	ERR_WRITE   = -7
    };

    enum
    {
        MODE_NONE   = 0,
	MODE_READ   = 1,
	MODE_WRITE  = 2
    };

    Impdata (void);
    ~Impdata (void);

    U32 mode (void) const { return _mode; }
    U32 vers (void) const { return _vers; }
    U32 type (void) const { return _type; }
    U32 rate_n (void) const { return _rate_n; }
    U32 rate_d (void) const { return _rate_d; }
    U32 n_chan (void) const { return _type & TYPE__CHAN; }
    U32 n_fram (void) const { return _n_fram; }
    U32 n_sect (void) const { return _n_sect; }
    U32 i_fram (void) const { return _i_fram; }
    U32 i_sect (void) const { return _i_sect; }
    S32 tref_i (void) const { return _tref_i; }
    U32 tref_n (void) const { return _tref_n; }
    U32 tref_d (void) const { return _tref_d; }

    int  set_type (U32 type);
    int  set_n_fram (U32 n_fram);
    int  set_n_sect (U32 n_sect);
    void set_rate (U32 rate_n, U32 rate_d = 1) { _rate_n = rate_n; _rate_d = rate_d; }
    void set_tref (S32 i, U32 n = 0, U32 d = 1) { _tref_i = i; _tref_n = n; _tref_d = d; }
    void set_bits (U32 bits) { _bits = bits; }
 
    double drate (void) const { return (double) _rate_n / (double) _rate_d; }
    double dtref (void) const { return (double) _tref_n / (double) _tref_d + _tref_i; }

    float *data (int c) const { return _data  ? (_data + c) : 0; }

    int alloc (void);
    int deall (void);
    int clear (void);

    int open_read (const char *name);
    int open_write (const char *name);
    int sf_open_read (const char *name);
    int sf_open_write (const char *name);
    int close (void);

    int read_sect  (U32 i_sect);
    int write_sect (U32 i_sect);
    
    int locate (U32 i_sect);
    int read_ext  (U32 k, float *p);     
    int write_ext (U32 k, float *p);     

    static void checkext (char *name);
    static const char *channame (U32 type, U32 chan);

private:

    U32       _vers;
    U32       _type;
    U32       _rate_n;
    U32       _rate_d;
    U32       _n_fram;
    U32       _n_sect;
    S32       _tref_i;
    U32       _tref_n;
    U32       _tref_d;
    U32       _bits;

    U32       _i_fram;
    U32       _i_sect;
    U32       _mode;
    U32       _size;
    float    *_data;
    FILE     *_aldfile;
    SNDFILE  *_sndfile;

    static U32 mapvers1 (U32 type);

    static char _suffix [12];
    static const char *_suffix2 [2];
    static const char *_suffix3 [2];
    static const char *_suffix4 [2];
    static const char *_suffix5 [4];
    static const char *_suffix7 [4];
};


#endif

