﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class SESkyboxUtil : EditorWindow
{
	[MenuItem("Tools/DSS/SpaceEngine skybox utilities")]
	public static void ShowWindow() {
		EditorWindow w = GetWindow<SESkyboxUtil>(false, "SpaceEngine skybox utilities", true);
		w.minSize = new Vector2(300, 230);
	}

	Texture2D galaxyFront, galaxyBack, galaxyLeft, galaxyRight, galaxyUp, galaxyDown, starsFront, starsBack, starsLeft, starsRight, starsUp, starsDown;
	float galaxyColorBias = 0;
	float starsColorBias = 0;
	float galaxyBrightness = 1;
	float starsBrightness = 1;
	Vector2 scrollPos = new Vector2(0, 0);

	private void OnGUI() {
		EditorGUI.BeginChangeCheck();
		GUILayout.BeginVertical();
		scrollPos = GUILayout.BeginScrollView(scrollPos);
		galaxyFront = (Texture2D)EditorGUILayout.ObjectField("Galaxy Front [+Z]", galaxyFront, typeof(Texture2D), true);
		galaxyBack = (Texture2D)EditorGUILayout.ObjectField("Galaxy Back [-Z]", galaxyBack, typeof(Texture2D), true);
		galaxyLeft = (Texture2D)EditorGUILayout.ObjectField("Galaxy Left [+X]", galaxyLeft, typeof(Texture2D), true);
		galaxyRight = (Texture2D)EditorGUILayout.ObjectField("Galaxy Right [-X]", galaxyRight, typeof(Texture2D), true);
		galaxyUp = (Texture2D)EditorGUILayout.ObjectField("Galaxy Up [+Y]", galaxyUp, typeof(Texture2D), true);
		galaxyDown = (Texture2D)EditorGUILayout.ObjectField("Galaxy Down [-Y]", galaxyDown, typeof(Texture2D), true);

		starsFront = (Texture2D)EditorGUILayout.ObjectField("Stars Front [+Z]", starsFront, typeof(Texture2D), true);
		starsBack = (Texture2D)EditorGUILayout.ObjectField("Stars Back [-Z]", starsBack, typeof(Texture2D), true);
		starsLeft = (Texture2D)EditorGUILayout.ObjectField("Stars Left [+X]", starsLeft, typeof(Texture2D), true);
		starsRight = (Texture2D)EditorGUILayout.ObjectField("Stars Right [-X]", starsRight, typeof(Texture2D), true);
		starsUp = (Texture2D)EditorGUILayout.ObjectField("Stars Up [+Y]", starsUp, typeof(Texture2D), true);
		starsDown = (Texture2D)EditorGUILayout.ObjectField("Stars Down [-Y]", starsDown, typeof(Texture2D), true);

		EditorGUILayout.LabelField("Galaxy color bias");
		galaxyColorBias = EditorGUILayout.Slider(galaxyColorBias, -1, 1);
		EditorGUILayout.LabelField("Stars color bias");
		starsColorBias = EditorGUILayout.Slider(starsColorBias, -1, 1);

		EditorGUILayout.LabelField("Galaxy brightness");
		galaxyBrightness = EditorGUILayout.Slider(galaxyBrightness, 0, 1);
		EditorGUILayout.LabelField("Stars brightness");
		starsBrightness = EditorGUILayout.Slider(starsBrightness, 0, 1);

		if(GUILayout.Button("Merge", GUILayout.Width(100), GUILayout.Height(25))) {
			System.IO.Directory.CreateDirectory("Assets/SE_Sky_Merged");
			string res;
			res = MergeTextures(galaxyFront, starsFront, "Assets/SE_Sky_Merged/sky_pos_z.png");
			if(res != null) goto skip;
			res = MergeTextures(galaxyBack, starsBack, "Assets/SE_Sky_Merged/sky_neg_z.png");
			if(res != null) goto skip;
			res = MergeTextures(galaxyLeft, starsLeft, "Assets/SE_Sky_Merged/sky_pos_x.png");
			if(res != null) goto skip;
			res = MergeTextures(galaxyRight, starsRight, "Assets/SE_Sky_Merged/sky_neg_x.png");
			if(res != null) goto skip;
			res = MergeTextures(galaxyUp, starsUp, "Assets/SE_Sky_Merged/sky_pos_y.png");
			if(res != null) goto skip;
			res = MergeTextures(galaxyDown, starsDown, "Assets/SE_Sky_Merged/sky_neg_y.png");
			if(res != null) goto skip;
		skip:
			AssetDatabase.Refresh();
			if(res != null) {
				EditorGUILayout.HelpBox(res, MessageType.Error);
			}
		}
		GUILayout.EndScrollView ();
		GUILayout.EndVertical();
	}

	private string MergeTextures(Texture2D galaxy, Texture2D stars, string outPath) {
		if(galaxy.width != stars.width || galaxy.height != stars.height) return "Texture dimension mismatch between galaxy and stars.";
		Texture2D res = new Texture2D(stars.width, stars.height);
		for(int i = 0; i < res.width; i++) {
			for(int j = 0; j < res.height; j++) {
				Color cg = galaxy.GetPixel(i, j);
				Color cs = stars.GetPixel(i, j);
				cg.r *= galaxyBrightness;
				cg.g *= galaxyBrightness;
				cg.b *= galaxyBrightness;
				cs.r *= starsBrightness;
				cs.g *= starsBrightness;
				cs.b *= starsBrightness;

				cg.r = BiasFunction(cg.r, galaxyColorBias);
				cg.g = BiasFunction(cg.g, galaxyColorBias);
				cg.b = BiasFunction(cg.b, galaxyColorBias);
				cs.r = BiasFunction(cs.r, starsColorBias);
				cs.g = BiasFunction(cs.g, starsColorBias);
				cs.b = BiasFunction(cs.b, starsColorBias);

				cg.r *= 1 - cs.r;
				cg.g *= 1 - cs.g;
				cg.b *= 1 - cs.b;

				res.SetPixel(i, j, new Color(cg.r + cs.r, cg.g + cs.g, cg.b + cs.b));
			}
		}
		res.Apply();
		byte[] texData = res.EncodeToPNG();
		System.IO.FileStream stream = System.IO.File.Create(outPath);
		stream.Write(texData, 0, texData.Length);
		stream.Dispose();
		return null;
	}

	private float BiasFunction(float x, float bias) {
		float k = 1.0f - bias;
		k = k * k * k;
		return (x * k) / (x * k - x + 1.0f);
	}
}
