/*
 *
 *    soniK digital audio editor
 *    Copyright (C) 2003-2006  Robert Walker <rob@tenfoot.org.uk>
 *
 *    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
 *
 */
#ifndef SONIK_TYPES_H
#define SONIK_TYPES_H

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "sonik_autobuffer.h"

#include <kdebug.h>

#include <qvaluevector.h>

#include <sys/types.h>
#include <stdint.h>
#include <math.h>

#include <ostream>

namespace Sonik
{
  // Real samples
  typedef float   Sample;
  typedef int8_t  Sample8;
  typedef int16_t Sample16;
  typedef int32_t Sample24;

  typedef auto_buffer<Sample>      SampleBuffer;
  typedef auto_buffer<Sample8>     Sample8Buffer;
  typedef auto_buffer<Sample16>    Sample16Buffer;
  typedef auto_buffer<Sample24>    Sample24Buffer;

  typedef auto_buffer_2d<Sample>   SampleSegment;
  typedef auto_buffer_2d<Sample8>  Sample8Segment;
  typedef auto_buffer_2d<Sample16> Sample16Segment;
  typedef auto_buffer_2d<Sample24> Sample24Segment;

  // Sample format ranges
  // TODO: handle systems without lrintf
  template <typename T> struct SampleTraits
  {
    static const float    range()        { return 0.0f; }
    static const int      min()          { return 0; }
    static const int      max()          { return 0; }
    static const int      zero()         { return 0; }
    static const int      cast(Sample x) { return 0; }
  };

  template<> struct SampleTraits<Sample>
  {
    static const float    range()        { return 1.0f; }
    static const Sample   min()          { return -1; }
    static const Sample   max()          { return 1; }
    static const Sample   zero()         { return 0.0f; }
    static const Sample   cast(Sample x) { return x; }
  };

  template<> struct SampleTraits<Sample8>
  {
    static const float    range()        { return 128.0f; }
    static const Sample8  min()          { return -128; }
    static const Sample8  max()          { return 127; }
    static const Sample8  zero()         { return 0; }
    static const Sample8  cast(Sample x) { return (Sample8)lrintf(x*range()); }
  };

  template<> struct SampleTraits<Sample16>
  {
    static const float    range()        { return 32768.0f; }
    static const Sample16 min()          { return -32768; }
    static const Sample16 max()          { return 32767; }
    static const Sample16 zero()         { return 0; }
    static const Sample16 cast(Sample x) { return (Sample16)lrintf(x*range()); }
  };

  template<> struct SampleTraits<Sample24>
  {
    static const float    range()        { return 8388608.0f; }
    static const Sample24 min()          { return -8388608; }
    static const Sample24 max()          { return 8388607; }
    static const Sample24 zero()         { return 0; }
    static const Sample24 cast(Sample x) { return (Sample24)lrintf(x*range()); }
  };

  // Wave format
  struct Format
  {
    Format(uint8_t _channels = 0, uint32_t _sampleRate = 0, uint8_t _bits = 0)
      : channels(_channels), sampleRate(_sampleRate), bits(_bits) { }

    uint8_t  channels;
    uint32_t sampleRate;
    uint8_t  bits;
  };

  std::ostream& operator<<(std::ostream& s, const Format& fmt);
  kdbgstream& operator<<(kdbgstream& s, const Format& fmt);
  kndbgstream& operator<<(kndbgstream& s, const Format& fmt);

  // IO result codes
  enum IOResult { kSuccess,
                  kReadError, kWriteError,
                  kFileNotFound, kPermissionDenied, kFileFormat,
                  kDeviceError, kDeviceFormat };

  typedef QValueVector<uint8_t> ChannelSeq;

  enum TimeFormat  { kH_M, kH_M_S, kH_M_S_Ms, kSamples, kMs,
                     kH_M_S_FCDDA, kH_M_S_FPAL, kH_M_S_FNTSC };

  enum ValueFormat
  {
    kNormalised,
    kValue,
    kValueDB,
    kFreq
  };

  enum InsertPosition
  {
    kInsertStart, kInsertCursor, kInsertEnd,
    kOverwriteCursor, kReplaceSelection, kReplaceAll
  };

  typedef QValueVector<QString> QStringVector;
}

#endif // SONIK_TYPES_H
