context: using System;
  using System.Diagnostics;
  using System.Drawing;
  using System.Drawing.Drawing2D;
  using System.Windows.Forms;
  using Aga.Controls.Tree.NodeControls;
  
  namespace Aga.Controls.Tree
  {
  	public partial class TreeViewAdv
  	{
  		public void AutoSizeColumn(TreeColumn column)
  		{
  			if (!Columns.Contains(column))
  				throw new ArgumentException("column");
  
  			DrawContext context = new DrawContext();
  			context.Graphics = Graphics.FromImage(new Bitmap(1, 1));
  			context.Font = this.Font;
  			int res = 0;
  			for (int row = 0; row < RowCount; row++)
  			{
  				if (row < RowMap.Count)
  				{
  					int w = 0;
  					TreeNodeAdv node = RowMap[row];
  					foreach (NodeControl nc in NodeControls)
  					{
  						if (nc.ParentColumn == column)
  							w += nc.GetActualSize(node, _measureContext).Width;
  					}
  					res = Math.Max(res, w);
  				}
  			}
  
  			if (res > 0)
  				column.Width = res;
  		}
  
  		private void CreatePens()
  		{
  			CreateLinePen();
  			CreateMarkPen();
  		}
  
  		private void CreateMarkPen()
  		{
  			GraphicsPath path = new GraphicsPath();
  			path.AddLines(new Point[] { new Point(0, 0), new Point(1, 1), new Point(-1, 1), new Point(0, 0) });
  			CustomLineCap cap = new CustomLineCap(null, path);
  			cap.WidthScale = 1.0f;
  
  			_markPen = new Pen(_dragDropMarkColor, _dragDropMarkWidth);
  			_markPen.CustomStartCap = cap;
  			_markPen.CustomEndCap = cap;
  		}
  
  		private void CreateLinePen()
  		{
  			_linePen = new Pen(_lineColor);
  			_linePen.DashStyle = DashStyle.Dot;
  		}
  
          protected override void OnPaint(PaintEventArgs e)
          {
              BeginPerformanceCount();
  			PerformanceAnalyzer.Start("OnPaint");
  
              DrawContext context = new DrawContext();
              context.Graphics = e.Graphics;
              context.Font = this.Font;
              context.Enabled = Enabled;
  
              int y = 0;
              int gridHeight = 0;
  
              if (UseColumns)
              {
  				DrawColumnHeaders(e.Graphics);
  				y += ColumnHeaderHeight;
                  if (Columns.Count == 0 || e.ClipRectangle.Height <= y)
                      return;
              }
  
  			int firstRowY = _rowLayout.GetRowBounds(FirstVisibleRow).Y;
              y -= firstRowY;
  
              e.Graphics.ResetTransform();
              e.Graphics.TranslateTransform(-OffsetX, y);
              Rectangle displayRect = DisplayRectangle;
              for (int row = FirstVisibleRow; row < RowCount; row++)
              {
                  Rectangle rowRect = _rowLayout.GetRowBounds(row);
                  gridHeight += rowRect.Height;
                  if (rowRect.Y + y > displayRect.Bottom)
                      break;
                  else
                      DrawRow(e, ref context, row, rowRect);
              }
  
  			if ((GridLineStyle & GridLineStyle.Vertical) == GridLineStyle.Vertical && UseColumns)
  				DrawVerticalGridLines(e.Graphics, firstRowY);
  
  			if (_dropPosition.Node != null && DragMode && HighlightDropPosition)
                  DrawDropMark(e.Graphics);
  
              e.Graphics.ResetTransform();
              DrawScrollBarsBox(e.Graphics);
  
              if (DragMode && _dragBitmap != null)
                  e.Graphics.DrawImage(_dragBitmap, PointToClient(MousePosition));
  
  			PerformanceAnalyzer.Finish("OnPaint");
  			EndPerformanceCount(e);
          }
  
  		private void DrawRow(PaintEventArgs e, ref DrawContext context, int row, Rectangle rowRect)
  		{
  			TreeNodeAdv node = RowMap[row];
  			context.DrawSelection = DrawSelectionMode.None;
  			context.CurrentEditorOwner = CurrentEditorOwner;
  			if (DragMode)
  			{
  				if ((_dropPosition.Node == node) && _dropPosition.Position == NodePosition.Inside && HighlightDropPosition)
  					context.DrawSelection = DrawSelectionMode.Active;
  			}
  			else
  			{
  				if (node.IsSelected && Focused)
  					context.DrawSelection = DrawSelectionMode.Active;
  				else if (node.IsSelected && !Focused && !HideSelection)
  					context.DrawSelection = DrawSelectionMode.Inactive;
  			}
  			context.DrawFocus = Focused && CurrentNode == node;
  			
  			OnRowDraw(e, node, context, row, rowRect);
  
  			if (FullRowSelect)
  			{
  				context.DrawFocus = false;
  				if (context.DrawSelection == DrawSelectionMode.Active || context.DrawSelection == DrawSelectionMode.Inactive)
  				{
  					Rectangle focusRect = new Rectangle(OffsetX, rowRect.Y, ClientRectangle.Width, rowRect.Height);
  					if (context.DrawSelection == DrawSelectionMode.Active)
  					{
  						e.Graphics.FillRectangle(SystemBrushes.Highlight, focusRect);
  						context.DrawSelection = DrawSelectionMode.FullRowSelect;
  					}
  					else
  					{
  						e.Graphics.FillRectangle(SystemBrushes.InactiveBorder, focusRect);
  						context.DrawSelection = DrawSelectionMode.None;
  					}
  				}
  			}
  
              if ((GridLineStyle & GridLineStyle.Horizontal) == GridLineStyle.Horizontal)
  				e.Graphics.DrawLine(SystemPens.InactiveBorder, 0, rowRect.Bottom, e.Graphics.ClipBounds.Right, rowRect.Bottom);
  
  			if (ShowLines)
  				DrawLines(e.Graphics, node, rowRect);
  
  			DrawNode(node, context);
  		}
  
  		private void DrawVerticalGridLines(Graphics gr, int y)
  		{
  			int x = 0;
  			foreach (TreeColumn c in Columns)
  			{
  				if (c.IsVisible)
  				{
  					x += c.Width;
  					gr.DrawLine(SystemPens.InactiveBorder, x - 1, y, x - 1, gr.ClipBounds.Bottom);
  				}
  			}
  		}
  
  		private void DrawColumnHeaders(Graphics gr)
  		{
  			PerformanceAnalyzer.Start("DrawColumnHeaders");
  			ReorderColumnState reorder = Input as ReorderColumnState;
  			int x = 0;
  			TreeColumn.DrawBackground(gr, new Rectangle(0, 0, ClientRectangle.Width + 2, ColumnHeaderHeight - 1), false, false);
  			gr.TranslateTransform(-OffsetX, 0);
  			foreach (TreeColumn c in Columns)
  			{
  				if (c.IsVisible)
  				{
  					if (x >= OffsetX && x - OffsetX < this.Bounds.Width)// skip invisible columns
  					{
  						Rectangle rect = new Rectangle(x, 0, c.Width, ColumnHeaderHeight - 1);
  						gr.SetClip(rect);
  						bool pressed = ((Input is ClickColumnState || reorder != null) && ((Input as ColumnState).Column == c));
  						c.Draw(gr, rect, Font, pressed, _hotColumn == c);
  						gr.ResetClip();
  
  						if (reorder != null && reorder.DropColumn == c)
  							TreeColumn.DrawDropMark(gr, rect);
  					}
  					x += c.Width;
  				}
  			}
  
  			if (reorder != null)
  			{
  				if (reorder.DropColumn == null)
  					TreeColumn.DrawDropMark(gr, new Rectangle(x, 0, 0, ColumnHeaderHeight));
  				gr.DrawImage(reorder.GhostImage, new Point(reorder.Location.X +  + reorder.DragOffset, reorder.Location.Y));
  			}
  			PerformanceAnalyzer.Finish("DrawColumnHeaders");
  		}
  
  		public void DrawNode(TreeNodeAdv node, DrawContext context)
  		{
  			foreach (NodeControlInfo item in GetNodeControls(node))
  			{
  				if (item.Bounds.Right >= OffsetX && item.Bounds.X - OffsetX < this.Bounds.Width)// skip invisible nodes
  				{
  					context.Bounds = item.Bounds;
  					context.Graphics.SetClip(context.Bounds);
  					item.Control.Draw(node, context);
  					context.Graphics.ResetClip();
  				}
  			}
  		}
  
  		private void DrawScrollBarsBox(Graphics gr)
  		{
  			Rectangle r1 = DisplayRectangle;
  			Rectangle r2 = ClientRectangle;
  			gr.FillRectangle(SystemBrushes.Control,
  				new Rectangle(r1.Right, r1.Bottom, r2.Width - r1.Width, r2.Height - r1.Height));
  		}
  
  		private void DrawDropMark(Graphics gr)
  		{
  			if (_dropPosition.Position == NodePosition.Inside)
  				return;
  
  			Rectangle rect = GetNodeBounds(_dropPosition.Node);
  			int right = DisplayRectangle.Right - LeftMargin + OffsetX;
  			int y = rect.Y;
  			if (_dropPosition.Position == NodePosition.After)
  				y = rect.Bottom;
  			gr.DrawLine(_markPen, rect.X, y, right, y);
  		}
  
  		private void DrawLines(Graphics gr, TreeNodeAdv node, Rectangle rowRect)
  		{
  			if (UseColumns && Columns.Count > 0)
  				gr.SetClip(new Rectangle(0, rowRect.Y, Columns[0].Width, rowRect.Bottom));
  
  			TreeNodeAdv curNode = node;
  			while (curNode != _root && curNode != null)
  			{
  				int level = curNode.Level;
  				int x = (level - 1) * _indent + NodePlusMinus.ImageSize / 2 + LeftMargin;
  				int width = NodePlusMinus.Width - NodePlusMinus.ImageSize / 2;
  				int y = rowRect.Y;
  				int y2 = y + rowRect.Height;
  
  				if (curNode == node)
  				{
  					int midy = y + rowRect.Height / 2;
  					gr.DrawLine(_linePen, x, midy, x + width, midy);
  					if (curNode.NextNode == null)
  						y2 = y + rowRect.Height / 2;
  				}
  
  				if (node.Row == 0)
  					y = rowRect.Height / 2;
  
gt: 				if (curNode.NextNode != null || curNode == node)