<repo_name>MehdiNezamipour/TapsellTaskWithKotlin<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/mainclasses/AdMediator.kt
package com.nezamipour.mehdi.admediator.mainclasses

import android.app.Activity
import android.app.Application
import android.content.Context
import android.util.Log
import com.chartboost.sdk.Chartboost
import com.nezamipour.mehdi.admediator.mainclasses.companies.ChartBoostManager
import com.nezamipour.mehdi.admediator.mainclasses.companies.CompanyManager
import com.nezamipour.mehdi.admediator.mainclasses.companies.TapSellManager
import com.nezamipour.mehdi.admediator.mainclasses.companies.UnityAdsManager
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdRequestCallback
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdShowCallback
import com.nezamipour.mehdi.admediator.model.AdConfig
import com.nezamipour.mehdi.admediator.model.AppConfig
import com.nezamipour.mehdi.admediator.network.AdMediatorService
import com.nezamipour.mehdi.admediator.utils.Constants
import com.unity3d.ads.UnityAds
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO

class AdMediator {

    companion object {

        private val allCompanies: HashMap<String, CompanyManager> = hashMapOf()
        private val TAG = "AdMediator"

        private lateinit var appConfig: AppConfig
        private lateinit var adConfig: AdConfig
        internal lateinit var zoneType: String


        internal var adFound: Boolean = false
        internal var sAdId: String? = null


        fun initialize(application: Application, adMediatorAppId: String) {
            getAppConfig(adMediatorAppId)
            // initialization adNetworks base on appConfig
            if (appConfig.adNetworks.tapsell != null) {
                TapSellManager.initial(application, appConfig.adNetworks.tapsell!!)
                allCompanies["Tapsell"] = TapSellManager
            }
            if (appConfig.adNetworks.unityAds != null) {
                UnityAds.initialize(application, appConfig.adNetworks.unityAds)
                allCompanies["UnityAds"] = UnityAdsManager
            }
            if (appConfig.adNetworks.chartboost != null) {
                Chartboost.startWithAppId(application, appConfig.adNetworks.chartboost, null)
                allCompanies["Chartboost"] = ChartBoostManager
            }
        }

        private fun getAppConfig(appId: String) {
            try {
                CoroutineScope(IO).launch {
                    appConfig = AdMediatorService.getAppConfig(appId)
                }
            } catch (e: Exception) {
                e.printStackTrace()
                Log.d(TAG, "getAppConfig: " + e.message)
            }

            Log.d(TAG, "getAppConfig : " + appConfig.adNetworks.tapsell)
            Log.d(TAG, "getAppConfig : " + adConfig.waterfall.toString())
        }

        private fun getAdConfigBaseOnZoneId(zoneId: String) {
            try {
                CoroutineScope(IO).launch {
                    adConfig = AdMediatorService.getAdConfig(zoneId)
                    zoneType = adConfig.zoneType
                }
            } catch (e: Exception) {
                e.printStackTrace()
                Log.d(TAG, "getAdConfigBaseOnZoneId : " + e.message)
            }
        }

        fun requestAd(
            context: Context,
            adMediatorZoneId: String,
            adRequestCallback: AdRequestCallback
        ) {
            // TODO : get ad config with new waterfall if not exist waterfall with this zoneId in catch
            getAdConfigBaseOnZoneId(zoneId = adMediatorZoneId)
            loadAd(context, adRequestCallback)

        }

        private fun loadAd(
            context: Context,
            adRequestCallback: AdRequestCallback
        ) {

            val parentJob = CoroutineScope(IO).launch {
                withTimeoutOrNull(adConfig.waterfall[0].timeout) {
                    if (!adFound)
                        try {
                            //delay(2100)
                            Log.d(TAG, "loadAd: ${adConfig.waterfall[0].zoneId}")
                            allCompanies[adConfig.waterfall[0].adNetwork]?.requestAd(
                                context,
                                adConfig.waterfall[0].zoneId,
                                adRequestCallback
                            )

                        } catch (e: Exception) {
                            Log.d(TAG, "loadAd: exception message =  ${e.message}")
                        }
                    else
                        cancel()
                }
                withTimeoutOrNull(adConfig.waterfall[1].timeout) {
                    if (!adFound)
                        try {
                            Log.d(TAG, "loadAd: ${adConfig.waterfall[1].zoneId}")
                            allCompanies[adConfig.waterfall[1].adNetwork]?.requestAd(
                                context,
                                adConfig.waterfall[1].zoneId,
                                adRequestCallback
                            )

                        } catch (e: Exception) {
                            Log.d(TAG, "loadAd: exception message = ${e.message}")
                        }
                    else
                        cancel()
                }
                withTimeoutOrNull(adConfig.waterfall[2].timeout) {
                    if (!adFound)
                        try {
                            Log.d(TAG, "loadAd: ${adConfig.waterfall[2].zoneId}")
                            allCompanies[adConfig.waterfall[2].adNetwork]?.requestAd(
                                context,
                                adConfig.waterfall[2].zoneId,
                                adRequestCallback
                            )

                        } catch (e: Exception) {
                            Log.d(TAG, "loadAd: exception message = ${e.message}")
                        }
                    else
                        cancel()
                }

            }
        }


        fun showAd(
            activity: Activity,
            zoneId: String,
            adId: String,
            adShowCallback: AdShowCallback
        ) {

            when (zoneId) {
                Constants.TAPSELL_INTERSTITIAL_BANNER, Constants.TAPSELL_INTERSTITIAL_VIDEO, Constants.TAPSELL_REWARDED_VIDEO ->
                    sAdId?.let {
                        allCompanies["Tapsell"]?.showAd(
                            activity,
                            zoneId,
                            it,
                            adShowCallback
                        )
                    }
                Constants.CHART_BOOST_INTERSTITIAL_BANNER, Constants.CHART_BOOST_INTERSTITIAL_VIDEO ->
                    sAdId?.let {
                        allCompanies["Chartboost"]?.showAd(
                            activity,
                            zoneId,
                            it,
                            adShowCallback
                        )
                    }
                Constants.CHART_BOOST_REWARDED_VIDEO -> sAdId?.let {
                    allCompanies["Chartboost"]?.showAd(
                        activity,
                        zoneId,
                        it,
                        adShowCallback
                    )
                }
                Constants.UNITY_AD_INTERSTITIAL_BANNER, Constants.UNITY_AD_INTERSTITIAL_VIDEO, Constants.UNITY_AD_REWARDED_VIDEO ->
                    sAdId?.let {
                        allCompanies["UnityAds"]?.showAd(
                            activity,
                            zoneId,
                            it,
                            adShowCallback
                        )
                    }
                else -> adShowCallback.onError("showAd : network not exist")
            }
        }


    }

}<file_sep>/app/src/main/java/com/nezamipour/mehdi/tapselltaskwithkotlin/InterstitialBannerActivity.kt
package com.nezamipour.mehdi.tapselltaskwithkotlin

import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import com.nezamipour.mehdi.admediator.mainclasses.AdMediator
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdRequestCallback
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdShowCallback
import com.nezamipour.mehdi.admediator.utils.Constants
import com.nezamipour.mehdi.tapselltaskwithkotlin.databinding.ActivityInterstitialBannerBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch

class InterstitialBannerActivity : AppCompatActivity() {

    private lateinit var binding: ActivityInterstitialBannerBinding
    private lateinit var adId: String

    companion object {
        fun newIntent(context: Context): Intent {
            return Intent(context, InterstitialBannerActivity::class.java)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityInterstitialBannerBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.buttonRequestAd.setOnClickListener {
            CoroutineScope(IO).launch {
                AdMediator.requestAd(
                    context = this@InterstitialBannerActivity,
                    Constants.AD_MEDIATOR_INTERSTITIAL_BANNER,
                    object : AdRequestCallback {
                        override fun onSuccess(adId: String?) {
                            binding.buttonShowAd.isEnabled = true
                            if (adId != null) {
                                this@InterstitialBannerActivity.adId = adId
                            }
                        }

                        override fun error(message: String?) {
                            Toast.makeText(
                                this@InterstitialBannerActivity,
                                message,
                                Toast.LENGTH_SHORT
                            )
                                .show()
                        }

                    })
            }
        }

        binding.buttonShowAd.setOnClickListener {
            AdMediator.showAd(
                this,
                Constants.AD_MEDIATOR_INTERSTITIAL_BANNER,
                adId,
                object : AdShowCallback {
                    override fun onOpened() {
                        TODO("Not yet implemented")
                    }

                    override fun onClosed() {
                        TODO("Not yet implemented")
                    }

                    override fun onRewarded() {
                        TODO("Not yet implemented")
                    }

                    override fun onError(message: String?) {
                        TODO("Not yet implemented")
                    }

                })
        }

    }
}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/mainclasses/companies/CompanyManager.kt
package com.nezamipour.mehdi.admediator.mainclasses.companies

import android.app.Activity
import android.app.Application
import android.content.Context
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdRequestCallback
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdShowCallback

interface CompanyManager {


    fun initial(application: Application, appId: String)


    fun requestAd(context: Context, zoneId: String, adRequestCallback: AdRequestCallback)

    fun showAd(activity: Activity,
               zoneId: String?,
               adId: String,
               adShowCallback: AdShowCallback
    )


}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/mainclasses/listeners/AdRequestCallback.kt
package com.nezamipour.mehdi.admediator.mainclasses.listeners

interface AdRequestCallback {

    fun onSuccess(adId: String?)

    fun error(message: String?)

}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/network/ApiService.kt
package com.nezamipour.mehdi.admediator.network

import com.nezamipour.mehdi.admediator.model.AdConfig
import com.nezamipour.mehdi.admediator.model.AppConfig
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query

interface ApiService {

    // fake api
    // base url : https://api.admediator.com/
    // path : mobile_ad


    @GET(NetworkConstants.MOBILE_AD)
    suspend fun getAppConfig(@Query("appId") appId: String): Response<AppConfig>


    @GET(NetworkConstants.MOBILE_AD)
    suspend fun getAdConfig(@Query("zoneId") zoneId: String): Response<AdConfig>

}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/mainclasses/companies/TapSellManager.kt
package com.nezamipour.mehdi.admediator.mainclasses.companies

import android.app.Activity
import android.app.Application
import android.content.Context
import com.nezamipour.mehdi.admediator.mainclasses.AdMediator
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdRequestCallback
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdShowCallback
import ir.tapsell.sdk.Tapsell
import ir.tapsell.sdk.TapsellAdRequestListener
import ir.tapsell.sdk.TapsellAdShowListener

object TapSellManager : CompanyManager {


    override fun initial(application: Application, appId: String) {
        Tapsell.initialize(application, appId)
    }


    override fun requestAd(context: Context, zoneId: String, adRequestCallback: AdRequestCallback) {
        Tapsell.requestAd(context, zoneId, null, object : TapsellAdRequestListener() {
            override fun onAdAvailable(adId: String) {
                super.onAdAvailable(adId)
                adRequestCallback.onSuccess(adId)
                AdMediator.sAdId = adId
                AdMediator.adFound = true
            }

            override fun onError(message: String) {
                super.onError(message)
                AdMediator.adFound = false
            }
        })
    }

    override fun showAd(
        activity: Activity,
        zoneId: String?,
        adId: String,
        adShowCallback: AdShowCallback
    ) {

        Tapsell.showAd(activity, zoneId, adId, null, object : TapsellAdShowListener() {
            override fun onOpened() {
                super.onOpened()
                adShowCallback.onOpened()
            }

            override fun onError(s: String) {
                super.onError(s)
                adShowCallback.onError(s)
            }
        })
    }
}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/mainclasses/companies/UnityAdsManager.kt
package com.nezamipour.mehdi.admediator.mainclasses.companies

import android.app.Activity
import android.app.Application
import android.content.Context
import com.nezamipour.mehdi.admediator.mainclasses.AdMediator
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdRequestCallback
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdShowCallback
import com.nezamipour.mehdi.admediator.mainclasses.listeners.UnityAdListeners
import com.unity3d.ads.IUnityAdsLoadListener
import com.unity3d.ads.UnityAds

object UnityAdsManager : CompanyManager {


    override fun initial(application: Application, appId: String) {
        UnityAds.initialize(application, appId)
    }

    override fun requestAd(context: Context, zoneId: String, adRequestCallback: AdRequestCallback) {

        UnityAds.load(zoneId, object : IUnityAdsLoadListener {
            override fun onUnityAdsAdLoaded(adId: String) {
                adRequestCallback.onSuccess(adId)
                AdMediator.adFound = true
                AdMediator.sAdId = adId
            }

            override fun onUnityAdsFailedToLoad(placementId: String) {
                adRequestCallback.error("placementId :  $placementId")
                AdMediator.adFound = false
            }
        })
    }

    override fun showAd(
        activity: Activity,
        zoneId: String?,
        adId: String,
        adShowCallback: AdShowCallback
    ) {
        UnityAds.addListener(object : UnityAdListeners() {
            override fun onUnityAdsStart(placementId: String?) {
                super.onUnityAdsStart(placementId)
                adShowCallback.onOpened()
            }

            override fun onUnityAdsError(error: UnityAds.UnityAdsError?, message: String?) {
                super.onUnityAdsError(error, message)
                adShowCallback.onError(message)
            }
        })

        if (UnityAds.isReady(zoneId))
            UnityAds.show(activity, zoneId)
    }
}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/mainclasses/companies/ChartBoostManager.kt
package com.nezamipour.mehdi.admediator.mainclasses.companies

import android.app.Activity
import android.app.Application
import android.content.Context
import com.chartboost.sdk.Chartboost
import com.chartboost.sdk.ChartboostDelegate
import com.chartboost.sdk.Model.CBError
import com.nezamipour.mehdi.admediator.mainclasses.AdMediator
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdRequestCallback
import com.nezamipour.mehdi.admediator.mainclasses.listeners.AdShowCallback
import com.nezamipour.mehdi.admediator.utils.Constants

object ChartBoostManager : CompanyManager {


    override fun initial(application: Application, appId: String) {
        Chartboost.startWithAppId(application, appId, null)
    }


    override fun requestAd(context: Context, zoneId: String, adRequestCallback: AdRequestCallback) {
        when (AdMediator.zoneType) {
            Constants.AD_MEDIATOR_INTERSTITIAL_BANNER, Constants.AD_MEDIATOR_INTERSTITIAL_VIDEO -> requestInterstitialFromChartBoost(
                zoneId, adRequestCallback
            )
            Constants.AD_MEDIATOR_REWARDED_VIDEO -> requestRewardedFromChartBoost(
                zoneId,
                adRequestCallback
            )
        }
    }

    private fun requestInterstitialFromChartBoost(
        chartBoostZoneId: String,
        adRequestCallback: AdRequestCallback
    ) {
        Chartboost.setDelegate(object : ChartboostDelegate() {
            override fun didCacheInterstitial(location: String?) {
                super.didCacheInterstitial(location)
                adRequestCallback.onSuccess(location)

            }

            override fun didFailToLoadInterstitial(
                location: String?,
                error: CBError.CBImpressionError?
            ) {
                super.didFailToLoadInterstitial(location, error)
                adRequestCallback.error(error.toString())
            }
        })
        Chartboost.cacheInterstitial(chartBoostZoneId)
    }

    private fun requestRewardedFromChartBoost(
        chartBoostZoneId: String,
        adRequestCallback: AdRequestCallback
    ) {
        Chartboost.setDelegate(object : ChartboostDelegate() {
            override fun didCacheRewardedVideo(location: String?) {
                super.didCacheRewardedVideo(location)
                adRequestCallback.onSuccess(location)
            }

            override fun didFailToLoadRewardedVideo(
                location: String?,
                error: CBError.CBImpressionError?
            ) {
                super.didFailToLoadRewardedVideo(location, error)
                adRequestCallback.error(error.toString())
            }
        })
        Chartboost.cacheRewardedVideo(chartBoostZoneId)
    }

    override fun showAd(
        activity: Activity,
        zoneId: String?,
        adId: String,
        adShowCallback: AdShowCallback
    ) {
        when (AdMediator.zoneType) {
            Constants.AD_MEDIATOR_INTERSTITIAL_BANNER, Constants.AD_MEDIATOR_INTERSTITIAL_VIDEO -> showInterstitialFromChartBoost(
                zoneId, adShowCallback
            )
            Constants.AD_MEDIATOR_REWARDED_VIDEO -> showRewardedFromChartBoost(
                zoneId,
                adShowCallback
            )
        }
    }


    private fun showInterstitialFromChartBoost(
        zoneId: String?, adShowCallback: AdShowCallback
    ) {
        Chartboost.setDelegate(object : ChartboostDelegate() {
            override fun didCloseInterstitial(location: String?) {
                super.didCloseInterstitial(location)
                adShowCallback.onClosed()
            }

            override fun didDisplayInterstitial(location: String?) {
                super.didDisplayInterstitial(location)
                adShowCallback.onOpened()
            }

        })
        Chartboost.showInterstitial(zoneId)
    }

    private fun showRewardedFromChartBoost(
        zoneId: String?, adShowCallback: AdShowCallback
    ) {
        Chartboost.setDelegate(object : ChartboostDelegate() {
            override fun didCloseRewardedVideo(location: String?) {
                super.didCloseRewardedVideo(location)
                adShowCallback.onClosed()
            }

            override fun didClickRewardedVideo(location: String?) {
                super.didClickRewardedVideo(location)

            }

            override fun didCompleteRewardedVideo(location: String?, reward: Int) {
                super.didCompleteRewardedVideo(location, reward)
                adShowCallback.onRewarded()
            }

            override fun didDisplayRewardedVideo(location: String?) {
                super.didDisplayRewardedVideo(location)
                adShowCallback.onOpened()

            }
        })
        Chartboost.showRewardedVideo(zoneId)
    }
}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/model/AppConfig.kt
package com.nezamipour.mehdi.admediator.model

import android.os.Parcelable
import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize

@Parcelize
data class AppConfig(

    @SerializedName("adNetworks")
    @Expose
    var adNetworks: AdNetworks
): Parcelable<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/model/Waterfall.kt
package com.nezamipour.mehdi.admediator.model

import android.os.Parcelable
import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize

@Parcelize
data class Waterfall(
    @SerializedName("adNetwork")
    @Expose
    var adNetwork: String,

    @SerializedName("zoneId")
    @Expose
    var zoneId: String,

    @SerializedName("timeout")
    @Expose
    var timeout: Long
) : Parcelable<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/model/AdConfig.kt
package com.nezamipour.mehdi.admediator.model

import android.os.Parcelable
import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize

@Parcelize
data class AdConfig(

    @SerializedName("zoneType")
    @Expose
    var zoneType: String,

    @SerializedName("waterfall")
    @Expose
    var waterfall: List<Waterfall>,

    @SerializedName("ttl")
    @Expose
    var ttl: Long

) : Parcelable<file_sep>/app/src/main/java/com/nezamipour/mehdi/tapselltaskwithkotlin/InterstitialVideoActivity.kt
package com.nezamipour.mehdi.tapselltaskwithkotlin

import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class InterstitialVideoActivity : AppCompatActivity() {

    companion object {
        fun newIntent(context: Context): Intent {
            return Intent(context, InterstitialVideoActivity::class.java)
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_interstitial_video)
    }
}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/network/RetrofitInstance.kt
package com.nezamipour.mehdi.admediator.network

import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitInstance {

    val retrofitInstance = Retrofit.Builder()
        .baseUrl(NetworkConstants.BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
        .build()

}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/network/NetworkConstants.kt
package com.nezamipour.mehdi.admediator.network

class NetworkConstants {

    companion object {

        const val BASE_URL = "https://api.admediator.com/"
        const val MOBILE_AD = "mobile_ad"


    }
}<file_sep>/app/src/main/java/com/nezamipour/mehdi/tapselltaskwithkotlin/App.kt
package com.nezamipour.mehdi.tapselltaskwithkotlin

import android.app.Application
import com.nezamipour.mehdi.admediator.mainclasses.AdMediator

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AdMediator.initialize(this, "AppId")

    }
}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/model/AdNetworks.kt
package com.nezamipour.mehdi.admediator.model

import android.os.Parcelable
import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize

@Parcelize
class AdNetworks(
    @SerializedName("Tapsell")
    @Expose
    var tapsell: String?,

    @SerializedName("UnityAds")
    @Expose
    var unityAds: String?,

    @SerializedName("Chartboost")
    @Expose
    var chartboost: String?
): Parcelable<file_sep>/app/src/main/java/com/nezamipour/mehdi/tapselltaskwithkotlin/MainActivity.kt
package com.nezamipour.mehdi.tapselltaskwithkotlin

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.nezamipour.mehdi.admediator.mainclasses.AdMediator
import com.nezamipour.mehdi.tapselltaskwithkotlin.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.buttonRewardedVideo.setOnClickListener {
            startActivity(RewardedVideoActivity.newIntent(this))
        }

        binding.buttonInterstitialBanner.setOnClickListener {
            startActivity(InterstitialBannerActivity.newIntent(this))
        }

        binding.buttonInterstitialVideo.setOnClickListener {
            startActivity(InterstitialVideoActivity.newIntent(this))
        }


    }
}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/utils/Constants.kt
package com.nezamipour.mehdi.admediator.utils

class Constants {

    companion object {


        // Our Mediator
        const val AD_MEDIATOR_INTERSTITIAL_BANNER = "INTERSTITIAL_BANNER_ZONE_ID"
        const val AD_MEDIATOR_INTERSTITIAL_VIDEO = "INTERSTITIAL_VIDEO_ZONE_ID"
        const val AD_MEDIATOR_REWARDED_VIDEO = "REWARDED_VIDEO_ZONE_ID"

        //TapSell
        const val TAPSELL_KEY =
            "<KEY>"
        const val TAPSELL_INTERSTITIAL_BANNER = "5caae7c33a2e170001ef9392"
        const val TAPSELL_INTERSTITIAL_VIDEO = "5caaeffec1ed8b000149cedc"
        const val TAPSELL_REWARDED_VIDEO = "5caaf03dc1ed8b000149cedd"


        //UnityAd
        const val UNITY_AD_INTERSTITIAL_BANNER = "UNITY_AD_INTERSTITIAL_BANNER"
        const val UNITY_AD_INTERSTITIAL_VIDEO = "UNITY_AD_INTERSTITIAL_VIDEO"
        const val UNITY_AD_REWARDED_VIDEO = "UNITY_AD_REWARDED_VIDEO"


        //Chartboost
        const val CHART_BOOST_INTERSTITIAL_BANNER = "CHART_BOOST_INTERSTITIAL_BANNER"
        const val CHART_BOOST_INTERSTITIAL_VIDEO = "CHART_BOOST_INTERSTITIAL_VIDEO"
        const val CHART_BOOST_REWARDED_VIDEO = "CHART_BOOST_REWARDED_VIDEO"

        const val APP_CONFIG = "{\n" +
                "\"adNetworks\" : {\n" +
                "\"Tapsell\" : \"appIdInTapsell\",\n" +
                "\"UnityAds\" : \"appIdInUnityAds\",\n" +
                "\"Chartboost\" : \"appIdInChartboost\"\n" +
                "}\n" +
                "}"

        const val AD_CONFIG = "{\n" +
                "\"zoneType\": \"Interstitial\",\n" +
                "\"waterfall\": [\n" +
                "{\n" +
                "\"adNetwork\": \"UnityAds\",\n" +
                "\"zoneId\": \"zoneIdInUnityAds\",\n" +
                "\"timeout\": 2000\n" +
                "},\n" +
                "{\n" +
                "\"adNetwork\": \"Tapsell\",\n" +
                "\"zoneId\": \"zoneIdInTapsell\",\n" +
                "\"timeout\": 3000\n" +
                "},\n" +
                "{\n" +
                "\"adNetwork\": \"Chartboost\",\n" +
                "\"zoneId\": \"zoneIdInChartboost\",\n" +
                "\"timeout\": 1000\n" +
                "}\n" +
                "],\n" +
                "\"ttl\": 3600000\n" +
                "}"


    }

}<file_sep>/settings.gradle
include ':AdMediator'
include ':app'
rootProject.name = "TapsellTaskWithKotlin"<file_sep>/README.md
# TapsellTaskWithKotlin

Simple Ad Mediator Library
# Add dependency
add these to gradle (project):

 maven { url 'https://jitpack.io' }
 <br>
 maven {url 'https://dl.bintray.com/tapsellorg/maven'}
 <br>
 maven { url "https://chartboostmobile.bintray.com/Chartboost" }

then add these dependencies to app module:

 implementation 'com.github.MehdiNezamipour:TapsellTaskWithKotlin:v.1.0'
 
 
 
# Guide of usage
  
 call static methods on AdMediator class like initialize, adRequest, showAd. 
<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/network/AdMediatorService.kt
package com.nezamipour.mehdi.admediator.network

import com.nezamipour.mehdi.admediator.model.AdConfig
import com.nezamipour.mehdi.admediator.model.AppConfig

object AdMediatorService : BaseService() {

    private val apiService = RetrofitInstance.retrofitInstance.create(ApiService::class.java)

    suspend fun getAppConfig(appId: String): AppConfig {
        when (val result = createCall { apiService.getAppConfig(appId) }) {
            is Result.Success -> result.data
            is Result.Error -> result.throwable
        }
        throw Throwable("getAppConfig : not work")
    }

    suspend fun getAdConfig(zoneId: String): AdConfig {
        when (val result = createCall { apiService.getAdConfig(zoneId) }) {
            is Result.Success -> result.data
            is Result.Error -> result.throwable
        }
        throw Throwable("getAdConfig : not work")
    }
}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/mainclasses/listeners/UnityAdListeners.kt
package com.nezamipour.mehdi.admediator.mainclasses.listeners

import com.unity3d.ads.IUnityAdsListener
import com.unity3d.ads.UnityAds.FinishState
import com.unity3d.ads.UnityAds.UnityAdsError

open class UnityAdListeners : IUnityAdsListener {

    override fun onUnityAdsReady(placementId: String?) {}

    override fun onUnityAdsStart(placementId: String?) {}

    override fun onUnityAdsFinish(placementId: String?, result: FinishState?) {}

    override fun onUnityAdsError(error: UnityAdsError?, message: String?) {}
}<file_sep>/AdMediator/src/main/java/com/nezamipour/mehdi/admediator/mainclasses/listeners/AdShowCallback.kt
package com.nezamipour.mehdi.admediator.mainclasses.listeners

interface AdShowCallback {

    fun onOpened()

    fun onClosed()

    fun onRewarded()

    fun onError(message: String?)
}