/*
 * +================================================================================+
 *      __  ___  ______________  __  __  ______________   ____
 *     / / / / |/ /  _/_  __/\ \/ / / / / /_  __/  _/ /  / __/
 *    / /_/ /    // /  / /    \  / / /_/ / / / _/ // /___\ \
 *    \____/_/|_/___/ /_/     /_/  \____/ /_/ /___/____/___/
 *
 * +================================================================================+
 *
 *    "THE BEER-WARE LICENSE"
 *    -----------------------
 *
 *    As long as you retain this notice you can do whatever you want with this
 *    stuff. However it is expressly forbidden to sell or commercially distribute
 *    Unity Utils or parts of it apart from your games.
 *    If you meet any of the authors some day, and you think this stuff is
 *    worth it, you can buy them a beer in return.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *    THE SOFTWARE.
 *
 * +================================================================================+
 *
 *    Authors:
 *    David Krummenacher (dave@timbookedtwo.com)
 *
 */

using System.IO;
using System.Text.RegularExpressions;
using UnityEngine;

namespace Utils.Helpers {

	/// <summary>
	/// Screenshot helper.
	/// </summary>
	public abstract class ScreenshotHelper {

		/// <summary>
		/// Takes a screenshot.
		/// </summary>
		/// <param name="filepath">The filepath. Determines the files location and name (eg. "Screenshots/SuperCoolScreenshot.png").</param>
		/// <param name="supersize">The supersize. Determines how many times the resolution is upscaled..</param>
		public static void TakeScreenshot(string filepath, int supersize) {
			GameObject screenshotTakerObject = new GameObject("ScreenshotTaker");
			ScreenshotTaker screenshotTaker = screenshotTakerObject.AddComponent<ScreenshotTaker>();
			screenshotTaker.Filepath = filepath;
			screenshotTaker.Supersize = supersize;
		}

		/// <summary>
		/// Takes a screenshot.
		/// </summary>
		/// <param name="filepath">The filepath. Determines the files location and name (eg. "Screenshots/SuperCoolScreenshot.png").</param>
		public static void TakeScreenshot(string filepath) {
			TakeScreenshot(filepath, 1);
		}

		/// <summary>
		/// Takes a screenshot.
		/// </summary>
		/// <param name="supersize">The supersize. Determines how many times the resolution is upscaled..</param>
		public static void TakeScreenshot(int supersize) {
			// Illegal characters handling for product name
			string regexSearch = new string(Path.GetInvalidFileNameChars());
			Regex regex = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch)));
			string productName = regex.Replace(Application.productName, "");

			TakeScreenshot("Screenshots/" + productName + ".png", supersize);
		}

		/// <summary>
		/// Takes a screenshot.
		/// </summary>
		public static void TakeScreenshot() {
			TakeScreenshot(1);
		}

		/// <summary>
		/// Screenshot taker behaviour that is added to an object to take the screenshot in late update.
		/// </summary>
		private class ScreenshotTaker : MonoBehaviour {

			/// <summary>
			/// The file path.
			/// </summary>
			public string Filepath = "";
			/// <summary>
			/// The supersize. Determines how many times the resolution is upscaled.
			/// </summary>
			public int Supersize = 1;

			/// <summary>
			/// The extention reference.
			/// </summary>
			private static string extention = ".png";

			void LateUpdate() {
				// File extention handling
				if (Path.HasExtension(Filepath)) {
					if (Path.GetExtension(Filepath) != extention) Filepath = Path.ChangeExtension(Filepath, extention);
				} else if (!Filepath.EndsWith(extention)) {
					Filepath += extention;
				}

				// Full path handling to always place screenshots at executable location if no absolute path is specified
				if (!Application.isMobilePlatform) Filepath = Path.GetFullPath(Filepath);

				// Directory handling
				if (!Directory.Exists(Path.GetDirectoryName(Filepath)))
					Directory.CreateDirectory(Path.GetDirectoryName(Filepath));

				// File duplicate handling
				if (File.Exists(Filepath)) {
					int number = 2;
					string file  = Filepath.Substring(0, Filepath.Length - extention.Length);
					while (File.Exists(file + " " + number.ToString() + extention)) number++;
					Filepath = file + " " + number.ToString() + extention;
				}

				// Take screenshot and destroy yourself
				Debug.Log("Saving Screenshot (" + Supersize + "x): " + Filepath);
				Application.CaptureScreenshot(Filepath, Supersize);
				Destroy(gameObject);
			}
		}
	}
}
