using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Text;
using System.Collections;
using System.Diagnostics;
using NUnit.Framework;
using Orciid.Media.Converters;

namespace Orciid.Media
{
	[TestFixture]
	public class TestMediaRepository
	{
		private string rootdirectory = null;
		private static Bitmap defaultbitmap;
		private static ArrayList tempfiles = new ArrayList();

		static TestMediaRepository()
		{
			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;
			string temp = Path.GetTempPath();
			int i = 0;
			do
			{
				rootdirectory = Path.Combine(temp, "mediarepository" + i.ToString());
				i++;
			} while (Directory.Exists(rootdirectory));
			Directory.CreateDirectory(rootdirectory);
			Console.WriteLine("Using {0} as root directory", rootdirectory);
		}

		[TearDown]
		public void Cleanup()
		{
			Debug.Listeners.Clear();
			while (tempfiles.Count > 0)
			{
				try
				{
					File.Delete(tempfiles[0] as string);
				}
				finally
				{
					tempfiles.RemoveAt(0);
				}
			}
			if (rootdirectory != null)
				Directory.Delete(rootdirectory, true);
		}

		[Test]
		public void IsValidFileName()
		{
			MediaRepository rep = new MediaRepository(rootdirectory);
			Assert.IsTrue(rep.IsValidFileName(@"test.jpg"));
			Assert.IsFalse(rep.IsValidFileName(@"c:\test.jpg"));
			Assert.IsFalse(rep.IsValidFileName(@"..\test.jpg"));
			Assert.IsFalse(rep.IsValidFileName(@"temp\..\test.jpg"));
			Assert.IsFalse(rep.IsValidFileName(@".\test.jpg"));
		}

		[Test]
		public void IsValidSubdirectory()
		{
			MediaRepository rep = new MediaRepository(@"c:\test");
			Assert.IsTrue(rep.IsValidSubdirectory(@"full"));
			Assert.IsTrue(rep.IsValidSubdirectory(@"full\part1"));
			Assert.IsFalse(rep.IsValidSubdirectory(@"full\..\.."));
			Assert.IsFalse(rep.IsValidSubdirectory(@".."));
			Assert.IsFalse(rep.IsValidSubdirectory(@"c:\testing"));
			Assert.IsFalse(rep.IsValidSubdirectory(@"..\testing"));
			Assert.IsTrue(rep.IsValidSubdirectory(@"..\test\full"));
		}

		[Test]
		public void StoreAndRetrieve()
		{
			MediaRepository rep = new MediaRepository(rootdirectory);
			MemoryStream stream = new MemoryStream(100000);
			for (int i = 0; i < 100000; i++)
				stream.WriteByte((byte)(i & 0xFF));
			stream.Position = 0;
			rep.StoreFile(stream, "test.dat");
			using (Stream instream = rep.RetrieveFile("test.dat"))
			{
				for (int j = 0; j < 100000; j++)
					Assert.AreEqual((byte)(j & 0xFF), instream.ReadByte());
				Assert.AreEqual(-1, instream.ReadByte());
			}
		}

		[Test]
		public void GetCacheFileName()
		{
			MediaRepository rep = new MediaRepository(rootdirectory);
			Console.WriteLine(rep.GetCacheFileName("filename.jp2", "subdirectory", "image/jpeg",
				new Parameters(800, 600, 95)));
		}

		[Test]
		public void Repository()
		{
			MediaRepository rep = new MediaRepository(rootdirectory);
			using (Bitmap original = GetTestBitmap())
			{
				MemoryStream stream = new MemoryStream();
				original.Save(stream, ImageFormat.Tiff);
				stream.Position = 0;
				rep.StoreFile(stream, "test.tif");
			}
			using (Stream image = 
					   rep.RetrieveFile("test.tif", null, "image/jpeg", 
					   new Parameters(30, 40, true, Color.Purple, 85)))
			{
				using (Bitmap test = new Bitmap(image))
				{
					Assert.AreEqual(30, test.Width);
					Assert.AreEqual(40, test.Height);
				}
			}
		}
	}
}