context: #if UNITY_EDITOR
  //////////////////////////////////////////////////////////////////////
  //
  // Copyright (c) 2014 Audiokinetic Inc. / All Rights Reserved
  //
  //////////////////////////////////////////////////////////////////////
  
  using UnityEngine;
  using UnityEditor;
  using System;
  using System.Reflection;
  
  [CanEditMultipleObjects]
  [CustomEditor(typeof(AkEvent))]
  public class AkEventInspector : AkBaseInspector
  {
  	AkEvent m_akEvent;
  
  	SerializedProperty eventID;
  	SerializedProperty enableActionOnEvent;    
  	SerializedProperty actionOnEventType;
  	SerializedProperty curveInterpolation;
  	SerializedProperty transitionDuration;
  
  	string[]	m_supportedCallbackFlags;
  	int[]		m_supportedCallbackValues;
  
  	AkUnityEventHandlerInspector m_UnityEventHandlerInspector = new AkUnityEventHandlerInspector();
  
  	public void OnEnable()
  	{
  		m_akEvent = target as AkEvent;
  		
  		m_UnityEventHandlerInspector.Init(serializedObject);
  		
  		eventID				= serializedObject.FindProperty("eventID");
  		enableActionOnEvent	= serializedObject.FindProperty("enableActionOnEvent");
  		actionOnEventType	= serializedObject.FindProperty("actionOnEventType");
  		curveInterpolation	= serializedObject.FindProperty("curveInterpolation");
  		transitionDuration	= serializedObject.FindProperty("transitionDuration");
  		
  		m_guidProperty		= new SerializedProperty[1];
  		m_guidProperty[0]	= serializedObject.FindProperty("valueGuid.Array");
  		
  		//Needed by the base class to know which type of component its working with
  		m_typeName		= "Event";
  		m_objectType	= AkWwiseProjectData.WwiseObjectType.EVENT;
  
  
  		//Build a list of all supported callback type names and values
  		int[] callbacktypes = (int[])Enum.GetValues (typeof(AkCallbackType));
  		int[] unsupportedCallbackValues =
  		{
  			(int)AkCallbackType.AK_SpeakerVolumeMatrix,
  			(int)AkCallbackType.AK_MusicSyncAll,
  			(int)AkCallbackType.AK_CallbackBits,
  			(int)AkCallbackType.AK_EnableGetSourcePlayPosition,
  			(int)AkCallbackType.AK_EnableGetMusicPlayPosition,
  			(int)AkCallbackType.AK_EnableGetSourceStreamBuffering,
  			(int)AkCallbackType.AK_Monitoring,
  			(int)AkCallbackType.AK_AudioSourceChange,
  			(int)AkCallbackType.AK_Bank,
  			(int)AkCallbackType.AK_AudioInterruption
  		};
  
  		m_supportedCallbackFlags 	= new string[callbacktypes.Length - unsupportedCallbackValues.Length];
  		m_supportedCallbackValues 	= new int	[callbacktypes.Length - unsupportedCallbackValues.Length];
  
  		int index = 0;
  		for(int i = 0; i < callbacktypes.Length; i++)
  		{
  			if(!Contain(unsupportedCallbackValues, callbacktypes[i]))
  			{
  				m_supportedCallbackFlags[index] = Enum.GetName(typeof(AkCallbackType), callbacktypes[i]).Substring(3);
  				m_supportedCallbackValues[index] = callbacktypes[i];
  				index++;
  			}
  		}
  	}
  
  	bool Contain(int[] in_array, int in_value)
  	{
  		for(int i = 0; i < in_array.Length; i++)
  		{
  			if(in_array[i] == in_value) return true;
  		}
  
  		return false;
  	}
  
  	public override void OnChildInspectorGUI ()
  	{	
  		serializedObject.Update ();
  
  		m_UnityEventHandlerInspector.OnGUI();
  		
  		GUILayout.Space(2);
  		
  		GUILayout.BeginVertical("Box");
  		{
  			EditorGUILayout.PropertyField(enableActionOnEvent, new GUIContent("Action On Event: "));
  			
  			if(enableActionOnEvent.boolValue)
  			{
  				EditorGUILayout.PropertyField(actionOnEventType, new GUIContent("Action On EventType: "));
  				EditorGUILayout.PropertyField(curveInterpolation, new GUIContent("Curve Interpolation: "));
  				EditorGUILayout.Slider(transitionDuration, 0.0f, 60.0f, new GUIContent("Fade Time (secs): "));
  			}
  			
  		}
  		GUILayout.EndVertical();
  
  		GUILayout.Space (2);
  
  		GUILayout.BeginVertical ("Box");
  		{
  			bool useCallback = m_akEvent.m_callbackData != null;
  #if UNITY_5_3_OR_NEWER
  			EditorGUI.BeginChangeCheck();
  #endif
  			useCallback = EditorGUILayout.Toggle ("Use Callback: ", useCallback);
  #if UNITY_5_3_OR_NEWER
  			if (EditorGUI.EndChangeCheck())
  #endif
  			{
  #if UNITY_5_3_OR_NEWER
  				Undo.RecordObject(target, "Use Callback Change");
  #endif
  
  				if (m_akEvent.m_callbackData == null && useCallback)
  				{
  					m_akEvent.m_callbackData = ScriptableObject.CreateInstance<AkEventCallbackData>();
  
  					m_akEvent.m_callbackData.callbackFunc.Add(string.Empty);
  					m_akEvent.m_callbackData.callbackFlags.Add(0);
  					m_akEvent.m_callbackData.callbackGameObj.Add(null);
  				}
  				else if (!useCallback)
  				{
  					m_akEvent.m_callbackData = null;
  				}
  			}
  
  			if (m_akEvent.m_callbackData != null)
  			{
  				GUILayout.Space(3);
  
  				GUILayout.BeginHorizontal();
  				{
  					GUILayout.Label("Game Object");
  					GUILayout.Label("Callback Function");
  					GUILayout.Label("Callback Flags");
  				}
  				GUILayout.EndHorizontal();
  
  				m_akEvent.m_callbackData.uFlags = 0;
  
  				for (int i = 0; i < m_akEvent.m_callbackData.callbackFunc.Count; i++)
  				{
  					GUILayout.BeginHorizontal();
  					{
  #if UNITY_5_3_OR_NEWER
  						EditorGUI.BeginChangeCheck();
  #endif
  						GameObject gameObj = (GameObject)EditorGUILayout.ObjectField(m_akEvent.m_callbackData.callbackGameObj[i], typeof(GameObject), true);
  						string func = EditorGUILayout.TextField(m_akEvent.m_callbackData.callbackFunc[i]);
  
  						//Since some callback flags are unsupported, some bits are not used.
  						//But when using EditorGUILayout.MaskField, clicking the third flag will set the third bit to one even if the third flag in the AkCallbackType enum is unsupported.
  						//This is a problem because cliking the third supported flag would internally select the third flag in the AkCallbackType enum which is unsupported.
  						//To solve this problem we use a mask for display and another one for the actual callback
  						int displayMask = GetDisplayMask(m_akEvent.m_callbackData.callbackFlags[i]);
  						displayMask = EditorGUILayout.MaskField(displayMask, m_supportedCallbackFlags);
  						int flags = GetWwiseCallbackMask(displayMask);
  
  #if UNITY_5_3_OR_NEWER
  						if (EditorGUI.EndChangeCheck())
  #endif
  						{
  #if UNITY_5_3_OR_NEWER
  							Undo.RecordObject(m_akEvent.m_callbackData, "Modified Callback");
  #endif
  							m_akEvent.m_callbackData.callbackGameObj[i] = gameObj;
  							m_akEvent.m_callbackData.callbackFunc[i] = func;
  							m_akEvent.m_callbackData.callbackFlags[i] = flags;
  						}
  
  						if (GUILayout.Button("X"))
  						{
  #if UNITY_5_3_OR_NEWER
  							Undo.RecordObject(m_akEvent.m_callbackData, "Remove Callback");
  #endif
  
  							if (m_akEvent.m_callbackData.callbackFunc.Count == 1)
  							{
  								m_akEvent.m_callbackData.callbackFunc[0] = string.Empty;
  								m_akEvent.m_callbackData.callbackFlags[0] = 0;
  								m_akEvent.m_callbackData.callbackGameObj[0] = null;
  
  								//Changes to the textfield string will not be picked up by the text editor if it is selected.
  								//So we remove focus from the textfield to make sure it will get updated
  								GUIUtility.keyboardControl = 0;
  								GUIUtility.hotControl = 0;
  							}
  							else
  							{
  								m_akEvent.m_callbackData.callbackFunc.RemoveAt(i);
  								m_akEvent.m_callbackData.callbackFlags.RemoveAt(i);
  								m_akEvent.m_callbackData.callbackGameObj.RemoveAt(i);
  
  								GUIUtility.keyboardControl = 0;
  								GUIUtility.hotControl = 0;
  
  								i--;
  								continue;
  							}
  						}
  
  						m_akEvent.m_callbackData.uFlags |= m_akEvent.m_callbackData.callbackFlags[i];
  					}
  					GUILayout.EndHorizontal();
  				}
  
  				GUILayout.Space(3);
  
  				if (GUILayout.Button("Add"))
  				{
  #if UNITY_5_3_OR_NEWER
  					Undo.RecordObject(m_akEvent.m_callbackData, "Add Callback");
  #endif
  
  					m_akEvent.m_callbackData.callbackFunc.Add(string.Empty);
  					m_akEvent.m_callbackData.callbackFlags.Add(0);
  					m_akEvent.m_callbackData.callbackGameObj.Add(null);
  				}
  
  				GUILayout.Space(3);
  			}
  		}
  		GUILayout.EndVertical();
  
  		serializedObject.ApplyModifiedProperties ();
  	}
  
  	public override string UpdateIds (Guid[] in_guid)
  	{
  		for(int i = 0; i < AkWwiseProjectInfo.GetData().EventWwu.Count; i++)
  		{
  			AkWwiseProjectData.Event e = AkWwiseProjectInfo.GetData().EventWwu[i].List.Find(x => new Guid(x.Guid).Equals(in_guid[0]));
  			
  			if(e != null)
  			{
  				serializedObject.Update();
  				eventID.intValue = e.ID;
  				serializedObject.ApplyModifiedProperties();
  
  				return e.Name;
  			}
  		}
  
  		return string.Empty;
  	}
  
  	int GetDisplayMask(int in_wwiseCallbackMask)
  	{
  		int displayMask = 0;
  
gt: 		for(int i = 0; i < m_supportedCallbackValues.Length; i++)