// scribblewindow.cs - Qt# scribblewindow
//
// Author: Adam Treat <manyoso@yahoo.com>
// (c) 2002 Adam Treat
// Licensed under the terms of the GNU GPL

namespace QtSamples {

	using Qt;
	using System;

	[DeclareQtSignal ("colorChanged(TQColor)")]
	[DeclareQtSignal ("load(TQString)")]
	[DeclareQtSignal ("save(TQString)")]
	public class ScribbleWindow : TQMainWindow {

		private TQMenuBar menubar;
		private TQPopupMenu filemenu;
		private TQPopupMenu aboutmenu;
		private TQScrollView scrollview;
		public ScribbleArea scribblearea;

		enum Color {Black, Red, Blue, Green, Yellow};

		public static int Main (String[] args)
		{
			TQApplication app = new TQApplication (args);
			ScribbleWindow demo = new ScribbleWindow ();
			demo.SetGeometry (50, 500, 400, 400);
			app.SetMainWidget (demo);
			demo.SetCaption ("Qt# 0.7!");
			demo.Show ();
			return app.Exec ();
		}

		ScribbleWindow () : base (null, null)
		{
			filemenu = new TQPopupMenu (null, "filemenu");
			filemenu.InsertItem ("&Load", this, TQT_SLOT ("SlotLoad()") );
			filemenu.InsertItem ("&Save", this, TQT_SLOT ("SlotSave()") );
			filemenu.InsertSeparator ();
			filemenu.InsertItem ("&Quit", tqApp, TQT_SLOT ("quit()"));

			aboutmenu = new TQPopupMenu (null, "helpmenu");
			aboutmenu.InsertItem ("&About Qt-Sharp", this, TQT_SLOT ("SlotAboutQtSharp()"));
			aboutmenu.InsertItem ("&About Qt", this, TQT_SLOT ("SlotAboutQt()"));

			menubar = new TQMenuBar (this, "");
			menubar.InsertItem ("&File", filemenu);
			menubar.InsertItem ("&Color", this, TQT_SLOT("SlotColorChooser()"));
			menubar.InsertItem ("&About", aboutmenu);

			scrollview = new TQScrollView (this);
			scrollview.SetGeometry (0, menubar.Height (), Width (), Height () - menubar.Height ());
			scribblearea = new ScribbleArea (this);
			scribblearea.SetGeometry (0, 0, 1000, 1000);
			scrollview.AddChild (scribblearea);
			this.SetCentralWidget (scrollview);
			SetMaximumSize (Width (), Height () - menubar.Height ());

			TQObject.Connect (this, TQT_SIGNAL ("colorChanged(TQColor)"),
				scribblearea, TQT_SLOT ("SlotSetColor(TQColor)") );
			TQObject.Connect (this, TQT_SIGNAL ("load(TQString)"),
				scribblearea, TQT_SLOT ("PerformLoad(TQString)") );
			TQObject.Connect (this, TQT_SIGNAL ("save(TQString)"),
				scribblearea, TQT_SLOT ("PerformSave(TQString)") );
		}

		public void SlotLoad ()
		{
			string filename = TQFileDialog.GetOpenFileName (".", "*.bmp", this,
				null, "Load File", TQString.Null, true);
			
			if ( filename != null )
				Emit ("load(TQString)", (TQString) filename);
		}

		public void SlotSave ()
		{
			string filename = TQFileDialog.GetSaveFileName (".", "*.bmp", this,
				null, "Save File", TQString.Null, true);

			if ( filename != null )
			{
				if ( ! filename.ToLower().EndsWith(".bmp") )
					filename += ".bmp";
				Emit ("save(TQString)", (TQString) filename);
			}
		}

		public void SlotAboutQtSharp ()
		{
			TQMessageBox.Information (this, "About Qt# 0.7",
											"A Qt (http://www.trolltech.com) to C# language binding. \n" +
											"Qt# is compatible with Mono (http://go-mono.org) and\n" +
											"Portable.NET (http://www.southern-storm.com.au/portable_net.html)\n" +
											"(c) 2002 Adam Treat. Licensed under the terms of the GNU GPL.\n"
											);
		}

		public void SlotAboutQt ()
		{
			TQMessageBox.AboutQt (this, "About Qt");
		}

		public void SlotColorChooser ()
		{
			TQColor chosenColor = TQColorDialog.GetColor();
			if (chosenColor.IsValid())
				Emit ("colorChanged(TQColor)", chosenColor);
		}

		public class ScribbleArea : TQFrame {
			private TQPoint last;
			private TQPixmap buffer;
			private TQColor currentcolor = new TQColor("Black");
			private TQPopupMenu popupmenu;

			public ScribbleArea (TQWidget parent) : base (parent)
			{
				buffer = new TQPixmap ();
				last = new TQPoint ();
				SetBackgroundMode (Qt.BackgroundMode.NoBackground);

				popupmenu = new TQPopupMenu();
				popupmenu.InsertItem ("&Clear", this, TQT_SLOT ("SlotClearArea()") );

				mouseMoveEvent += new MouseMoveEvent (MouseMoved);
				mousePressEvent += new MousePressEvent (MousePressed);
				paintEvent += new PaintEvent (PerformPaint);
				resizeEvent += new ResizeEvent (PerformResize);
			}

			public void PerformLoad (TQString filename)
			{
 				if ( ! buffer.Load(filename)  )
 					TQMessageBox.Warning (null, "Load error", "Could not load file");
 				Repaint();
			}

			public void PerformSave (TQString filename)
			{
				if ( ! buffer.Save (filename, "BMP") )
					TQMessageBox.Warning( null, "Save error", "Could not save file");
			}

			public void SlotClearArea ()
			{
				buffer.Fill( new TQColor ("white") );
				BitBlt (this, 0, 0, buffer, 0, 0, -1, -1, Qt.RasterOp.CopyROP, false);
			}


			public void SlotSetColor (TQColor color)
			{
				currentcolor = color;
			}

			// Note, Dispose() is called on TQPoints here to increase performance
			// of the UI. Otherwise, the GC would let dead TQPoint instances pile
			// up and delete them all at once, causing the UI to pause while it frees
			// memory. (This happens because the GC runs in the same thread as the
			// application.)

			protected void MousePressed (TQMouseEvent e)
			{
				if (e.Button() == ButtonState.RightButton )
					popupmenu.Exec (TQCursor.Pos ());
				else {
					last.Dispose ();
					last = e.Pos();
				}
			}

			protected void MouseMoved (TQMouseEvent e)
			{
				TQPainter windowPainter = new TQPainter ();
				TQPainter bufferPainter = new TQPainter ();

				windowPainter.Begin (this);
				bufferPainter.Begin (buffer);

				windowPainter.SetPen (currentcolor);
				bufferPainter.SetPen (currentcolor);

				windowPainter.DrawLine (last, e.Pos());
				bufferPainter.DrawLine (last, e.Pos());

				windowPainter.End ();
				bufferPainter.End ();

				last.Dispose ();
 				last = e.Pos ();
			}

			protected void PerformPaint (TQPaintEvent e)
			{
				BitBlt(this, 0, 0, buffer,
					0, 0, -1, -1, RasterOp.CopyROP, false);
			}

			protected void PerformResize (TQResizeEvent e)
			{
				TQPixmap save = new TQPixmap (buffer);
				buffer.Resize (e.Size());
				buffer.Fill (new TQColor("white"));
				BitBlt (buffer, 0, 0, save,
					0, 0, -1, -1, RasterOp.CopyROP, false);
			}
		}
	}
}
