using System;
using System.IO;
using FreeImageAPI;

namespace Sample02
{
	class Program
	{
		static void Main(string[] args)
		{
			// Check if FreeImage.dll is available (can be in %path%).
			if (!FreeImage.IsAvailable())
			{
				Console.WriteLine("FreeImage.dll seems to be missing. Aborting.");
				return;
			}

			Sample sample = new Sample();
			sample.Example();
		}
	}

	public class Sample
	{
		const string fileName = @"multipaged.tif";
		FIMULTIBITMAP dib = new FIMULTIBITMAP();
		Random rand = new Random();

		public void Example()
		{
			if (!File.Exists(fileName))
			{
				Console.WriteLine("File not found. Aborting.");
				return;
			}

			// Load the multipaged bitmap.
			// 'OpenMultiBitmapEx' tries to find the correct file format, loads the bitmap
			// with default options, with write support and does not use caching.
			dib = FreeImage.OpenMultiBitmapEx(fileName);

			// Check whether loading succeeded.
			if (dib.IsNull)
			{
				Console.WriteLine("File could not be loaded. Aborting.");
				return;
			}

			// Get the number of bitmaps the multipaged bitmap contains.
			int count = FreeImage.GetPageCount(dib);

			// Multipaged bitmaps consist of multiple single FIBITMAPs
			FIBITMAP page = new FIBITMAP();

			// There are bitmaps we can work with.
			if (count > 0)
			{
				// Lock a random bitmap to work with.
				page = FreeImage.LockPage(dib, rand.Next(0, count));
			}

			// Check whether locking succeeded.
			if (page.IsNull)
			{
				// Locking failed. Unload the bitmap and return.
				FreeImage.CloseMultiBitmapEx(ref dib);
				return;
			}

			// Get a list of locked pages. This can be usefull to check whether a page has already been locked.
			int[] lockedPages = FreeImage.GetLockedPages(dib);

			// Lets modify the page.
			if (FreeImage.AdjustGamma(page, 2d))
			{
				Console.WriteLine("Successfully changed gamma of page {0}.", lockedPages[0]);
			}
			else
			{
				Console.WriteLine("Failed to adjust gamma ...");
			}

			// Print out the list of locked pages
			foreach (int i in lockedPages)
				Console.WriteLine("Page {0} is locked.", i);

			// Use 'UnlockPage' instead of 'Unload' to free the page. Set the third parameter to 'true'
			// so that FreeImage can store the changed page within the multipaged bitmap.
			FreeImage.UnlockPage(dib, page, true);

			// Retieve the list again to see whether unlocking succeeded.
			lockedPages = FreeImage.GetLockedPages(dib);

			// No output should be produced here.
			foreach (int i in lockedPages)
				Console.WriteLine("Page {0} is still locked.", i);

			// If there are more than one page we can swap them
			if (count > 1)
			{
				if (!FreeImage.MovePage(dib, 1, 0))
				{
					Console.WriteLine("Swapping pages failed.");
				}
			}

			if (count > 2)
			{
				// Lock page 2
				page = FreeImage.LockPage(dib, 2);
				if (!page.IsNull)
				{
					// Clone the page for later appending
					FIBITMAP temp = FreeImage.Clone(page);

					// Unlock the page again
					FreeImage.UnlockPage(dib, page, false);

					// Delete the page form the multipaged bitmap
					FreeImage.DeletePage(dib, 2);

					// Append the clone again
					FreeImage.AppendPage(dib, temp);

					// Check whether the number of pages is still the same
					Console.WriteLine("Pages before: {0}. Pages after: {1}", count, FreeImage.GetPageCount(dib));

					// Unload clone to prevent memory leak
					FreeImage.UnloadEx(ref temp);
				}
			}

			// We are done and close the multipaged bitmap.
			if (!FreeImage.CloseMultiBitmapEx(ref dib))
			{
				Console.WriteLine("Closing bitmap failed!");
			}
		}
	}
}
