using System;
using System.Collections;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Diagnostics;
using NUnit.Framework;

namespace Orciid.Media.Converters
{
	[TestFixture]
	public class TestJpeg2000Converter
	{
		private static Bitmap defaultbitmap;
		private static ArrayList tempfiles = new ArrayList();

		static TestJpeg2000Converter()
		{
			defaultbitmap = new Bitmap(128, 128, PixelFormat.Format24bppRgb);
			for (int x = 0; x < 128; x++)
				for (int y = 0; y < 128; y++)
					defaultbitmap.SetPixel(x, y, Color.FromArgb(x * 2, y * 2, x + y));
		}

		private static Bitmap GetTestBitmap()
		{
			return defaultbitmap.Clone() as Bitmap;
		}

		private static string GetTempFileName(string ext)
		{
			string target = Util.Tools.GetTempFileName(ext);
			tempfiles.Add(target);
			Debug.WriteLine("Created temporary file " + target);
			return target;
		}

		[SetUp]
		public void Setup()
		{
			Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
			Debug.AutoFlush = true;
		}

		[TearDown]
		public void Cleanup()
		{
			Debug.Listeners.Clear();
			while (tempfiles.Count > 0)
			{
				try
				{
					File.Delete(tempfiles[0] as string);
				}
				finally
				{
					tempfiles.RemoveAt(0);
				}
			}
		}

		[Test]
		public void TestBitmapToJpeg2000Conversion()
		{
			string tempfile = GetTempFileName("bmp");
			string testfile = GetTempFileName("jp2");
			using (Bitmap original = GetTestBitmap())
				original.Save(tempfile, ImageFormat.Bmp);
			Assert.IsTrue(MediaConverter.Convert(tempfile, testfile));
			Assert.IsTrue(File.Exists(testfile));
		}

		[Test]
		public void TestJpegToJpeg2000Conversion()
		{
			string tempfile = GetTempFileName("jpg");
			string testfile = GetTempFileName("jp2");
			using (Bitmap original = GetTestBitmap())
			{
				original.Save(tempfile, ImageFormat.Jpeg);
				Assert.IsTrue(MediaConverter.Convert(tempfile, testfile));
				Assert.IsTrue(File.Exists(testfile));
				Size dimensions = Jpeg2000Converter.GetDimensions(testfile);
				Assert.AreEqual(original.Width, dimensions.Height);
				Assert.AreEqual(original.Height, dimensions.Width);
			}
		}

		[Test]
		public void TestJpeg2000ToBitmapConversion()
		{
			string tempfile = GetTempFileName("bmp");
			string jp2tempfile = GetTempFileName("jp2");
			string testfile = GetTempFileName("bmp");
			// create original bitmap
			using (Bitmap original = GetTestBitmap())
			{
				original.Save(tempfile, ImageFormat.Bmp);
				// convert to JPEG2000
				Assert.IsTrue(MediaConverter.Convert(tempfile, jp2tempfile));
				Assert.IsTrue(File.Exists(jp2tempfile));
				// convert back to bitmap
				Assert.IsTrue(MediaConverter.Convert(jp2tempfile, testfile));
				Assert.IsTrue(File.Exists(testfile));
				// compare file contents
				using (Bitmap result = new Bitmap(testfile))
				{
					Assert.AreEqual(original.Height, result.Height);
					Assert.AreEqual(original.Width, result.Width);
					for (int y = 0; y < original.Height; y++)
						for (int x = 0; x < original.Width; x++)
							if (original.GetPixel(x, y) != result.GetPixel(x, y))
								Assert.Fail("Original and resulting bitmap are not equal");
				}
			}
		}

		[Test]
		public void TestResizeConversion()
		{
			string tempfile = GetTempFileName("bmp");
			string jp2tempfile = GetTempFileName("jp2");
			string testfile = GetTempFileName("bmp");
			// create original bitmap
			using (Bitmap original = GetTestBitmap())
			{
				original.Save(tempfile, ImageFormat.Bmp);
				// convert to JPEG2000
				Assert.IsTrue(MediaConverter.Convert(tempfile, jp2tempfile));
				Assert.IsTrue(File.Exists(jp2tempfile));

				DateTime start = DateTime.Now;
				Parameters parameters = new Parameters(50, 50, Parameters.Unspecified);
				Assert.IsTrue(MediaConverter.Convert(jp2tempfile, testfile, parameters));
				Debug.WriteLine("Conversion time: " + (DateTime.Now - start));

				Assert.IsTrue(File.Exists(testfile));
				using (Bitmap test = new Bitmap(testfile))
				{
					Assert.AreEqual(50, test.Width);
					Assert.AreEqual(50, test.Height);
				}
			}
		}

		[Test]
		public void TestJpeg2000ToJpegConversion()
		{
			string tempfile = GetTempFileName("bmp");
			string jp2tempfile = GetTempFileName("jp2");
			string testfile = GetTempFileName("jpg");
			// create original bitmap
			using (Bitmap original = GetTestBitmap())
			{
				original.Save(tempfile, ImageFormat.Bmp);
				// convert to JPEG2000
				Assert.IsTrue(MediaConverter.Convert(tempfile, jp2tempfile));
				Assert.IsTrue(File.Exists(jp2tempfile));
				// convert back to bitmap
				Assert.IsTrue(MediaConverter.Convert(jp2tempfile, testfile));
				Assert.IsTrue(File.Exists(testfile));
				// compare file contents
				using (Bitmap result = new Bitmap(testfile))
				{
					Assert.AreEqual(original.Height, result.Height);
					Assert.AreEqual(original.Width, result.Width);
				}
			}
		}

		[Test]
		public void TestGetDimensions()
		{
			string tempfile = GetTempFileName("bmp");
			string jp2tempfile = GetTempFileName("jp2");
			// create original bitmap
			using (Bitmap original = GetTestBitmap())
				original.Save(tempfile, ImageFormat.Bmp);
			// convert to JPEG2000
			Assert.IsTrue(MediaConverter.Convert(tempfile, jp2tempfile));
			Assert.IsTrue(File.Exists(jp2tempfile));
			Size dimensions = Media.Converters.Jpeg2000Converter.GetDimensions(jp2tempfile);
			Assert.AreEqual(128, dimensions.Width);
			Assert.AreEqual(128, dimensions.Height);
		}

		[Test]
		public void TestCropConversion()
		{
			string tempfile = GetTempFileName("bmp");
			string jp2tempfile = GetTempFileName("jp2");
			string testfile = GetTempFileName("bmp");
			// create original bitmap
			using (Bitmap original = GetTestBitmap())
			{
				original.Save(tempfile, ImageFormat.Bmp);
				// convert to JPEG2000
				Assert.IsTrue(MediaConverter.Convert(tempfile, jp2tempfile));
				Assert.IsTrue(File.Exists(jp2tempfile));

				DateTime start = DateTime.Now;
				Parameters parameters = new Parameters(100, 100, false, Color.Empty, 20, 30, 40, 50, Parameters.Unspecified);
				Assert.IsTrue(MediaConverter.Convert(jp2tempfile, testfile, parameters));
				Debug.WriteLine("Conversion time: " + (DateTime.Now - start));

				Assert.IsTrue(File.Exists(testfile));
				using (Bitmap test = new Bitmap(testfile))
				{
					Assert.AreEqual(40, test.Width);
					Assert.AreEqual(50, test.Height);
				}
			}
		}
	}
}
