//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
//  
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Diagnostics;

namespace Polygon
{
	/// <summary>
	/// Podsumowanie dla PolyForm.
	/// </summary>
	public class PolyForm : System.Windows.Forms.Form
	{
		/// <summary>
		/// Wymagana zmienna.
		/// </summary>
		private System.ComponentModel.Container components = null;
		private ArrayList points = null;
		private bool fill = false;
		public PolyForm()
		{
			//
			// Wymagane do obsługi Windows Form Designer
			//
			InitializeComponent();
			points = new ArrayList();
		}

		/// <summary>
		/// Oczyszczenie używanych zasobów.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Metoda wymagana do obsługi Designera - nie należy modyfikować
		/// zawartości tej metody przy użyciu edytora kodu.
		/// </summary>
		private void InitializeComponent()
		{
			// 
			// PolyForm
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.BackColor = System.Drawing.SystemColors.Window;
			this.ClientSize = new System.Drawing.Size(292, 266);
			this.Name = "PolyForm";
			this.Text = "Wielokąt";
			this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDown);
			this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseDown);

		}
		#endregion

		/// <summary>
		/// Główny punkt wejścia dla aplikacji.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new PolyForm());
		}

		private void OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			Graphics dc = CreateGraphics();
			if(fill)
			{
				fill = false;
				dc.Clear(Color.White);
				points.Clear();
			}
			dc.FillEllipse(Brushes.Red,
				           e.X - 5, e.Y - 5,
				           10, 10);
			dc.DrawEllipse(new Pen(Color.Black),
				           e.X - 5, e.Y - 5,
				           10,10);
			points.Add(new PointF(e.X, e.Y));
			dc.Dispose();
		}

		private void OnKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			if(e.KeyCode == Keys.C)
			{
				Debug.WriteLine(string.Format("Wypełnienie: {0} punktów", points.Count));
				Graphics dc = CreateGraphics();
				dc.SmoothingMode = SmoothingMode.HighQuality;
				Point [] pa = new Point [points.Count + 1];
				byte [] pt = new Byte [points.Count + 1];
				int index = 0;
				foreach(PointF p in points)
				{
					pa[index] = new Point((int)p.X, (int)p.Y);
					pt[index] = (byte)PathPointType.Line;
					index++;
				}
				pt[0] |= (byte)PathPointType.Start;
				pt[index] = (byte)PathPointType.CloseSubpath | (byte)PathPointType.Line;
				pa[index] = pa[0];
				Pen pen = new Pen(Color.Red, 10);
				pen.StartCap = LineCap.Round;
				pen.EndCap = LineCap.Round;
				pen.LineJoin = LineJoin.Round;
				GraphicsPath gp = new GraphicsPath(pa, pt);
				dc.DrawPath(pen, gp);
				pen.Dispose();
				gp.Dispose();
				dc.Dispose();
				fill = true;
			}
			if(e.KeyCode == Keys.R &&
			   fill)
			{
				Graphics dc = CreateGraphics();
				dc.Clear(Color.White);
				RectangleF bounds = dc.VisibleClipBounds;
				PointF point = new PointF(bounds.Location.X + bounds.Width/2.0F, bounds.Location.Y + bounds.Height/2.0F);
				Matrix m = new Matrix();
				m.RotateAt(10, point);

				dc.SmoothingMode = SmoothingMode.HighQuality;
				Point [] pa = new Point [points.Count + 1];
				byte [] pt = new Byte [points.Count + 1];
				int index = 0;
				foreach(PointF p in points)
				{
					pa[index] = new Point((int)p.X, (int)p.Y);
					pt[index] = (byte)PathPointType.Line;
					index++;
				}
				pt[0] |= (byte)PathPointType.Start;
				pt[index] = (byte)PathPointType.CloseSubpath | (byte)PathPointType.Line;
				pa[index] = pa[0];

				Pen pen = new Pen(Color.Red, 10);
				pen.StartCap = LineCap.Round;
				pen.EndCap = LineCap.Round;
				pen.LineJoin = LineJoin.Round;

				GraphicsPath gp = new GraphicsPath(pa, pt);
				gp.Transform(m);
				dc.DrawPath(pen, gp);
				PointF [] pathPoints = gp.PathPoints;
				points.Clear();
				foreach(PointF p in pathPoints)
				{
					points.Add(p);
				}
				pen.Dispose();
				gp.Dispose();
				dc.Dispose();
			}
		}
	}
}
