#if UNITY_IOS

using AOT;	//MonoPInvokeCallback
using System;
using System.Reflection;
using UnityEngine;
using System.Runtime.CompilerServices;

public class VrtcalIos {
	private static VrtcalIos singleton = new VrtcalIos();

    public static VrtcalIos Singleton
    {
        get
        {
            return singleton;
        }
    }


    #region Public API
		public static void InitSdk(int appId) {
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUInitializeSdk(
				appId, 
				
				SdkInitializationCompleteCallback,
				SdkInitializationFailedWithErrorCallback,

				BannerAdLoadedCallback,
				BannerAdFailedToLoadCallback,
				BannerVideoStartedCallback,
				BannerVideoCompletedCallback,
				BannerAdClickedCallback,
				BannerAdWillLeaveApplicationCallback,
				BannerAdWillPresentModalCallback,
				BannerAdDidPresentModalCallback,
				BannerAdWillDismissModalCallback,
				BannerAdDidDismissModalCallback,

				InterstitialAdLoadedCallback,
				InterstitialAdFailedToLoadCallback,
				InterstitialAdWillShowCallback,
				InterstitialAdDidShowCallback,
				InterstitialAdFailedToShowCallback,
				InterstitialVideoStartedCallback,
				InterstitialVideoCompletedCallback,
				InterstitialAdClickedCallback,
				InterstitialAdWillLeaveApplicationCallback,
				InterstitialAdWillDismissCallback,
				InterstitialAdDidDismissCallback
			);	
		}	

	    public static void LoadTopBanner(int zoneId, float width, float height)
	    {
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUBannerLoadTop(zoneId,width,height);
	    }	

	    public static void LoadBottomBanner(int zoneId, float width, float height)
	    {
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUBannerLoadBottom(zoneId,width,height);
	    }   

	    public static void LoadBanner(int zoneId, float x, float y, float width, float height)
	    { 
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUBannerLoad(zoneId, x, y, width, height);
	    }

	    public static void MoveBanner(int zoneId, float x, float y)
	    {
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUBannerMove(zoneId, x, y);
	    }

	    public static void DestroyBanner(int zoneId)
	    {
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUBannerDestroy(zoneId);
	    }

	    public static void LoadInterstitial(int zoneId)
	    {
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUInterstitialLoad(zoneId);
	    }

	    public static void ShowInterstitial(int zoneId)
	    {
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUInterstitialShow(zoneId);
	    }

	    public static void DestroyInterstitial(int zoneId)
	    {
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUInterstitialDestroy(zoneId);
	    }

	    public static void SetPiiData(string piiData)
	    {
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUSetPiiData(piiData);
	    }

	    public static void SetPiiDataTypes(string piiDataTypes)
	    {
			if (shouldReturnEarly()) {return;}
			VrtcalExterns.VRTUSetPiiDataTypes(piiDataTypes);
	    }	    
    #endregion


    #region SDK Init Callbacks
	    public delegate void VRTUSdkInitializedCallback();
		[MonoPInvokeCallback(typeof(VRTUSdkInitializedCallback))]
		private static void SdkInitializationCompleteCallback()
		{
			Vrtcal.OnSdkInitializedEvent.Invoke(null);
		}

	    public delegate void VRTUSdkInitializationFailedWithErrorCallback(string error);
		[MonoPInvokeCallback(typeof(VRTUSdkInitializationFailedWithErrorCallback))]
		private static void SdkInitializationFailedWithErrorCallback(string error)
		{
			Vrtcal.OnSdkFailedToInitializeEvent.Invoke(error);
		}		
	#endregion

    #region Banner Callbacks
	    public delegate void VRTUBannerAdLoadedCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUBannerAdLoadedCallback))]
	    private static void BannerAdLoadedCallback(int zoneId)
	    {
			Vrtcal.OnBannerLoadedEvent.Invoke(zoneId, null);
	    }

	    public delegate void VRTUBannerAdFailedToLoadCallback(int zoneId, string error);
	    [MonoPInvokeCallback(typeof(VRTUBannerAdFailedToLoadCallback))]
	    private static void BannerAdFailedToLoadCallback(int zoneId, string error)
	    {
			Vrtcal.OnBannerFailedToLoadEvent.Invoke(zoneId, error);
	    }

	    public delegate void VRTUBannerAdClickedCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUBannerAdClickedCallback))]
	    private static void BannerAdClickedCallback(int zoneId)
	    {
			Vrtcal.OnBannerClickedEvent.Invoke(zoneId, null);
	    }
	    
	    public delegate void VRTUBannerAdWillPresentModalCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUBannerAdWillPresentModalCallback))]
	    private static void BannerAdWillPresentModalCallback(int zoneId)
	    {
			Vrtcal.OnBannerWillPresentModalEvent.Invoke(zoneId, null);
	    }

	    public delegate void VRTUBannerAdDidPresentModalCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUBannerAdDidPresentModalCallback))]
	    private static void BannerAdDidPresentModalCallback(int zoneId)
	    {
	    	Vrtcal.Log("Not mapped to a Vrtcal.cs event. zoneId: " + zoneId);
	    }

	    public delegate void VRTUBannerAdWillDismissModalCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUBannerAdWillDismissModalCallback))]
	    private static void BannerAdWillDismissModalCallback(int zoneId) {
			Vrtcal.Log("Not mapped to a Vrtcal.cs event. zoneId: " + zoneId);	    	
	    }

	    public delegate void VRTUBannerAdDidDismissModalCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUBannerAdDidDismissModalCallback))]
	    private static void BannerAdDidDismissModalCallback(int zoneId)
	    {
			Vrtcal.OnBannerDidDismissModalEvent.Invoke(zoneId, null);
	    }

	    public delegate void VRTUBannerVideoStartedCallback(int zoneId, string error);
	    [MonoPInvokeCallback(typeof(VRTUBannerVideoStartedCallback))]
	    private static void BannerVideoStartedCallback(int zoneId, string error)
	    {
			Vrtcal.OnBannerVideoStartedEvent.Invoke(zoneId, error);
	    }

	    public delegate void VRTUBannerVideoCompletedCallback(int zoneId, string error);
	    [MonoPInvokeCallback(typeof(VRTUBannerVideoCompletedCallback))]
	    private static void BannerVideoCompletedCallback(int zoneId, string error)
	    {
			Vrtcal.OnBannerVideoCompletedEvent.Invoke(zoneId, error);
	    }

		public delegate void VRTUBannerAdWillLeaveApplicationCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUBannerAdWillLeaveApplicationCallback))]
	    private static void BannerAdWillLeaveApplicationCallback(int zoneId)
	    {
	    	Vrtcal.Log("Not mapped to a Vrtcal.cs event. zoneId: " + zoneId);
	    }
    #endregion

    #region Interstitial Callbacks
	    public delegate void VRTUInterstitialAdLoadedCallback(int zoneId);    
	    [MonoPInvokeCallback(typeof(VRTUInterstitialAdLoadedCallback))]
	    private static void InterstitialAdLoadedCallback(int zoneId)
	    {
			Vrtcal.OnInterstitialLoadedEvent.Invoke(zoneId, null);
	    }

	    public delegate void VRTUInterstitialAdFailedToLoadCallback(int zoneId, string error);
	    [MonoPInvokeCallback(typeof(VRTUInterstitialAdFailedToLoadCallback))]
	    private static void InterstitialAdFailedToLoadCallback(int zoneId, string error)
	    {
			Vrtcal.OnInterstitialFailedToLoadEvent.Invoke(zoneId, error);
	    }   

	    public delegate void VRTUInterstitialAdWillShowCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUInterstitialAdWillShowCallback))]
	    private static void InterstitialAdWillShowCallback(int zoneId)
	    {	    	
			Vrtcal.Log("Not mapped to a Vrtcal.cs event. zoneId: " + zoneId);
	    }

	    public delegate void VRTUInterstitialAdDidShowCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUInterstitialAdDidShowCallback))]
	    private static void InterstitialAdDidShowCallback(int zoneId)
	    {
			Vrtcal.OnInterstitialShownEvent.Invoke(zoneId, null);	
	    }

	    public delegate void VRTUInterstitialAdFailedToShowCallback(int zoneId, string error);
	    [MonoPInvokeCallback(typeof(VRTUInterstitialAdFailedToShowCallback))]
	    private static void InterstitialAdFailedToShowCallback(int zoneId, string error)
	    {
			Vrtcal.Log("Not mapped to a Vrtcal.cs event. zoneId: " + zoneId, " error: " + error);
	    }

	    public delegate void VRTUInterstitialVideoStartedCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUInterstitialVideoStartedCallback))]
	    private static void InterstitialVideoStartedCallback(int zoneId)
	    {
			Vrtcal.Log("Not mapped to a Vrtcal.cs event. zoneId: " + zoneId);
	    }

	    public delegate void VRTUInterstitialVideoCompletedCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUInterstitialVideoCompletedCallback))]
	    private static void InterstitialVideoCompletedCallback(int zoneId)
	    {
			Vrtcal.Log("Not mapped to a Vrtcal.cs event. zoneId: " + zoneId);
	    }	    

		public delegate void VRTUInterstitialAdClickedCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUInterstitialAdClickedCallback))]
	    private static void InterstitialAdClickedCallback(int zoneId)
	    {   	
			Vrtcal.OnInterstitialClickedEvent.Invoke(zoneId, null);	
	    }

	    public delegate void VRTUInterstitialAdWillLeaveApplicationCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUInterstitialAdWillLeaveApplicationCallback))]
	    private static void InterstitialAdWillLeaveApplicationCallback(int zoneId)
	    {
			Vrtcal.Log("Not mapped to a Vrtcal.cs event. zoneId: " + zoneId);
	    }	  
	    
		public delegate void VRTUInterstitialAdWillDismissCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUInterstitialAdWillDismissCallback))]
	    private static void InterstitialAdWillDismissCallback(int zoneId)
	    {
			Vrtcal.Log("Not mapped to a Vrtcal.cs event. zoneId: " + zoneId);
	    }

	    public delegate void VRTUInterstitialAdDidDismissCallback(int zoneId);
	    [MonoPInvokeCallback(typeof(VRTUInterstitialAdDidDismissCallback))]
	    private static void InterstitialAdDidDismissCallback(int zoneId)
	    {
			Vrtcal.OnInterstitialDismissedEvent.Invoke(zoneId, null);
	    }


    #endregion

	#region Utility
	    private static bool shouldReturnEarly([CallerMemberName] string method = null) {
	    	bool ret = Application.platform != RuntimePlatform.IPhonePlayer;

			if (ret) {
				Vrtcal.Log("Platform not IPhonePlayer, returning early from " + method);
			}

			return ret;
	    }
	#endregion	    
}

#endif