mergeInto(LibraryManager.library, {
	_LogState: function(state) {
		if(state) {
			window.log = (label, data) => console.log(`[Arkadium SDK JsLib] - ${label}`, data);
		}
		else {
			window.log = () => {};
		}
	},
	_Initialize: function(environment_, gameObjectName_, cb_) {
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }
		if (arkSt.api) {
			cb(1);
			return
		}
		
		const environment = UTF8ToString(environment_);
		const gameObjectName = UTF8ToString(gameObjectName_);
		

		arkSt.environment = environment;
		arkSt.gameObjectName = gameObjectName;

		arkSt.load(environment).then(() => {
			if (window.ArkadiumGameSDK) {
				window.ArkadiumGameSDK.getInstance().then((api) => {
					log('initialized');
					arkSt.api = api;
					cb(1);
				}, (err) => {
					log('not initialized', err);
					cb(0);
				});
			}
			else {
				log('not initialized - SDK not available');
				cb(0);
			}
		});
	},

	// ads
	_ShowInterstitialAd: function(duration, cb_) {
		const options = duration ? { duration } : undefined;
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		if (arkSt.api.ads.showInterstitialAd) {
			log('showing interstitial ad', duration);
			arkSt.api.ads.showInterstitialAd(options).then(() => {
				log('returning from interstitial ad...');
				cb(1);
			}, (err) => {
				log('show interstitial ad failed', err);
				cb(0);
			});
		}
		else {
			log('interstitial ad API not available');
			cb(0);
		}
	},
	_ShowRewardAd: function(duration, cb_) {
		const options = duration ? { duration } : undefined;
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		if (arkSt.api.ads.showRewardAd) {
			log('showing reward ad', duration);
			arkSt.api.ads.showRewardAd(options).then((res) => {
				log('returning from reward ad...', res);
				cb(res.value);
			}, (err) => {
				log('show rewarded ad failed', err);
				cb(0);
			});
		}
		else {
			log('reward ad API not available');
			cb(0);
		}
	},
	_ShowBannerAd: function(elementId_, bannerSizes_) {
		const elementId = UTF8ToString(elementId_);
		const bannerSizesSerialized = UTF8ToString(bannerSizes_);
		const bannerSizes = JSON.parse(bannerSizesSerialized);

		if (arkSt.api.ads.showBannerAd) {
			log('showing banner ad...', [elementId, bannerSizes]);
			arkSt.api.ads.showBannerAd(elementId, bannerSizes);
		}
		else {
			log('show banner ad API not available');
		}
	},

	// analytics
	_ConfigureProvider: function(provider, appId_) {
		const appId = UTF8ToString(appId_);

		arkSt.api.analytics.configureProvider({ provider, appId });
	},

	_SendEvent: function(eventCategory_, eventAction_, dimensionsObj_) {
		const eventCategory = UTF8ToString(eventCategory_);
		const eventAction = UTF8ToString(eventAction_);
		const dimensionsObj = UTF8ToString(dimensionsObj_);

		let dimensions = {}
		try {
			dimensions = JSON.parse(dimensionsObj);
		} catch (_) {}

		arkSt.api.analytics.sendEvent(eventCategory, eventAction, dimensions);
	},

	_SendPageView: function(pageName_, dimensionsObj_) {
		const pageName = UTF8ToString(pageName_);
		const dimensionsObj = UTF8ToString(dimensionsObj_);

		let dimensions = {}
		try {
			dimensions = JSON.parse(dimensionsObj);
		} catch (_) {}

		arkSt.api.analytics.sendPageView(pageName, dimensions);
	},

	_SetDimensions: function(dimensionsObj_) {
		const dimensionsObj = UTF8ToString(dimensionsObj_);

		let dimensions = {}
		try {
			dimensions = JSON.parse(dimensionsObj);
		} catch (_) {}

		arkSt.api.analytics.setDimensions(dimensions);
	},

	// auth
	_IsUserAuthorized: function(cb_) {
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		arkSt.api.auth.isUserAuthorized().then((result) => {
			log('authorization check:', result);
			cb(result ? 1 : 0);
		}, (err) => {
			log('failed user authorization check:', err);
			cb(0);
		})
	},
	_SubscribeToAuthStatus: function(cb_) {
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		arkSt.api.auth.onAuthStatusChange((isAuthenticated) => {
			log('auth status changed:', isAuthenticated);
			cb(isAuthenticated ? 1 : 0);
		});
	},
	_GetUserProfile: function(cb_) {
		const cb = (s) => {
			const buffer = stringToNewUTF8(s);
			{{{ makeDynCall('vi', 'cb_') }}} (buffer);
			_free(buffer);
		}

		arkSt.api.auth.getUserProfile().then((result) => {
			log('got user profile:', result);
			cb(JSON.stringify(result));
		}, (err) => {
			log('failed get user profile:', err);
			cb('');
		})
	},
	_OpenAuthForm: function(cb_) {
		const cb = () => { {{{ makeDynCall('v', 'cb_') }}} (undefined); }

		arkSt.api.auth.openAuthForm().then(() => {
			cb();
		}, (err) => {
			log('failed open auth form:', err);
		})
	},

	// host
	_GetQueryParameter: function(key_, cb_) {
		const key = UTF8ToString(key_);
		const cb = (s) => {
			const buffer = stringToNewUTF8(s);
			{{{ makeDynCall('vi', 'cb_') }}} (buffer);
			_free(buffer);
		}

		arkSt.api.host.getQueryParameter(key).then(
			(result) => cb(result === null ? '' : result),
			() => cb('')
		);
	},
	_GetDetails: function(cb_) {
		const cb = (s) => {
			const buffer = stringToNewUTF8(s);
			{{{ makeDynCall('vi', 'cb_') }}} (buffer);
			_free(buffer);
		}

		arkSt.api.host.getDetails().then((result) => cb(JSON.stringify(result)), () => cb(''));
	},
	_OpenPurchaseForm: function(currencySku_, cb_) {
		const currencySku = UTF8ToString(currencySku_);
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		if(currencySku_ == "default") {
			arkSt.api.host.openPurchaseForm().then(() => cb(1), (_) => cb(0));
		} else {
			arkSt.api.host.openPurchaseForm({
				type: 'PURCHASE_VIRTUAL_CURRENCY',
				currencySku
			}).then(() => cb(1), (_) => cb(0));
		}
	},

	// lifecycle
	_OnTestReady: function() {
		arkSt.api.lifecycle.onTestReady();
	},
	_OnInteract: function() {
		arkSt.api.lifecycle.onInteract();
	},
	_OnGameStart: function() {
		arkSt.api.lifecycle.onGameStart();
	},
	_OnGameEnd: function() {
		arkSt.api.lifecycle.onGameEnd();
	},
	_OnGameResume: function() {
		arkSt.api.lifecycle.onGameResume();
	},
	_OnPauseReady: function() {
		arkSt.api.lifecycle.onPauseReady();
	},
	_OnGamePause: function() {
		arkSt.api.lifecycle.onGamePause();
	},
	_OnChangeScore: function(scoreValue) {
		arkSt.api.lifecycle.onChangeScore({ score: scoreValue });
	},
	_OnGemsUpdate: function() {
		arkSt.api.lifecycle.onGemsUpdate();
	},
	_OnLevelStart: function(level) {
		arkSt.api.lifecycle.onLevelStart(level);
	},
	_OnLevelEnd: function(level) {
		arkSt.api.lifecycle.onLevelEnd(level);
	},
	_RegisterEventCallback: function(eventId, cb_) {
		const callback = (eventId) => { console.log('Calling callback'); {{{ makeDynCall('vi', 'cb_') }}} (eventId); }
		arkSt.api.lifecycle.registerEventCallback(eventId, () => callback(eventId));
	},

	// persistence
	_GetLocalStorageItem: function(key_, cb_) {
		const key = UTF8ToString(key_);
		const cb = (s) => {
			const buffer = stringToNewUTF8(s);
			{{{ makeDynCall('vi', 'cb_') }}} (buffer);
			_free(buffer);
		}

		arkSt.api.persistence.getLocalStorageItem(key).then(
			(result) => cb(result === null ? '' : result),
			() => cb('')
		);
	},
	_SetLocalStorageItem: function(key_, value_, cb_) {
		const key = UTF8ToString(key_);
		const value = UTF8ToString(value_);
		
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		arkSt.api.persistence.setLocalStorageItem(key, value).then(() => cb(1), () => cb(0));
	},
	_RemoveLocalStorageItem: function(key_, cb_) {
		const key = UTF8ToString(key_);
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		arkSt.api.persistence.removeLocalStorageItem(key).then(() => cb(1), () => cb(0));
	},
	_GetCookie: function(key_, cb_) {
		const key = UTF8ToString(key_);
		const cb = (s) => {
			const buffer = stringToNewUTF8(s);
			{{{ makeDynCall('vi', 'cb_') }}} (buffer);
			_free(buffer);
		}

		arkSt.api.persistence.getCookie(key).then(
			(result) => cb(result === null ? '' : result),
			() => cb('')
		);
	},
	_GetRemoteStorageItem: function(key_, cb_) {
		const key = UTF8ToString(key_);
		const cb = (s) => {
			const buffer = stringToNewUTF8(s);
			{{{ makeDynCall('vi', 'cb_') }}} (buffer);
			_free(buffer);
		}

		arkSt.api.persistence.getRemoteStorageItem(key).then(
			(result) => cb(result === null ? '' : result),
			() => cb('')
		);
	},
	_SetRemoteStorageItem: function(key_, value_, cb_) {
		const key = UTF8ToString(key_);
		const value = UTF8ToString(value_);
		
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		arkSt.api.persistence.setRemoteStorageItem(key, value).then(() => cb(1), () => cb(0));
	},
	_RemoveRemoteStorageItem: function(key_, cb_) {
		const key = UTF8ToString(key_);
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		arkSt.api.persistence.removeRemoteStorageItem(key).then(() => cb(1), () => cb(0));
	},

	// wallet
	_IsGemsSupported: function(cb_) {
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }
		if (arkSt.api.wallet.isGemsSupported) {
			arkSt.api.wallet.isGemsSupported().then(
				(result) => cb(result ? 1 : 0),
				() => cb(0)
			);
		} else {
			cb(0);
		}
	},
	_GetGems: function(cb_) {
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		arkSt.api.wallet.getGems().then(
			(result) => cb(result === null ? 0 : result ),
			() => cb(-1)
		);
	},
	_ConsumeGems: function(value, cb_) {
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }
		arkSt.api.wallet.consumeGems(value).then(() => cb(1), () => cb(0));
	},

	// leaderboard
	_LeaderboardIsSupported: function(cb_) {
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		arkSt.api.leaderboard.isSupported().then(
			(result) => cb(result === null ? 0 : result ),
			() => cb(-1)
		);
	},

	_LeaderboardPostScore: function(scoreValue, cb_) {
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		arkSt.api.leaderboard.postScore(scoreValue).then(
			() => cb(1),
			() => cb(-1)
		);
	},

	_LeaderboardGetUserScore: function(cb_, type_) {
		let type = UTF8ToString(type_)
		type = type === '' ? undefined : type
		const cb = (i) => { {{{ makeDynCall('vi', 'cb_') }}} (i); }

		arkSt.api.leaderboard.getUserScore(type).then(
			(result) => cb(result === null ? 0 : result ),
			() => cb(-1)
		);
	},

	_LeaderboardGetTopScores: function(cb_, type_, limit) {
		let type = UTF8ToString(type_)
		type = type === '' ? undefined : type
		const cb = (s) => {
			const buffer = stringToNewUTF8(s);
			{{{ makeDynCall('vi', 'cb_') }}} (buffer);
			_free(buffer);
		}

		arkSt.api.leaderboard.getTopScores(type, limit).then(
			(result) => cb(result === null ? JSON.stringify([]) : JSON.stringify(result) ),
			() => cb(-1)
		);
	},

});
