using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Media;

namespace OPlanner {

	public enum SpacingMode {
		Relative, Absolute
	}

	public enum CustomTileMode {
		Normal, Honeycomb
	}

	public enum CustomOffsetMode {
		Predictable, Normal
	}

	public class HatchedArea : Control {

		public static DependencyProperty DataProperty;
		public static DependencyProperty HatchLineWidthProperty;
		public static DependencyProperty HatchLineSpacingProperty;
		public static DependencyProperty HatchColorProperty;
		public static DependencyProperty FillTransformProperty;
		public static DependencyProperty SpacingModeProperty;
		public static DependencyProperty OffsetModeProperty;

		static HatchedArea() {
			DataProperty = DependencyProperty.Register("Data", typeof(Geometry), typeof(HatchedArea));
			HatchLineWidthProperty = DependencyProperty.Register("HatchLineWidth", typeof(double), typeof(HatchedArea));
			HatchLineSpacingProperty = DependencyProperty.Register("HatchLineSpacing", typeof(double), typeof(HatchedArea));
			HatchColorProperty = DependencyProperty.Register("HatchColor", typeof(Color), typeof(HatchedArea));
			FillTransformProperty = DependencyProperty.Register("FillTransform", typeof(Transform), typeof(HatchedArea));
			SpacingModeProperty = DependencyProperty.Register("SpacingMode", typeof(SpacingMode), typeof(HatchedArea));
			OffsetModeProperty = DependencyProperty.Register("OffsetMode", typeof(CustomOffsetMode), typeof(HatchedArea));
		}

		public Geometry Data {
			get {
				return (Geometry)base.GetValue(DataProperty);
			}
			set {
				if (Data != value) {
					InvalidateVisual();
				}
				base.SetValue(DataProperty, value);
			}
		}

		public double HatchLineWidth {
			get {
				return (double)base.GetValue(HatchLineWidthProperty);
			}
			set {
				base.SetValue(HatchLineWidthProperty, value);
			}
		}

		public double HatchLineSpacing {
			get {
				return (double)base.GetValue(HatchLineSpacingProperty);
			}
			set {
				base.SetValue(HatchLineSpacingProperty, value);
			}
		}

		public Color HatchColor {
			get {
				return (Color)base.GetValue(HatchColorProperty);
			}
			set {
				base.SetValue(HatchColorProperty, value);
			}
		}

		public Transform FillTransform {
			get {
				return (Transform)base.GetValue(FillTransformProperty);
			}
			set {
				base.SetValue(FillTransformProperty, value);
			}
		}

		public SpacingMode SpacingMode {
			get {
				return (SpacingMode)base.GetValue(SpacingModeProperty);
			}
			set {
				base.SetValue(SpacingModeProperty, value);
			}
		}

		public CustomOffsetMode OffsetMode {
			get {
				return (CustomOffsetMode)base.GetValue(OffsetModeProperty);
			}
			set {
				base.SetValue(OffsetModeProperty, value);
			}
		}

		protected override void OnRender(DrawingContext drawingContext) {
			if (HatchLineWidth <= 0 || Data == null) {
				return;
			}
			drawingContext.PushClip(Data);
			Rect rect = Data.Bounds;
			Rect newRect = rect;
			if (FillTransform != null) {
				if (FillTransform.Inverse != null) {
					newRect = FillTransform.Inverse.TransformBounds(rect);
				}
			}
			double width;
			if (SpacingMode == SpacingMode.Absolute && HatchLineSpacing > 0) {
				width = HatchLineSpacing;
			} else {
				width = HatchLineWidth + HatchLineSpacing;
				if (width <= 0) {
					return;
				}
			}
			if (FillTransform != null) {
				drawingContext.PushTransform(FillTransform);
			}
			Pen pen = new Pen(new SolidColorBrush(HatchColor), HatchLineWidth);
			double extraXOffset = 0;
			if (OffsetMode == CustomOffsetMode.Predictable) {
				int num = (int)Math.Round(newRect.Left / width);
				extraXOffset = width * num - newRect.Left;
			}
			for (double xPos = newRect.Left + extraXOffset; xPos <= newRect.Right + HatchLineWidth / 2; xPos += width) {
				drawingContext.DrawLine(pen, new Point(xPos, newRect.Top), new Point(xPos, newRect.Bottom));
			}
			if (FillTransform != null) {
				drawingContext.Pop();
			}
			drawingContext.Pop();
		}

	}

}