context: // *****************************************************************************
  // 
  //  (c) Crownwood Consulting Limited 2002-2003
  //  All rights reserved. The software and associated documentation 
  //  supplied hereunder are the proprietary information of Crownwood Consulting 
  //	Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject 
  //  to licence terms.
  // 
  //  Magic Version 1.7.4.0 	www.dotnetmagic.com
  // *****************************************************************************
  
  using System;
  using System.IO;
  using System.Text;
  using System.Drawing;
  using System.Resources;
  using System.Reflection;
  using System.Collections;
  using System.Drawing.Text;
  using System.Windows.Forms;
  using System.ComponentModel;
  using System.Drawing.Imaging;
  using Microsoft.Win32;
  using Crownwood.Magic.Win32;
  using Crownwood.Magic.Menus;
  using Crownwood.Magic.Common;
  using Crownwood.Magic.Collections;
  
  namespace Crownwood.Magic.Controls
  {
      [ToolboxBitmap(typeof(TabControl))]
      [DefaultProperty("Appearance")]
      [DefaultEvent("SelectionChanged")]
      [Designer(typeof(Crownwood.Magic.Controls.TabControlDesigner))]
      public class TabControl : Panel
      {
          // Enumeration of appearance styles
          public enum VisualAppearance
          {
              MultiDocument = 0,
              MultiForm = 1,
              MultiBox = 2
          }
  
          // Enumeration of modes that control display of the tabs area
          public enum HideTabsModes
          {
              ShowAlways,
              HideAlways,
              HideUsingLogic,
              HideWithoutMouse
          }
  
          // Indexes into the menu images strip
          protected enum ImageStrip
          {
              LeftEnabled = 0,
              LeftDisabled = 1,
              RightEnabled = 2,
              RightDisabled = 3,
              Close = 4,
              Error = 5
          }
  
          // Enumeration of Indexes into positioning constants array
          protected enum PositionIndex
          {
              BorderTop			= 0,
              BorderLeft			= 1,
              BorderBottom		= 2, 
              BorderRight			= 3,
              ImageGapTop			= 4,
              ImageGapLeft		= 5,
              ImageGapBottom		= 6,
              ImageGapRight		= 7,
              TextOffset			= 8,
              TextGapLeft			= 9,
              TabsBottomGap		= 10,
              ButtonOffset		= 11,
          }
  
          // Helper class for handling multiline calculations
          protected class MultiRect
          {
              protected Rectangle _rect;
              protected int _index;
  
              public MultiRect(Rectangle rect, int index)
              {
                  _rect = rect;
                  _index = index;
              }
  
              public int Index
              {
                  get { return _index; }
              }            
              
              public Rectangle Rect
              {
                  get { return _rect; }
                  set { _rect = value; }
              }
              
              public int X
              {
                  get { return _rect.X; }
                  set { _rect.X = value; }
              }
  
              public int Y
              {
                  get { return _rect.Y; }
                  set { _rect.Y = value; }
              }
  
              public int Width
              {
                  get { return _rect.Width; }
                  set { _rect.Width = value; }
              }
  
              public int Height
              {
                  get { return _rect.Height; }
                  set { _rect.Height = value; }
              }
          }
          
          // Class constants for sizing/positioning each style
          protected static int[,] _position = { 
                                                  {3, 1, 1, 1, 1, 2, 1, 1, 2, 1, 3, 2},	// IDE
                                                  {6, 2, 2, 3, 3, 1, 1, 0, 1, 1, 2, 0}	// Plain
                                              };
  
          // Class constants
          protected static int _plainBorder = 3;
          protected static int _plainBorderDouble = 6;
          protected static int _tabsAreaStartInset = 5;
          protected static int _tabsAreaEndInset = 5;
          protected static float _alphaIDE = 1.5F;
          protected static int _buttonGap = 3;
          protected static int _buttonWidth = 14;
          protected static int _buttonHeight = 14;
          protected static int _imageButtonWidth = 12;
          protected static int _imageButtonHeight = 12;
          protected static int _multiBoxAdjust = 2;
          protected readonly Rectangle _nullPosition = new Rectangle(-999, -999, 0, 0);
  
          // Class state
          protected static ImageList _internalImages;
  
          // Instance fields - size/positioning
          protected int _textHeight;
          protected int _imageWidth;
          protected int _imageHeight;
          protected int _imageGapTopExtra;
          protected int _imageGapBottomExtra;
          protected Rectangle _pageRect;
          protected Rectangle _pageAreaRect;
          protected Rectangle _tabsAreaRect;
  
          // Instance fields - state
          protected int _ctrlTopOffset;			// How far from top edge embedded controls should offset
          protected int _ctrlLeftOffset;			// How far from left edge embedded controls should offset
          protected int _ctrlRightOffset;			// How far from right edgeembedded controls should offset
          protected int _ctrlBottomOffset;	    // How far from bottom edge embedded controls should offset
          protected int _styleIndex;				// Index into position array
          protected int _pageSelected;			// index of currently selected page (-1 is none)
          protected int _startPage;				// index of first page to draw, used when scrolling pages
          protected int _hotTrackPage;			// which page is currently displayed as being tracked
          protected int _topYPos;                 // Y position of first line in multiline mode
          protected int _bottomYPos;              // Y position of last line in multiline mode
          protected int _leaveTimeout;            // How long from leaving to timeout occuring
          protected bool _dragFromControl;        // Must drag away from whole control before drag events generated
          protected bool _mouseOver;              // Mouse currently over the control (or child pages)
          protected bool _multiline;              // should tabs that cannot fit on a line create new lines
          protected bool _multilineFullWidth;     // when in multiline mode, all lines are extended to end 
          protected bool _shrinkPagesToFit;		// pages are shrunk so they all fit in control width
          protected bool _changed;				// Flag for use when updating contents of collection
          protected bool _positionAtTop;			// display tabs at top or bottom of the control
          protected bool _showClose;				// should the close button be displayed
          protected bool _showArrows;				// should then scroll arrow be displayed
          protected bool _insetPlain;				// Show the inset border for controls
          protected bool _insetBorderPagesOnly;   // Remove the border entirely for Plain mode
          protected bool _selectedTextOnly;	    // Only draw text for selected tab
          protected bool _rightScroll;			// Should the right scroll button be enabled
          protected bool _leftScroll;				// Should the left scroll button be enabled
          protected bool _dimUnselected;			// should unselected pages be drawn slightly dimmed
          protected bool _boldSelected;			// should selected page use a bold font
          protected bool _hotTrack;				// should mouve moving over text hot track it
          protected bool _hoverSelect;			// select a page when he mouse hovers over it
          protected bool _recalculate;			// flag to indicate recalculation is needed before painting
          protected bool _leftMouseDown;			// Is the left mouse button down
          protected bool _leftMouseDownDrag;		// Has a drag operation begun
          protected bool _ignoreDownDrag;         // When pressed the left button cannot generate two drags
          protected bool _defaultColor;			// Is the background color the default one?
          protected bool _defaultFont;			// Is the Font the default one?
  		protected bool _recordFocus;			// Record the control with focus when leaving a page
          protected bool _idePixelArea;           // Place a one pixel border at top/bottom of tabs area
          protected bool _idePixelBorder;         // Place a one pixel border around control
  		protected bool _dragOverSelect;			// Should dragging over a tab cause selection?
          protected PopupMenu _contextMenu;       // Context menu to show on right mouse up
          protected Point _leftMouseDownPos;		// Initial mouse down position for left mouse button
  		protected Point _mouseDragOver;			// Mouse position for drag over event
          protected Color _hotTextColor;			// color for use when drawing text as hot
          protected Color _textColor;				// color for use when text not hot
          protected Color _textInactiveColor;	    // color for use when text not hot and not the active tab
          protected Color _backIDE;				// background drawing color when in IDE appearance
          protected Color _buttonActiveColor;		// color for drawing buttons images when active
          protected Color _buttonInactiveColor;	// color for drawing buttons images when inactive
          protected Color _backLight;				// light variation of the back color
          protected Color _backLightLight;		// lightlight variation of the back color
          protected Color _backDark;				// dark variation of the back color
          protected Color _backDarkDark;			// darkdark variation of the back color
          protected VisualStyle _style;			// which style of use 
          protected HideTabsModes _hideTabsMode;  // Decide when to hide/show tabs area
          protected Timer _overTimer;             // Time when mouse has left control
  		protected Timer _dragTimer;             // Time when mouse hovers in drag over
  		protected VisualAppearance _appearance;	// which appearance style
          protected ImageList _imageList;			// collection of images for use is tabs
          protected ArrayList _tabRects;			// display rectangles for associated page
          protected TabPageCollection _tabPages;	// collection of pages
  
          // Instance fields - buttons
          protected InertButton _closeButton;
          protected InertButton _leftArrow;
          protected InertButton _rightArrow;
  
          public delegate void DoubleClickTabHandler(TabControl sender, TabPage page);
  
          // Exposed events
          public event EventHandler ClosePressed;
          public event EventHandler SelectionChanging;
          public event EventHandler SelectionChanged;
          public event EventHandler PageGotFocus;
          public event EventHandler PageLostFocus;
          public event CancelEventHandler PopupMenuDisplay;
          public event MouseEventHandler PageDragStart;
          public event MouseEventHandler PageDragMove;
          public event MouseEventHandler PageDragEnd;
          public event MouseEventHandler PageDragQuit;
          public event DoubleClickTabHandler DoubleClickTab;
  
          static TabControl()
          {
              // Create a strip of images by loading an embedded bitmap resource
              _internalImages = ResourceHelper.LoadBitmapStrip(Type.GetType("Crownwood.Magic.Controls.TabControl"),
                                                               "Crownwood.Magic.Resources.ImagesTabControl.bmp",
                                                               new Size(_imageButtonWidth, _imageButtonHeight),
                                                               new Point(0,0));
          }
  
          public TabControl()
          {
              // Prevent flicker with double buffering and all painting inside WM_PAINT
  			SetStyle(ControlStyles.DoubleBuffer | 
  				     ControlStyles.AllPaintingInWmPaint |
  				     ControlStyles.UserPaint, true);
  
              // Create collections
              _tabRects = new ArrayList();
              _tabPages = new TabPageCollection();
  
              // Hookup to collection events
              _tabPages.Clearing += new CollectionClear(OnClearingPages);
              _tabPages.Cleared += new CollectionClear(OnClearedPages);
              _tabPages.Inserting += new CollectionChange(OnInsertingPage);
              _tabPages.Inserted += new CollectionChange(OnInsertedPage);
              _tabPages.Removing += new CollectionChange(OnRemovingPage);
              _tabPages.Removed += new CollectionChange(OnRemovedPage);
  
              // Define the default state of the control
              _startPage = -1;						
              _pageSelected = -1;						
              _hotTrackPage = -1;					
              _imageList = null;						
              _insetPlain = true;
              _multiline = false;
              _multilineFullWidth = false;
              _dragFromControl = true;
              _mouseOver = false;
              _leftScroll = false;
              _defaultFont = true;
              _defaultColor = true;
              _rightScroll = false;
              _hoverSelect = false;
              _leftMouseDown = false;
              _ignoreDownDrag = true;
              _selectedTextOnly = false;
              _leftMouseDownDrag = false;
              _insetBorderPagesOnly = false;
  			_dragOverSelect = true;
              _hideTabsMode = HideTabsModes.ShowAlways;
  			_recordFocus = true;
              _styleIndex = 1;
              _leaveTimeout = 200;
              _ctrlTopOffset = 0;
              _ctrlLeftOffset = 0;
              _ctrlRightOffset = 0;
              _ctrlBottomOffset = 0;
              _style = VisualStyle.IDE;
              _buttonActiveColor = Color.FromArgb(128, this.ForeColor);
              _buttonInactiveColor = _buttonActiveColor;
              _textColor = TabControl.DefaultForeColor;	
              _textInactiveColor = Color.FromArgb(128, _textColor);
              _hotTextColor = SystemColors.ActiveCaption;
  
              // Create hover buttons
              _closeButton = new InertButton(_internalImages, (int)ImageStrip.Close);
              _leftArrow = new InertButton(_internalImages, (int)ImageStrip.LeftEnabled, (int)ImageStrip.LeftDisabled);
              _rightArrow = new InertButton(_internalImages, (int)ImageStrip.RightEnabled, (int)ImageStrip.RightDisabled);
  
              // We want our buttons to have very thin borders
              _closeButton.BorderWidth = _leftArrow.BorderWidth = _rightArrow.BorderWidth = 1;
  
              // Hookup to the button events
              _closeButton.Click += new EventHandler(OnCloseButton);
              _leftArrow.Click += new EventHandler(OnLeftArrow);
              _rightArrow.Click += new EventHandler(OnRightArrow);
  
              // Set their fixed sizes
              _leftArrow.Size = _rightArrow.Size = _closeButton.Size = new Size(_buttonWidth, _buttonHeight);
  
              // Add child controls
              Controls.AddRange(new Control[]{_closeButton, _leftArrow, _rightArrow});
  
              // Grab some contant values
              _imageWidth = 16;
              _imageHeight = 16;
  
              // Default to having a MultiForm usage
              SetAppearance(VisualAppearance.MultiForm);
              
              // Need a timer so that when the mouse leaves, a fractionaly delay occurs before
              // noticing and hiding the tabs area when the appropriate style is set
              _overTimer = new Timer();
              _overTimer.Interval = _leaveTimeout;
              _overTimer.Tick += new EventHandler(OnMouseTick);
  
  			// Need a timer so that when the mouse hovers in drag over mode the page then changes
  			_dragTimer = new Timer();
  			_dragTimer.Interval = 200;
  			_dragTimer.Tick += new EventHandler(OnDragOverTick);
  
              // Need notification when the MenuFont is changed
              Microsoft.Win32.SystemEvents.UserPreferenceChanged += 
                  new UserPreferenceChangedEventHandler(OnPreferenceChanged);
  
              // Define the default Font, BackColor and Button images
              DefineFont(SystemInformation.MenuFont);
              DefineBackColor(SystemColors.Control);
              DefineButtonImages();
  			ResetAllowDrop();
  			ResetDragOverSelect();
  
              Recalculate();
          }
  
          protected override void Dispose( bool disposing )
          {
              if(disposing)
              {
                  // Remove notifications
                  Microsoft.Win32.SystemEvents.UserPreferenceChanged -= 
                      new UserPreferenceChangedEventHandler(OnPreferenceChanged);
              }
              base.Dispose(disposing);
          }
  
  		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  		public new Control.ControlCollection Controls 
  		{
  			get { return base.Controls; }
  		}
  
  		[Category("Appearance")]
          [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
          public virtual TabPageCollection TabPages
          {
              get { return _tabPages; }
          }
  
          [Category("Appearance")]
          public override Font Font
          {
              get { return base.Font; }
  
              set
              {
  				if (value != null)
  				{
  					if (value != base.Font)
  					{
  
gt: 						_defaultFont = (value == SystemInformation.MenuFont);