using System;
using System.Collections.Generic;
using System.Text;

namespace Vortex.Drawing {

	static class CanvasStateScopes {

		//---------------------------------------------------------------------
		/// <summary>
		/// Implementation of Vertex Shader scope
		/// </summary>
		public class VertexShaderScope : StateScope {
			private VertexShader _state;

			public VertexShaderScope(StateScope scope, VertexShader state) : base(scope) {
				Canvas2D canvas = ReferredCanvas;
				_state = canvas.VertexShader;
				canvas.VertexShader = state;
			}

			/// <summary>
			/// Closes the scope: setting initial vertex shader.
			/// </summary>
			protected override void CloseScope() {
				ReferredCanvas.VertexShader = _state;
			}
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Implementation of Pixel Shader scope
		/// </summary>
		public class PixelShaderScope : StateScope {
			private PixelShader _state;

			public PixelShaderScope(StateScope scope, PixelShader state)
				: base(scope) {
				Canvas2D canvas = ReferredCanvas;
				_state = canvas.PixelShader;
				canvas.PixelShader = state;
			}

			/// <summary>
			/// Closes the scope: setting initial vertex shader.
			/// </summary>
			protected override void CloseScope() {
				ReferredCanvas.PixelShader = _state;
			}
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Implementation of CanvasBrush scope
		/// </summary>
		public class CanvasBrushScope : StateScope {
			private CanvasBrush _state;

			public CanvasBrushScope(StateScope scope, CanvasBrush state)
				: base(scope) {
				Canvas2D canvas = ReferredCanvas;
				_state = canvas.Brush;
				canvas.Brush = state;
			}

			/// <summary>
			/// Closes the scope: setting initial brush.
			/// </summary>
			protected override void CloseScope() {
				ReferredCanvas.Brush = _state;
				base.CloseScope();
			}
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Implementation of Blending scope
		/// </summary>
		public class BlendingScope : StateScope {
			private Blending _state;

			public BlendingScope(StateScope scope, Blending state)
				: base(scope) {
				Canvas2D canvas = ReferredCanvas;
				_state = canvas.Blending;
				canvas.Blending = state;
			}

			/// <summary>
			/// Closes the scope: setting initial blending.
			/// </summary>
			protected override void CloseScope() {
				ReferredCanvas.Blending = _state;
				base.CloseScope();
			}
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Implementation of Clipping scope
		/// </summary>
		public class ClippingScope : StateScope {
			private Clipping _state;

			public ClippingScope(StateScope scope, Clipping state)
				: base(scope) {
				Canvas2D canvas = ReferredCanvas;
				_state = canvas.Clipping;
				canvas.Clipping = state;
			}

			/// <summary>
			/// Closes the scope: setting initial clipping.
			/// </summary>
			protected override void CloseScope() {
				ReferredCanvas.Clipping = _state;
				base.CloseScope();
			}
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Implementation of Clipping scope
		/// </summary>
		public class TextureIndexScope : StateScope {
			private int _index;
			private BaseTexture _texture;


			public TextureIndexScope(StateScope scope, TextureIndex state)
				: base(scope) {
				Canvas2D canvas = ReferredCanvas;
				_texture = canvas[state.Index];
				_index = state.Index;
				canvas[state.Index] = state.Texture;
			}

			/// <summary>
			/// Closes the scope: setting initial clipping.
			/// </summary>
			protected override void CloseScope() {
				ReferredCanvas[_index] = _texture;
				base.CloseScope();
			}
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Implementation of AlphaTest scope
		/// </summary>
		public class AlphaTestScope : StateScope {
			private AlphaTest _state;

			public AlphaTestScope(StateScope scope, AlphaTest state)
				: base(scope) {
				Canvas2D canvas = ReferredCanvas;
				_state = canvas.AlphaTest;
				canvas.AlphaTest = state;
			}

			/// <summary>
			/// Closes the scope: setting initial alpha test.
			/// </summary>
			protected override void CloseScope() {
				ReferredCanvas.AlphaTest = _state;
				base.CloseScope();
			}
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Implementation of ZEffect scope
		/// </summary>
		public class ZEffectScope : StateScope {
			private ZEffect _state;

			public ZEffectScope(StateScope scope, ZEffect state)
				: base(scope) {
				Canvas2D canvas = ReferredCanvas;
				_state = canvas.ZEffect;
				canvas.ZEffect = state;
			}

			/// <summary>
			/// Closes the scope: setting initial z-effect.
			/// </summary>
			protected override void CloseScope() {
				ReferredCanvas.ZEffect = _state;
				base.CloseScope();
			}
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Implementation of Transform scope
		/// </summary>
		public class TransformScope : StateScope {
			public TransformScope(StateScope scope, ref Transform2D transform, bool overrideTransform)
				: base(scope) {
				Canvas2D canvas = ReferredCanvas;
				canvas.PushTransform();
				if (overrideTransform) {
					canvas.SetTransform(ref transform);
				} else {
					canvas.ApplyTransformBefore(ref transform);
				}
			}

			/// <summary>
			/// Closes the scope: setting initial z value.
			/// </summary>
			protected override void CloseScope() {
				ReferredCanvas.PopTransform();
				base.CloseScope();
			}
		}

		//---------------------------------------------------------------------
		/// <summary>
		/// Implementation of Z Value scope
		/// </summary>
		public class ZValueScope : StateScope {
			private float _zValue;

			public ZValueScope(StateScope scope, float value)
				: base(scope) {
				Canvas2D canvas = ReferredCanvas;
				_zValue = canvas.Z;
				canvas.Z = value;
			}

			/// <summary>
			/// Closes the scope: setting initial z value.
			/// </summary>
			protected override void CloseScope() {
				ReferredCanvas.Z = _zValue;
				base.CloseScope();
			}
		}


	}
}
