/// <summary>
        /// Delete the light
        /// </summary>
        public override bool DeleteLight(RhinoDoc doc, Light light, bool bUndelete)
        {
            int index = doc.Lights.Find(light.Id, false);

            if (index > -1)
            {
                return(doc.Lights.Delete(index, true));
            }
            else
            {
                for (int i = 0; i < m_light_array.Count; i++)
                {
                    Rhino.Geometry.Light custom_light = m_light_array[i];
                    if (light.Id == custom_light.Id)
                    {
                        m_light_array.RemoveAt(i);

                        // In case of custom lights, we need to trigger our own event that triggers
                        // a light table event so that the lightmanager will be notified.
                        OnCustomLightEvent(doc, LightMangerSupportCustomEvent.light_deleted, ref light);

                        return(true);
                    }
                }
            }
            return(false);
        }
        /// <summary>
        /// Modify light
        /// </summary>
        public override void ModifyLight(RhinoDoc doc, Light light)
        {
            // If light is in doc, we modify the light and the light
            // table will generate events
            int modifyed_index = doc.Lights.Find(light.Id, true);

            if (modifyed_index > -1)
            {
                Rhino.Geometry.Light light_geometry = doc.Lights[modifyed_index].LightGeometry;
                light_geometry.Intensity = light.Intensity;
                light_geometry.Diffuse   = light.Diffuse;
                light_geometry.IsEnabled = light.IsEnabled;
                light_geometry.Name      = light.Name;
                doc.Lights.Modify(light.Id, light_geometry);
            }
            else
            {
                // If not in doc, check if light matches custom light and
                // modify custom light.
                foreach (Rhino.Geometry.Light custom_light in m_light_array)
                {
                    if (light.Id == custom_light.Id)
                    {
                        custom_light.Intensity = light.Intensity;
                        custom_light.Diffuse   = light.Diffuse;
                        custom_light.IsEnabled = light.IsEnabled;
                        custom_light.Name      = light.Name;

                        // In case of custom lights, we need to trigger our own event that triggers
                        // a light table event so that the lightmanager will be notified.
                        OnCustomLightEvent(doc, LightMangerSupportCustomEvent.light_modified, ref light);
                    }
                }
            }
        }
        /// <summary>
        /// Get the Light from id
        /// </summary>
        public override bool LightFromId(RhinoDoc doc, Guid uuid, ref Light rLight)
        {
            // Check if light is in doc and return it
            int index = doc.Lights.Find(uuid, true);

            if (index > -1)
            {
                Rhino.Geometry.Light light_geometry = doc.Lights[index].LightGeometry;
                rLight = light_geometry;
                return(true);
            }
            else
            {
                // If not in doc, check if light matches custom light and return it
                foreach (Rhino.Geometry.Light custom_light in m_light_array)
                {
                    if (custom_light.Id == uuid)
                    {
                        rLight = custom_light;
                        return(true);
                    }
                }
            }
            return(false);
        }
    /// <summary>
    /// Constructs a light that represents the Sun.
    /// </summary>
    /// <param name="northAngleDegrees">The angle of North in degrees. North is the angle between positive World Y axis and model North, as measured on World XY plane.</param>
    /// <param name="azimuthDegrees">The Azimut angle value in degrees. Azimuth is the compass angle from North.</param>
    /// <param name="altitudeDegrees">The Altitude angle in degrees. Altitude is the angle above the ground plane.</param>
    /// <returns>A new sun light.</returns>
    /// <exception cref="Rhino.Runtime.RdkNotLoadedException">If the RDK is not loaded.</exception>
    public static Light CreateSunLight(double northAngleDegrees, double azimuthDegrees, double altitudeDegrees)
    {
      Rhino.Runtime.HostUtils.CheckForRdk(true, true);

      IntPtr pSun = UnsafeNativeMethods.Rdk_SunNew();
      IntPtr pSunInterface = UnsafeNativeMethods.Rdk_SunInterface(pSun);
      UnsafeNativeMethods.Rdk_Sun_SetNorth(pSunInterface, northAngleDegrees);
      UnsafeNativeMethods.Rdk_Sun_SetAzimuthAltitude(pSunInterface, azimuthDegrees, altitudeDegrees);

      Light rc = new Light();
      IntPtr pLight = rc.NonConstPointer();
      UnsafeNativeMethods.Rdk_Sun_Light(pSunInterface, pLight);
      UnsafeNativeMethods.Rdk_SunDelete(pSun);
      return rc;
    }
 /// <summary>
 /// Selects the lights and opens the Light Properties page
 /// </summary>
 public override bool OnEditLight(RhinoDoc doc, ref LightArray light_array)
 {
     for (int i = 0; i < light_array.Count(); i++)
     {
         Rhino.Geometry.Light light = light_array.ElementAt(i);
         int index = doc.Lights.Find(light.Id, true);
         if (index > -1)
         {
             Rhino.DocObjects.LightObject light_obj = doc.Lights[index];
             light_obj.Select(true);
             RhinoApp.RunScript("_-PropertiesPage _Light", true);
         }
         return(true);
     }
     return(false);
 }
    /// <summary>
    /// Constructs a light which simulates the Sun based on a given time and location on Earth.
    /// </summary>
    /// <param name="northAngleDegrees">The angle of North in degrees. North is the angle between positive World Y axis and model North, as measured on World XY plane.</param>
    /// <param name="when">The time of the measurement. The Kind property of DateTime specifies whether this is in local or universal time.
    /// <para>Local and Undefined <see cref="DateTimeKind">daytime kinds</see> in this argument are considered local.</para></param>
    /// <param name="latitudeDegrees">The latitude, in degrees, of the location on Earth.</param>
    /// <param name="longitudeDegrees">The longitude, in degrees, of the location on Earth.</param>
    /// <returns>A newly constructed light object.</returns>
    /// <exception cref="Rhino.Runtime.RdkNotLoadedException">If the RDK is not loaded.</exception>
    public static Light CreateSunLight(double northAngleDegrees, DateTime when, double latitudeDegrees, double longitudeDegrees)
    {
      Rhino.Runtime.HostUtils.CheckForRdk(true, true);

      IntPtr pSun = UnsafeNativeMethods.Rdk_SunNew();
      IntPtr pSunInterface = UnsafeNativeMethods.Rdk_SunInterface(pSun);
      UnsafeNativeMethods.Rdk_Sun_SetNorth(pSunInterface, northAngleDegrees);
      UnsafeNativeMethods.Rdk_Sun_SetLatitudeLongitude(pSunInterface, latitudeDegrees, longitudeDegrees);

      bool local = (when.Kind == DateTimeKind.Local || when.Kind == DateTimeKind.Unspecified);
      UnsafeNativeMethods.Rdk_Sun_SetDateTime(pSunInterface, local, when.Year, when.Month, when.Day, when.Hour, when.Minute, when.Second);
      Light rc = new Light();
      IntPtr pLight = rc.NonConstPointer();
      UnsafeNativeMethods.Rdk_Sun_Light(pSunInterface, pLight);
      UnsafeNativeMethods.Rdk_SunDelete(pSun);
      return rc;
    }
 public bool SetFromLight(Light light)
 {
   IntPtr pThis = NonConstPointer();
   IntPtr pConstLight = light.ConstPointer();
   return UnsafeNativeMethods.CRhinoGumball_SetFromLight(pThis, pConstLight);
 }
    internal static GeometryBase CreateGeometryHelper(IntPtr pGeometry, object parent, int subobject_index)
    {
      if (IntPtr.Zero == pGeometry)
        return null;

      int type = UnsafeNativeMethods.ON_Geometry_GetGeometryType(pGeometry);
      if (type < 0)
        return null;
      GeometryBase rc = null;

      switch (type)
      {
        case idxON_Curve: //1
          rc = new Curve(pGeometry, parent, subobject_index);
          break;
        case idxON_NurbsCurve: //2
          rc = new NurbsCurve(pGeometry, parent, subobject_index);
          break;
        case idxON_PolyCurve: // 3
          rc = new PolyCurve(pGeometry, parent, subobject_index);
          break;
        case idxON_PolylineCurve: //4
          rc = new PolylineCurve(pGeometry, parent, subobject_index);
          break;
        case idxON_ArcCurve: //5
          rc = new ArcCurve(pGeometry, parent, subobject_index);
          break;
        case idxON_LineCurve: //6
          rc = new LineCurve(pGeometry, parent, subobject_index);
          break;
        case idxON_Mesh: //7
          rc = new Mesh(pGeometry, parent);
          break;
        case idxON_Point: //8
          rc = new Point(pGeometry, parent);
          break;
        case idxON_TextDot: //9
          rc = new TextDot(pGeometry, parent);
          break;
        case idxON_Surface: //10
          rc = new Surface(pGeometry, parent);
          break;
        case idxON_Brep: //11
          rc = new Brep(pGeometry, parent);
          break;
        case idxON_NurbsSurface: //12
          rc = new NurbsSurface(pGeometry, parent);
          break;
        case idxON_RevSurface: //13
          rc = new RevSurface(pGeometry, parent);
          break;
        case idxON_PlaneSurface: //14
          rc = new PlaneSurface(pGeometry, parent);
          break;
        case idxON_ClippingPlaneSurface: //15
          rc = new ClippingPlaneSurface(pGeometry, parent);
          break;
        case idxON_Annotation2: // 16
          rc = new AnnotationBase(pGeometry, parent);
          break;
        case idxON_Hatch: // 17
          rc = new Hatch(pGeometry, parent);
          break;
        case idxON_TextEntity2: //18
          rc = new TextEntity(pGeometry, parent);
          break;
        case idxON_SumSurface: //19
          rc = new SumSurface(pGeometry, parent);
          break;
        case idxON_BrepFace: //20
          {
            int faceindex = -1;
            IntPtr pBrep = UnsafeNativeMethods.ON_BrepSubItem_Brep(pGeometry, ref faceindex);
            if (pBrep != IntPtr.Zero && faceindex >= 0)
            {
              Brep b = new Brep(pBrep, parent);
              rc = b.Faces[faceindex];
            }
          }
          break;
        case idxON_BrepEdge: // 21
          {
            int edgeindex = -1;
            IntPtr pBrep = UnsafeNativeMethods.ON_BrepSubItem_Brep(pGeometry, ref edgeindex);
            if (pBrep != IntPtr.Zero && edgeindex >= 0)
            {
              Brep b = new Brep(pBrep, parent);
              rc = b.Edges[edgeindex];
            }
          }
          break;
        case idxON_InstanceDefinition: // 22
          rc = new InstanceDefinitionGeometry(pGeometry, parent);
          break;
        case idxON_InstanceReference: // 23
          rc = new InstanceReferenceGeometry(pGeometry, parent);
          break;
#if USING_V5_SDK
        case idxON_Extrusion: //24
          rc = new Extrusion(pGeometry, parent);
          break;
#endif
        case idxON_LinearDimension2: //25
          rc = new LinearDimension(pGeometry, parent);
          break;
        case idxON_PointCloud: // 26
          rc = new PointCloud(pGeometry, parent);
          break;
        case idxON_DetailView: // 27
          rc = new DetailView(pGeometry, parent);
          break;
        case idxON_AngularDimension2: // 28
          rc = new AngularDimension(pGeometry, parent);
          break;
        case idxON_RadialDimension2: // 29
          rc = new RadialDimension(pGeometry, parent);
          break;
        case idxON_Leader: // 30
          rc = new Leader(pGeometry, parent);
          break;
        case idxON_OrdinateDimension2: // 31
          rc = new OrdinateDimension(pGeometry, parent);
          break;
        case idxON_Light: //32
          rc = new Light(pGeometry, parent);
          break;
        case idxON_PointGrid: //33
          rc = new Point3dGrid(pGeometry, parent);
          break;
        case idxON_MorphControl: //34
          rc = new MorphControl(pGeometry, parent);
          break;
        case idxON_BrepLoop: //35
          {
            int loopindex = -1;
            IntPtr pBrep = UnsafeNativeMethods.ON_BrepSubItem_Brep(pGeometry, ref loopindex);
            if (pBrep != IntPtr.Zero && loopindex >= 0)
            {
              Brep b = new Brep(pBrep, parent);
              rc = b.Loops[loopindex];
            }
          }
          break;
        case idxON_BrepTrim: // 36
          {
            int trimindex = -1;
            IntPtr pBrep = UnsafeNativeMethods.ON_BrepSubItem_Brep(pGeometry, ref trimindex);
            if (pBrep != IntPtr.Zero && trimindex >= 0)
            {
              Brep b = new Brep(pBrep, parent);
              rc = b.Trims[trimindex];
            }
          }
          break;
        default:
          rc = new UnknownGeometry(pGeometry, parent, subobject_index);
          break;
      }

      return rc;
    }
        /// <summary>
        /// Given a Rhino light, modifies the uniforms accordingly...
        /// </summary>
        public void SetupLight(Light light)
        {
            if (m_Uniforms.rglLightAmbient >= 0) {
                float[] amb = { light.Ambient.R / 255.0f, light.Ambient.G / 255.0f, light.Ambient.B / 255.0f, 1.0f };
                GL.Uniform4 (m_Uniforms.rglLightAmbient, 1, amb);
            }

            if (m_Uniforms.rglLightDiffuse >= 0) {
                float[] diff = { light.Diffuse.R / 255.0f, light.Diffuse.G / 255.0f, light.Diffuse.B / 255.0f, 1.0f };
                GL.Uniform4 (m_Uniforms.rglLightDiffuse, 1, diff);
            }

            if (m_Uniforms.rglLightSpecular >= 0) {
                float[] spec = { light.Specular.R / 255.0f, light.Specular.G / 255.0f, light.Specular.B / 255.0f, 1.0f };
                GL.Uniform4 (m_Uniforms.rglLightSpecular, 1, spec);
            }

            if (m_Uniforms.rglLightPosition >= 0) {
                float[] pos = {
                    (float)light.Direction.X,
                    (float)light.Direction.Y,
                    (float)light.Direction.Z
                };
                GL.Uniform3 (m_Uniforms.rglLightPosition, 1, pos);
            }
        }