
using Gtk;
using GtkSharp;
using System;
using System.Collections;


public class TestPyramid
{
	public static int Main (string[] args)
	{
		Application.Init ();

		Window win = new Window ("Image pyramid test program");
		win.DefaultSize = new System.Drawing.Size (400, 300);
		win.DeleteEvent += new DeleteEventHandler (Window_Delete);

		string fileName = "test.jpg";
		if (args.Length > 0)
			fileName = args[0];

		PyramidTest pt = new PyramidTest (fileName);
		pt.CreateDisplay ();
		win.Add (pt.Display);

		win.ShowAll ();
		Application.Run ();

		return (0);
	}

	static void Window_Delete (object obj, DeleteEventArgs args)
	{
		Application.Quit ();
		args.RetVal = true;
	}
}


public class PyramidTest
{
	Gtk.VBox pyramidDisplay;
	public Gtk.Widget Display {
		get {
			return ((Gtk.Widget) pyramidDisplay);
		}
	}

	private PyramidTest ()
	{
	}


	string filename;

	public PyramidTest (string filename)
	{
		this.filename = filename;
	}

	public void CreateDisplay ()
	{
		pyramidDisplay = new Gtk.VBox (false, 0);
		Gtk.HBox pyramidDisplay1Line = new Gtk.HBox (false, 0);

		DisplayImage pic = new DisplayImage (filename);
		pyramidDisplay1Line.Add (new Image (pic.Pbuf));
		ImageMap picMap = pic.ConvertToImageMap (null);

		pyramidDisplay1Line.Add (new Image
			((new DisplayImage (pic.ConvertToImageMap (null), 1.0)).Pbuf));
		pyramidDisplay.Add (pyramidDisplay1Line);

		LoweFeatureDetector lf = new LoweFeatureDetector ();
		lf.DetectFeatures (picMap);
		Console.WriteLine ("found {0} global keypoints",
			lf.GlobalKeypoints.Count);

		// factor for displaying the keypoints relative to their real circle
		// area
		double showFactor = 0.25;

		foreach (Keypoint kp in lf.GlobalKeypoints) {
			/*
			if (kp.Scale <= 2.0)
				continue;
			*/

			int kpX = (int) (kp.X + 0.5);
			int kpY = (int) (kp.Y + 0.5);

			// From ScaleSpace.cs
			int radius = (int) (3.0 * 3.0 * kp.Scale / 2.0 + 0.5);
			pic.DrawCircle (kpX, kpY, (int) (radius * showFactor),
				255, 0, 0);

			// FIXME: what does angle = 0 mean in kp? We assume it points
			//        upwards, but that could be wrong.
			int tY = (int) (-kp.Scale * 4.5 * showFactor);
			int tX = 0;
			int LtX = (int) (Math.Cos (kp.Orientation) * tX -
				Math.Sin (kp.Orientation) * tY);
			int LtY = (int) (Math.Sin (kp.Orientation) * tX +
				Math.Cos (kp.Orientation) * tY);

			pic.DrawLine (kpX, kpY, kpX + LtX, kpY + LtY, 255, 0, 0);
		}

		Console.WriteLine ("did keypoints");
		/*
		for (int sp = 0 ; sp < lf.Pyr.Count ; ++sp) {
			DScaleSpace dsp = lf.Pyr[sp];

			Gtk.HBox line = new Gtk.HBox (false, 3);

			for (int sd = 1 ; sd < dsp.Count ; ++sd) {
				ImageMap gauss = dsp.GetGaussianMap (sd);
				line.Add (new Image ((new DisplayImage (gauss, 1.0)).Pbuf));
			}

			pyramidDisplay.Add (line);
		}
		Console.WriteLine ("did maps");
		*/
		// TEST
		//picMap.Normalize ();
		/*
		DScaleSpace dsp = new DScaleSpace ();
		dsp.BuildSpace (picMap, 3, 1.6);

		for (int n = 0 ; n < dsp.Count ; ++n) {
			Image scaleImg = new Image
				((new DisplayImage (dsp[n], 1.0)).Pbuf);
			pyramidDisplay.Add (scaleImg);
		}
		return;
		*/

		/*
		ConvolutionMask gaussian2sq =
			ConvolutionMask.GenerateGaussian (7, 1.4142);
		picMap = picMap.ApplyConvolutionMask (gaussian2sq);
		//picMap.Normalize ();

		ImageMap picMapConv2 = picMap.ApplyConvolutionMask (gaussian2sq);
		ImageMap diffMap = picMap - picMapConv2;
		*/

		/*
		pyramidDisplay.Add (new Image ((new DisplayImage (picMap, picMap.MaxElem)).Pbuf));
		pyramidDisplay.Add (new Image ((new DisplayImage (picMapConv2, picMapConv2.MaxElem)).Pbuf));
		pyramidDisplay.Add (new Image ((new DisplayImage (diffMap, diffMap.MaxElem)).Pbuf));
		*/

		/*
		ImagePyramid32 pyramid = new ImagePyramid32 (picMapConv2);

		for (ImagePyramid32 pyrWalk = pyramid ; pyrWalk != null ;
			pyrWalk = pyrWalk.Up)
		{
			ImageMap furtherSmoothed =
				pyrWalk.Current.ApplyConvolutionMask (gaussian2sq);
			//furtherSmoothed.Normalize ();
			Console.WriteLine ("current max = {0}, smooth max = {1}",
				pyrWalk.Current.MaxElem, furtherSmoothed.MaxElem);
			ImageMap diffFunc = pyrWalk.Current - furtherSmoothed;
			//diffFunc.Normalize ();
			pyrWalk.Current = diffFunc;

		*/
			/*
			Image scaleImg = new Image
				((new DisplayImage (pyrWalk.Current, pyrWalk.Current.MaxElem)).Pbuf);
			*/
		/*
			Image scaleImg = new Image
				((new DisplayImage (pyrWalk.Current, 0.1)).Pbuf);
			pyramidDisplay.Add (scaleImg);
		}
		*/
	}
}


