﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using System;
using UnityEditor;
#endif

namespace GLogUnity
{
	public class GLogChannel : ScriptableObject
	{
		public bool active = true;

		#region Verbose

		protected int level = 255;

		/// <summary>
		/// Allow to get/set the channel verbose level
		/// </summary>
		public int Level
		{
			get { return level; }
			set { level = value; }
		}

		/// <summary>
		/// Allow to check if channel has a specific verbose level
		/// </summary>
		public bool HasLevel(VerboseLevel level)
		{
			return (this.level & (int)level) != 0;
		}

		/// <summary>Add a Verbose level to the channel</summary>
		public void AddLevel(VerboseLevel level)
		{
			this.level = this.level | (int)level;
		}

		/// <summary>Remove a Verbose level to the channel</summary>
		public void RemoveLevel(VerboseLevel level)
		{
			this.level = this.level & ~(int)level;
		}

		/// <summary>Set the channel verbose level on or off</summary>
		public void SetLevel(VerboseLevel level, bool on)
		{
			if (on)
				this.level = this.level | (int)level;
			else
				this.level = this.level & ~(int)level;
		}

		#endregion

		#region Channel

		/// <summary>Open is called when ever a channel is initialized</summary>
		public virtual void Open()
		{
		}

		/// <summary>Open is called when ever a channel is initialized</summary>
		public virtual void Shutdown()
		{
		}

		/// <summary>Check if the channel is open</summary>
		public virtual bool IsOpen()
		{
			return true;
		}

		/// <summary>
		/// Submits the list to the media (e.g. online, screen) and then clears the log list
		/// </summary>
		public virtual void Flush()
		{
		}

		/// <summary>
		/// Updates the log channel for temporal procedures
		/// </summary>
		public virtual void UpdateChannel(float deltaTime)
		{
		}

		#endregion

		#region Session

		protected SessionInfo activeSession = null;

		/// <summary>Starts a new game session. 
		/// <remarks>If a new game session is already active, it closes that session. See <see cref="CloseSession"/></remarks>
		/// </summary>
		public virtual void StartSession(SessionInfo session)
		{
			if (activeSession != null)
				CloseSession(activeSession);
			activeSession = session;
		}

		/// <summary>
		/// Close the current game session, and pushes/flushed all the cached logs
		/// </summary>
		public virtual void CloseSession(SessionInfo session)
		{
			if (activeSession == null) return;
			activeSession = session;
			Flush();
			activeSession = null;
		}

		#endregion

		#region Logs

		/// <summary>Adds the log to the loglist</summary>
		/// <param name="log">Predefined Log Info</param>
		public virtual void Log(LogInfo log)
		{
		}

		#endregion
	}

#if UNITY_EDITOR


	[CustomEditor(typeof(GLogChannel))]
	public class GLogChannelEditor : Editor
	{
		protected GLogChannel targetChannel;

		void OnEnable()
		{
			targetChannel = (GLogChannel) target;
		}

		public override void OnInspectorGUI()
		{
			bool result, level;

			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.LabelField("Name", GUILayout.Width(40));
			targetChannel.name = EditorGUILayout.TextField(targetChannel.name);
			targetChannel.active = EditorGUILayout.ToggleLeft("Active", targetChannel.active, GUILayout.Width(60));
			EditorGUILayout.EndHorizontal();

			targetChannel.Level = EditorGUILayout.MaskField("Verbose Level", targetChannel.Level, Enum.GetNames(typeof(VerboseLevel)));
		}
	}
#endif
}