using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Fiesta.FileFormats
{
	public class SHBD
	{
		public Int32 xSize;
		public Int32 ySize;
		public byte[] content;

		public static SHBD Load(string path, bool readHeader = true)
		{
			return Load(File.ReadAllBytes(path), readHeader);
		}

		public static SHBD Load(byte[] data, bool readHeader = true)
		{
			SHBD shbd = new SHBD();

			using (MemoryStream memoryStream = new MemoryStream(data))
			using (BinaryReader binaryReader = new BinaryReader(memoryStream))
			{
				if (readHeader)
				{
					shbd.xSize = binaryReader.ReadInt32();
					shbd.ySize = binaryReader.ReadInt32();
				}

				shbd.content = binaryReader.ReadBytes(shbd.xSize * shbd.ySize);
			}

			shbd.Decompress();

			return shbd;
		}

		public void Compress()
		{
			
		}
		
		public void Decompress()
		{


			/*
			Int32 numOfImages = 8;
			Int32 bytesPerPixel = 1;

			Int32 imageRowSize = (xSize * bytesPerPixel);

			byte[] newContent = new byte[content.Length];

			Int32 imageInx = 0;
			
			Int32 numOfImages = 8;
			Int32 bytesPerPixel = 1;

			Int32 imageRowSize = (xSize * bytesPerPixel);

			byte[] newContent = new byte[content.Length];

			Int32 imageInx = 0;
			
			while (imageInx < numOfImages)
			{
				Int32 baseOffset = (imageRowSize * imageInx);

				Int32 rowInx = 0;
				for (Int32 i = 0; i < (imageRowSize * xSize); i += bytesPerPixel)
				{
					if (i > 0 && (i % imageRowSize) == 0)
					{
						baseOffset += (imageRowSize * (numOfImages - 1));

						rowInx++;
					}

					byte value = content[baseOffset + (i % imageRowSize)];

					if (bytesPerPixel > 1)
					{
						for (Int32 x = 1; x < bytesPerPixel; x++)
						{
							value |= content[(baseOffset + i + x)];
						}
					}

					//newContent[(i * numOfImages) + imageInx] = value;
					newContent[((imageRowSize * numOfImages) * rowInx) + (((numOfImages - 1) - imageInx) * imageRowSize) + (i % imageRowSize)] |= value;
				}

				imageInx++;
			}

			content = newContent;
			*/
		}

		public void Save(string path, bool writeHeader = false)
		{
			using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
			using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
			{
				if (writeHeader)
				{
					binaryWriter.Write(xSize);
					binaryWriter.Write(ySize);
				}

				binaryWriter.Write(content);
			}
		}

		public SHBD Import(string path, ImageFormat imageFormat, bool generateHeader = true)
		{
			return Import(Image.FromFile(path), imageFormat, generateHeader);
		}

		public SHBD Import(Image image, ImageFormat imageFormat, bool generateHeader = true)
		{
			SHBD shbd = new SHBD();

			using (MemoryStream memoryStream = new MemoryStream())
			{
				image.Save(memoryStream, imageFormat);

				byte[] content = memoryStream.ToArray();

				if (generateHeader)
				{
					this.xSize = image.Width;
					this.ySize = this.xSize * 8;
				}

				this.content = content;
			}

			return shbd;
		}

		public Bitmap Export()
		{
			File.WriteAllBytes(@"D:\Games\Fiesta\CN_Mix\resmap\field\Eld\Eld.shbd.raw", content);

			//Bitmap bitmap = new Bitmap((xSize * 8), (xSize * 8), PixelFormat.Format1bppIndexed);
			Bitmap bitmap = new Bitmap((xSize * 8), (xSize * 8), PixelFormat.Format1bppIndexed);
			//Bitmap bitmap = new Bitmap((xSize * 1), (xSize * 1), PixelFormat.Format8bppIndexed);
			BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);

			Int32 size = bitmapData.Stride * bitmapData.Height;

			Marshal.Copy(content, 0, bitmapData.Scan0, content.Length);

			bitmap.UnlockBits(bitmapData);
			
			return bitmap;
		}

		public void Export(string path, ImageFormat imageFormat)
		{
			Bitmap bitmap = Export();

			bitmap.Save(path, imageFormat);
		}
	}
}