context: #region Copyright GPLv3
  //
  //  This file is part of ILNumerics.Net. 
  //
  //  ILNumerics.Net supports numeric application development for .NET 
  //  Copyright (C) 2007, H. Kutschbach, http://ilnumerics.net 
  //
  //  This program is free software: you can redistribute it and/or modify
  //  it under the terms of the GNU General Public License as published by
  //  the Free Software Foundation, either version 3 of the License, or
  //  any later version.
  //
  //  This program is distributed in the hope that it will be useful,
  //  but WITHOUT ANY WARRANTY; without even the implied warranty of
  //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  //  GNU General Public License for more details.
  //
  //  You should have received a copy of the GNU General Public License
  //   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  // 
  //  Non-free licenses are also available. Contact info@ilnumerics.net 
  //  for details.
  //
  #endregion
  
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Drawing; 
  using System.Reflection; 
  using System.Windows.Forms;
  using System.IO; 
  using ILNumerics.Drawing; 
  using ILNumerics.Drawing.Interfaces;
  using ILNumerics.Drawing.Collections; 
  using ILNumerics.Drawing.Graphs; 
  using ILNumerics.Drawing.Labeling; 
  using ILNumerics.Drawing.Misc; 
  using System.Diagnostics; 
  
  namespace ILNumerics.Drawing.Controls {
  
      /// <summary>
      /// Basic abstract base class for GL dependent display.
      /// </summary>
      /// <remarks>This control is the main plot control of ILNumerics.Net.</remarks>
      public abstract class ILPanel : Control {
  
          #region attributes 
          protected ILRendererManager m_textRendererManager; 
          protected ILClippingData m_clippingView; 
          protected ILAxisCollection m_axes;
          protected ILGraphCollection m_graphs;
          protected ILTextureManager m_textureManager; 
          protected Point m_mouseStart; 
          protected bool m_isDragging; 
          protected bool m_active = false; 
          protected bool m_drawHidden = true; 
          protected bool m_ready = false; 
          private bool m_isStartingUp = true; 
          protected ILCamera m_camera;
          protected ILCamera m_defaultView;
          protected bool m_autoDefaultView = true; 
          protected InteractiveModes m_selectingMode = InteractiveModes.Rotating; 
          protected InteractiveModes m_oldSelectingMode; 
          protected bool m_isCtrlKeyDown; 
          protected ILPoint3Df m_scaling;
          protected Projection m_projection = Projection.Orthographic; 
          protected Color m_backColor = Color.FromKnownColor(KnownColor.Control);
          protected Color m_cubeBGColor = Color.Snow; 
          protected ILColormap m_colormap; 
          protected ILLegend m_legend; 
          protected ZoomModes m_zoomMode = ZoomModes.RollHard; 
          protected ILZoomAction m_zoomAction; 
          protected float m_zoomOffset = 50f;
          protected GraphicDeviceType m_graphicsDevice; 
          protected ILLineProperties m_selectionRectangle; 
          protected bool m_fillBackground = true; 
          private AutoZoomOptions m_autoZoomOptions = AutoZoomOptions.OnDataChanges; 
          protected ILLayoutData m_layoutData = new ILLayoutData(); 
          protected ILLightCollection m_lights = new ILLightCollection(); 
          protected ILRenderProperties m_renderProperties; 
          protected ILAction m_action;
          protected List<ILGraph> m_sortingCacheList = new List<ILGraph>(); 
          /// <summary>
          /// pixel size of the current PlotCubeScreenRectangle
          /// </summary>
          protected RectangleF m_plotBoxScreenRectF;
          protected PlotBoxScreenSizeMode m_plotBoxScreenSizeMode;
          protected AspectRatioMode m_aspectRatio; 
          protected double[] m_clipplanes = new double[24]; 
          
          private const int MAXRENDERPASSES = 2; 
          private const float LABELS_VERTICAL_MIN_RHO = 0.8f; 
          protected const float pi05 = (float) Math.PI / 2; 
          protected const float pi2 = (float) Math.PI * 2; 
          protected const float pi32 = (float) Math.PI / 2 * 3; 
          protected const float pi4 = (float) Math.PI / 4; 
          protected const float pi8 = (float) Math.PI / 8; 
          #endregion
  
          #region properties
          public bool AutoDefaultView { 
              get { return m_autoDefaultView; }
              set { m_autoDefaultView = value; }
          }
          /// <summary>
          /// Determines how the projected data plots are mapped to PlotCubeScreenRectF
          /// </summary>
          public AspectRatioMode AspectRatio {
              get { return m_aspectRatio; }
              set { m_aspectRatio = value; }
          }
          /// <summary>
          /// the normalizes projected size (range 0..1) of plot cube on 2D client area, set: sets PlotCubeScreenMode -> Manual
          /// </summary>
          public RectangleF PlotBoxScreenRect {
              get { return m_plotBoxScreenRectF; }
              set { 
                  m_plotBoxScreenRectF = value;
                  m_plotBoxScreenSizeMode = PlotBoxScreenSizeMode.Manual; 
                  //Invalidate(); 
              }
          }
          /// <summary>
          /// options for determining the size of the plot cube on the 2D screen client area, default: optimal
          /// </summary>
          public PlotBoxScreenSizeMode PlotBoxScreenSizeMode {
              get { return m_plotBoxScreenSizeMode; }
              set {
                  m_plotBoxScreenSizeMode = value;
                  if (value == PlotBoxScreenSizeMode.Maximum) {
                      m_plotBoxScreenRectF = new RectangleF(0, 0, 1f, 1f);
                  }
              }
          }
          /// <summary>
          /// Access collection of lights for configuration
          /// </summary>
          public ILLightCollection Lights {
              get { return m_lights; }
          }
          /// <summary>
          /// Legend for panel's graphs
          /// </summary>
          public ILLegend Legend {
              get {
                  return m_legend; 
              }
          }
          /// <summary>
          /// Get texture manager instance, storing all textures used in the scene
          /// </summary>
          internal ILTextureManager TextureManager {
              get {
                  return m_textureManager; 
              }
          }
          /// <summary>
          /// Colormap used to translate color indices into true colors
          /// </summary>
          public ILColormap Colormap {
              get {
                  return m_colormap; 
              }
              set {
                  m_colormap = value;
                  OnColormapChanged(); 
              }
          }
          /// <summary>
          /// Determines if background of the rendering cube will be filled with the CubeBackgroundColor property value
          /// </summary>
          public bool BackgroundFilled {
              get {
                  return m_fillBackground; 
              }
              set {
                  m_fillBackground = value; 
                  //Invalidate(); 
              }
          }
          /// <summary>
          /// true: the control will always be drawn, even if it does not own the focus
          /// </summary>
          public bool DrawInactive {
              get {
                  return m_drawHidden; 
              }
              set {
                  m_drawHidden = value; 
                  //Invalidate(); 
              }
          }
          /// <summary>
          /// Get/set the background color for the inner cube drawing 
          /// </summary>
          public Color BackColorCube {
              get {
                  return m_cubeBGColor; 
              }
              set {
                  m_cubeBGColor = value; 
                  //Invalidate();
              }
          }
          /// <summary>
          /// View settings, get access to the clipping limits for all axises 
          /// </summary>
          public ILClippingData Limits {
              get {
                  return m_clippingView; 
              } 
          }
          /// <summary>
          /// Get the type of device currently used for rendering
          /// </summary>
          public GraphicDeviceType GraphicDeviceType {
              get {
                  return m_graphicsDevice; 
              }
          }
          /// <summary>
          /// Get/set properties for selection rectangle, drawn when zooming with the mouse
          /// </summary>
          public ILLineProperties SelectionRectangle {
              get {
                  return m_selectionRectangle; 
              }
          }
          /// <summary>
          /// color of the figure background
          /// </summary>
          public override Color BackColor {
              get {
                  return m_backColor; 
              }
              set {
                  m_backColor = value; 
                  //Invalidate();
              }
          }
          /// <summary>
          /// type of projection: orthographic (default) or perspective
          /// </summary>
          public Projection Projection {
              get {
                  return m_projection; 
              }
              set {
                  m_projection = value; 
                  //Invalidate();
              }
          }
          /// <summary>
          /// Get or set viewport properties (distance &amp; angles)
          /// </summary>
          /// <remarks>Changing </remarks>
          public ILCamera Camera {
              get {
                  return m_camera; 
              }
          }
          /// <summary>
          /// Get the current mode for mouse interaction or set's it
          /// </summary>
          public InteractiveModes InteractiveMode {
              get {
                  return m_selectingMode; 
              } 
              set {
                  m_selectingMode = value;
                  m_oldSelectingMode = value;
                  //if (value == InteractiveModes.Rotating)
                  //    m_axes[AxisNames.ZAxis].Visible = true;
                  //else if (value == InteractiveModes.ZoomRectangle) 
                  //    m_axes[AxisNames.ZAxis].Visible = false; 
              }
          }
          /// <summary>
          /// Gives all graphs as value collection (readonly)
          /// </summary>
          public ILGraphCollection Graphs {
              get { 
                  if (m_graphs == null) 
                      CreateControl(); 
                  return m_graphs;
              }
          }
          /// <summary>
          /// Get axes collection - holds all 3 axes
          /// </summary>
          public ILAxisCollection Axes {
              get {
                  if (m_axes == null) 
                      CreateControl();
                  return m_axes; 
              }
          }
          /// <summary>
          /// (experimental) content for graphs will be clipped outside the unit cube
          /// </summary>
          /// <remarks>For 2D plots, not clipping the vertex data may lead to hiding 
          /// the labels drawn next to axes. For 3D plots Clipping may cause unexpected behavior. 
          /// <para>Therefore Clipping will be activated for 2D plots by default and 
          /// deactivated for 3D plots by default.</para></remarks>
          public bool ClipViewData {
              get {
                  return m_renderProperties.Clipping; 
              }
              set {
                  m_renderProperties.Clipping = value; 
              }
          }
          /// <summary>
          /// Manager providing collection of available IILTextRenderer types
          /// </summary>
          /// <remarks>IILTextRenderer are used to draw labels for axis of this panel (device specific).
          /// <para>Text renderer objects must be instantiated through the ILTextRendererManager instance's
          /// CreateInstance() method.</para></remarks>
          public ILRendererManager TextRendererManager {
              get {
                  return m_textRendererManager; 
              }
          }
          /// <summary>
          /// Get or set default camera position for reset of the scene
          /// </summary>
          /// <remarks>The default position is used when the scene is reset. That
          /// reset is usually triggered by double clicking the panel with the mouse.
          /// <para>setting this value to null will make the panel ignore any double
          /// clicks, which enables the user to manually react to double click via the 
          /// common DoubleClick event of the panel and reset the camera position from
          /// outside the component.</para></remarks>
          public ILCamera DefaultView {
              get {
                  return m_defaultView; 
              }
              protected set {
                  if (value != null) {
                      m_defaultView = value;
                      m_autoDefaultView = false; 
                  } else {
                      m_autoDefaultView = true; 
                  }
              }
          }
          /// <summary>
          /// Options for the view cube adapting data limit changes 
          /// </summary>
          public AutoZoomOptions AutoZoomContent {
              get {
                  return m_autoZoomOptions; 
              }
              set {
                  m_autoZoomOptions = value;
              }
          }
          /// <summary>
          /// choose the ramp for zooming
          /// </summary>
          public ZoomModes ZoomMode {
              get { return m_zoomMode; }
              set { m_zoomMode = value; }
          }
          /// <summary>
          /// How much the view cube will be shrinked/expanded on zooming operations (percent)
          /// </summary>
          public float ZoomOffset {
              set { m_zoomOffset = value; }
              get { return m_zoomOffset; }
  
          }
          protected ILZoomAction ZoomAction {
              get {
                  return m_zoomAction; 
              }   
          }
          #endregion
  
          #region constructors
          protected ILPanel(GraphicDeviceType graphicsDevice) : base () {
  #if TRACE 
              Trace.TraceInformation("{0},{1} ILPanel.ctor()",DateTime.Now, Environment.TickCount); 
  #endif
              this.DoubleBuffered = false; 
              //BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
              m_plotBoxScreenSizeMode = PlotBoxScreenSizeMode.Optimal; 
              m_graphicsDevice = graphicsDevice; 
              m_textureManager = new ILTextureManager(m_graphicsDevice);
              m_textureManager.DefaultHeight = 500; 
              m_textureManager.DefaultWidth = 500; 
              m_selectionRectangle = new ILLineProperties();
              m_selectionRectangle.Antialiasing = false; 
              m_selectionRectangle.Color = Color.Blue; 
              m_selectionRectangle.Width = 1; 
              m_selectionRectangle.Style = LineStyle.Solid; 
              m_selectionRectangle.Changed += new EventHandler(m_selectionRectangle_Changed);
              m_camera = new ILCamera((float)0.0f,0.0f,10.0f);
              m_defaultView = new ILCamera(m_camera);
              m_defaultView.Changed += new EventHandler(m_defaultView_Changed);
              m_renderProperties = new ILRenderProperties ();
              m_renderProperties.Camera = Camera; 
              m_textRendererManager = new ILRendererManager(this); 
              m_clippingView = new ILClippingData();
              m_clippingView.AllowZeroVolume = false; 
              m_layoutData = new ILLayoutData(m_camera);
              m_clippingView.Changed += new ILClippingDataChangedEvent(m_viewLimits_Changed);
              m_colormap = new ILColormap();
              m_colormap.Changed += new EventHandler(m_colormap_Changed);
              Padding = new Padding(5);
              BackColor = Color.White;
              Dock = DockStyle.Fill; 
              m_legend = ILLegend.Create(this);
  
gt:             m_legend.Changed += new EventHandler(m_legend_Changed);