/*
 * +================================================================================+
 *      __  ___  ______________  __  __  ______________   ____
 *     / / / / |/ /  _/_  __/\ \/ / / / / /_  __/  _/ /  / __/
 *    / /_/ /    // /  / /    \  / / /_/ / / / _/ // /___\ \
 *    \____/_/|_/___/ /_/     /_/  \____/ /_/ /___/____/___/
 *
 * +================================================================================+
 *
 *    "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;
using UnityEngine;

namespace Utils.Settings {

	/// <summary>
	/// Resolution settings.
	/// </summary>
	public class ResolutionSetting : Setting {

		/// <summary>
		/// The resolution identifier.
		/// </summary>
		private int resolutionId;
		/// <summary>
		/// The resolution identifier.
		/// </summary>
		public int ResolutionId {
			get { return resolutionId; }
			set {
				resolutionId = value;
				RaiseOnValueChanged(this);
			}
		}
		/// <summary>
		/// Determines wheter fullscreen is activated or not.
		/// </summary>
		public bool fullscreen;
		/// <summary>
		/// Determines wheter fullscreen is activated or not.
		/// </summary>
		public bool Fullscreen {
			get { return fullscreen; }
			set {
				fullscreen = value;
				RaiseOnValueChanged(this);
			}
		}

		/// <summary>
		/// The key for the resolution used in the player preferences.
		/// </summary>
		public static string ResolutionKey = "Resolution";
		/// <summary>
		/// The key for fullscreen used in the player preferences.
		/// </summary>
		public static string FullscreenKey = "Fullscreen";

		/// <summary>
		/// Initializes the resolution settings.
		/// </summary>
		protected override void InitSetting() {
			LoadSetting();
		}

		/// <summary>
		/// Loads the resolution settings from the player preferences.
		/// </summary>
		protected override void LoadSetting() {
			// Resolution handling
			if (HasKey(ResolutionKey)) {
				resolutionId = Mathf.Clamp(GetInt(ResolutionKey), 0, Screen.resolutions.Length);
			} else {
				int id = Screen.resolutions.Length - 1;
				for (int i = 0; i < Screen.resolutions.Length; i++) {
					if (Screen.resolutions[i].width == Screen.currentResolution.width && Screen.resolutions[i].height == Screen.currentResolution.height) {
						id = i;
						break;
					}
				}
				resolutionId = id;
			}
			
			// Fullscreen handling
			if (HasKey(FullscreenKey)) fullscreen = GetBool(FullscreenKey);
			else fullscreen = Screen.fullScreen;

			// Raise value changed event
			RaiseOnValueChanged(this);
		}

		/// <summary>
		/// Saves the resolution settings to the player preferences.
		/// </summary>
		protected override void SaveSetting() {
			SetInt(ResolutionKey, ResolutionId);
			SetBool(FullscreenKey, Fullscreen);
		}

		/// <summary>
		/// Applies the resolution settings.
		/// </summary>
		protected override void ApplySetting() {
			// Don't change anything if not necessairy
			if (Screen.resolutions[ResolutionId].width == Screen.currentResolution.width &&
				Screen.resolutions[ResolutionId].height == Screen.currentResolution.height &&
				Screen.fullScreen == Fullscreen
			) return;

			Screen.SetResolution(
				Screen.resolutions[ResolutionId].width,
				Screen.resolutions[ResolutionId].height,
				Fullscreen
			);
		}

		/// <summary>
		/// Gets the available resolutions.
		/// Use the position in the array to set the resolution id.
		/// </summary>
		/// <returns>The resolutions.</returns>
		public string[] GetResolutions() {
			string[] resolutionNames = new string[Screen.resolutions.Length];
			
			for (int i = 0; i < Screen.resolutions.Length; i++) {
				resolutionNames[i] = Screen.resolutions[i].width + "x" + Screen.resolutions[i].height;
			}
			
			return resolutionNames;
		}
	}
}
