using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Telerik.QuickStart.WinControls
{
	#region Enums
	public enum CornerStyles
	{
		Rounded,
		Square
	}
	public enum Orientations
	{
		Vertical,
		Horizontal
	}
	public enum Poles
	{
		Left,
		Right,
		Top,
		Bottom
	}

	#endregion

	/// <summary>
	/// Summary description for UserControl1.
	/// </summary>
	[Description("Color Track Bar")]
	//[ToolboxBitmap(typeof(TrackBar))]
	//	[Designer(typeof(ColorTrackBarDesigner))]
	public class ColorTrackBar : System.Windows.Forms.Control
	{
		/// <summary>
		/// Required designer variable.TODO
		/// </summary>
		#region Private Properties
		private int trackSize = 25;
		private Poles maxSide = Poles.Right;
		private CornerStyles cornerStyle = CornerStyles.Square;
		private Orientations barOrientation = Orientations.Horizontal;
		private Rectangle trackRect = Rectangle.Empty;
		private int mousestartPos = -1;
		private bool leftbuttonDown = false;
		private Color barborderColor = Color.Black;
		private Color barColor = Color.White;
		private Color barColor2 = Color.Gray;
		private Color trackborderColor = Color.Black;
		private Color trackColor = Color.Red;
		private Color trackColor2 = Color.Red;
		private Color barColor3 = Color.FromArgb(13, 102, 135 );
		private Color trackColor3 = Color.FromArgb( 105, 187, 218 );
		private int borderWidth = 1;
		private int trackerValue = 25;
		private int barMinimum = 0;
		private int barMaximum = 100;
		private System.ComponentModel.Container components = null;
		#endregion

		#region Public Properites
		/// <summary>
		/// Set Trackerbar size
		/// </summary>
		[Description("Set Trackbar size")]
		[Category("ColorTrackBar")]
		public int TrackerSize
		{
			get
			{
				return trackSize;
			}
			set
			{
				if (value <= 0)
					throw new ArgumentException("value must be greater then zero");
				//cannot set TrackerSize for rounded corners
				if (cornerStyle == CornerStyles.Rounded)
				{
					switch (barOrientation)
					{
						case Orientations.Horizontal:
							value = this.Height;
							break;
						case Orientations.Vertical:
							value = this.Width;
							break;
					}
				}
				switch (barOrientation)
				{
					case Orientations.Horizontal:
						if (value > ClientRectangle.Width / 2)
							value = ClientRectangle.Width / 2;
						break;
					case Orientations.Vertical:
						if (value > ClientRectangle.Height / 2)
							value = ClientRectangle.Height / 2;
						break;
				}
				trackSize = value;
				trackRect = Rectangle.Empty;
				this.Invalidate();
			}
		}
		/// <summary>
		/// Set Trackerbar minimum value
		/// </summary>
		[Description("Set Minimum value of the Track bar")]
		[Category("ColorTrackBar")]
		[RefreshProperties(RefreshProperties.All)]
		public int Minimum
		{
			set
			{
				if (value >= barMaximum)
				{
					throw new ArgumentException("'" + value + "' is not a valid value for 'Mimimum'.\n" +
						"'Minimum' must be less than 'Maximum'.");
				}
				this.barMinimum = value;
				if (this.trackerValue < this.barMinimum)
					this.trackerValue = value;
				trackRect = Rectangle.Empty;
				this.Invalidate();
			}
			get { return this.barMinimum; }
		}
		/// <summary>
		/// Set TrackerBar maximum value
		/// </summary>
		[Description("Set Maximum value of the Track bar")]
		[Category("ColorTrackBar")]
		[RefreshProperties(RefreshProperties.All)]
		public int Maximum
		{
			set
			{
				if (value <= barMinimum)
				{
					throw new ArgumentException("'" + value + "' is not a valid value for 'Maximum'.\n" +
						"'Maximum' must be greater than 'Minimum'.");
				}
				if (this.trackerValue > value)
					this.trackerValue = value;
				this.barMaximum = value;
				trackRect = Rectangle.Empty;
				this.Invalidate();
			}
			get { return this.barMaximum; }
		}

		/// <summary>
		/// Set the poles of the trackbar
		/// </summary>
		[Description("Select the side of the control to represent the maximum range value")]
		[Category("ColorTrackBar")]
		public Poles MaximumValueSide
		{
			get
			{
				return maxSide;
			}
			set
			{
				switch (barOrientation)
				{
					case Orientations.Horizontal:
						if (value == Poles.Top || value == Poles.Bottom)
						{
							throw new ArgumentException("Since your Orientation is set to Horizontal, you can only select" +
								" Left or Right for this property");
						}
						break;
					case Orientations.Vertical:
						if (value == Poles.Left || value == Poles.Right)
						{
							throw new ArgumentException("Since your Orientation is set to Vertical, you can only select" +
								" Top or Bottom for this property");
						}
						break;
				}
				maxSide = value;
				trackRect = Rectangle.Empty;
				this.Invalidate();
			}
		}
		/// <summary>
		/// Set tracker bar orientation
		/// </summary>
		[Description("Set whether the bar will be Veirtically or Horizontally oriented")]
		[Category("ColorTrackBar")]
		[RefreshProperties(RefreshProperties.All)]
		public Orientations BarOrientation
		{
			set
			{
				//check old value//set new size 
				if (this.barOrientation == Orientations.Horizontal)
					base.Size = new Size(base.Size.Height, base.Size.Width);
				else
					base.Size = new Size(base.Size.Height, base.Size.Width);
				this.barOrientation = value;
				if (value == Orientations.Vertical &&
					(this.maxSide != Poles.Bottom && this.maxSide != Poles.Top))
					this.MaximumValueSide = Poles.Bottom;
				if (value == Orientations.Horizontal &&
					(this.maxSide != Poles.Left && this.maxSide != Poles.Right))
					this.MaximumValueSide = Poles.Right;
				trackRect = Rectangle.Empty;
				this.Invalidate();
			}
			get { return this.barOrientation; }
		}

		/// <summary>
		/// Background Bar Border Color
		/// </summary>
		[Description("Bar border color")]
		[Category("ColorTrackBar")]
		public Color BarBorderColor
		{
			set { this.barborderColor = value; this.Invalidate(); }
			get { return this.barborderColor; }
		}
		/// <summary>
		/// Background bar Color
		/// </summary>
		[Description("Bar color")]
		[Category("ColorTrackBar")]
		public Color BarColor
		{
			set { this.barColor = value; this.Invalidate(); }
			get { return this.barColor; }
		}

		/// <summary>
		/// Background bar Color
		/// </summary>
		[Description("Bar color2")]
		[Category("ColorTrackBar")]
		public Color BarColor2
		{
			set { this.barColor2 = value; this.Invalidate(); }
			get { return this.barColor2; }
		}

		[Description("Bar color2")]
		[Category("ColorTrackBar")]
		public Color TrackerColor3
		{
			set { this.trackColor3 = value; this.Invalidate(); }
			get { return this.trackColor3; }
		}

		[Description("Bar color3")]
		[Category("ColorTrackBar")]
		public Color BarColor3
		{
			set { this.barColor3 = value; this.Invalidate(); }
			get { return this.barColor3; }
		}
		/// <summary>
		/// Set control corner style
		/// </summary>
		[Description("Set the shape of the control's corners")]
		[Category("ColorTrackBar")]
		[RefreshProperties(RefreshProperties.All)]
		public CornerStyles ControlCornerStyle
		{
			set
			{
				switch (barOrientation)
				{
					case Orientations.Horizontal:
						if (value == CornerStyles.Rounded)
						{
							if (this.Width < this.Height)
								this.Width = this.Height;
							this.trackSize = this.Height;
						}
						break;
					case Orientations.Vertical:
						if (value == CornerStyles.Rounded)
						{
							if (this.Height < this.Width)
								this.Height = this.Width;
							this.trackSize = this.Width;
						}
						break;
					default:
						break;
				}
				this.cornerStyle = value;
				trackRect = Rectangle.Empty;
				this.Invalidate();
			}
			get { return this.cornerStyle; }
		}
		/// <summary>
		/// Set Trakcer border color
		/// </summary>
		[Description("Tracker border color")]
		[Category("ColorTrackBar")]
		public Color TrackerBorderColor
		{
			set { this.trackborderColor = value; this.Invalidate(); }
			get { return this.trackborderColor; }
		}
		/// <summary>
		/// Tracker bar COlor
		/// </summary>
		[Description("Tracker color")]
		[Category("ColorTrackBar")]
		public Color TrackerColor
		{
			set { this.trackColor = value; this.Invalidate(); }
			get { return this.trackColor; }
		}

		[Description("Tracker color")]
		[Category("ColorTrackBar")]
		public Color TrackerColor2
		{
			set { this.trackColor2 = value; this.Invalidate(); }
			get { return this.trackColor2; }
		}

		/// <summary>
		/// Setr Tracker var current value
		/// </summary>
		[Description("Set or get the Tracker position")]
		[Category("ColorTrackBar")]
		public int Value
		{
			set
			{
				if (value <= barMinimum)
					value = barMinimum;
				if (value >= barMaximum)
					value = barMaximum;
				trackerValue = value;
				trackRect = Rectangle.Empty;
				this.Invalidate();
			}
			get { return trackerValue; }
		}
		#endregion

		#region Position Macros
		public static ushort LowWord(uint value)
		{
			return (ushort)(value & 0xFFFF);
		}
		public static ushort HighWord(uint value)
		{
			return (ushort)(value >> 16);
		}
		#endregion

		#region Event Delegates
		public delegate void ScrollEventHandler(object sender, EventArgs e);
		public delegate void ValueChangedEventHandler(object sender, EventArgs e);
		#endregion

		#region Events
		/// <summary>
		/// Fires when track bar posotion has changed
		/// </summary>
		[Description("Event fires when the Value property changes")]
		[Category("Action")]
		public event ValueChangedEventHandler ValueChanged;
		/// <summary>
		/// Fires when track bar changes positions
		/// </summary>
		[Description("Event fires when the Trackbar position is changed")]
		[Category("Behavior")]
		public event ScrollEventHandler Scroll;
		#endregion

		#region Public Methods
		protected virtual void OnScroll()
		{
			try
			{
				if (Scroll != null)
					Scroll(this, new EventArgs());
			}
			catch (Exception Err)
			{
				MessageBox.Show("OnScroll Exception: " + Err.Message);
			}
		}
		protected virtual void OnValueChanged()
		{
			try
			{
				if (ValueChanged != null)
					ValueChanged(this, new EventArgs());
			}
			catch (Exception Err)
			{
				MessageBox.Show("OnValueChanged Exception: " + Err.Message);
			}
		}
		#endregion

		#region WndProc
		protected override void WndProc(ref Message m)
		{
			//WM_LBUTTONDOWN
			#region WM_LBUTTONDOWN
			if (m.Msg == 0x0201)
			{
				Point CurPoint = new Point(LowWord((uint)m.LParam), HighWord((uint)m.LParam));
				if (trackRect.Contains(CurPoint))
				{
					if (!leftbuttonDown)
					{
						leftbuttonDown = true;
						switch (this.barOrientation)
						{
							case Orientations.Horizontal:
								mousestartPos = CurPoint.X - trackRect.X;
								break;
							case Orientations.Vertical:
								mousestartPos = CurPoint.Y - trackRect.Y;
								break;
						}
					}
				}
				else
				{
					int OffSet = 0;
					switch (this.barOrientation)
					{
						case Orientations.Horizontal:
							if (trackRect.Right + (CurPoint.X - trackRect.X - (trackRect.Width / 2)) >= this.Width)
								OffSet = this.Width - trackRect.Right - 1;
							else if (trackRect.Left + (CurPoint.X - trackRect.X - (trackRect.Width / 2)) <= 0)
								OffSet = (trackRect.Left - 1) * -1;
							else
								OffSet = CurPoint.X - trackRect.X - (trackRect.Width / 2);
							trackRect.Offset(OffSet, 0);
							trackerValue = (int)(((trackRect.X - 1) * (barMaximum - barMinimum)) / (this.Width - trackSize - 2));
							if (maxSide == Poles.Left)
								trackerValue = (trackerValue - (barMaximum - barMinimum)) * -1;
							break;
						case Orientations.Vertical:
							if (trackRect.Bottom + (CurPoint.Y - trackRect.Y - (trackRect.Height / 2)) >= this.Height)
								OffSet = this.Height - trackRect.Bottom - 1;
							else if (trackRect.Top + (CurPoint.Y - trackRect.Y - (trackRect.Height / 2)) <= 0)
								OffSet = (trackRect.Top - 1) * -1;
							else
								OffSet = CurPoint.Y - trackRect.Y - (trackRect.Height / 2);
							trackRect.Offset(0, OffSet);
							trackerValue = (int)(((trackRect.Y - 1) * (barMaximum - barMinimum)) / (this.Height - trackSize - 2));
							if (maxSide == Poles.Top)
								trackerValue = (trackerValue - (barMaximum - barMinimum)) * -1;
							break;
						default:
							break;
					}
					trackerValue += barMinimum;
					this.Invalidate();
					if (OffSet != 0)
					{
						OnScroll();
						OnValueChanged();
					}
				}
				this.Focus();
			}
			#endregion

			#region WM_LBUTTONUP
			if (m.Msg == 0x0202)
			{
				leftbuttonDown = false;
			}
			#endregion

			#region WM_MOUSEMOVE
			//WM_MOUSEMOVE
			if (m.Msg == 0x0200)
			{
				int OldValue = trackerValue;
				Point CurPoint = new Point(LowWord((uint)m.LParam), HighWord((uint)m.LParam));
				if (leftbuttonDown && ClientRectangle.Contains(CurPoint))
				{
					int OffSet = 0;
					try
					{
						switch (this.barOrientation)
						{
							case Orientations.Horizontal:
								if (trackRect.Right + (CurPoint.X - trackRect.X - mousestartPos) >= this.Width)
									OffSet = this.Width - trackRect.Right - 1;
								else if (trackRect.Left + (CurPoint.X - trackRect.X - mousestartPos) <= 0)
									OffSet = (trackRect.Left - 1) * -1;
								else
									OffSet = CurPoint.X - trackRect.X - mousestartPos;
								trackRect.Offset(OffSet, 0);
								trackerValue = (int)(((trackRect.X - 1) * (barMaximum - barMinimum)) / (this.Width - trackSize - 2));
								if (maxSide == Poles.Left)
									trackerValue = (trackerValue - (barMaximum - barMinimum)) * -1;
								break;
							case Orientations.Vertical:
								if (trackRect.Bottom + (CurPoint.Y - trackRect.Y - mousestartPos) >= this.Height)
									OffSet = this.Height - trackRect.Bottom - 1;
								else if (trackRect.Top + (CurPoint.Y - trackRect.Y - mousestartPos) <= 0)
									OffSet = (trackRect.Top - 1) * -1;
								else
									OffSet = CurPoint.Y - trackRect.Y - mousestartPos;
								trackRect.Offset(0, OffSet);
								trackerValue = (int)(((trackRect.Y - 1) * (barMaximum - barMinimum)) / (this.Height - trackSize - 2));
								if (maxSide == Poles.Top)
									trackerValue = (trackerValue - (barMaximum - barMinimum)) * -1;
								break;
						}

					}
					catch (Exception) { }
					finally
					{
						//force redraw
						trackerValue += barMinimum;
						this.Invalidate();
						if (OffSet != 0)
						{
							OnScroll();
							OnValueChanged();
						}
					}
				}
			}
			#endregion
			base.WndProc(ref m);
		}
		#endregion

		#region Class Consruct and Dispose
		public ColorTrackBar()
		{
			//set initla size
			base.Size = new Size(150, 25);
			//set styles
			SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.UserPaint |
				ControlStyles.DoubleBuffer | ControlStyles.SupportsTransparentBackColor, true);
			//set cursor
			this.Cursor = Cursors.Hand;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (components != null)
					components.Dispose();
			}
			base.Dispose(disposing);
		}

		#endregion

		#region Overrides
		protected override void OnSizeChanged(EventArgs e)
		{
			trackRect = Rectangle.Empty;
			base.OnSizeChanged(e);
		}

		protected override void OnPaint(
			PaintEventArgs e)
		{
			e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
			//clear rectangle
			SolidBrush ControlBrush = null;
			if (this.barColor != Color.Empty)
				ControlBrush = new SolidBrush(this.barColor);
			else
				ControlBrush = new SolidBrush(Color.FromName("Control"));
			DrawControl(e.Graphics);
			e.Graphics.SmoothingMode = SmoothingMode.Default;
			base.OnPaint(e);
		}
		#endregion

		#region Drawing GDI+
		protected void DrawControl(Graphics g)
		{
			bool NewRect = false;
			if (trackRect == Rectangle.Empty)
				NewRect = true;
			try
			{
				//get parent color
				Color ParentColor = Color.FromName("Control");
				if (this.Parent != null)
					ParentColor = this.Parent.BackColor;
				switch (barOrientation)
				{
					case Orientations.Horizontal:
						if (trackRect == Rectangle.Empty)
						{
							int TrackX = (int)(((trackerValue - barMinimum) * (ClientRectangle.Width - trackSize)) / (barMaximum - barMinimum));
							//don't go past the borders
							if (TrackX == 0)
								TrackX++;
							if (TrackX + trackSize == ClientRectangle.Width)
								TrackX--;
							if (maxSide != Poles.Right)
								TrackX = (TrackX - ClientRectangle.Width + trackSize) * -1;
							trackRect = new Rectangle(TrackX, 1, trackSize, ClientRectangle.Height - 2);
						}
						break;

					case Orientations.Vertical:
						if (trackRect == Rectangle.Empty)
						{
							int TrackY = (int)(((trackerValue - barMinimum) * (ClientRectangle.Height - trackSize)) / (barMaximum - barMinimum));
							//don't go past the borders
							if (TrackY == 0)
								TrackY++;
							if (TrackY + ClientRectangle.Width == ClientRectangle.Height)
								TrackY--;
							if (maxSide != Poles.Bottom)
								TrackY = (TrackY - ClientRectangle.Height + trackSize) * -1;
							trackRect = new Rectangle(1, TrackY, ClientRectangle.Width - 2, trackSize);
						}
						break;
					default:
						break;
				}
				Region TrackRegion = null;
				Region BarRegion = null;
				switch (cornerStyle)
				{
					case CornerStyles.Square:
						PaintRectangle(ClientRectangle, barColor, this.barColor2, barborderColor, g);
						BarRegion = new Region(ClientRectangle);
						TrackRegion = new Region(trackRect);
						PaintRectangle(trackRect, trackColor, this.trackColor2, trackborderColor, g);
						break;
					case CornerStyles.Rounded:
						//first draw bar
						GraphicsPath BarPath = //DrawRoundedCorners(ClientRectangle, barborderColor, g);
						GetRoundedRect(ClientRectangle, 5);
						BarRegion = new Region(BarPath);
						PaintPath(ClientRectangle, BarPath, barColor, this.barColor2, this.barColor3, g);
						GraphicsPath borderPath = GetRoundedRect(new RectangleF(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1,
							ClientRectangle.Height - 1), 5);

						g.DrawPath(new Pen(this.barborderColor), borderPath);
					
					//check if tracker size is correct
						if (trackRect.Width != trackRect.Height)
						{
							if (barOrientation == Orientations.Horizontal)
							{
								trackRect = new Rectangle(trackRect.Location,
									new Size(80, ClientRectangle.Height - 2));
							}
							else
							{
								trackRect = new Rectangle(trackRect.Location,
									new Size(ClientRectangle.Width - 2, ClientRectangle.Width));
							}
						}
						//now draw Tracker
						GraphicsPath TrackPath =
								GetRoundedRect(trackRect, 5);

						GraphicsPath TrackBorderPath =
							GetRoundedRect(new Rectangle(trackRect.X, trackRect.Y, trackRect.Width - 1, trackRect.Height - 1), 5);
					
					
						//DrawRoundedCorners(trackRect, trackborderColor, g);
						TrackRegion = new Region(TrackPath);
						PaintPath(trackRect, TrackPath, trackColor, this.trackColor2, this.trackColor3, g);
						g.DrawPath(new Pen(this.trackborderColor), TrackBorderPath);
					
						break;
					default:
						break;
				}

			}
			catch (Exception )
			{
				//throw new Exception("DrawBackGround Error: "+Err.Message);
			}
			finally
			{
				if (NewRect)
				{
					/*OnScroll();
					OnValueChanged();*/
				}
			}
		}

		protected void PaintRectangle(Rectangle Rect, Color RectColor, Color RectColor2, Color RectBorderColor, Graphics g)
		{
			//draw rectangle
			Pen LinePen = new Pen(RectBorderColor, borderWidth);
			g.DrawRectangle(LinePen, new Rectangle(Rect.X, Rect.Y, Rect.Width - 1, Rect.Height - 1));
			LinePen.Dispose();
			Rect = new Rectangle(Rect.X + 1, Rect.Y + 1, Rect.Width - 2, Rect.Height - 2);
			//
			// Fill background
			//
			//		SolidBrush bgBrush = new SolidBrush(ControlPaint.Dark(RectColor));
			//		g.FillRectangle(bgBrush, Rect);
			//		bgBrush.Dispose();

			//
			// The gradient brush
			//
			LinearGradientBrush brush;
			Rectangle FirstRect, SecondRect;
			switch (barOrientation)
			{
				case Orientations.Horizontal:
					FirstRect = new Rectangle(Rect.X, Rect.Y, Rect.Width, Rect.Height / 2);
					SecondRect = new Rectangle(Rect.X, Rect.Height / 2, Rect.Width, Rect.Height / 2);
					// Paint upper half
					brush = new LinearGradientBrush(
						new Point(FirstRect.Width / 2, FirstRect.Top),
						new Point(FirstRect.Width / 2, FirstRect.Bottom),
						RectColor2,
						RectColor);
					g.FillRectangle(brush, FirstRect);
					brush.Dispose();
					// Paint lower half
					// (SecondRect.Y - 1 because there would be a dark line in the middle of the bar)
					brush = new LinearGradientBrush(
						new Point(SecondRect.Width / 2, SecondRect.Top - 1),
						new Point(SecondRect.Width / 2, SecondRect.Bottom),
						RectColor,
						RectColor2);
					g.FillRectangle(brush, SecondRect);
					brush.Dispose();

					break;
				case Orientations.Vertical:
					FirstRect = new Rectangle(Rect.X, Rect.Y, Rect.Width / 2, Rect.Height);
					SecondRect = new Rectangle(Rect.Width / 2, Rect.Y, Rect.Width / 2, Rect.Height);
					// Paint left half
					brush = new LinearGradientBrush(
						new Point(FirstRect.Left, FirstRect.Height / 2),
						new Point(FirstRect.Right, FirstRect.Height / 2),
						RectColor2,
						RectColor);
					g.FillRectangle(brush, FirstRect);
					brush.Dispose();
					// Paint right half
					// (SecondRect.X - 1 because there would be a dark line in the middle of the bar)
					brush = new LinearGradientBrush(
						new Point(SecondRect.Left - 1, SecondRect.Height / 2),
						new Point(SecondRect.Right, SecondRect.Height / 2),
						RectColor,
						RectColor2);
					g.FillRectangle(brush, SecondRect);
					brush.Dispose();
					break;
				default:
					break;
			}
		}
		protected void PaintPath(Rectangle rect, GraphicsPath PaintPath, Color PathColor, Color PathColor2, Color PathColor3, Graphics g)
		{
			//
			// Fill background
			//

			using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Black, Color.Black, 0f))
			{
				brush.WrapMode = WrapMode.TileFlipXY;
				ColorBlend blend = new ColorBlend();
				blend.Colors = new Color[] { PathColor, PathColor3, PathColor2 };
				blend.Positions = new float[] { 0f, 0.5f, 1f };
				brush.InterpolationColors = blend;
				g.FillRegion(brush, new Region(PaintPath));

			}
		}

		private GraphicsPath GetCapsule(RectangleF baseRect)
		{
			float diameter;
			RectangleF arc;
			GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
			try
			{
				if (baseRect.Width > baseRect.Height)
				{
					// return horizontal capsule 
					diameter = baseRect.Height;
					SizeF sizeF = new SizeF(diameter, diameter);
					arc = new RectangleF(baseRect.Location, sizeF);
					path.AddArc(arc, 90, 180);
					arc.X = baseRect.Right - diameter;
					path.AddArc(arc, 270, 180);
				}
				else if (baseRect.Width < baseRect.Height)
				{
					// return vertical capsule 
					diameter = baseRect.Width;
					SizeF sizeF = new SizeF(diameter, diameter);
					arc = new RectangleF(baseRect.Location, sizeF);
					path.AddArc(arc, 180, 180);
					arc.Y = baseRect.Bottom - diameter;
					path.AddArc(arc, 0, 180);
				}
				else
				{
					// return circle 
					path.AddEllipse(baseRect);
				}
			}
			catch (Exception )
			{
				path.AddEllipse(baseRect);
			}
			finally
			{
				path.CloseFigure();
			}
			return path;
		}

		private GraphicsPath GetRoundedRect(RectangleF baseRect,
		 float radius)
		{
			// if corner radius is less than or equal to zero, 
			// return the original rectangle 
			if (radius <= 0.0F)
			{
				GraphicsPath mPath = new GraphicsPath();
				mPath.AddRectangle(baseRect);
				mPath.CloseFigure();
				return mPath;
			}

			// if the corner radius is greater than or equal to 
			// half the width, or height (whichever is shorter) 
			// then return a capsule instead of a lozenge 
			if (radius >= (Math.Min(baseRect.Width, baseRect.Height)) / 2.0)
				return GetCapsule(baseRect);

			// create the arc for the rectangle sides and declare 
			// a graphics path object for the drawing 
			float diameter = radius * 2.0F;
			SizeF sizeF = new SizeF(diameter, diameter);
			RectangleF arc = new RectangleF(baseRect.Location, sizeF);
			GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();

			// top left arc 
			path.AddArc(arc, 180, 90);

			// top right arc 
			arc.X = baseRect.Right - diameter;
			path.AddArc(arc, 270, 90);

			// bottom right arc 
			arc.Y = baseRect.Bottom - diameter;
			path.AddArc(arc, 0, 90);

			// bottom left arc
			arc.X = baseRect.Left;
			path.AddArc(arc, 90, 90);

			path.CloseFigure();
			return path;
		}

		protected GraphicsPath DrawRoundedCorners(Rectangle Rect, Color BorderColor, Graphics g)
		{
			GraphicsPath gPath = new GraphicsPath();
			try
			{
				Pen LinePen = new Pen(BorderColor, borderWidth + 1);
				switch (barOrientation)
				{
					case Orientations.Horizontal:
						Rectangle LeftRect, RightRect;
						LeftRect = new Rectangle(Rect.X, Rect.Y + 1, Rect.Height - 1, Rect.Height - 2);
						RightRect = new Rectangle(Rect.X + (Rect.Width - Rect.Height), Rect.Y + 1, Rect.Height - 1, Rect.Height - 2);
						//build shape

						gPath.AddArc(LeftRect, 90, 180);
						gPath.AddLine(
							LeftRect.X + LeftRect.Width / 2 + 2, LeftRect.Top + 1,
							RightRect.X + (RightRect.Width / 2) - 1, RightRect.Top + 1);
						gPath.AddArc(RightRect, 270, 180);
						gPath.AddLine(RightRect.X + (RightRect.Width / 2), RightRect.Bottom, LeftRect.X + (LeftRect.Width / 2), LeftRect.Bottom);

						gPath.CloseFigure();
						g.DrawPath(LinePen, gPath);
						break;
					case Orientations.Vertical:
						Rectangle TopRect, BotRect;
						TopRect = new Rectangle(Rect.X + 1, Rect.Y, Rect.Width - 2, Rect.Width - 1);
						BotRect = new Rectangle(Rect.X + 1, Rect.Y + (Rect.Height - Rect.Width), Rect.Width - 2, Rect.Width - 1);
						//build shape
						gPath.AddArc(TopRect, 180, 180);
						gPath.AddLine(TopRect.Right, TopRect.Y + TopRect.Height / 2, BotRect.Right, BotRect.Y + BotRect.Height / 2 + 1);
						gPath.AddArc(BotRect, 0, 180);
						gPath.AddLine(BotRect.Left + 1, BotRect.Y + BotRect.Height / 2 - 1,
							TopRect.Left + 1, TopRect.Y + TopRect.Height / 2 + 2);
						gPath.CloseFigure();
						g.DrawPath(LinePen, gPath);
						break;
					default:
						break;
				}
			}
			catch (Exception )
			{
				//throw new Exception("DrawRoundedCornersException: "+Err.Message);
			}
			return gPath;

		}
		#endregion
	}
}
