using System;
using System.Collections.Generic;
using UnityEngine;

namespace Cryville.Crtr.Skin.Components {
	public class SpriteScale3 : SpritePlane {
		public SpriteScale3() {
			SubmitProperty("border", new PropOp.Vector2(v => Border = v));
		}

		static readonly Dictionary<float, int> uvrefl
			= new Dictionary<float, int>() {
			{-0.5f, 0}, {-0.4f, 1}, {0.4f, 2}, {0.5f, 3},
		};
		static Vector2[] _origuv;
		protected static new Vector2[] OriginalUV {
			get {
				if (_origuv == null) {
					var m = BuiltinResources.Meshes["quad_scale3h"];
					Vector2[] uv = new Vector2[m.vertices.Length];
					for (int i = 0; i < uv.Length; i++) {
						uv[i] = new Vector2(
							uvrefl[m.vertices[i].x],
							uvrefl[m.vertices[i].z]
						);
					}
					_origuv = uv;
				}
				return _origuv;
			}
		}

		Vector2 _border = new Vector2(0, 1);
		public Vector2 Border {
			get { return _border; }
			set {
				_border = value;
				UpdateScale();
			}
		}
		protected override void UpdateScale() {
			base.UpdateScale();
			if (!mesh.Initialized) return;
			UpdateUV();
		}

		readonly Vector2[] _uvs = new Vector2[8];
		readonly Vector3[] _verts = new Vector3[8];
		protected override void UpdateUV() {
			var frame = CurrentFrame;
			if (SpriteInfo.IsNullOrEmpty(frame)) return;

			Vector2[] muv = OriginalUV;

			var or = frame.Ratio;
			var sr = Scale.x / Scale.y;
			var rr = or / sr;
			var b1 = rr * _border.x;
			var b2 = 1 - rr * (1 - _border.y);

			for (int i = 0; i < muv.Length; i++) {
				float x; float bx;
				switch ((int)muv[i].x) {
					case 0: x = 0; bx = 0; break;
					case 1: x = _border.x; bx = b1; break;
					case 2: x = _border.y; bx = b2; break;
					case 3: x = 1; bx = 1; break;
					default: throw new NotSupportedException("Built-in resource corrupted");
				}
				float y;
				switch ((int)muv[i].y) {
					case 0: y = 0; break;
					case 3: y = 1; break;
					default: throw new NotSupportedException("Built-in resource corrupted");
				}
				_uvs[i] = frame.Frame.GetUV(x, y);
				bx -= 0.5f; y -= 0.5f;
				_verts[i] = new Vector3(bx, 0, y);
			}
			mesh.Mesh.uv = _uvs;
			mesh.Mesh.vertices = _verts;
		}
		
		public override void Init() {
			InternalInit("quad_scale3h");
			OnFrameUpdate();
		}
	}
}
