Shader "CrispyPin/WireWorld"
{
	Properties
	{
		_LastFrame ("Texture", 2D) = "white" {}
		[Toggle]
		_Running ("Running", Int) = 0
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
				UNITY_VERTEX_OUTPUT_STEREO
			};

			sampler2D _LastFrame;
			int _Running;

			v2f vert (appdata v)
			{
				v2f o;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_INITIALIZE_OUTPUT(v2f, o);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				return o;
			}

			int close(float4 a, float4 b) {
				return dot(normalize(a), normalize(b)) > 0.95;
			}

			#define EMPTY 0
			#define WIRE 1
			#define SIGNAL 2
			#define TAIL 3
			#define UNKNOWN 4
			#define C_EMPTY float4(0, 0, 0, 1)
			#define C_WIRE float4(1, 0.5, 0, 1)
			#define C_SIGNAL float4(0.5, 0.5, 1, 1)
			#define C_TAIL float4(0.5, 1, 0.5, 1)

			int value(float2 center, float x, float y) {
				fixed4 col = tex2D(_LastFrame, center + float2(x, y));
				col = sqrt(col);
				// col = col*col;
				col.a = 1;
				if (close(col, C_SIGNAL)) {
					return SIGNAL;
				}
				if (close(col, C_TAIL)) {
					return TAIL;
				}
				if (close(col, C_WIRE)) {
					return WIRE;
				}
				return EMPTY;
			}


			fixed4 frag (v2f i) : SV_Target
			{
				const float resolution = 32.0;
				const float d = 1.0/resolution;

				float t = tex2D(_LastFrame, 0).r;
				if (i.uv.x < d && i.uv.y < d) {
					if (t > 0.9) {
						return float4(0, 0, 0, 1);
					}
					t += unity_DeltaTime.x * 4;
					return float4(t, t, t, 1);
				}

				int old_state = value(i.uv, 0, 0) ;

				if (old_state == EMPTY) {
					return C_EMPTY * C_EMPTY;
				}

				if (t > 0 || _Running == 0) {
					if (old_state == SIGNAL) {
						return C_SIGNAL * C_SIGNAL;
					}
					if (old_state == TAIL) {
						return C_TAIL * C_TAIL;
					}
					return C_WIRE * C_WIRE;
				}

				if (old_state == SIGNAL) {
					// return C_SIGNAL * C_SIGNAL;
					return C_TAIL * C_TAIL;
				}
				if (old_state == TAIL) {
					// return C_TAIL * C_TAIL;
					return C_WIRE * C_WIRE;
				}

				int count =
				(int)(value(i.uv, -d, -d) == SIGNAL) +
				(int)(value(i.uv, 0, -d) == SIGNAL) +
				(int)(value(i.uv, d, -d) == SIGNAL) +

				(int)(value(i.uv, -d, 0) == SIGNAL) +
				(int)(value(i.uv, d, 0) == SIGNAL) +

				(int)(value(i.uv, -d, d) == SIGNAL) +
				(int)(value(i.uv, 0, d) == SIGNAL) +
				(int)(value(i.uv, d, d) == SIGNAL) ;

				if (count == 1 || count == 2){
					return C_SIGNAL * C_SIGNAL;
				}

				return C_WIRE * C_WIRE;
			}
			ENDCG
		}
	}
}
