#if UNITY_EDITOR
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;

namespace Sabresaurus.SabreCSG
{
    public class DrawEditor : Tool
    {
		Polygon activePolygon = null; // The polygon currently overriding the grid plane
		PrimitiveBrush activeBrush = null; // The polygon currently overriding the grid plane

		Vector3 downPoint; // The 3D point the mouse was over at the start of the mouse click
		Vector3 hoverPoint; // The 3D point the mouse is hovering over

		// Whether a drawing operation is taking place and what it is
		enum DrawMode 
		{ 
			None, // Drawing is not active or has been cancelled
			Ambiguous, // They've started drawing but we're not sure if it's a rectangle or point sequence
			RectangleBase, // They're drawing a rectangle through a click and drag
			PolygonBase // They're defining a polygon by clicking a sequence of points
		};
		// Current drawing operation
		DrawMode drawMode = DrawMode.None;

		CSGMode csgMode = CSGMode.Add; // What sort of brush is currently being created

		bool selectingHeight = false; // In 3D views after drawing the prism base the height maps to the mouse
		float prismHeight = 0; // The height (or depth) of the prism being created

		float unroundedPrismHeight = 0; // Used to preserve height changes that have been snapped

		// The 3D points that they have clicked, in rectangle mode this is just the start and end point
		List<Vector3> hitPoints = new List<Vector3>();

		bool startedSubtract = false;
		bool ignoreNextMouseUp = false; // Double clicks occur in the down event, so we need to then ignore next mouse up

		bool Is3DView
		{
			get
			{
				if(!Camera.current.orthographic
					|| EditorHelper.GetSceneViewCamera(Camera.current) == EditorHelper.SceneViewCamera.Other)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
		}

        public override void ResetTool()
        {
			Selection.activeGameObject = null;
			drawMode = DrawMode.None;
			hitPoints.Clear();
			activePolygon = null;
			selectingHeight = false;
			prismHeight = 0;
            unroundedPrismHeight = 0;
        }

        public override void OnSceneGUI(SceneView sceneView, Event e)
        {
			base.OnSceneGUI(sceneView, e); // Allow the base logic to calculate first

			if(e.button == 0
				&& !EditorHelper.IsMousePositionInInvalidRects(e.mousePosition)
				&& !CameraPanInProgress)
			{
				if (e.type == EventType.MouseDown) 
				{
					OnMouseDown(sceneView, e);
				}
				else if (e.type == EventType.MouseDrag) 
				{
					OnMouseDrag(sceneView, e);
				}
				else if (e.type == EventType.MouseMove) 
				{
					OnMouseMove(sceneView, e);
				}
				// If you mouse up on a different scene view to the one you started on it's surpressed as Ignore, so
				// make sure to check the real type
				else if (e.type == EventType.MouseUp || e.rawType == EventType.MouseUp)
				{
					OnMouseUp(sceneView, e);
				}
			}

			if (e.type == EventType.KeyDown || e.type == EventType.KeyUp)
			{
				OnKeyAction(sceneView, e);
			}

			if (e.type == EventType.Layout || e.type == EventType.Repaint)
			{
				OnRepaint(sceneView, e);
			}
        }

        Polygon GetActivePolygon()
        {
            if (Camera.current.orthographic && EditorHelper.GetSceneViewCamera(Camera.current) != EditorHelper.SceneViewCamera.Other)
            {
                // Axis aligned iso view
                return null;
            }
            else
            {
                return activePolygon;
            }
        }

		Plane GetActivePlane()
		{
			if(Camera.current.orthographic && EditorHelper.GetSceneViewCamera(Camera.current) != EditorHelper.SceneViewCamera.Other)
			{
				// Axis aligned iso view
				return new Plane() { normal = -Camera.current.transform.forward, distance = 0 };
			}
			else
			{
				if(activePolygon != null)
				{
					// A polygon plane is overriding the grid plane, so return that
					return activePolygon.Plane;
				}
				else
				{
					// No plane override, so use ground plane
					return new Plane() { normal = Vector3.up, distance = 0 };
				}
			}
		}

		PolygonRaycastHit? CalculateHitPolygon(Vector2 currentPosition)
		{
			if(EditorHelper.GetSceneViewCamera(SceneView.lastActiveSceneView) == EditorHelper.SceneViewCamera.Other)
			{
				// Convert the mouse position into a ray to intersect with a plane in the world
				Ray currentRay = Camera.current.ScreenPointToRay(EditorHelper.ConvertMousePointPosition(currentPosition));
				List<PolygonRaycastHit> hits = csgModel.RaycastBrushesAll(currentRay, false);
				if(hits.Count > 0)
				{
					return hits[0];
				}
				else
				{
					return null;
				}
			}
			else
			{
				// If the scene view is axis-aligned iso then we don't raycast polygons
				return null;
			}
		}

        bool IsPrismBaseValid(List<Vector3> points)
        {
            Vector2 hitPointsSize = CalculateHitPointsSize(points);
            
            if (hitPointsSize.x > 0 && hitPointsSize.y > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        Vector2 CalculateHitPointsSize(List<Vector3> points)
        {
            Vector3 normal = GetActivePlane().normal;
            Vector3 tangent = Vector3.zero;

            for (int i = 0; i < points.Count; i++)
            {
                Vector3 delta = points[(i + 1) % points.Count] - points[i];
                if(delta.magnitude > 0.01f)
                {
                    tangent = delta.normalized;
                    break;
                }
            }

            if(tangent == Vector3.zero)
            {
                if (Vector3.Dot(normal.Abs(), Vector3.up) > 0.9f)
                {
                    tangent = Vector3.Cross(normal, Vector3.forward).normalized;
                }
                else
                {
                    tangent = Vector3.Cross(normal, Vector3.up).normalized;
                }
            }

            Vector3 binormal = Vector3.Cross(normal, tangent);

            float minX = Vector3.Dot(tangent, points[0]);
            float maxX = minX;

            float minY = Vector3.Dot(binormal, points[0]);
            float maxY = minY;

            for (int i = 1; i < points.Count; i++)
            {
                float testX = Vector3.Dot(tangent, points[i]);
                float testY = Vector3.Dot(binormal, points[i]);

                minX = Mathf.Min(minX, testX);
                maxX = Mathf.Max(maxX, testX);

                minY = Mathf.Min(minY, testY);
                maxY = Mathf.Max(maxY, testY);
            }

            return new Vector2(maxX - minX, maxY - minY);
        }

		Vector3? GetHitPoint(Vector2 currentPosition)
		{
			// Conver the mouse position into a ray to intersect with a plane in the world
			Ray currentRay = Camera.current.ScreenPointToRay(EditorHelper.ConvertMousePointPosition(currentPosition));

			// Find the currently active plane
			Plane plane = GetActivePlane();

			// If we hit the plane, return the hit point, otherwise return null
			float distance;
			if(plane.Raycast(currentRay, out distance))
			{
				Vector3 hitPoint = currentRay.GetPoint(distance);

				if(CurrentSettings.PositionSnappingEnabled)
				{
                    Polygon activePolygon = GetActivePolygon();

                    if (activePolygon != null)
                    {
                        // Rotation to go from the polygon's plane to XY plane (for sorting)
                        Quaternion cancellingRotation = Quaternion.Inverse(Quaternion.LookRotation(plane.normal));
                        Quaternion restoringRotation = Quaternion.LookRotation(plane.normal);
                        hitPoint -= activePolygon.GetCenterPoint();
                        Vector3 localHitPoint = cancellingRotation * hitPoint;
                        // Round in local space
                        localHitPoint = MathHelper.RoundVector3(localHitPoint, CurrentSettings.PositionSnapDistance);
                        // Convert back to correct space
                        hitPoint = restoringRotation * localHitPoint;
                        hitPoint += activePolygon.GetCenterPoint();
                    }
                    else
                    {
					    hitPoint = MathHelper.RoundVector3(hitPoint, CurrentSettings.PositionSnapDistance);
                    }
				}
				return hitPoint;
			}
			else
			{
				return null;
			}
		}

		void UpdateCSGMode(Event e)
		{
			csgMode = e.shift ? CSGMode.Subtract : CSGMode.Add;
			if(csgMode == CSGMode.Add)
			{
				startedSubtract = false;
			}
		}

		void OnMouseDown(SceneView sceneView, Event e)
		{
            UpdateCSGMode(e);

            if (selectingHeight)
                return;

			
			if(e.clickCount == 2) 
			{
				// Double click, so finish the polygon
				if(drawMode == DrawMode.PolygonBase)
				{
					if(Is3DView && !startedSubtract)
					{
						selectingHeight = true;
						prismHeight = 0;
						ignoreNextMouseUp = true;
						SceneView.RepaintAll();
					}
					else
					{
						CreateBrush(hitPoints);

						ResetTool();

						sceneView.Repaint();
					}
				}
			}
			else
			{
				if(drawMode == DrawMode.None)
				{
					PolygonRaycastHit? hit = CalculateHitPolygon(e.mousePosition);
					if(hit.HasValue)
					{
						activePolygon = hit.Value.Polygon;
						activeBrush = hit.Value.GameObject.GetComponent<PrimitiveBrush>();
					}
					else
					{
						activePolygon = null;
						activeBrush = null;
					}


					Vector3? hitPoint = GetHitPoint(e.mousePosition);
					if(hitPoint.HasValue)
					{
						downPoint = hitPoint.Value;
						hoverPoint = downPoint;
					}

					hitPoints.Clear();

					if(hitPoint.HasValue)
					{
						drawMode = DrawMode.Ambiguous;
					}
				}
				else
				{
					Vector3? hitPoint = GetHitPoint(e.mousePosition);
					if(hitPoint.HasValue)
					{
						downPoint = hitPoint.Value;
						hoverPoint = downPoint;
					}
				}
			}
		}

		void OnMouseDrag(SceneView sceneView, Event e)
		{
			UpdateCSGMode(e);
			Vector3? hitPoint = GetHitPoint(e.mousePosition);

			if(hitPoint.HasValue)
			{
				if(drawMode == DrawMode.PolygonBase && !selectingHeight)
                {
                    hoverPoint = hitPoint.Value;
                    SceneView.RepaintAll();
                }

				if(drawMode == DrawMode.Ambiguous)
				{
					if(drawMode != DrawMode.RectangleBase)
					{
						startedSubtract = e.shift;
					}
					hitPoints.Clear();
					drawMode = DrawMode.RectangleBase;
					hitPoints.Add(downPoint);
				}

				if(drawMode == DrawMode.Ambiguous
                    || (drawMode == DrawMode.RectangleBase && !selectingHeight))
				{
					if(hitPoints.Count < 2)
					{
						hitPoints.Add(hitPoint.Value);
					}
					else
					{
						hitPoints[1] = hitPoint.Value;
					}

					// We have something to draw so make sure the sceneview repaints
					sceneView.Repaint();

					if(drawMode != DrawMode.RectangleBase)
					{
						startedSubtract = e.shift;
					}
					drawMode = DrawMode.RectangleBase;
				}
			}
		}

		void OnMouseMoveSelectHeight(SceneView sceneView, Event e)
		{
			Rect pixelRect = sceneView.camera.pixelRect;

			// Resize a handle
			Vector2 currentPosition = e.mousePosition;

			// Clamp the current position to the screen rect. Otherwise we get some odd problems if you carry on 
			// resizing off screen.
			currentPosition.x = Mathf.Clamp(currentPosition.x, pixelRect.xMin, pixelRect.xMax);
			currentPosition.y = Mathf.Clamp(currentPosition.y, pixelRect.yMin, pixelRect.yMax);

			Vector2 lastPosition = currentPosition - e.delta;

			Ray lastRay = Camera.current.ScreenPointToRay(EditorHelper.ConvertMousePointPosition(lastPosition));

			Ray currentRay = Camera.current.ScreenPointToRay(EditorHelper.ConvertMousePointPosition(currentPosition));
			Vector3 direction = GetActivePlane().normal;

			Vector3 lineStart = hitPoints[0];
			Vector3 lineEnd = hitPoints[0] + direction;

			Vector3 lastPositionWorld = MathHelper.ClosestPointOnLine(lastRay, lineStart, lineEnd);
			Vector3 currentPositionWorld = MathHelper.ClosestPointOnLine(currentRay, lineStart, lineEnd);

			Vector3 deltaWorld = (currentPositionWorld - lastPositionWorld);

			float deltaScale = Vector3.Dot(direction, deltaWorld);
			float snapDistance = CurrentSettings.PositionSnapDistance;

			if (CurrentSettings.PositionSnappingEnabled)
			{
				deltaScale += unroundedPrismHeight;
				float roundedDeltaScale = MathHelper.RoundFloat(deltaScale, snapDistance);

				unroundedPrismHeight = deltaScale- roundedDeltaScale;
				deltaScale = roundedDeltaScale;
			}

			prismHeight += deltaScale;

			SceneView.RepaintAll();
		}

		void OnMouseMove(SceneView sceneView, Event e)
		{
			UpdateCSGMode(e);

			if(selectingHeight)
			{
				// Mouse movement while selecting depth controls prism height
				OnMouseMoveSelectHeight(sceneView, e);
			}
			else
			{
				// Not currently drawing, so update the active polygon to whatever they are currently hovering over
				if(drawMode == DrawMode.None)
				{
					PolygonRaycastHit? hit = CalculateHitPolygon(e.mousePosition);
					if(hit.HasValue)
					{
						activePolygon = hit.Value.Polygon;
						activeBrush = hit.Value.GameObject.GetComponent<PrimitiveBrush>();
					}
					else
					{
						activePolygon = null;
						activeBrush = null;
					}
				}

				// Find the snapped hover point based on any active polygon or the grid
				Vector3? hitPoint = GetHitPoint(e.mousePosition);
				if(hitPoint.HasValue)
				{
					hoverPoint = hitPoint.Value;
					SceneView.RepaintAll();
				}
			}
		}

		void OnMouseUp(SceneView sceneView, Event e)
		{			
			if(ignoreNextMouseUp)
			{
				// Double click just occurred, so don't process the up event
				ignoreNextMouseUp = false;
				return;
			}
			UpdateCSGMode(e);

			if(selectingHeight)
			{
				if(drawMode == DrawMode.RectangleBase)
				{
					CreateBrush(GetRectanglePoints());
				}
				else
				{
					CreateBrush(hitPoints);
				}
				selectingHeight = false;

				ResetTool();

				sceneView.Repaint();
            }
            else
            {
                if (drawMode == DrawMode.RectangleBase)
                {
                    if (Is3DView && !startedSubtract)
                    {                        
                        // Verify that it will form a valid prism by trying to create a polygon out the base
                        if(IsPrismBaseValid(GetRectanglePoints()))
                        {
						    selectingHeight = true;
						    prismHeight = 0;
                        }
                        else
                        {
                            // Will not form a valid prism so cancel the draw
                            ResetTool();

                            sceneView.Repaint();
                        }
                    }
					else
					{
						CreateBrush(GetRectanglePoints());

						ResetTool();

						sceneView.Repaint();
					}
				}
				else if(drawMode == DrawMode.Ambiguous || drawMode == DrawMode.PolygonBase)
				{
					Vector3? hitPoint = GetHitPoint(e.mousePosition);

					if(hitPoint.HasValue)
					{
						drawMode = DrawMode.PolygonBase;

						hitPoints.Add(hitPoint.Value);

						if(hitPoints.Count > 2 && hitPoint.Value.EqualsWithEpsilon(hitPoints[0]))
						{
							if(Is3DView && !startedSubtract)
							{
                                // Verify that it will form a valid prism by trying to create a polygon out the base
                                if (IsPrismBaseValid(hitPoints))
                                {
                                    selectingHeight = true;
                                    prismHeight = 0;
                                }
                                else
                                {
                                    // Will not form a valid prism so cancel the draw
                                    ResetTool();

                                    sceneView.Repaint();
                                }
                            }
							else
							{
								CreateBrush(hitPoints);

								ResetTool();

								sceneView.Repaint();
							}
						}
					}
				}
			}
		}

		void CreateBrush(List<Vector3> positions)
		{
			Polygon sourcePolygon = PolygonFactory.ConstructPolygon(positions, true);

			// Early out if it wasn't possible to create the polygon
			if(sourcePolygon == null)
			{
				return;
			}

            if(activePolygon != null)
            {
                for (int i = 0; i < sourcePolygon.Vertices.Length; i++)
                {
                    Vector2 newUV = GeometryHelper.GetUVForPosition(activePolygon, sourcePolygon.Vertices[i].Position);
                    sourcePolygon.Vertices[i].UV = newUV;
                }
            }

			Vector3 planeNormal = GetActivePlane().normal;

//			Debug.Log(Vector3.Dot(sourcePolygon.Plane.normal, planeNormal));

			// Flip the polygon if the winding order is wrong
			if(Vector3.Dot(sourcePolygon.Plane.normal, planeNormal) < 0)
			{
				sourcePolygon.Flip();

				// Need to flip the UVs across the U (X) direction
				for (int i = 0; i < sourcePolygon.Vertices.Length; i++) 
				{
					Vector2 uv = sourcePolygon.Vertices[i].UV;
					uv.x = 1 - uv.x;
					sourcePolygon.Vertices[i].UV = uv;
				}
			}

			float extrusionDistance = 1;
			Vector3 positionOffset = Vector3.zero;

			if(selectingHeight)
			{
				extrusionDistance = prismHeight;
			}
			else
			{
				if(activePolygon != null && activeBrush != null)
				{
					extrusionDistance = activeBrush.CalculateExtentsInAxis(planeNormal);
				}
				else
				{
					Brush lastSelectedBrush = csgModel.LastSelectedBrush;
					if(lastSelectedBrush != null)
					{
						Bounds lastSelectedBrushBounds = lastSelectedBrush.GetBoundsTransformed();

						for (int i = 0; i < 3; i++) 
						{
							if(!planeNormal[i].EqualsWithEpsilon(0))
							{
								if(lastSelectedBrushBounds.size[i] != 0)
								{
									extrusionDistance = lastSelectedBrushBounds.size[i];

									if(planeNormal[i] > 0)
									{
										positionOffset[i] = lastSelectedBrushBounds.center[i] - lastSelectedBrushBounds.extents[i]; 
									}
									else
									{
										positionOffset[i] = lastSelectedBrushBounds.center[i] + lastSelectedBrushBounds.extents[i]; 
									}
								}
							}
						}
					}
				}

				// Subtractions should go through
				if(csgMode == CSGMode.Subtract)
				{
					sourcePolygon.Flip();
				}
			}

			Quaternion rotation;
			Polygon[] polygons;
			SurfaceUtility.ExtrudePolygon(sourcePolygon, extrusionDistance, out polygons, out rotation);

			GameObject newObject = csgModel.CreateCustomBrush(polygons);

			PrimitiveBrush newBrush = newObject.GetComponent<PrimitiveBrush>();

			newObject.transform.rotation = rotation;
			newObject.transform.position += positionOffset;

            if(activePolygon != null
                && activePolygon.Material != csgModel.GetDefaultMaterial())
            {
                for (int i = 0; i < polygons.Length; i++)
                {
                    polygons[i].Material = activePolygon.Material;
                }
            }
			// Finally give the new brush the other set of polygons
			newBrush.SetPolygons(polygons, true);

			newBrush.Mode = csgMode;

			newBrush.ResetPivot();

			// Use this brush as the basis for drawing the next brush
			csgModel.SetLastSelectedBrush(newBrush);

			Undo.RegisterCreatedObjectUndo(newObject, "Draw Brush");
		}

		void OnKeyAction(SceneView sceneView, Event e)
		{
			if (KeyMappings.EventsMatch(e, Event.KeyboardEvent(KeyMappings.Instance.CancelCurrentOperation)))
			{
				if (e.type == EventType.KeyDown)
				{
					if(drawMode != DrawMode.None || hitPoints.Count > 0)
					{
						// Drawing is in progress so cancel it
						ResetTool();
					}
					else
					{
						// No draw in progress, so user wants to cancel out of draw mode
						csgModel.ExitOverrideMode();
					}
				}
				e.Use();
			}
			else if (KeyMappings.EventsMatch(e, Event.KeyboardEvent(KeyMappings.Instance.Back))
				|| KeyMappings.EventsMatch(e, Event.KeyboardEvent(KeyMappings.Instance.Delete), false, true))
			{
				if (e.type == EventType.KeyDown)
				{
					if(drawMode == DrawMode.PolygonBase)
					{
						if(hitPoints.Count > 1)
						{
							// Remove the last point
							hitPoints.RemoveAt(hitPoints.Count-1);
						}
						else
						{
							ResetTool();
						}
					}
					else
					{
						ResetTool();
					}
				}
				e.Use();
			}
		}

		List<Vector3> GetRectanglePoints()
		{
			Plane plane = GetActivePlane();
            Vector3 planeNormal = plane.normal; //MathHelper.VectorAbs(plane.normal);

			Vector3 axis1;
			Vector3 axis2;

			if(Vector3.Dot(planeNormal.Abs(), Vector3.up) > 0.99f)
			{
				axis1 = Vector3.forward;
				axis2 = Vector3.right;
			}
			else
			{
				axis1 = Vector3.up;
				axis2 = Vector3.Cross(Vector3.up, planeNormal).normalized;
			}


			Vector3 startPoint = hitPoints[0];
			Vector3 endPoint = hitPoints[1];

			List<Vector3> points = new List<Vector3>(4);

			Vector3 delta = endPoint - startPoint;

			Vector3 deltaAxis1 = Vector3.Dot(delta, axis1) * axis1;
			Vector3 deltaAxis2 = Vector3.Dot(delta, axis2) * axis2;

			points.Add(startPoint);
			points.Add(startPoint + deltaAxis1);
			points.Add(endPoint);
			points.Add(startPoint + deltaAxis2);

			return points;
		}

		void OnRepaint(SceneView sceneView, Event e)
		{
			Camera sceneViewCamera = sceneView.camera;

//			if(hoverPoint.HasValue)
			{
				// Draw the active polygon
				if(activePolygon != null)
				{
					SabreCSGResources.GetSelectedBrushMaterial().SetPass(0);

					SabreGraphics.DrawPolygons(new Color(1,1,0,0.15f), new Color(1,1,0,0.5f), activePolygon);	
				}


				SabreCSGResources.GetVertexMaterial().SetPass (0);
				GL.PushMatrix();
				GL.LoadPixelMatrix();

				GL.Begin(GL.QUADS);

				if(activePolygon != null)
				{
					GL.Color(Color.yellow);// new Color(0.75f,0.75f,0.75f,1));
				}
				else
				{
					GL.Color(Color.white);
				}


				Vector3 target = sceneViewCamera.WorldToScreenPoint(hoverPoint);

				if(target.z > 0)
				{
					// Make it pixel perfect
					target = MathHelper.RoundVector3(target);
					SabreGraphics.DrawBillboardQuad(target, 8, 8);
				}


				for (int i = 0; i < hitPoints.Count; i++) {
					target = sceneViewCamera.WorldToScreenPoint(hitPoints[i]);
					GL.Color(Color.blue);
					if(target.z > 0)
					{
						// Make it pixel perfect
						target = MathHelper.RoundVector3(target);
						SabreGraphics.DrawBillboardQuad(target, 8, 8);
					}
				}

				GL.End();
				GL.PopMatrix();
			}

			if(drawMode == DrawMode.RectangleBase || drawMode == DrawMode.PolygonBase)
			{
				List<Vector3> pointsToDraw = new List<Vector3>();
				if(drawMode == DrawMode.RectangleBase)
				{
					pointsToDraw.AddRange(GetRectanglePoints());
				}
				else
				{
					pointsToDraw.AddRange(hitPoints);
					pointsToDraw.Insert(pointsToDraw.Count, hoverPoint);
				}

				SabreCSGResources.GetSelectedBrushMaterial().SetPass(0);

//				GL.Begin(GL);
//				GL.Color(new Color32(0, 181, 255, 100));
//
//				// Draw each point
//				for (int i = 0; i < pointsToDraw.Count; i++) 
//				{
//					GL.Vertex(pointsToDraw[i]);
//				}
//
//				GL.End();

				// Marquee border
				GL.Begin(GL.LINES);

				if(csgMode == CSGMode.Add)
				{
					GL.Color(Color.blue);
				}
				else
				{
					GL.Color(Color.yellow);
				}

				// Draw lines between all the points
				for (int i = 0; i < pointsToDraw.Count; i++) 
				{
					// In polygon mode, if it's bigger than a line, draw the last edge in grey
					if(i == pointsToDraw.Count-1 
						&& drawMode == DrawMode.PolygonBase 
						&& pointsToDraw.Count > 2
						&& !selectingHeight)
					{
						GL.Color(Color.grey);
					}
					// Draw a line from one point to the next
					GL.Vertex(pointsToDraw[i]);
					GL.Vertex(pointsToDraw[(i+1) % pointsToDraw.Count]);
				}

				if(selectingHeight)
				{
					Vector3 offset = GetActivePlane().normal * prismHeight;

					for (int i = 0; i < pointsToDraw.Count; i++) 
					{
						// Draw a line from one point to the next
						GL.Vertex(pointsToDraw[i]);
						GL.Vertex(pointsToDraw[i] + offset);
					}

					GL.Color(Color.grey);
					// Draw grid lines along the prism to indicate size
					for (int heightLine = 1; heightLine < Mathf.Abs(prismHeight); heightLine++) 
					{
						for (int i = 0; i < pointsToDraw.Count; i++) 
						{
							Vector3 gridOffset = GetActivePlane().normal * heightLine * Mathf.Sign(prismHeight);
							// Draw a line from one point to the next
							GL.Vertex(pointsToDraw[i] + gridOffset);
							GL.Vertex(pointsToDraw[(i+1) % pointsToDraw.Count] + gridOffset);
						}
					}

					GL.Color(Color.green);
					for (int i = 0; i < pointsToDraw.Count; i++) 
					{
						// Draw a line from one point to the next
						GL.Vertex(pointsToDraw[i] + offset);
						GL.Vertex(pointsToDraw[(i+1) % pointsToDraw.Count] + offset);
					}
				}

				GL.End();
			}

//			Rect rectangle = new Rect(0, 50, 210, 130);
//			GUIStyle toolbar = new GUIStyle(EditorStyles.toolbar);
//			toolbar.normal.background = SabreCSGResources.ClearTexture;
//			toolbar.fixedHeight = rectangle.height;
//			GUILayout.Window(140010, rectangle, OnToolbarGUI, "",toolbar);
		}

//		void OnToolbarGUI(int windowID)
//		{
//			raycastBrushes = EditorGUILayout.Toggle("Raycast Brushes", raycastBrushes);
//		}


		public override void Deactivated ()
		{

		}

		public override bool PreventBrushSelection 
		{
			get 
			{
				// Some special logic for clicking brushes
				return true;
			}
		}
    }
}
#endif