// -*- C++ -*- 
// $Id: field_impl.h,v 1.4 2002/06/29 14:43:00 t1mpy Exp $

// id3lib: a C++ library for creating and manipulating id3v1/v2 tags
// Copyright 1999, 2000  Scott Thomas Haug

// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Library General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This library 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 Library General Public License
// along with this library; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

// The id3lib authors encourage improvements and optimisations to be sent to
// the id3lib coordinator.  Please see the README file for details on where to
// send such submissions.  See the AUTHORS file for a list of people who have
// contributed to id3lib.  See the ChangeLog file for a list of changes to
// id3lib.  These files are distributed with id3lib at
// http://download.sourceforge.net/id3lib/

#ifndef _ID3LIB_FIELD_IMPL_H_
#define _ID3LIB_FIELD_IMPL_H_

#include <stdlib.h>
#include "field.h"
#include "id3/id3lib_strings.h"

struct ID3_FieldDef;
struct ID3_FrameDef;
class ID3_Frame;
class ID3_Reader;

class ID3_FieldImpl : public ID3_Field
{
  friend class ID3_FrameImpl;
public:
  ~ID3_FieldImpl();
  
  void Clear();

  size_t Size() const;
  size_t BinSize() const;
  size_t GetNumTextItems() const;

  // integer field functions
  ID3_Field&    operator= (uint32 val) { this->Set(val); return *this; }
  void          Set(uint32); // we have SetInteger functions. Why do we try to overload Set?
  uint32        Get() const; // same for GetInteger

  // text field functions
  dami::String  GetText(                    size_t index = 0, ID3_TextEnc enc = ID3TE_ISO8859_1 ) const;
  size_t        SetText( dami::String data, size_t index = 0, ID3_TextEnc enc = ID3TE_ISO8859_1 );

  // ASCII string field functions
  ID3_Field&    operator= (const char* s) { this->Set(s); return *this; }
  size_t        Set(const char* data);
  size_t        Get(char*, size_t) const;
  size_t        Get(char*, size_t, size_t) const;
  const char*   GetRawText() const;
  const char*   GetRawTextItem(size_t) const;
  size_t        Add(const char* data);

  // Unicode string field functions
  ID3_Field&    operator= (const unicode_t* s) { this->Set(s); return *this; }
  size_t        Set(const unicode_t*);
  size_t        Get(unicode_t *buffer, size_t) const;
  size_t        Get(unicode_t *buffer, size_t, size_t) const;
  const unicode_t* GetRawUnicodeText() const;
  const unicode_t* GetRawUnicodeTextItem(size_t) const;
  size_t        Add(const unicode_t*);

  // binary field functions
  size_t        Set(const uchar* buf, size_t size);
  size_t        Set(const char* buf, size_t size)
  {
    return this->Set(reinterpret_cast<const uchar *>(buf), size);
  }
  size_t        Get(uchar*, size_t) const;
  const uchar*  GetRawBinary() const;
  void          FromFile(const char*);
  void          ToFile(const char *sInfo) const;
  size_t        GetBinaryStartPosition();

  // miscelaneous functions
  ID3_Field&    operator=( const ID3_Field & );
  bool          InScope(ID3_V2Spec spec) const
  { return _spec_begin <= spec && spec <= _spec_end; }

  ID3_FieldID   GetID() const { return _id; }
  ID3_FieldType GetType() const { return _type; }
  bool          SetEncoding(ID3_TextEnc enc);
  ID3_TextEnc   GetEncoding() const { return _enc; }
  bool          IsEncodable() const { return (_flags & ID3FF_ENCODABLE) > 0; }
  

  void          Render(ID3_Writer&) const;
  bool          Parse(ID3_Reader&);
  bool          HasChanged() const;

private:
  size_t        GetRawTextItemLen( size_t index =0 ) const;

private:
  // To prevent public instantiation, the constructor is made private
  ID3_FieldImpl();
  ID3_FieldImpl(const ID3_FieldDef&);

  const ID3_FieldID   _id;          // the ID of this field
  const ID3_FieldType _type;        // what type is this field or should be
  const ID3_V2Spec    _spec_begin;  // spec end
  const ID3_V2Spec    _spec_end;    // spec begin
  const flags_t       _flags;       // special field flags
  mutable bool        _changed;     // field changed since last parse/render?

  dami::BString       _binary;      // for binary strings
  dami::String        _text;        // for all strings
  uint32              _integer;     // for numbers

  const size_t        _fixed_size;  // for fixed length fields (0 if not)
  size_t              _num_items;   // the number of items in the text string
  ID3_TextEnc         _enc;         // encoding for text fields

  uint32              _start_position;
protected:
  void          SetInteger(uint32);
  uint32        GetInteger() const;

  size_t        SetBinary(dami::BString);
  dami::BString GetBinary() const;

  void RenderInteger(ID3_Writer&) const;
  void RenderText(ID3_Writer&) const;
  void RenderBinary(ID3_Writer&) const;
  
  bool ParseInteger(ID3_Reader&);
  bool ParseText(ID3_Reader&);
  bool ParseBinary(ID3_Reader&);
  
};


// Ack! Not for public use
ID3_FrameDef *ID3_FindFrameDef(ID3_FrameID id);
ID3_FrameID   ID3_FindFrameID(const char *id);

#endif /* _ID3LIB_FIELD_H_ */

