using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using hive;
using GameNetwork;
using System;
using System.Dynamic;

public class HIVEManager : MonoBehaviour {

	// delegate format
	public delegate void onHIVEManagerEvent(bool isSuccess, string message);
	public delegate void onHIVEManagerRedirectEvent(bool isSuccess, string message, bool moveToTitle);
	public delegate void onHIVEManagerRemotePushEvent(bool isSuccess, string message, RemotePush remotePush);
	public delegate void onHIVEManagerPurchaseEvent(bool isSuccess, string message, IAPV4.IAPV4Receipt iapV4Receipt);
	public delegate void onHIVEManagerRestoreEvent(bool isSuccess, string message, List<IAPV4.IAPV4Receipt> iapV4ReceiptList);
	public delegate void onHIVEManagerRestoreSubscriptionEvent(bool isSuccess, string message, List<IAPV4.IAPV4Receipt> iapV4ReceiptList);
	public delegate void onHIVEManagerRequestPermissionEvent(bool isNeedToShow, string message, PermissionViewData data);
	public delegate void onHIVEManagerPromotionBannerInfoEvent(bool isSuccess, List<PromotionBannerInfo> bannerInfoList);

	// delegate list
	// HIVE SDK AuthV4 delegates
	static onHIVEManagerEvent onHIVEManagerSetup;
	static onHIVEManagerRequestPermissionEvent onHIVEManagerRequestPermissionViewData;
	static onHIVEManagerEvent onHIVEManagerSignIn;
	static onHIVEManagerEvent onHIVEManagerSignOut;
	static onHIVEManagerEvent onHIVEManagerDisconnect;
	static onHIVEManagerEvent onHIVEManagerShowProfile;
	static onHIVEManagerEvent onHIVEManagerShowInquiry;
	static onHIVEManagerEvent onHIVEManagerShowCafe;
	static onHIVEManagerEvent onHIVEManagerShowDeviceManagement;
	static onHIVEManagerEvent onHIVEManagerShowTerms;
	static onHIVEManagerEvent onHIVEManagerCheckMaintenance;
    
	static onHIVEManagerRedirectEvent onHIVEManagerConnect;
	static onHIVEManagerRedirectEvent onHIVEManagerLeaderboard;
	static onHIVEManagerRedirectEvent onHIVEManagerAchievements;

	// HIVE SDK Promotion
	static onHIVEManagerPromotionBannerInfoEvent onHIVEManagerGetBannerInfo;

	// HIVE SDK PUSHdelegate
	static onHIVEManagerRemotePushEvent onHIVEManagerGetRemotePush;
	static onHIVEManagerRemotePushEvent onHIVEManagerSetRemotePush;

	// HIVE SDK IAPV4 delegates
	static onHIVEManagerEvent onHIVEManagerShopSetup;
	static onHIVEManagerPurchaseEvent onHIVEManagerPurchase;
	static onHIVEManagerPurchaseEvent onHIVEManagerPurchaseSubscription;
	static onHIVEManagerRestoreEvent onHIVEManagerRestore;
	static onHIVEManagerRestoreSubscriptionEvent onHIVEManagerRestoreSubscription;
	static onHIVEManagerEvent onHIVEManagerTransactionFinish;

	static event onHIVEManagerEvent onHIVEManagerShowExit;
	// static event onHIVEManagerEvent onHIVEManagerShowReview;

	// HIVE SDK DataStore
	static onHIVEManagerEvent onHIVEManagerGetDataStore;


	public bool isPermissionAgreed
	{
		set
		{
			_isPermissionAgreed = value;


			if (_isPermissionAgreed == false)
			{
				// HIVE SDK 권한 동의가 안되면 초기화 및 로그인 단계도 초기화
				_isSetup = false;
				_isSignIn = false;
			}
		}
		get
		{
			return _isPermissionAgreed;
		}
	}
	public bool isSetup {
		set {
			_isSetup = value;

			if (_isSetup == false) {
				// HIVE SDK Setup 이 안되면 로그인 단계도 초기화
				_isSignIn = false;
			}
		}

		get {
			return _isSetup;
		}
	}

	public bool isSignIn {
		set {
			_isSignIn = value;
		}

		get {
			return _isSignIn;
		}
	}

	// Shop 상품 목록(readonly)
	public List<IAPV4.IAPV4Product> productList {
		get {
			if (_isMarkConnected == true 
			&& _isGetProductInfo == true) {
				return _productList;
			} else {
				return null;
			}
		}
	}

	public List<IAPV4.IAPV4Product> subscriptionProductList {
		get {
			if (_isMarkConnected == true 
			&& _isGetSubscriptionProductInfo == true) {
				return _subscriptionProductList;
			} else {
				return null;
			}
		}
	}

	public AuthV4.PlayerInfo playerInfo = null;

	private bool _isPermissionAgreed = false;			// HIVE SDK 권한 동의 여부.
	private bool _isSetup = false;			// HIVE SDK 초기화 여부.
	private bool _isSignIn = false;			// HIVE SDK 인증 여부.
	private bool _isMarkConnected = false;	// HIVE SDK IAP V4 마켓 연동 여부.
	private bool _isGetProductInfo = false;	// HIVE SDK IAP V4 상품 목록 수신 여부.
	private bool _isGetSubscriptionProductInfo = false;	// HIVE SDK IAP V4 구독 상품 목록 수신 여부.

	public List<IAPV4.IAPV4Product> _productList = null;	// HIVE SDK IAP V4 상품 목록.
	public List<IAPV4.IAPV4Product> _subscriptionProductList = null;	// HIVE SDK IAP V4 구독 상품 목록.

	public static int item1Index = 3;
	public static int item2Index = 4;
	public static int item3Index = 5;
	public static int item4Index = 6;
	public static int subGold1Index = 3;
	public static int subGold2Index = 4;
	public static int subSpeed1Index = 5;
	public static int subSpeed2Index = 6;
	public static int subSuperSuitIndex = 7;
	public static int subDevilSuitIndex = 8;


	public static string marketPid_handfulGold 	= "com.gcp2.stepbystep.handfulgold";
	public static string marketPid_bundleGold 	= "com.gcp2.stepbystep.bundlegold";
	public static string marketPid_sackGold 		= "com.gcp2.stepbystep.sackgold";
	public static string marketPid_boxGold 		= "com.gcp2.stepbystep.boxgold";
			
	public static string marketPid_subGold1 		= "com.gcp2.stepbystep.goldpack1";
	public static string marketPid_subGold2 		= "com.gcp2.stepbystep.goldpack2";
	public static string marketPid_subSpeed1 	= "com.gcp2.stepbystep.speedpack1";
	public static string marketPid_subSpeed2 	= "com.gcp2.stepbystep.speedpack2";
	public static string marketPid_subSuperSuit 	= "com.gcp2.stepbystep.supersuit";
	public static string marketPid_subDevilSuit 	= "com.gcp2.stepbystep.devilsuit";


	bool _isPaused = false;			// Application resume/pause flag
	bool _isResumeProcess = false;	// Application resume/pause flag

	// Use this for initialization
	void Awake () {
		Debug.Log("HIVEManager - Awake");

#if !UNITY_EDITOR
		hive.HIVEUnityPlugin.InitPlugin();	// HIVE SDK 플로그인을 위한 게임오브젝트를 생성한다.
		HiveAdizManager.shared.InitPlugin(); // Hive Adiz 플러그인을 위한 게임오브젝트를 생성한다.

		// Step by Step 은 영문만 지원하므로 GameLanguage 를 영어로 설정한다.
		Configuration.setGameLanguage("en");
		Configuration.setHiveTheme(HiveThemeType.hiveDark);
		// HIVE SDK 환경설정
		// Configuration.setUseLog(true);	// HIVE SDK 로그 설정
		// Configuration.setZone(ZoneType.TEST); // HIVE SDK 서버 설정(LIVE, SANDBOX)

		Promotion.setEngagementReady(false);	// HIVE SDK Engagement 설정(set default - false)
		Promotion.setEngagementListener(onPromotionEngagement); // HIVE SDK Engagement 리스너 설정.
		
#endif // UNITY_EDITOR
	}

	static HIVEManager _instance = null;	// 싱글톤 객체
	private static object _syncobj = new object();
	private static bool appIsClosing = false;
	//singleton method
	static public HIVEManager shared {
	// [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
		get {
			if (appIsClosing)
                return null;
				
			lock (_syncobj)  
            {  
				if (_instance == null) {
					_instance = FindObjectOfType<HIVEManager> ();
					if (_instance == null) {
						//create gameobject and add component postbox
						GameObject obj = new GameObject ();
						obj.name = "HIVEManager";
						_instance = obj.AddComponent<HIVEManager> ();
						DontDestroyOnLoad (obj);
					}
				}
			}
			return _instance;
		}
	}

	protected virtual void OnApplicationQuit()
    {
        // release reference on exit
        appIsClosing = true;
    }

	void OnApplicationPause(bool pauseStatus)
	{
		_isPaused = pauseStatus;

		if (_isPaused == false) {
			if (_isResumeProcess == false && _isSignIn == true) {
				_isResumeProcess = true;

				#if !UNITY_EDITOR
				AuthV4.Helper.syncAccount(AuthV4.ProviderType.AUTO, onAuthV4HelperSyncAccount);
				#endif // UNITY_EDITOR
			}
		}
	}

	// MARK: - 
	public void reset()
	{
		_isSetup = false;
		_isSignIn = false;
		_isMarkConnected = false;
		_isGetProductInfo = false;

		_productList = null;
		_subscriptionProductList = null;
	}

	// HIVE SDK 인증 및 GameServer 인증이 완료 후 호출
	public void didLogin()
	{
		Debug.Log("HIVEManager - didLogin");

#if !UNITY_EDITOR
		shopSetup(null);	// 미리 마켓 상점 연결하여 상품 정보를 얻어온다.

		// promotionShowBanner(); // HIVE SDK 대배너 프로모션 UI 노출

		Promotion.setEngagementReady(true); // engagement 설정을 변경. true
#endif // !UNITY_EDITOR
	}

	// 서버별 점검공지 팝업지원을 위한 serverId 설정
	public void setServerId(string serverId)
	{
		Configuration.setServerId (serverId);
	}


	public string getHiveSdkVersion()
	{
		string version = "";
#if !UNITY_EDITOR
		version = Configuration.getHiveSDKVersion();
#else
		version = "EditorGame Test";
#endif
		return version;
	}

	// MARK: - 
	/*******************************************
	 *	Setup & Sign in/out & connect/disconnect, ...
	 *******************************************/
	
	// HIVE SDK 초기화 함수를 호출한다.
	public void setup(onHIVEManagerEvent listener) 
	{
		Debug.Log("HIVEManager - setup");

		// if (_isSetup == true) {
		// 	Debug.Log("HIVEManager - Already did setup.");

		// 	listener(true, "Success");
		// 	return;
		// }

		onHIVEManagerSetup = listener;
#if !UNITY_EDITOR
		AuthV4.setup(onAuthV4Setup);
#else
		onAuthV4Setup(null, false, null, null);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK 권한 고지 Custom 팝업 함수를 호출한다.
	public void requestPermissionViewData(onHIVEManagerRequestPermissionEvent listener)
	{
		Debug.Log("HIVEManager - requestPermissionViewData");

		// TODO : Daun
		onHIVEManagerRequestPermissionViewData = listener;

#if !UNITY_EDITOR
		AuthV4.requestPermissionViewData(onPermissionViewData);
#else
		onPermissionViewData(null, null);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK 인증 함수를 호출한다.
	public void signIn(onHIVEManagerEvent listener)
	{
		Debug.Log("HIVEManager - signIn");

		if (_isSignIn == true) {
			Debug.Log("HIVEManager - Already did signin.");

			listener(true, "Success");
			return;
		}

		onHIVEManagerSignIn = listener;

#if !UNITY_EDITOR
		AuthV4.Helper.signIn(onAuthV4HelperSignIn);
#else
		onAuthV4HelperSignIn(null, null);
#endif // !UNITY_EDITOR
	}

	void showSignIn()
	{
		Debug.Log("HIVEManager - showSignIn");

#if !UNITY_EDITOR
		AuthV4.showSignIn(onAuthV4ShowSignIn);
#else 
		onAuthV4ShowSignIn(null, null);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK 인증 해제 함수를 호출한다.
	public void signOut(onHIVEManagerEvent listener)
	{
		Debug.Log("HIVEManager - signOut");

		onHIVEManagerSignOut = listener;

#if !UNITY_EDITOR
		AuthV4.Helper.signOut(onAuthV4HelperSignOut);
#else
		onAuthV4HelperSignOut(null, null);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK IDP 연동 함수를 호출한다.
	public void connect(AuthV4.ProviderType type, onHIVEManagerRedirectEvent listener)
	{
		Debug.Log("HIVEManager - connect");

		onHIVEManagerConnect = listener;

#if !UNITY_EDITOR
		AuthV4.Helper.connect(type, onAuthV4HelperConnect);
#else
		onAuthV4HelperConnect(null, null);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK IDP 연동 해제 함수를 호출한다.
	public void disconnect(AuthV4.ProviderType type, onHIVEManagerEvent listener)
	{
		Debug.Log("HIVEManager - disconnect");

		onHIVEManagerDisconnect = listener;

#if !UNITY_EDITOR
		AuthV4.Helper.disconnect(type, onAuthV4HelperDisconnect);
#else
		onAuthV4HelperDisconnect(null, null);
#endif // !UNITY_EDITOR
	}

	// 계정 충돌 팝업을 노출한다.
	public void showConflictPopup(AuthV4.PlayerInfo playerInfo) 
	{
#if !UNITY_EDITOR
		AuthV4.Helper.ConflictSingleViewInfo conflictInfo = new AuthV4.Helper.ConflictSingleViewInfo(playerInfo.playerId);
		conflictInfo.setValue("Player ID", playerInfo.playerId);

		GameConnect.shared.AccountInfo (playerInfo.playerId, (success, message, info) => {

			if (success == true) {
				conflictInfo.setValue("Player Name", info.nickname);

				if (info != null) {
					foreach (Item item in info.items) {
						if (string.Equals (item.code, "gold")) {
							conflictInfo.setValue("Gold", item.amount.ToString());
						} else if (string.Equals (item.code, "health")) {
							conflictInfo.setValue("Health", item.amount.ToString());
						} else if (string.Equals (item.code, "speed")) {
							conflictInfo.setValue("Speed", item.amount.ToString());
						}
					}
				}

				AuthV4.Helper.showConflict(conflictInfo, onAuthV4HelperShowConflict);

			} else {
				List<Int64> playerIdList = new List<Int64>();
				playerIdList.Add(playerInfo.playerId);

				AuthV4.getProfile(playerIdList, (result, profileInfoList) =>
					{
						if (result.isSuccess()) {
							AuthV4.ProfileInfo conflictUserProfile = profileInfoList[0] as AuthV4.ProfileInfo;
							conflictInfo.setValue("Player Name", conflictUserProfile.playerName);
						} else {
							conflictInfo.setValue("Player Name", "");
						}

						AuthV4.Helper.showConflict(conflictInfo, onAuthV4HelperShowConflict);
					});
			}

		});
#else
		onAuthV4HelperShowConflict(null, null);
		#endif // !UNITY_EDITOR	
	}

	// HIVE SDK 프로필 UI 노출 함수를 호출한다.
	public void showProfile(onHIVEManagerEvent listener)
	{
		Debug.Log("HIVEManager - showProfile");

		onHIVEManagerShowProfile = listener;

#if !UNITY_EDITOR
		AuthV4.showProfile(AuthV4.getPlayerInfo().playerId, onAuthV4ShowProfile);
#else
		onAuthV4ShowProfile(null);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK 1:1 문의(inquiry) UI 노출 함수를 호출한다.
	public void showInquiry(onHIVEManagerEvent listener)
	{
		Debug.Log("HIVEManager - showInquiry");

		onHIVEManagerShowInquiry = listener;

#if !UNITY_EDITOR
		AuthV4.showInquiry(onAuthV4ShowInquiry);
#else
		onAuthV4ShowInquiry(null);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK 카페 UI 노출 함수를 호출한다.
// 	public void showCafe(onHIVEManagerEvent listener)
// 	{
// 		Debug.Log("HIVEManager - showCafe");

// 		onHIVEManagerShowCafe = listener;

// #if !UNITY_EDITOR
// 		AuthV4.showCafe(onAuthV4ShowCafe);
// #else
// 		onAuthV4ShowCafe(null);
// #endif // !UNITY_EDITOR
// 	}

// HIVE SDK 기기 관리 서비스 UI 노출 함수를 호출한다.
	public void showDeviceManagement(onHIVEManagerEvent listener)
	{
		Debug.Log("HIVEManager - showDeviceManagement");

		onHIVEManagerShowDeviceManagement = listener;

#if !UNITY_EDITOR
		AuthV4.showDeviceManagement(onAuthV4ShowDeviceManagement);
#else
		onAuthV4ShowDeviceManagement(null);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK 약관 다시보기 UI 노출 함수를 호출한다.
	public void showTerms(onHIVEManagerEvent listener)
	{
		Debug.Log("HIVEManager - showTerms");

		onHIVEManagerShowTerms = listener;

#if !UNITY_EDITOR
		AuthV4.showTerms(onAuthV4ShowTerms);
#else
		onAuthV4ShowTerms(null);
#endif // !UNITY_EDITOR
	}

	// 게임 서버 점검 체크
	public void checkMaintenance(onHIVEManagerEvent listener)
	{
		Debug.Log ("HIVEManager - checkMaintenance");

		onHIVEManagerCheckMaintenance = listener;

#if !UNITY_EDITOR
		AuthV4.checkMaintenance(true, onAuthV4CheckMaintenance);
#else
		onAuthV4CheckMaintenance(new ResultAPI(), null);
#endif // !UNITY_EDITOR
	}

	// 약관 동의 정보 초기화
	public void resetAgreement()
    {
		Debug.Log("HIVEManager - resetAgreement");

#if !UNITY_EDITOR
		AuthV4.resetAgreement();
#endif // !UNITY_EDITOR
	}


	/*******************************************
	 *	Promotion
	 *******************************************/

	// HIVE SDK Promotion 배너 보기 함수를 호출한다.
	public void promotionShowBanner()
	{
		Debug.Log("HIVEManager - promotionShowBanner");

#if !UNITY_EDITOR
		 // 대배너. forced 값이 false
		 Promotion.showPromotion(PromotionType.BANNER, false, onPromotionView);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK Promotion 배너 보기 함수를 호출한다.
	public void promotionShowNews()
	{
		Debug.Log("HIVEManager - promotionShowNews");

#if !UNITY_EDITOR
		// forced 값이 true
		Promotion.showPromotion(PromotionType.NEWS, true, onPromotionView);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK Promotion Spot 배너 보기 함수를 호출한다.
	public void promotionShowInAppPromotion()
	{
		Debug.Log("HIVEManager - promotionShowInAppPromotion");

#if !UNITY_EDITOR
		// Spot 배너를 이용하여 Game 종료시 InApp 상품 노출.
		string code = "";
		
		#if UNITY_ANDROID
		code ="10000";
		#elif UNITY_IOS
		code = "10001";
		#else
		return;
		#endif 
		
		Promotion.showCustomContents(PromotionCustomType.SPOT, code, null);
#endif // !UNITY_EDITOR
	}

public void promotionGetBannerInfo(onHIVEManagerPromotionBannerInfoEvent listener) {

	Debug.Log("HIVEManager - promotion get banner info");

	onHIVEManagerGetBannerInfo = listener;

	#if !UNITY_EDITOR
		Promotion.getBannerInfo(PromotionCampaignType.NOTICE, PromotionBannerType.SMALL, onGetBannerInfoCB);
	#else
		onGetBannerInfoCB(null, null);
	#endif // !UNITY_EDITOR 

}
	/*******************************************
	*	HIVE PUSH
	*******************************************/

	public void requestPushPermission()
    {
		Debug.Log("HIVEManager - request push permission");
#if !UNITY_EDITOR
		Push.requestPushPermission();
#endif
	}

	// HIVE 서버에 저장된 유저의 리모트 푸시 수신 여부 정보를 조회
	public void getRemotePush(onHIVEManagerRemotePushEvent listener) 
	{
		Debug.Log("HIVEManager - get Remote Push");

		onHIVEManagerGetRemotePush = listener;
#if !UNITY_EDITOR
		Push.getRemotePush (onGetRemotePushCB);
#else
		onGetRemotePushCB(null, null);
#endif // !UNITY_EDITOR
	}

	// 변경된 수신 정보를 HIVE 서버에 전달
	public void setRemotePush(RemotePush remotePush, onHIVEManagerRemotePushEvent listener) 
	{
		Debug.Log("HIVEManager - set Remote Push");

		onHIVEManagerSetRemotePush = listener;
#if !UNITY_EDITOR
		Push.setRemotePush (remotePush, onSetRemotePushCB);
#else
		onSetRemotePushCB(null, null);
#endif // !UNITY_EDITOR
	}
	
	/*******************************************
	 *	HIVE IAP V4
	 *******************************************/
	
	// HIVE SDK IAP V4 상점 연동 및 상품 정보를 얻어온다.
	// marketConnect() 가 성공한 이후에 getProductInfo() 를 호출.
	public void shopSetup(onHIVEManagerEvent listener)
	{
		Debug.Log("HIVEManager - shop setup");

		if (_isMarkConnected == false) {
			// 마켓 연동 시도.
			Debug.Log("HIVEManager - marketConnect");

			onHIVEManagerShopSetup = listener;
#if !UNITY_EDITOR
			IAPV4.marketConnect(onIAPV4MarketConnect);
#else
			onIAPV4MarketConnect(null, null);
#endif // !UNITY_EDITOR

		} else if (_isGetProductInfo == false || _isGetSubscriptionProductInfo == false) {
			// 상품 정보 얻어오기 시도.
			Debug.Log("HIVEManager - productInfo");

			onHIVEManagerShopSetup = listener;

#if !UNITY_EDITOR
			IAPV4.getProductInfo(onIAPV4ProductInfo);
#else
			onIAPV4ProductInfo(null, null, 0);
#endif // !UNITY_EDITOR
		} else {
			// 이미 마켓 연동 및 상품 목록 얻어오기 완료.
			Debug.Log("HIVEManager - Already setup.");
			if (listener != null) {
				listener(true, null);
			}
		}
	}

	// HIVE SDK IAP V4 상품 구매 함수를 호출한다.
	public void shopPurchase(string marketPid, onHIVEManagerPurchaseEvent listener)
	{
		Debug.Log("HIVEManager - shopPurchase");
		
		if (_isMarkConnected == true && _isGetProductInfo == true) {
			// 상품 구매를 시도한다.
			onHIVEManagerPurchase = listener;
			
#if !UNITY_EDITOR
			IAPV4.purchase(marketPid, AuthV4.getPlayerInfo().playerId.ToString(), onIAPV4Purchase);
#else
			onIAPV4Purchase(null, null);
#endif // !UNITY_EDITOR

		} else {
			// 상품 구매 전 마켓 연동 및 상품 목록을 얻어와야 한다.
			listener(false, "Need setup.", null);
		}
	}

	public void shopSubscriptionPurchase(string marketPid, string oldMarketPid, onHIVEManagerPurchaseEvent listener)
	{
		Debug.Log("HIVEManager - shopSubscriptionPurchase");
		
		if (_isMarkConnected == true && _isGetSubscriptionProductInfo == true) {
			// 상품 구매를 시도한다.
			onHIVEManagerPurchaseSubscription = listener;

#if !UNITY_EDITOR
			IAPV4.purchaseSubscriptionUpdate(marketPid, oldMarketPid, AuthV4.getPlayerInfo().playerId.ToString(), onIAPV4PurchaseSubscription);
#else
			onIAPV4PurchaseSubscription(null, null);
#endif // !UNITY_EDITOR

		} else {
			// 상품 구매 전 마켓 연동 및 상품 목록을 얻어와야 한다.
			listener(false, "Need setup.", null);
		}
	}

	// HIVE SDK IAP V4 미지급된 상품에 대한 지급 요청처리 함수를 호출한다..
	public void shopRestore(onHIVEManagerRestoreEvent listener)
	{
		Debug.Log("HIVEManager - shopRestore");

		if (_isMarkConnected == true && _isGetProductInfo == true) {
			// 상품 구매 복원 시도.
			onHIVEManagerRestore = listener;

#if !UNITY_EDITOR
			IAPV4.restore(onIAPV4Restore);
#else
			onIAPV4Restore(null, null);
#endif // !UNITY_EDITOR
		} else {
			// 상품 구매 전 마켓 연동 및 상품 목록을 얻어와야 한다.
			listener(false, "Need setup.", null);
		}
	}

	public void shopRestoreSubscription(onHIVEManagerRestoreSubscriptionEvent listener)
	{
		Debug.Log("HIVEManager - shopRestoreSubscription");

		if (_isMarkConnected == true && _isGetSubscriptionProductInfo == true) {
			// 상품 구매 복원 시도.
			onHIVEManagerRestoreSubscription = listener;

#if !UNITY_EDITOR
			IAPV4.restoreSubscription(onIAPV4RestoreSubscription);
#else
			onIAPV4RestoreSubscription(null, null);
#endif // !UNITY_EDITOR
		} else {
			// 상품 구매 전 마켓 연동 및 상품 목록을 얻어와야 한다.
			listener(false, "Need setup.", null);
		}
	}


	// HIVE SDK IAP V4 지급이 완료된 상품에 대한 transaction finish 처리 함수를 호출한다.
	public void shopTransactionFinish(string marketPid, onHIVEManagerEvent listener)
	{
		Debug.Log("HIVEManager - shopTransactionFinish");

		onHIVEManagerTransactionFinish = listener;

		if (_isMarkConnected == true && _isGetProductInfo == true) {
#if !UNITY_EDITOR
			// transaction-finish 시도
			IAPV4.transactionFinish(marketPid, onIAPV4TransactionFinish);
#else
			onIAPV4TransactionFinish(null, null);
#endif // !UNITY_EDITOR
		} else {
			// 상품 구매 전 마켓 연동 및 상품 목록을 얻어와야 한다.
			listener(false, "Need setup.");
		}
	}

	/*******************************************
	 *	Achievements & Leaderboard
	 *******************************************/
	// HIVE SDK 업적 보기 함수를 호출한다.
	public void showAchievements(onHIVEManagerRedirectEvent listener)
	{
		Debug.Log("HIVEManager - showAchievements");

		onHIVEManagerAchievements = listener;

#if !UNITY_EDITOR
		AuthV4.Helper.showAchievements(onAuthV4HelperShowAchievements);
#else
		onAuthV4HelperShowAchievements(null, null);
#endif // !UNITY_EDITOR
	}

	// HIVE SDK 리더보드 보기 함수를 호출한다.
	public void showLeaderboard(onHIVEManagerRedirectEvent listener)
	{
		Debug.Log("HIVEManager - showLeaderboard");

		onHIVEManagerLeaderboard = listener;

#if !UNITY_EDITOR
		AuthV4.Helper.showLeaderboard(onAuthV4HelperShowLeaderboard);
#else
		onAuthV4HelperShowLeaderboard(null, null);
#endif // !UNITY_EDITOR
	}


	public void showExit(onHIVEManagerEvent listener)
	{
		Debug.Log("HIVEManager - showExit");

		onHIVEManagerShowExit = listener;

#if !UNITY_EDITOR
		Promotion.showExit (onPromotionShowExitCB);
#else
		onPromotionShowExitCB(new ResultAPI(), PromotionEventType.EXIT);
#endif // !UNITY_EDITOR
	}


	public void showReview()
	{
		Debug.Log("HIVEManager - showReview");

		// onHIVEManagerShowReview = listener;
#if !UNITY_EDITOR
		Promotion.showReview (null);
#else
		Debug.Log("showReview");
#endif // !UNITY_EDITOR
	}


	public bool getAgeGateU13()
	{
		bool ret = AuthV4.getAgeGateU13();
		Debug.Log("HIVEManager - getAgeGateU13 : " + ret);

		return ret;
	}


	public bool sendAnalyticsScoreLog(string name,int score)
	{
		JSONObject logData = new JSONObject();
		// Sets pre-defined log
		logData.AddField("category", "pub_user_property_log");
		logData.AddField("propertyDataType", "integer");
		logData.AddField("propertyName", name);
		logData.AddField("propertyValue", score);

		bool ret = Analytics.sendAnalyticsLog(logData);
		Debug.Log("HIVEManager - sendAnalyticsLog : " + ret);

		return ret;
	}


	public void dataStoreSet(string key, string data)
	{
		DataStore.set(key, data, (ResultAPI result) => {
			Debug.Log("HIVEManager - dataStoreSet: (" + key + "/" + data + ") " + result.message);
		});
	}
	

	public void dataStoreGet(string key, onHIVEManagerEvent listener)
	{
		DataStore.get(key, (ResultAPI result, string data) => {
			Debug.Log("HIVEManager - dataStoreGet: (" + key + ") " + result.message + " data: " + data);

			switch (result.code)
            {
				case ResultAPI.Code.Success:
					listener(true, data);
					break;
				case ResultAPI.Code.DataStoreNotExistKey:
				case ResultAPI.Code.DataStoreNotExistColumn:
					listener(true, "0");
					break;
				default:
					listener(false, result.message);
					break;
            }
		});
    }


	/*******************************************
	 *	Callback
	 *******************************************/
	
	// HIVE SDK 초기화 결과 콜백 핸들러
	void onAuthV4Setup(ResultAPI result, bool isAutoSignIn, string did, List<AuthV4.ProviderType> providerTypeList) 
	{
		Debug.Log ("onAuthV4Setup result : " + result.toString());
		Debug.Log ("onAuthV4Setup isAutoSignIn : " + isAutoSignIn);
		Debug.Log ("onAuthV4Setup did : " + did);

#if !UNITY_EDITOR
		if (result.isSuccess() == true) {
			_isSetup = true;
		} else if (result.needExit()) {
			_isSetup = false;
			Application.Quit(0);
		} else {
			_isSetup = false;
		}
#else
        _isSetup = true;
#endif // !UNITY_EDITOR

		if (onHIVEManagerSetup != null) {
			onHIVEManagerSetup(_isSetup, result.code.ToString());
			onHIVEManagerSetup = null;
		}

		switch (Configuration.getZone()) {
			case ZoneType.REAL:
		 		GameRequest.server = GameRequest.GameRequestServer.Product;
			break;
			case ZoneType.TEST:
		 		GameRequest.server = GameRequest.GameRequestServer.Test;
			break;
			case ZoneType.SANDBOX:
		 		GameRequest.server = GameRequest.GameRequestServer.Sandbox;
			break;
		}
	}

	// HIVE SDK 권한 고지 Custom 함수 호출 결과 콜백 핸들러
	void onPermissionViewData(ResultAPI result, PermissionViewData data)
	{
		// TODO: Daun
		Debug.Log("onPermissionViewData");
		bool isNeedToShow = false;
		string message = "";
		string contents = "";
		PermissionViewData permissionData = null;

#if !UNITY_EDITOR
		message = result.message;
		if (result.isSuccess()) {
			Debug.Log("onPermissionViewData result is success");
			if (result.code == ResultAPI.Code.AuthV4SkipPermissionView) {
				isNeedToShow = false;
			} else {
				isNeedToShow = true;
				permissionData = data;
			}
		} else {
			// Nothing to do 
			Debug.Log("onPermissionViewData result is error");
			isNeedToShow = false;
		}
#else
			Debug.Log("onPermissionViewData result is success");
			Debug.Log("onPermissionViewData result is success222222");

			isNeedToShow = true;
			contents = "Access Authority Notice For GamePlay";
			// Unity 테스트용 퍼미션 데이터를 생성하여 전달한다.
			PermissionViewUnitData firstPermission = new PermissionViewUnitData("CAMERA","The authority is required to take photos and record videos.","Camera", hive.PermissionViewPermissionCategory.Camera);
			PermissionViewUnitData secondPermission = new PermissionViewUnitData("PHOTOS","The authority is required to get photos and record videos.","Photos", hive.PermissionViewPermissionCategory.Photo);
			PermissionViewUnitData thirdPermission = new PermissionViewUnitData("PUSH","The authority is required to send remote notification.","Push", hive.PermissionViewPermissionCategory.Push);

			PermissionViewUnitData commonPermission = new PermissionViewUnitData("COMMON","Common Text", "Common", hive.PermissionViewPermissionCategory.Common);

			List<PermissionViewUnitData> _permissions = new List<PermissionViewUnitData>();
			_permissions.Add(firstPermission);
			_permissions.Add(secondPermission);
			_permissions.Add(thirdPermission);

			List<PermissionViewUnitData> _commons = new List<PermissionViewUnitData>();

			permissionData = new PermissionViewData(contents, _permissions, _commons);
#endif
		onHIVEManagerRequestPermissionViewData(isNeedToShow, message, permissionData);

	}

	// HIVE SDK 인증 결과 콜백 핸들러
	void onAuthV4HelperSignIn(ResultAPI result, AuthV4.PlayerInfo aPlayerInfo)
	{
		Debug.Log("onAuthV4HelperSignIn result: " + result.toString());

		string message = null;
		bool sendResult = true;

#if !UNITY_EDITOR
		if (result.needExit())
        {
			Application.Quit(0);
        }

		message = result.code.ToString();
		switch (result.code) 
		{
			case ResultAPI.Code.Success:
			case ResultAPI.Code.AuthV4PlayerResolved:
			case ResultAPI.Code.AuthV4PlayerChange:
				// 충돌 발생 후 현재 계정 유지시 게임 진행
				isSignIn = true; // signIn flag 변경.

				if (aPlayerInfo != null) {
					playerInfo = aPlayerInfo;
				}
				break;

			case ResultAPI.Code.AuthV4ConflictPlayer: 
				sendResult = false;
				showConflictPopup(aPlayerInfo);		
				break;

			case ResultAPI.Code.AuthV4HelperImplifiedLoginFail:
				sendResult = false;
				// 묵시적 로그인 실패. 명시적 로그인 UI를 호출한다.
				Debug.Log("Failed implicit sign-in.");
				showSignIn();
				break;
		}

#else

        isSignIn = true;

#endif // !UNITY_EDITOR
		
		if (sendResult) {
			if (onHIVEManagerSignIn != null) {
				onHIVEManagerSignIn(isSignIn, message);
				onHIVEManagerSignIn = null;
			}
		}
	}

	// HIVE SDK 명시적 로그인 UI 결과 콜백 핸들러
	void onAuthV4ShowSignIn(ResultAPI result, AuthV4.PlayerInfo aPlayerInfo)
	{
		Debug.Log("onAuth4ShowSignIn result: " + result.toString());

		string message = null;
#if !UNITY_EDITOR
		if (result.needExit())
        {
			Application.Quit(0);
        }

		isSignIn = result.isSuccess();

		message = result.code.ToString();
		playerInfo = result.isSuccess() ? aPlayerInfo : null;
#else
		isSignIn = true;
#endif // UNITY_EDITOR

			if (onHIVEManagerSignIn != null) {
				onHIVEManagerSignIn(isSignIn, message);
				onHIVEManagerSignIn = null;
			}
	}

	// HIVE SDK 인증 해제 결과 콜백 핸들러
	void onAuthV4HelperSignOut(ResultAPI result, AuthV4.PlayerInfo playerInfo)
	{
		Debug.Log ("onAuthV4HelperSignOut : " + result.toString());

		isSignIn = false; // signIn flag 변경.

#if !UNITY_EDITOR
		Promotion.setEngagementReady(false); // engagement 설정을 변경. false
#endif // !UNITY_EDITOR

		onHIVEManagerSignOut(true, result.code.ToString());
		onHIVEManagerSignOut -= new onHIVEManagerEvent(onHIVEManagerSignOut);
	}

	// HIVE SDK IDP 연동 결과 콜백 핸들러
	void onAuthV4HelperConnect(ResultAPI result, AuthV4.PlayerInfo playerInfo)
	{
		Debug.Log ("onAuthV4HelperConnect : " + result.toString());

		bool success = result.isSuccess();
		bool moveToTitle = false;	// 사용자 정보 변경으로 인하여 타이틀 화면으로 이동하여 게임 세션 재인증 여부.
		string message = null;

		bool sendResult = true;		// 계정 충돌 상황 발생시엔 결과 전달 하지 않음.

#if !UNITY_EDITOR
		message = result.message;

		switch (result.code) 
		{
			case ResultAPI.Code.Success:
				success = true; // signIn flag 변경.
				if (onHIVEManagerConnect != null) {
					onHIVEManagerConnect(success, message, moveToTitle);
					onHIVEManagerConnect = null;
				}
				break;

			case ResultAPI.Code.AuthV4PlayerChange:
				success = true;
				moveToTitle = true;
				break;

			case ResultAPI.Code.AuthV4ConflictPlayer: 
				sendResult = false;
				showConflictPopup(playerInfo);			
				break;

			case ResultAPI.Code.AuthV4NotRegisteredDevice:
				success = false;
				moveToTitle = true;
				break;

			default:
				success = false;
				break;
		}

		// if (result.isSuccess() == true) {
		// 	success = true;
		// } else if (result.errorCode == ResultAPI.ErrorCode.PLAYER_CHANGE && playerInfo != null) {
		// 	success = true;
		// 	moveToTitle = true;
		// } else {
		// 	success = false;
		// }
#endif // !UNITY_EDITOR

		if (sendResult){
			if (onHIVEManagerConnect != null) {
				onHIVEManagerConnect(success, message, moveToTitle);
				onHIVEManagerConnect = null;
			}
		}
	}

	// HIVE SDK IDP 연동 해제 결과 콜백 핸들러
	void onAuthV4HelperDisconnect(ResultAPI result, AuthV4.PlayerInfo playerInfo)
	{
		Debug.Log ("onAuthV4HelperDisconnect : " + result.toString());
		if (onHIVEManagerDisconnect != null) {
			onHIVEManagerDisconnect(result.isSuccess(), result.code.ToString());
			onHIVEManagerDisconnect = null;
		}
	}

	// HIVE SDK 프로필 UI 호출 결과 콜백 핸들러
	void onAuthV4ShowProfile(ResultAPI result)
	{
		Debug.Log ("onAuthV4ShowProfile : " + result.toString());

		// showProfile() 콜백 핸들러. HIVE 연동 유저의 경우 프로필 이미지를 바꾸거나 연동을
		// 해제 할 수 있기 때문에, 프로필 웹뷰가 닫히면 데이터를 갱신해준다.
		if (onHIVEManagerShowProfile != null) {
			onHIVEManagerShowProfile(result.isSuccess(), result.message);
			onHIVEManagerShowProfile = null;
		}
	}

	// HIVE SDK 1:1 문의(inquiry) UI 호출 결과 콜백 핸들러
	void onAuthV4ShowInquiry(ResultAPI result)
	{
		Debug.Log ("onAuthV4ShowInquiry : " + result.toString());

		if (onHIVEManagerShowInquiry != null) {
			onHIVEManagerShowInquiry(result.isSuccess(), result.message);
			onHIVEManagerShowInquiry = null;
		}
	}

	// HIVE SDK 카페(Cafe) UI 호출 결과 콜백 핸들러
	// void onAuthV4ShowCafe(ResultAPI result)
	// {
	// 	Debug.Log ("onAuthV4ShowCafe : " + result.toString());

	// 	if (onHIVEManagerShowCafe != null) {
	// 		onHIVEManagerShowCafe(result.isSuccess(), result.message);
	// 		onHIVEManagerShowCafe = null;
	// 	}
	// }

	// HIVE SDK 기기 관리 서비스 UI 호출 결과 콜백 핸들러
	void onAuthV4ShowDeviceManagement(ResultAPI result)
	{
		Debug.Log ("onAuthV4ShowDeviceManagement : " + result.toString());

		if (onHIVEManagerShowDeviceManagement != null) {
			onHIVEManagerShowDeviceManagement(result.isSuccess(), result.message);
			onHIVEManagerShowDeviceManagement = null;
		}
	}

	// HIVE SDK 약관 다시보기 UI 호출 결과 콜백 핸들러
	void onAuthV4ShowTerms(ResultAPI result)
	{
		Debug.Log ("onAuthV4ShowTerms : " + result.toString());

		if (onHIVEManagerShowTerms != null) {
			onHIVEManagerShowTerms(result.isSuccess(), result.message);
			onHIVEManagerShowTerms = null;
		}
	}

	void onAuthV4CheckMaintenance(ResultAPI result, List<AuthV4.AuthV4MaintenanceInfo> maintenanceInfoList)
	{
		Debug.Log ("onAuthV4CheckMaintenance : " + result.toString());
		if (result.needExit()) {
			Application.Quit(0);

        } else if (onHIVEManagerCheckMaintenance != null) {
			onHIVEManagerCheckMaintenance(result.isSuccess(), result.message);
			onHIVEManagerCheckMaintenance = null;
		}
	}

	// HIVE SDK 프로모션 UI 노출 결과 콜백 핸들러
	void onPromotionView(ResultAPI result, PromotionEventType promotionEventType)
	{
		Debug.Log ("onPromotionView : " + result.toString());
	}

	// HIVE SDK 프로모션 종료팝업 UI 노출 결과 콜백 핸들러
	void onPromotionShowExitCB(ResultAPI result, PromotionEventType promotionEventType)
	{
		Debug.Log ("onPromotionShowExitCB : " + result.toString());

		if (result.isSuccess () && promotionEventType == PromotionEventType.EXIT && onHIVEManagerShowExit != null) {
			onHIVEManagerShowExit (true, result.message);
		} else {
			onHIVEManagerShowExit (false, result.message);
		}
		// Exit 상황에 Close, Exit 2번 불림
		// onHIVEManagerShowExit = null;
	}

	// HIVE SDK 프로모션 get Banner info 결과 콜백 핸들러
	void onGetBannerInfoCB(ResultAPI result, List<PromotionBannerInfo> bannerInfoList) 
	{
		Debug.Log ("onGetBannerInfoCB : " + result.toString());

		if (onHIVEManagerGetBannerInfo != null) {
			if (result.isSuccess ()) {
				onHIVEManagerGetBannerInfo(true, bannerInfoList);
			} else {
				onHIVEManagerGetBannerInfo(false, null);
			}
			onHIVEManagerGetBannerInfo = null;
		}

	}

	// HIVE SDK 리모트 푸시 설정 조회 결과 콜백 핸들러
	void onGetRemotePushCB(ResultAPI result, RemotePush remotePush)
	{
		Debug.Log ("onGetRemotePushCB : " + result.toString());

		if (onHIVEManagerGetRemotePush != null) {
			onHIVEManagerGetRemotePush (result.isSuccess (), result.message, remotePush);
			onHIVEManagerGetRemotePush = null;
		}
	}

	// HIVE SDK 리모트 푸시 상태 설정 결과 콜백 핸들러
	void onSetRemotePushCB(ResultAPI result, RemotePush remotePush)
	{
		Debug.Log ("onSetRemotePushCB : " + result.toString());

		if (onHIVEManagerSetRemotePush != null) {
			onHIVEManagerSetRemotePush (result.isSuccess (), result.message, remotePush);
			onHIVEManagerSetRemotePush = null;
		}
	}

	// HIVE SDK IAP V4 마켓연동(marketConnect) 결과 콜백 핸들러
	void onIAPV4MarketConnect(ResultAPI result, List<IAPV4.IAPV4Type> iapV4TypList)
	{
		Debug.Log ("onIAPV4MarketConnect : " + result.toString());

		if (result.isSuccess() == true) {
			_isMarkConnected = true;
#if !UNITY_EDITOR
			IAPV4.getProductInfo(onIAPV4ProductInfo);
#else
			onIAPV4ProductInfo(null, null, 0);
#endif // UNITY_EDITOR
		} else if (result.code == ResultAPI.Code.IAPV4InProgressMarketConnect) {
			_isMarkConnected = false;
			if (onHIVEManagerShopSetup != null) {
				onHIVEManagerShopSetup(false, "INPROGRESS");
			}
		}  
		else {
			_isMarkConnected = false;
			if (onHIVEManagerShopSetup != null) {
				onHIVEManagerShopSetup(false, null);
			}
		}
	}

	// HIVE SDK IAP V4 상품 목록 요청 결과 콜백 핸들러
	void onIAPV4ProductInfo(ResultAPI result, List<IAPV4.IAPV4Product> iapV4ProductList, int balance)
	{
		Debug.Log ("onIAPV4ProductInfo : " + result.toString());

		bool success = false;
		string message = null;

#if !UNITY_EDITOR
		if (result.isSuccess() == true && iapV4ProductList != null) {
			_productList = iapV4ProductList;

			_isGetProductInfo = (_productList != null);

			int i = 0;
			foreach (IAPV4.IAPV4Product product in _productList) {

				if (string.Equals (product.marketPid, marketPid_handfulGold))
					item1Index = i++;
				else if (string.Equals (product.marketPid, marketPid_bundleGold))
					item2Index = i++;
				else if (string.Equals (product.marketPid, marketPid_sackGold))
					item3Index = i++;
				else if (string.Equals (product.marketPid, marketPid_boxGold))
					item4Index = i++;
				else
					i++;
			}

			success = true;
			message = result.message;

			IAPV4.getSubscriptionProductInfo(onIAPV4SubscriptionProductInfo);

		} else {
			_isGetProductInfo = false;
			success = false;
			message = result.message;

			if (onHIVEManagerShopSetup != null) {
				onHIVEManagerShopSetup(success, message);
				onHIVEManagerShopSetup = null;
			}
		}
#else
		if (onHIVEManagerShopSetup != null) {
			onHIVEManagerShopSetup(success, message);
			onHIVEManagerShopSetup = null;
		}
#endif // !UNITY_EDITOR
		
	}

	void onIAPV4SubscriptionProductInfo(ResultAPI result, List<IAPV4.IAPV4Product> iapV4ProductList, int balance)
	{
		Debug.Log ("onIAPV4SubscriptionProductInfo : " + result.toString());

		bool success = false;
		string message = null;

#if !UNITY_EDITOR
		if (result.isSuccess() == true && iapV4ProductList != null) {
			_subscriptionProductList = iapV4ProductList;

			_isGetSubscriptionProductInfo = (_subscriptionProductList != null);

			int i = 0;
			foreach (IAPV4.IAPV4Product product in _subscriptionProductList) {

				if (string.Equals (product.marketPid, marketPid_subGold1))
					subGold1Index = i++;
				else if (string.Equals (product.marketPid, marketPid_subGold2))
					subGold2Index = i++;
				else if (string.Equals (product.marketPid, marketPid_subSpeed1))
					subSpeed1Index = i++;
				else if (string.Equals (product.marketPid, marketPid_subSpeed2))
					subSpeed2Index = i++;
				else if (string.Equals (product.marketPid, marketPid_subSuperSuit))
					subSuperSuitIndex = i++;
				else if (string.Equals (product.marketPid, marketPid_subDevilSuit))
					subDevilSuitIndex = i++;
				else
					i++;
			}

			success = true;
			message = result.message;

		} else {
			_isGetSubscriptionProductInfo = false;
			success = false;
			message = result.message;
		}
#endif // !UNITY_EDITOR
		if (onHIVEManagerShopSetup != null) {
			onHIVEManagerShopSetup(success, message);
			onHIVEManagerShopSetup = null;
		}
	}

	// HIVE SDK IAP V4 구매 결과 콜백 핸들러
	void onIAPV4Purchase(ResultAPI result, IAPV4.IAPV4Receipt iapV4Receipt)
	{
		Debug.Log ("onIAPV4Purchase : " + result.toString());

		if (result.isSuccess() == true) {
			if (onHIVEManagerPurchase != null) {
				onHIVEManagerPurchase(true, result.code.ToString(), iapV4Receipt);
			}
		} else {
			if (onHIVEManagerPurchase != null) {
				onHIVEManagerPurchase(false, result.code.ToString(), null);
			}
		}

		if (onHIVEManagerPurchase != null) {
			onHIVEManagerPurchase = null;
		}
	}

	void onIAPV4PurchaseSubscription(ResultAPI result, IAPV4.IAPV4Receipt iapV4Receipt)
	{
		Debug.Log ("onIAPV4PurchaseSubscription : " + result.toString());

		if (result.isSuccess() == true) {
			if (onHIVEManagerPurchaseSubscription != null) {
				onHIVEManagerPurchaseSubscription(true, result.code.ToString(), iapV4Receipt);
			}
		} else {
			if (onHIVEManagerPurchaseSubscription != null) {
				onHIVEManagerPurchaseSubscription(false, result.code.ToString(), null);
			}
		}

		if (onHIVEManagerPurchaseSubscription != null) {
			onHIVEManagerPurchaseSubscription = null;
		}
	}

	// HIVE SDK IAP V4 구매 복원 결과 콜백 핸들러
	void onIAPV4Restore(ResultAPI result, List<IAPV4.IAPV4Receipt> iapV4ReceiptList)
	{
		Debug.Log ("onIAPV4Restore : " + result.toString());

		bool success = false;
		string message = result.code.ToString();
		List<IAPV4.IAPV4Receipt> receiptList = null;

		// 적절한 시점에 자동으로 해주어도 상관은 없으나 마켓 연결 여부와, 아이템 지급이 가능한 시점,
	 	// 결제 도중에 중복으로 호출되지 않도록 주의 한다.
		// NOT_OWNED 는 요청에는 성공했으나 복구할 아이템은 없다는 뜻이다. 일반적으로 대부분 이 경우에 해당.
		if (result.errorCode == ResultAPI.ErrorCode.NOT_OWNED) {
			success = true;
		} else if (result.isSuccess() == true) {
			success = true;
			receiptList = iapV4ReceiptList;
		} else {
			success = false;
		}

		if (onHIVEManagerRestore != null) {
			onHIVEManagerRestore(success, message, receiptList);
			onHIVEManagerRestore = null;
		}
	}


	void onIAPV4RestoreSubscription(ResultAPI result, List<IAPV4.IAPV4Receipt> iapV4ReceiptList)
	{
		Debug.Log ("onIAPV4RestoreSubscription : " + result.toString());

		bool success = false;
		string message = result.code.ToString();
		List<IAPV4.IAPV4Receipt> receiptList = null;

		// 적절한 시점에 자동으로 해주어도 상관은 없으나 마켓 연결 여부와, 아이템 지급이 가능한 시점,
	 	// 결제 도중에 중복으로 호출되지 않도록 주의 한다.
		// NOT_OWNED 는 요청에는 성공했으나 복구할 아이템은 없다는 뜻이다. 일반적으로 대부분 이 경우에 해당.
		if (result.errorCode == ResultAPI.ErrorCode.NOT_OWNED) {
			success = true;
		} else if (result.isSuccess() == true) {
			success = true;
			receiptList = iapV4ReceiptList;
		} else {
			success = false;
		}

		if (onHIVEManagerRestoreSubscription != null) {
			onHIVEManagerRestoreSubscription(success, message, receiptList);
			onHIVEManagerRestoreSubscription = null;
		}
	}

	// HIVE SDK IAP V4 TransactionFinish 콜백 핸들러
	void onIAPV4TransactionFinish(ResultAPI result, string marketPid)
	{
		Debug.Log ("onIAPV4TransacionFinish : " + result.toString());

		if (onHIVEManagerTransactionFinish != null) {
			onHIVEManagerTransactionFinish(result.isSuccess(), result.message);
			onHIVEManagerTransactionFinish = null;
		}
	}

	// HIVE SDK 업적 보기 결과 콜백 핸들러
	void onAuthV4HelperShowAchievements(ResultAPI result, AuthV4.PlayerInfo playerInfo)
	{
		Debug.Log ("onAuthV4HelperShowAchievements : " + result.toString());

		bool success = result.isSuccess() == true;
		bool moveToTitle = false; // 사용자 정보 변경으로 인하여 타이틀 화면으로 이동하여 게임 세션 재인증 여부.
		string message = result.message;

		// if (result.isSuccess() == true) {
		// 	success = true;
		// } else if (result.errorCode == ResultAPI.ErrorCode.PLAYER_CHANGE && playerInfo != null) {
		// 	// 사용자가 변경됨. Title로 이동.
		// 	success = true;
		// 	moveToTitle = true;
		// } else {
		// 	success = false;
		// }

		if(result.errorCode == ResultAPI.ErrorCode.CONFLICT_PLAYER) {
			Debug.Log ("[onAuthV4HelperShowAchievements] CONFLICT_PLAYER");
			// 다른 계정으로 로그인 함.
			showConflictPopup(playerInfo);			
		}else {
			if (onHIVEManagerAchievements != null) {
				onHIVEManagerAchievements(success, message, moveToTitle);
				onHIVEManagerAchievements = null;
			}
		}		
	}

	// HIVE SDK 리더보드 보기 결과 콜백 핸들러
	void onAuthV4HelperShowLeaderboard(ResultAPI result, AuthV4.PlayerInfo playerInfo)
	{
		Debug.Log ("onAuthV4HelperShowLeaderboard : " + result.toString());

		bool success = result.isSuccess() == true;;
		bool moveToTitle = false; // 사용자 정보 변경으로 인하여 타이틀 화면으로 이동하여 게임 세션 재인증 여부.
		string message = result.message;

		// if (result.isSuccess() == true) {
		// 	success = true;
		// } else if (result.errorCode == ResultAPI.ErrorCode.PLAYER_CHANGE && playerInfo != null) {
		// 	// 사용자가 변경됨. Title로 이동.
		// 	success = true;
		// 	moveToTitle = true;
		// } else {
		// 	success = false;
		// }

		// onHIVEManagerLeaderboard(success, message, moveToTitle);
		// onHIVEManagerLeaderboard -= new onHIVEManagerRedirectEvent(onHIVEManagerLeaderboard);

		if(result.errorCode == ResultAPI.ErrorCode.CONFLICT_PLAYER) {
			Debug.Log ("[onAuthV4HelperShowAchievements] CONFLICT_PLAYER");
			// 다른 계정으로 로그인 함.
			showConflictPopup(playerInfo);			
		}else {
			if (onHIVEManagerLeaderboard != null) {
				onHIVEManagerLeaderboard(success, message, moveToTitle);
				onHIVEManagerLeaderboard = null;
			}
		}		
	}

	// HIVE SDK IDP(GOOGLE, APPLE) 연동 자동화결과 콜백 핸들러
	void onAuthV4HelperSyncAccount(ResultAPI result, AuthV4.PlayerInfo playerInfo)
	{
		Debug.Log ("onAuthV4HelperSyncAccount : " + result.toString());

		if (result.isSuccess() == true) {
			// 상태 변경 없음.
		} else if (result.errorCode == ResultAPI.ErrorCode.CONFLICT_PLAYER) {
			// 다른 계정으로 로그인 함.
			showConflictPopup(playerInfo);	
		} else {
			// no operation.
		}

		_isResumeProcess = false;
	}

	// HIVE SDK IDP 연동시 충돌 선택 결과 콜백 핸들러
	void onAuthV4HelperShowConflict(ResultAPI result, AuthV4.PlayerInfo playerInfo)
	{
		Debug.Log ("onAuthV4HelperShowConflict : " + result.toString ());

		if (!isSignIn) {
			if (result.code == ResultAPI.Code.AuthV4CancelDialog)
			{
				isSignIn = true;

				if (onHIVEManagerSignIn != null)
				{
					onHIVEManagerSignIn(isSignIn, result.message);
					onHIVEManagerSignIn = null;
				}

				return;
			}

			onAuthV4HelperSignIn (result, playerInfo);

		} else {
		
			bool success = false;
			string message = "";
			bool moveToTitle = false;


			if (result.code == ResultAPI.Code.AuthV4PlayerChange && playerInfo != null) { 
				isSignIn = true;

				success = true;
				message = result.message;
				moveToTitle = true;

			} else if (result.code == ResultAPI.Code.AuthV4NotRegisteredDevice) {
				isSignIn = false;

				success = false;
				message = result.message;
				moveToTitle = true;

			} else if (result.isSuccess() || result.code == ResultAPI.Code.AuthV4CancelDialog) {
				isSignIn = true;

				success = true;
				message = result.message;
				moveToTitle = false;

			} else {
				success = false;
				message = result.message;
				moveToTitle = false;
			}


			if (onHIVEManagerConnect != null) {
				onHIVEManagerConnect (success, message, moveToTitle);
				onHIVEManagerConnect = null;
			}


		}
		

//		if (!isSignIn) {
//			Debug.Log ("LoadScene \"Main\"");
//
//			Game.PlayerSettings.Instance ().reset ();
//
//			SceneManager.LoadScene("Main", LoadSceneMode.Single);
//			isSignIn = true;
//			
//			onAuthV4HelperSignIn(result, playerInfo);
//		} else {
//
//			if (result.code == ResultAPI.Code.AuthV4PlayerChange &&  playerInfo != null) { 
//				Debug.Log ("LoadScene \"Home\"");
//
//				Game.PlayerSettings.Instance ().reset ();
//
//				SceneManager.LoadScene("Home", LoadSceneMode.Single);
//				isSignIn = true;
//				HIVEManager.shared.promotionShowBanner();
//			} else {
//				bool moveToTitle = false;	// 사용자 정보 변경으로 인하여 타이틀 화면으로 이동하여 게임 세션 재인증 여부.
//				string message = null;
//				if (onHIVEManagerConnect != null) {
//					onHIVEManagerConnect(false, message, moveToTitle);
//					onHIVEManagerConnect = null;
//				}
//			}
//		}
	}

	// HIVE SDK Promotion Engagement Listener
	void onPromotionEngagement(ResultAPI result, EngagementEventType engagementEventType, EngagementEventState engagementEventState, JSONObject param)
	{
		Debug.Log ("onPromotionEngagement : " + result.toString() + "\nparam :" + param);

		if (engagementEventType == EngagementEventType.IAP_PURCHASE) {
			if (engagementEventState == EngagementEventState.END) {

#if !UNITY_EDITOR
				 string bypassInfo = "";
				 param.GetField("iapV4Receipt").GetField(ref bypassInfo, "bypassInfo");

				if (bypassInfo != null) {
					GameConnect.shared.VerifyReceiptBypassInfo(bypassInfo, onGameConnectVerifyReceipt);
				}

				Promotion.setEngagementReady(true);
#endif // !UNITY_EDITOR

			}
		} 
	}

	void onGameConnectVerifyReceipt(bool success, string message, string pid)
	{
		if (success == true) {
			HIVEManager.shared.shopTransactionFinish(pid, onInternalHIVEManagerTransactionFinish);
		} else {
			// TODO: error handle.
		}
	}

	void onInternalHIVEManagerTransactionFinish(bool success, string message)
	{
		// no operation.
	}
}
