/***************************************************************************
    copyright            : (C) 2003 by Arnold Krille
    email                : arnold@arnoldarts.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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; version 2 of the License.               *
 *                                                                         *
 ***************************************************************************/

#ifndef KRECFILE_H
#define KRECFILE_H

#include <tqobject.h>
#include <tqstring.h>
#include <tqvaluelist.h>

#include <arts/common.h>

class KRecBuffer;
class KTempDir;
class TDESimpleConfig;
class TQFile;
class KRecFileViewWidget;

class KRecFile : virtual public TQObject {
   TQ_OBJECT
  
	friend class KRecFileWidget;
public:
	KRecFile( TQObject*, const char* =0 );
	KRecFile( const TQString &, TQObject*, const char* =0 );
	~KRecFile();

	TQString filename();
	void filename( const TQString &);

	bool saved() const { return _saved; }
	int samplerate() const { return _samplerate; }
	int channels() const { return _channels; }
	int bits() const { return _bits; }

	TQIODevice::Offset offsetSize() const { return samplesToOffset( _size ); }
	TQIODevice::Offset offsetPosition() const { return samplesToOffset( _pos ); }

	int size() const { return _size; }
	int position() const { return _pos; }

	/// Calculates an offset into a frames-value depending on the files settings (channels and bits)
	int offsetToSamples( TQIODevice::Offset ) const;
	TQIODevice::Offset samplesToOffset( int ) const;
public slots:
	/// Creates a new empty buffer and marks it for recording.
	void newBuffer();

	/// Deletes the buffer from the file.
	void deleteBuffer( KRecBuffer* =0 );

	void writeData( Arts::mcopbyte* data, uint length );
	void writeData( TQByteArray* );
	void writeData( TQByteArray& );

	void save( const TQString & );
	void exportwave( const TQString & );

	/// Fills a TQByteArray with values from the specified Offset.
	TQByteArray* getData( int );

	void getData( TQByteArray& );

	void newPos( int );

private slots:
	void newPos( KRecBuffer*, TQIODevice::Offset );
	void newSize( KRecBuffer*, TQIODevice::Offset );
signals:
	/// Position signals
	void posChanged( int );
	void sizeChanged( int );
	/// The end of the file is reached, you should stop reading.
	void endReached();

	/// GUI-Signals
	void sNewBuffer( KRecBuffer* );
	void sDeleteBuffer( KRecBuffer* );

	void filenameChanged( const TQString & );
private:
	void saveProps();
	void loadProps();
	/**
		Creates a new buffer for a given file
		@param filename Name of the file
	*/
	void newBuffer( const TQString &filename );
	/**
		Adds buffer to the buffers.
		@param buffer The to be added buffer
	*/
	void newBuffer( KRecBuffer* buffer );

	/// Get the top-most-buffer at the specified position.
	int getTopBuffer_int( int );
	KRecBuffer* getTopBuffer_buffer( int );

	bool _saved;
	TQString _filename;
	int _samplerate, _channels, _bits;
	int _currentBuffer;
	TQValueList<KRecBuffer*> _buffers;
	KTempDir *_dir;
	TDESimpleConfig *_config;
	int _pos, _size;

	void init();
};

class TQFile;
class TQDir;
class TQFileInfo;
class TDEConfig;
class TQDataStream;

class KRecBuffer : virtual public TQObject {
   TQ_OBJECT
  
public:
	KRecBuffer( const TQString &, int, bool, KRecFile*, const char* =0 );
	~KRecBuffer();

	// After how many samples in the File this Buffer starts...
	int startpos() const;

	TQIODevice::Offset size() const;
	int sizeInSamples() const { return _krecfile->offsetToSamples( size() ); }

	/**
		Writes out its Config
		It doesn't set the group.
		@param config the TDEConfig where the data gets written
	*/
	void writeConfig( TDEConfig* config );

	/**
		restores a KRecBuffer from Config
		The group has to be set the right way.
		@param config The configuration thats read
		@param dir The directory where the file is saved
	*/
	static KRecBuffer* fromConfig( TDEConfig* config, TQDir* dir, KRecFile* p, const char* n=0 );

	TQString filename() const;

	bool active() const;

	TQString title() const;
	TQString comment() const;
public slots:
	/// writes the data into the buffer
	void writeData( Arts::mcopbyte* data, uint length );
	void writeData( TQByteArray* );
	void writeData( TQByteArray& );
	/// gets the data from the stream
	void getData( TQByteArray& );

	void setPos( TQIODevice::Offset );

	void setActive( bool );

	void deleteBuffer();

	void setTitle( const TQString & );
	void setComment( const TQString & );

	/// Returns the sample at the specified position and channel.
	float getSample( int pos, int channel );
	float* getsamples( int start, int end, int channel );
signals:
	void posChanged( KRecBuffer*, TQIODevice::Offset );
	void sizeChanged( KRecBuffer*, TQIODevice::Offset );
	void activeChanged( bool );

	/// Is emitted when something has changed.
	void somethingChanged();

	void deleteSelf( KRecBuffer* );
private:
	KRecFile* _krecfile;
	TQFile* _file;
	TQDataStream* _stream;
	TQFileInfo* _fileinfo;
	bool _open, _active;
	TQIODevice::Offset _pos;
	int _start;
	TQString _title, _comment;
};

#endif
