#pragma once

#include "../Base.h"
#include "../File.h"
#include <Resource/Sound.h>
#include <Encoding/LZMA.h>

namespace gorgon {

	class Sound;

	Sound *LoadSound(Base *parent, File &File, std::istream &Data, int Size);

	class Sound : public gge::resource::Sound, public gorgon::Base {
	public:

		Sound() : Compression(LZMA) {}

		enum Compressor {
			Uncompressed=0,
			LZMA=gge::resource::GID::LZMA,
		} Compression;


		gge::Byte *GetData() {
			return &Data[0];
		}

		virtual void Save(std::ostream &out) {
			auto start=WriteObjectStart(out, *this);


			auto propstart=WriteSectionStart(out, gge::resource::GID::Sound_Props);

			WriteTo(out, Size);
			WriteTo(out, Format.Channels);
			WriteTo(out, Format.BlockAlign);
			WriteTo(out, Format.BitsPerSample);
			WriteTo(out, Format.SamplesPerSec);
			WriteTo(out, Format.AvgBytesPerSec);
			WriteTo(out, Format.FormatTag);

			WriteEnd(out, propstart);


			if(Compression==Uncompressed) {
				auto datastart=WriteSectionStart(out, gge::resource::GID::Sound_Wave);

				out.write((char*)(&Data[0]), Size);

				WriteEnd(out, datastart);
			}
			else if(Compression==LZMA) {
				auto propstart=WriteSectionStart(out, gge::resource::GID::Sound_Cmp_Props);
				WriteTo(out, (int)Compression);
				WriteEnd(out, propstart);

				auto datastart=WriteSectionStart(out, gge::resource::GID::Sound_Cmp_Wave);
				gge::encoding::Lzma.Encode(Data, out);
				WriteEnd(out, datastart);
			}

			WriteEnd(out, start);
		}

		void SetData(const gge::Byte *data, int size) {
			Data.resize(size);
			std::copy(data, data+size, Data.begin());;
			Size=size;
		}

		void SetCompression(Compressor compression) {
			Compression=compression;
		}

		Compressor GetCompression() const {
			return Compression;
		}

		virtual GID::Type GetGID() const {
			return gge::resource::Sound::GetGID();
		}

		virtual void Prepare(gge::GGEMain &main, File &file) {
			Prepare();
		}

		void Prepare() {
			gge::resource::Sound::Prepare();
		}

	protected:
		gge::resource::File dummy;
	};

}
