//
//  EnxRoomManager.swift
//  EnxRtc
//
//  Created by Daljeet Singh on 17/03/19.
//  Copyright © 2019 Facebook. All rights reserved.
//
import Foundation
import EnxRTCiOS

@objc(EnxRoomManager)
class EnxRoomManager: RCTEventEmitter {
    var localStream : EnxStream!
    var localStreamId : String!
    var objectJoin: EnxRtc!
    var remoteRoom : EnxRoom!
    var componentEvents: [String] = [];
    var jsEvents: [String] = [];
    var selectedCamera : Bool = true
    @objc override func supportedEvents() -> [String] {
        let allEvents = getSupportedEvents();
        return jsEvents + allEvents
    }
    
    override static func requiresMainQueueSetup() -> Bool {
        return true;
    }
    
    @objc func initRoom(){
        objectJoin = EnxRtc()
    }
   
    @objc func changePlayerScaleType(_ mode: Int, streamId:String?)
    {
      DispatchQueue.main.async {
        guard let player = EnxRN.sharedState.players[streamId!] else {
            return;
        }
        var contentMode = UIView.ContentMode.scaleAspectFit
        if mode == 1{
           contentMode = UIView.ContentMode.scaleAspectFill
        }
        player.contentMode = contentMode
      }
    }
    //Join Room
    @objc func joinRoom(_ token: String, localInfo: [String : Any], roomInfo: [String : Any], advanceOptions: [Any]?){
        var roomInformation : [String : Any] = [:]
        if let timeout_interval = roomInfo["timeout_interval"] as? String{
            if let timeOut = NumberFormatter().number(from: timeout_interval) {
                roomInformation.updateValue(timeOut.intValue, forKey: "timeout_interval")
            }
        }
        if let number_of_attempts = roomInfo["number_of_attempts"] as? String{
            if let number = NumberFormatter().number(from: number_of_attempts) {
                roomInformation.updateValue(number.intValue, forKey: "number_of_attempts")
            }
        }
        if let playerConfiguration = roomInfo["playerConfiguration"] as? [String: Any]{
            roomInformation.updateValue(playerConfiguration, forKey: "playerConfiguration")
        }
        if let activeviews = roomInfo["activeviews"] as? String{
            roomInformation.updateValue(activeviews, forKey: "activeviews")
        }
        if let allow_reconnect = roomInfo["allow_reconnect"] as? Bool{
            roomInformation.updateValue(allow_reconnect, forKey: "allow_reconnect")
        }
       if(self.localStream != nil){
        self.localStream!.detachRenderer()
             if(EnxRN.sharedState.publishStreams["abc-123-xyz"] != nil){
                   EnxRN.sharedState.publishStreams.removeValue(forKey: "abc-123-xyz")
                  }
                  self.localStream = nil
                 }

        DispatchQueue.main.async {
            guard let localStreamObject =   self.objectJoin.joinRoom(token, delegate: self, publishStreamInfo: localInfo, roomInfo: roomInformation, advanceOptions: advanceOptions) else{
                return
            }
            self.localStream = localStreamObject
            self.localStream.usingFrontCamera = self.selectedCamera
            self.localStream.delegate = self
        }
    }
    //Publish Stream
    @objc func publish(){
        guard localStream != nil else{
            return
        }
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.publish(localStream)
    }
    //create player for Self stream
    @objc func initStream(_ streamId:String?,isFrontCamera:Bool = true){
        selectedCamera = isFrontCamera
        guard streamId != nil else{
            return
        }
        if(streamId == "abc-123-xyz"){
            let enxRoom = EnxRoom()
            self.localStream = enxRoom.getPreviewStream()
        }else{
             if(EnxRN.sharedState.publishStreams["abc-123-xyz"] != nil){
                   EnxRN.sharedState.publishStreams.removeValue(forKey: "abc-123-xyz")
                  }
            localStreamId = streamId
                 
        }
        DispatchQueue.main.async {
            if(self.localStream != nil) {
                EnxRN.sharedState.publishStreams.updateValue(self.localStream, forKey: (streamId)!)
                guard let player = EnxRN.sharedState.players[streamId!] else{
                    return;
                }
               if(self.localStream!.enxPlayerView != nil){
                    self.localStream!.detachRenderer()
                   
                }
                self.localStream.attachRenderer(player)
            }
        }
    }
    // Get stream ID for local Stream
    @objc func getLocalStreamId(_ callback: @escaping RCTResponseSenderBlock) -> Void {
        let streamDict = EnxRN.sharedState.publishStreams
        var keyString: String = ""
        for (key, _) in streamDict {
            keyString = key
        }
        callback([keyString])
    }
    //Subscribe Remore Stream
    @objc func subscribe(_ streamId: String?, callback: @escaping RCTResponseSenderBlock) -> Void {
        DispatchQueue.main.async{
            if(streamId == nil || streamId?.count == 0){
                callback(["Error: Invalid streamId to subscribe."])
            }
            guard let stream = EnxRN.sharedState.room?.streamsByStreamId[streamId!] as? EnxStream else{
                return;
            }
           let _ = EnxRN.sharedState.room!.subscribe(stream)
        }
    }
    // Switch Camera
    @objc func switchCamera(_ streamId: String?){
        
        guard let stream = EnxRN.sharedState.publishStreams[streamId!] else{
            return;
        }
        let _ = stream.switchCamera()
    }
     @objc func switchCameraPreview(){
        guard let stream = EnxRN.sharedState.publishStreams["abc-123-xyz"] else{
            return;
        }
        let _ = stream.switchCameraPreview()
        selectedCamera = stream.usingFrontCamera
 

    }
    //Mute Self Audio
    @objc func muteSelfAudio(_ streamId: String, value: Bool){
         var sID : String = streamId
        if sID.isEmpty{
            sID = localStreamId
        }
        guard let stream = EnxRN.sharedState.publishStreams[sID] else{
            return;
        }
        
        DispatchQueue.main.async {
            stream.muteSelfAudio(value)
        }
    }
    //Mute Self Video
    @objc func muteSelfVideo(_ streamId: String?, value: Bool){
          var sID : String = streamId!
          if sID.isEmpty{
            sID = localStreamId
           }
        guard let stream = EnxRN.sharedState.publishStreams[sID] else{
            return;
        }

        DispatchQueue.main.async {
            stream.muteSelfVideo(value)
        }
    }
    // Start recording in room
    @objc func startRecord(){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.startRecord()
    }
    //Stop recording in room
    @objc func stopRecord(){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.stopRecord()
    }
    //Chair Control
    //For Participant
    //Request Floor
    @objc func requestFloor(){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.requestFloor()
    }
    //For Moderator
    //Accept floor requested
    @objc func grantFloor(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if clientId.count > 0{
            room.grantFloor(clientId)
        }
    }
    //Deny floor requested
    @objc func denyFloor(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if clientId.count > 0{
            room.denyFloor(clientId)
        }
    }
    //Released accepted floor request
    @objc func releaseFloor(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if clientId.count > 0{
            room.releaseFloor(clientId)
        }
    }
    //For Participant to finish floor
    //Finished floor
   @objc func finishFloor(){
        guard let room = EnxRN.sharedState.room else{
           return
        }
        room.finishFloor()
  }
    //For Participant to cancel floor
    //Cancel Floor
    @objc func cancelFloor(){
      guard let room = EnxRN.sharedState.room else{
           return
     }
      room.cancelFloor()
    }
   //For Invite Floor
   // Invite any participant on floor
   @objc func inviteToFloor(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if clientId.count > 0{
            room.invite(toFloor: clientId)
        }
    }
    //For Accept Invite Floor
    @objc func acceptInviteFloorRequest(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if clientId.count > 0{
            room.acceptInviteFloorRequest(clientId)
        }
    }
//Cancel Invite Floor Request
    @objc func cancelFloorInvite(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if clientId.count > 0{
            room.cancelFloorInvite(clientId)
        }
    }
//Reject Invite Floor Request
    @objc func rejectInviteFloor(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if clientId.count > 0{
            room.rejectInviteFloor(clientId)
        }
    }
    //Hard Mute audio
    @objc func hardMuteAudio(_ streamId: String?, _ clientId: String){
        guard let stream = EnxRN.sharedState.publishStreams[streamId!] else{
            return;
        }
        if clientId.count > 0{
          stream.hardMuteAudio(clientId)
        }
    }
    //Hard unmute audio
    @objc func hardUnmuteAudio(_ streamId: String?, _ clientId: String){
        guard let stream = EnxRN.sharedState.publishStreams[streamId!] else{
            return;
        }
        if clientId.count > 0{
            stream.hardUnMuteAudio(clientId)
        }
    }
    //hard mute video
    @objc func hardMuteVideo(_ streamId: String, _ clientId: String){
        guard let stream = EnxRN.sharedState.publishStreams[streamId] else{
            return;
        }
        if clientId.count > 0{
            stream.hardMuteVideo(clientId)
        }
    }
    //Hard unmute Video
    @objc func hardUnmuteVideo(_ streamId: String, _ clientId: String) {
        guard let stream = EnxRN.sharedState.publishStreams[streamId] else{
            return;
        }
        if clientId.count > 0{
            stream.hardUnMuteVideo(clientId)
        }
    }
    //Hard Room mute
    @objc func hardMute(){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.hardMute()
    }
    //hard room unmute
    @objc func hardUnmute(){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.hardUnMute()
    }
    //Send Data
    @objc func sendData(_ streamId: String, _ data: [String : Any]){
        guard let stream = EnxRN.sharedState.publishStreams[streamId] else{
            return;
        }
            stream.sendData(data)
    }
    //Post Client Logs
    // To enble Enx logs to write in the file.
    @objc func enableLogs(_ value: Bool)
    {
        if(value){
            let enxLog = EnxUtilityManager.shareInstance
            enxLog.startLog()
        }
        else{
            
        }
    }
    //Post client logs
    @objc func postClientLogs(){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.postClientLogs()
    }
    // Set Active Talker Count
    @objc func setTalkerCount(_ number: Int){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.setTalkerCount(number)
    }
    //Get current active talker count in room
    @objc func getTalkerCount(){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.getTalkerCount()
    }
    //Get max possible talker in room
    @objc func getMaxTalkers(){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.getMaxTalkers()
    }
    //Audio only call
    @objc func changeToAudioOnly(_ value:Bool){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.setAudioOnlyMode(value)
    }
    //Stop video track when app goes in background
    @objc func stopVideoTracksOnApplicationBackground(_ value: Bool, _ videoMuteLocalStream: Bool){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.stopVideoTracksOnApplication(background: !value)
    }
    //Start video track when app goes in forground
    @objc func startVideoTracksOnApplicationForeground(_ value: Bool, _ videoMuteLocalStream: Bool){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.stopVideoTracksOnApplication(background: !value)
    }
    //changes to any available audio media
    @objc func switchMediaDevice(_ mediaName: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.switchMediaDevice(mediaName)
    }
    //Get current selected audio media
    @objc func getSelectedDevice(_ callback: @escaping RCTResponseSenderBlock) -> Void {
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if let selectedDeviceString = room.getSelectedDevice(){
            let selectedDeviceArray = [selectedDeviceString]
            callback(selectedDeviceArray)
        }
    }
    //Get list of connected audio device
    @objc func getDevices(_ callback: @escaping RCTResponseSenderBlock) -> Void {
        guard let room = EnxRN.sharedState.room else{
            return
        }
        let deviceArray = room.getDevices()
        callback([deviceArray!])
    }
    //Stats Method
    @objc func enableStats(_ value: Bool){
        guard let room = EnxRN.sharedState.room else {
            return
        }
        room.enableStats(value)
    }
    //Send Message
    @objc func sendMessage(_ data: String, broadcast: Bool, clientIds: [String]?){
        guard let room = EnxRN.sharedState.room else {
            return
        }
        room.sendMessage(data, isBroadCast: broadcast, recipientIDs: clientIds)
    }
    //Send User Data
    @objc func sendUserData(_ data: [String : Any], broadcast: Bool, clientIds: [String]?) {
        guard let room = EnxRN.sharedState.room else {
            return
        }
        room.sendUserData(data, isBroadCast: broadcast, recipientIDs: clientIds)
    }
    //TO switch user role.
    @objc func switchUserRole(_ clientId: String){
        guard let room = EnxRN.sharedState.room else {
            return
        }
        room.switchUserRole(clientId)
    }
    //send files
    @objc func sendFiles(_ isBroadcast: Bool, clientIds: [String]){
        guard let room = EnxRN.sharedState.room else {
            return
        }
        DispatchQueue.main.async {
            room.sendFiles(isBroadcast, clientIds: clientIds)
        }
    }
    //download available files
    @objc func downloadFile(_ file: [String : Any], autoSave: Bool){
        guard let room = EnxRN.sharedState.room else {
            return
        }
        DispatchQueue.main.async {
            room.downloadFile(file , autoSave: autoSave)
        }
     }
    //Get list of available files
    @objc func getAvailableFiles(){
        guard let room = EnxRN.sharedState.room else {
            return
        }
        let array  = room.getAvailableFiles()
        self.emitEvent(event: "room:didAvailableFiles", data: array! as [Any])
    }
    //Cancel single Upload
    @objc func cancelUpload(_ jobId: String!){
           guard let room = EnxRN.sharedState.room else {
               return
           }
        if let jobid = NumberFormatter().number(from: jobId) {
            room.cancelUpload(jobid.intValue)
        }
    }
    //cancel single download
    @objc func cancelDownload(_ jobId: String!){
          guard let room = EnxRN.sharedState.room else {
               return
           }
        if let jobid = NumberFormatter().number(from: jobId) {
            room.cancelDownload(jobid.intValue)
        }
       
    }
    //cancel all upload
    @objc func cancelAllUploads(){
           guard let room = EnxRN.sharedState.room else {
               return
           }
        room.cancelAllUploads()
    }
    //cancel all download
    @objc func cancelAllDownloads(){
           guard let room = EnxRN.sharedState.room else {
               return
           }
        room.cancelAllDownloads()
    }
    //To get self connected user details
    @objc func whoAmI(){
       guard let room = EnxRN.sharedState.room else {
           return
        }
        guard let resDict = room.whoami() else{
          return
        }
       self.emitEvent(event: "room:whoAmI", data:resDict)
    }
    //To lock room
    @objc func lockRoom(){
        guard let room = EnxRN.sharedState.room else {
          return
        }
        
        room.lockRoom()
    }
    //To unlock Room
    @objc func unlockRoom(){
        guard let room = EnxRN.sharedState.room else {
         return
        }
        room.unlockRoom()
    }
    //To destroy Room
    @objc func destroy(){
        guard let room = EnxRN.sharedState.room else {
         return
        }
        room.destroy()
    }
    //To start out bound call
    @objc func makeOutboundCall(_ number: String, callerId : String){
        guard let room = EnxRN.sharedState.room else {
         return
        }
        room.makeOutboundCall(number , callerId: callerId)
    }
    @objc func makeOutboundCallwithJoinOption(_ number: String, callerId : String,dialOptions: [String : Any]){
        guard let room = EnxRN.sharedState.room else {
         return
        }
        room.makeOutboundCall(number , callerId: callerId,withDialOptions:dialOptions)
    }
     @objc func cancelOutboundCall(_ number: String){
        guard let room = EnxRN.sharedState.room else {
         return
        }
        room.cancelOutboundCall(number)
    }

     @objc func sendDTMF(_ number: String, digits : String){
        guard let room = EnxRN.sharedState.room else {
         return
        }
        room.sendDTMF(number , digits: digits)
    }

    //Drop Users
    @objc func dropUser(_ clientIds: [String]){
       guard let room = EnxRN.sharedState.room else {
         return
       }
        room.dropUser(clientIds)
    }
    // To enableProximitySensor
    @objc func enableProximitySensor(_ value: Bool){
        guard let room = EnxRN.sharedState.room else {
          return
        }
         room.enableProximitySensor(value)
    }
    //To setAudioOnlyMode
    @objc func setAudioOnlyMode(_ audioOnly: Bool){
       guard let room = EnxRN.sharedState.room else {
          return
        }
         room.setAudioOnlyMode(audioOnly)
    }
    //To setReceiveVideoQuality
    @objc func setReceiveVideoQuality(_ opt: [String : Any]){
      guard let room = EnxRN.sharedState.room else {
        return
      }
        room.setReceiveVideoQuality(opt)
    }
   
    //To getReceiveVideoQuality
    @objc func getReceiveVideoQuality(_ streamType: String){
      guard let room = EnxRN.sharedState.room else {
         return
      }
        let type = room.getReceiveVideoQuality(streamType)
        self.emitEvent(event: "room:getReceiveVideoQuality", data:type!)
    }
    //Start Annotation
    @objc func startAnnotation(_ streamId: String){
       guard let room = EnxRN.sharedState.room else {
          return
        }
        var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
            stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
        guard stream?.enxPlayerView != nil else{
            return;
        }
        room.startAnnotation(stream!)
    }
    //Stop Annotation
    @objc func stopAnnotation(){
       guard let room = EnxRN.sharedState.room else {
          return
       }
        room.stopAnnotation()
    }
    //Mute subscribe audio
    @objc func muteSubscribeStreamsAudio(_ flag: Bool){
        guard let room = EnxRN.sharedState.room else {
          return
        }
        room.muteSubscribeStreamsAudio(flag)
    }
    //Get Self role
    @objc func getRole(){
       guard let room = EnxRN.sharedState.room else {
          return
        }
       guard room.userRole as String? != nil else{
            return;
        }
        self.emitEvent(event: "room:getRole", data:room.userRole!)

    }
    //get self client id
    @objc func getClientId(){
        guard let room = EnxRN.sharedState.room else {
          return
        }
        guard room.clientId as String? != nil else{
            return;
        }
        self.emitEvent(event: "room:getClientId", data:room.clientId! as String)

    }
    //Get room ID
    @objc func getRoomId(){
        guard let room = EnxRN.sharedState.room else {
         return
        }
        guard room.roomId as String? != nil else{
        return;
        }
        self.emitEvent(event: "room:getRoomId", data:room.roomId! as String)
    }
    //Get client Name
    @objc func getClientName(){
        guard let room = EnxRN.sharedState.room else {
          return
        }
        guard room.clientName as String? != nil else{
         return;
        }
        self.emitEvent(event: "room:clientName", data:room.clientName! as String)
    }
    //
    @objc func isRoomActiveTalker(){
     guard let room = EnxRN.sharedState.room else {
        return
     }
      self.emitEvent(event: "room:isRoomActiveTalker", data:room.isRoomActiveTalker)
    }
    //Get room Zoom Factor
    @objc func setZoomFactor(_ value:CGFloat ,clientIds: [String]){
        guard let room = EnxRN.sharedState.room else {
              return
        }
        room.setZoomFactor(value, clientId: clientIds)
    }
    //Get User list
    @objc func getUserList(){
     guard let room = EnxRN.sharedState.room else {
       return
     }
        guard let userArray = room.getUserList() else{
          return
     }
     self.emitEvent(event: "room:getUserList", data:userArray)
    }
    //Extend Duration off confrence
    @objc func extendConferenceDuration(){
     guard let room = EnxRN.sharedState.room else {
      return
     }
     room.extendConferenceDuration()
    }
    //Room metadata
    @objc func getRoomMetadata(){
     guard let room = EnxRN.sharedState.room else {
        return
     }
        guard let metaData = room.roomMetadata else{
                 return
        }
        self.emitEvent(event: "room:getRoomMetadata", data:metaData)
    }
    //pin Users
    @objc func pinUsers(_ clientIds: [String]){
       guard let room = EnxRN.sharedState.room else {
        return
       }
      room.pinUsers(clientIds )
    }
    //Un Pin Users
    @objc func unpinUsers(_ clientIds: [String]){
      guard let room = EnxRN.sharedState.room else {
       return
      }
        room.unpinUsers(clientIds)
    }
    //Check stream local
    @objc func isLocal(_ streamId: String){
        var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
            stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
        self.emitEvent(event: "stream:isLocal", data:stream?.isLocal as Any)
    }
    //Check audio
    @objc func hasAudio(_ streamId: String){
        var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
            stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
        self.emitEvent(event: "stream:hasAudio", data:stream?.hasAudio() as Any)
    }
    
    @objc func hasData(_ streamId: String){
        var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
            stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
        self.emitEvent(event: "stream:hasData", data:stream?.hasData() as Any)
    }
    
    @objc func hasVideo(_ streamId: String){
        var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
            stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
        self.emitEvent(event: "stream:hasVideo", data:stream?.hasVideo() as Any)
    }
    
    @objc func hasScreen(_ streamId: String){
        var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
            stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
        self.emitEvent(event: "stream:hasScreen", data:stream?.screen as Any)
    }
    
    @objc func isAudioOnlyStream(_ streamId: String){
     var stream = EnxRN.sharedState.publishStreams[streamId]
      if(stream == nil){
        stream = EnxRN.sharedState.subscriberStreams[streamId]
      }
        self.emitEvent(event: "stream:isAudioOnlyStream", data:stream?.isAudioOnlyStream as Any)
    }
    @objc func getReasonForMuteVideo(_ streamId: String){
        var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
          stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
        self.emitEvent(event: "stream:getReasonForMuteVideo", data:stream?.reasonForMuteVideo as Any)
    }
    @objc func getMediaType(_ streamId: String){
     var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
          stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
        self.emitEvent(event: "stream:getMediaType", data:stream?.mediaType as Any)
    }
    
    @objc func getVideoAspectRatio(_ streamId: String){
        var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
          stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
      self.emitEvent(event: "stream:getVideoAspectRatio", data:stream?.videoAspectRatio as Any)
    }
    //To enable particular player stream stats.
    @objc func enablePlayerStats(_ value: Bool, _ streamId: String){
        var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
            stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
        guard stream?.enxPlayerView != nil else{
            return;
        }
        stream?.enxPlayerView?.delegate = self
        stream?.enxPlayerView?.enablePlayerStats(value)
    }
    //Set advance Option
    @objc func setAdvancedOptions(_ options: [Any] ){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.setAdvanceOptions(options)
    }
    //
    @objc func setConfigureOption(_ options: [String : Any], streamId: String){
        guard let stream = EnxRN.sharedState.subscriberStreams[streamId] else{
            return;
        }
        guard stream.enxPlayerView != nil else{
            return;
        }
        stream.enxPlayerView?.setConfigureOption(options)
    }
    //get list of advance Options
    @objc func getAdvancedOptions(){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        room.getAdvanceOptions()
    }
    //capture screen shot
    @objc func captureScreenShot(_ streamId: String){
        
        var stream = EnxRN.sharedState.publishStreams[streamId]
        if(stream == nil){
            stream = EnxRN.sharedState.subscriberStreams[streamId]
        }
        guard stream?.enxPlayerView != nil else{
            return;
        }
         DispatchQueue.main.async {
            stream?.enxPlayerView?.delegate = self
            stream?.enxPlayerView?.captureScreenShot()
        }
    }
    //Disconnect from room
    @objc func disconnect(){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        DispatchQueue.main.async {
           room.disconnect()
        }
    }
    @objc func setNativeEvents(_ events: [String]) -> Void {
        for event in events {
            if (!self.jsEvents.contains(event)) {
                self.jsEvents.append(event);
            }
        }
    }
    @objc func removeNativeEvents(_ events: [String]) -> Void {
        for event in events {
            if let i = self.jsEvents.firstIndex(of: event) {
                self.jsEvents.remove(at: i)
            }
        }
    }

    @objc func setJSComponentEvents(_ events: [String]) -> Void {
        for event in events {
            self.componentEvents.append(event);
        }
    }
    @objc func removeJSComponentEvents(_ events: [String]) -> Void {
        for event in events {
            if let i = self.componentEvents.firstIndex(of: event) {
                self.componentEvents.remove(at: i)
            }
        }
    }
//Knock-knock
  @objc func approveAwaitedUser(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if clientId.count > 0{
            room.approveAwaitedUser(clientId)
        }
    }
     @objc func denyAwaitedUser(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if clientId.count > 0{
            room.denyAwaitedUser(clientId)
        }
    }
    // method to subcribe tlker notification
   @objc func subscribeForTalkerNotification(_ flag: Bool){
        guard let room = EnxRN.sharedState.room else {
          return
        }
        room.subscribe(forTalkerNotification: flag)
    }
    // methods to handle breakout room
    @objc func createBreakOutRoom(_ data: [String : Any]){
      guard let room = EnxRN.sharedState.room else {
          return
        }
         room.createBreakOutRoom(data)
    }

    @objc func createAndInviteBreakoutRoom(_ data: [String : Any]){
      guard let room = EnxRN.sharedState.room else {
          return
        }
         room.createAndInviteBreakoutRoom(data)
    }

    @objc func joinBreakOutRoom(_ data: [String :Any],streamInfo: [String : Any]){
      guard let room = EnxRN.sharedState.room else {
          return
        }
        room.joinBreakOutRoom(data, withStreamInfo: streamInfo )
    }
    @objc func inviteToBreakOutRoom(_ data: [String :Any]){
      guard let room = EnxRN.sharedState.room else {
          return
        }
         room.invite(toBreakOutRoom: data)
    }
    @objc func pause(){
      guard let room = EnxRN.sharedState.room else {
          return
        }
         room.pause()
    }
    @objc func resume(){
      guard let room = EnxRN.sharedState.room else {
          return
        }
         room.resume()
    }
    @objc func muteRoom(_ data: [String:Any]){
      guard let room = EnxRN.sharedState.room else {
          return
        }
         room.muteRoom(data)
    }

    @objc func unmuteRoom(_ data: [String:Any]){
      guard let room = EnxRN.sharedState.room else {
          return
        }
         room.unmuteRoom(data)
    }


@objc func rejectBreakOutRoom(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if clientId.count > 0{
            room.rejectBreakOutRoom(clientId)
        }
    }

    // methods to handle precall test
    @objc func clientDiagnostics(_ opt: [String :Any]){
        self.emitEvent(event: "room:didEventError", data:["msg":"Not supported","errorCode":0000 ])
    }
     @objc func addSpotlightUsers(_ clientIds: [String]){
       guard let room = EnxRN.sharedState.room else {
        return
       }
      room.addSpotlightUsers(clientIds)
    }
    
    @objc func removeSpotlightUsers(_ clientIds: [String]){
      guard let room = EnxRN.sharedState.room else {
       return
      }
        room.removeSpotlightUsers(clientIds)
    }
    @objc func switchRoomMode(_ roomMode: String){
        guard let room = EnxRN.sharedState.room else{
            return
        }
        if roomMode.count > 0{
            room.switchRoomMode(roomMode)
        }
    }
    // Live Recording
    @objc func startLiveRecording(_ data: [String : Any]){
        guard let room = EnxRN.sharedState.room else{
            return}
        room.startLiveRecording(data)
    }
    @objc func stopLiveRecording(_ data: [String:Any]){
        guard let room = EnxRN.sharedState.room else{
            return}
        room.stopLiveRecording()
    }

 // Live Streaming
    @objc func startStreaming(_ data: [String : Any]){
        guard let room = EnxRN.sharedState.room else{
            return}
        room.startStreaming(data)
    }
    @objc func stopStreaming(_ data: [String:Any]){
        guard let room = EnxRN.sharedState.room else{
            return}
        room.stopStreaming(data)
    }

    // hardmute user Audio using room
    @objc func hardMuteUserAudio(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return}
        room.hardMuteUserAudio(clientId)
    }
    @objc func hardUnmuteUserAudio(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return}
        room.hardUnmuteUserAudio(clientId)
    }
    // hardmute user Audio using Video
    @objc func hardMuteUserVideo(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return}
        room.hardMuteUserVideo(clientId)
    }
    @objc func hardUnmuteUserVideo(_ clientId: String){
        guard let room = EnxRN.sharedState.room else{
            return}
        room.hardUnmuteUserVideo(clientId)
    }
//Live Transcription
    //Enable/Desiable Live Transcription
    @objc func subscribeForLiveTranscription(_ enable : Bool){
        guard let room = EnxRN.sharedState.room else {
           return
        }
        room.subscribe(forLiveTranscription: enable)
    }
     //start live transcriptions
    @objc func startLiveTranscriptionForRoom(_ languge : String){
       guard let room = EnxRN.sharedState.room else {
          return
       }
        room.startLiveTranscription(forRoom: languge)
    }
 //Stop Live Transcriptions
    @objc func stopLiveTranscription(){
       guard let room = EnxRN.sharedState.room else {
          return
       }
        room.stopLiveTranscription()
    }

//Share Privacy
//Share Privacy
    @objc func requestSharePermission(_ pubType : String){
           guard let room = EnxRN.sharedState.room else {
              return
           }
            var pType : EnxPubType!
            if pubType.caseInsensitiveCompare("screen") == .orderedSame{
                pType = .Screen
            }
            else{
                pType = .Canvas
            }
            room.requestSharePermission(pType)
    }

    @objc func cancelSharePermission(_ pubType : String){
           guard let room = EnxRN.sharedState.room else {
              return
           }
        var pType : EnxPubType!
        if pubType.caseInsensitiveCompare("screen") == .orderedSame{
            pType = .Screen
        }
        else{
            pType = .Canvas
        }
            room.cancelSharePermission(pType)
        }
    @objc func setSharePermissionMode(_ pubType : String, pubMode:String){
           guard let room = EnxRN.sharedState.room else {
              return
           }
        
        var pType : EnxPubType!
        if pubType.caseInsensitiveCompare("screen") == .orderedSame{
            pType = .Screen
        }
        else{
            pType = .Canvas
        }
        
        var pMode : EnxPubMode!
        if pubMode.caseInsensitiveCompare("all") == .orderedSame{
            pMode = .All
        }
        else if pubMode.caseInsensitiveCompare("authorize") == .orderedSame{
            pMode = .Authorize
        } else{
            pMode = .Moderators
        }
        room.setSharePermissionMode(pType,withmode: pMode)
        }
    
    @objc func grantSharePermission(_ pubType : String,requesterId:String){
           guard let room = EnxRN.sharedState.room else {
              return
           }
        var pType : EnxPubType!
        if pubType.caseInsensitiveCompare("screen") == .orderedSame{
            pType = .Screen
        }
        else{
            pType = .Canvas
        }
        
        room.grantSharePermission(pType,requestyId: requesterId)
        }
        @objc func denySharePermission(_ pubType : String,requesterId:String){
           guard let room = EnxRN.sharedState.room else {
              return
           }
            var pType : EnxPubType!
            if pubType.caseInsensitiveCompare("screen") == .orderedSame{
                pType = .Screen
            }
            else{
                pType = .Canvas
            }
            room.denySharePermission(pType,requestyId: requesterId)
        }
        @objc func releaseSharePermission(_ pubType : String,requesterId:String){
           guard let room = EnxRN.sharedState.room else {
              return
           }
            var pType : EnxPubType!
            if pubType.caseInsensitiveCompare("screen") == .orderedSame{
                pType = .Screen
            }
            else{
                pType = .Canvas
            }
            room.releaseSharePermission(pType,requestyId: requesterId)
        }
        @objc func getSharePermissions(){
           guard let room = EnxRN.sharedState.room else {
              return
           }
            guard room.getSharePermissions().count > 0 else {
                return
            }
            self.emitEvent(event: "room:getSharePermissions", data:room.getSharePermissions())
        }
      @objc func saveCustomData(_ dataOption: [String :Any], withData data: [String : Any]){
        guard let room = EnxRN.sharedState.room else {
            return
        }
           var options = dataOption
           options["scope"] = getScope(options["scope"] as! String)
           room.saveCustomData(options, withData: data)
    }
      @objc func getCustomData(_ data: [String :Any]){
      guard let room = EnxRN.sharedState.room else {
          return
        }
         room.getCustomData(data)
    }
     @objc func setCustomData(_ dataOption: [String :Any], withData data: [String : Any]){
      guard let room = EnxRN.sharedState.room else {
          return
      }
         var options = dataOption
         options["scope"] = getScope(options["scope"] as! String)
         room.setCustomData(options, withData: data)
    }
    func getScope(_ scope : String) -> EnxCustomDataScope{
        return (scope == "session") ? .session : (scope == "owner")  ? .owner : (scope == "room") ? .room : .user
    }
    func emitEvent(event : String , data: Any) -> Void {
        if (self.jsEvents.contains(event) || self.componentEvents.contains(event)) {
            self.sendEvent(withName: event, body: data);
        }
    }
}

extension EnxRoomManager : EnxRoomDelegate{
    func getSupportedEvents() -> [String] {
        return ["room:didActiveTalkerList","room:didScreenSharedStarted","room:didScreenShareStopped","room:didCanvasStarted","room:didCanvasStopped","room:didRoomRecordStart","room:didRoomRecordStop","room:didFloorRequested","room:didFloorCancelled","room:didFloorFinished","room:didLogUpload","room:didSetTalkerCount","room:didGetMaxTalkers","room:didGetTalkerCount","room:userDidConnected","room:userDidDisconnected","room:didHardUnMuteAllUser","room:didHardMutedAll","room:didUnMutedAllUser","room:didMutedAllUser","room:didProcessFloorRequested","room:didFloorRequestReceived","room:didReleasedFloorRequest","room:didCancelledFloorRequest","room:didInviteToFloorRequested","room:didACKInviteToFloorRequested","room:didInvitedForFloorAccess","room:didCanceledFloorInvite","room:didRejectedInviteFloor","room:didAcceptedFloorInvite","room:didFinishedFloorRequest","room:didDeniedFloorRequest","room:didGrantedFloorRequest","room:didStopRecordingEvent","room:didStartRecordingEvent","room:didSubscribedStream","room:didRoomDisconnect","room:didStreamAdded","room:didEventError","room:didError","room:didPublishedStream","room:didNotifyDeviceUpdate","room:didStatsReceive","room:didAcknowledgeStats","room:didBandWidthUpdated","room:didShareStreamEvent","room:didRoomConnected","room:didReconnect","room:didUserReconnectSuccess","room:didConnectionInterrupted","room:didConnectionLost","room:didCanvasStreamEvent","room:didAdvanceOptionsUpdate","room:didGetAdvanceOptions","room:didCapturedView","room:didMessageReceived","room:didUserDataReceived","room:didAcknowledgSendData","room:didSwitchUserRole","room:didFileUploaded","room:didFileAvailable","room:didFileUploadStarted","room:didInitFileUpload","room:didFileUploadFailed","didFileDownloaded","room:didFileDownloadFailed","room:didAvailableFiles","room:didFileUploadCancelled","room:didInitFileDownload","room:didFileDownloadCancelled","room:whoAmI","room:didLockRoom","room:didUnlockRoom","room:didAckLockRoom","room:didAckUnlockRoom","room:didOutBoundCallInitiated","room:didDialStateEvents","room:didDialStateWithInfo","room:didDTMFCollected","room:didOutBoundCallSendDtmf","room:didAckDropUser","room:didAckDestroy","room:getReceiveVideoQuality","room:didAnnotationStarted","room:didStartAnnotationACK","room:didAnnotationStopped","room:didStoppedAnnotationACK","room:getRole","room:getClientId","room:getRoomId","room:clientName","room:getUserList","room:didConferencessExtended","room:didConferenceRemainingDuration","room:getRoomMetadata","room:didACKAddPinUser","room:didACKRemovePinUser","room:didpinnedUsers","room:didRoomAwated","room:didAckForApproveAwaitedUser","room:didAckForDenyAwaitedUser","room:diduserAwaited","room:didRoomBandwidthAlert","room:didAckSubscribeTalkerNotification","room:didAckUnsubscribeTalkerNotification","room:didTalkerNotification","room:didAckCreateBreakOutRoom","room:didAckCreateAndInviteBreakOutRoom","room:didAckInviteBreakOutRoom","room:didAckPause","room:didAckResume","room:didAckMuteRoom","room:didAckUnmuteRoom","room:didFailedJoinBreakOutRoom","room:didConnectedBreakoutRoom","room:didDisconnectedBreakoutRoom","room:didUserJoinedBreakoutRoom","room:didInvitationForBreakoutRoom","room:didDestroyedBreakoutRoom","room:didUserDisconnectedFromBreakoutRoom","room:didAckRejectBreakoutRoom","room:didBreakoutRoomCreated","room:didBreakoutRoomInvited","room:didBreakoutRoomInviteRejected","room:didAckAddSpotlightUsers","room:didAckRemoveSpotlightUsers","room:didUpdatedSpotlightUsers","room:didAckSwitchedRoom","room:didRoomModeSwitched","room:didACKStartLiveRecording","room:didACKStopLiveRecording","room:didLiveRecordingNotification","room:didRoomliverecordOn","room:didOutBoundCallCancel","room:didAckHardMuteUserAudio","room:didAckHardunMuteUserAudio","room:didAckHardMuteUserVideo","room:didAckHardUnMuteUserVideo","room:didStopAllSharingACK","room:didBreakoutroomjoining","room:didUserPaused","room:didUserResumed","room:didACKStartLiveTranscription","room:didACKStopLiveTranscription","room:didACKSubscribeForLiveTranscription","room:didTranscriptionEvents","room:didRoomTranscriptionOn","room:didRoomTranscriptionOff","room:didSelfTranscriptionOn","room:didSelfTranscriptionOff","room:didACKSetSharePermissionMode","room:didACKGrantSharePermission","room:didACKDenySharePermission","room:didACKReleaseSharePermission","room:didACKRequestSharePermission","room:didACKCancelSharePermission","room:didSharePermissionsModeChanged","room:didSharePermissionRequested","room:didSharePermissionReleased","room:didSharePermissionDeny","room:didSharePermissionCancled","room:didSharePermissionGranted","room:getSharePermissions","room:didHlsStarted","room:didHlsStopped","room:didHlsFailed","room:didHlsWaiting","room:didAckStartStreaming","room:didAckStopStreaming","room:didStreamingStarted","room:didStreamingStopped","room:didStreamingFailed","room:didStreamingUpdated","stream:didAudioEvent","stream:didVideoEvent","stream:didhardMuteAudio","stream:didhardUnmuteAudio","stream:didRemoteStreamAudioMute","stream:didRemoteStreamAudioUnMute","stream:didRemoteStreamVideoMute","stream:didRecievedHardMutedAudio","stream:didRecievedHardUnmutedAudio","stream:didRemoteStreamVideoUnMute","stream:didHardVideoMute","stream:didHardVideoUnMute","stream:didReceivehardMuteVideo","stream:didRecivehardUnmuteVideo","stream:didReceiveData","stream:didPlayerStats","stream:isLocal","stream:hasScreen","stream:hasAudio","stream:hasVideo","stream:hasData","stream:isAudioOnlyStream","stream:getMediaType","stream:getVideoAspectRatio"];
    }
    func room(_ room: EnxRoom?, didConnect roomMetadata: [String : Any]?) {
        EnxRN.sharedState.room = room
        self.emitEvent(event: "room:didRoomConnected", data: roomMetadata as Any)
        
    }
    func room(_ room: EnxRoom?, didError reason: [Any]?) {
        guard let errorVal = reason else{
            return
        }
        self.emitEvent(event: "room:didError", data: errorVal)
    }
    
    func room(_ room: EnxRoom?, didEventError reason: [Any]?) {
        guard let resDict = reason?[0] as? [String : Any], reason!.count > 0 else{
            return
        }
        self.emitEvent(event: "room:didEventError", data:resDict)
    }
    
    func room(_ room: EnxRoom?, didReconnect reason: String?) {
        guard let reasonString = reason else {
            return
        }
        self.emitEvent(event: "room:didReconnect", data:reasonString)
    }
    
    func room(_ room: EnxRoom?, didUserReconnectSuccess data: [String : Any]?) {
        
        self.emitEvent(event: "room:didUserReconnectSuccess", data:data!)
    }
    
    func room(_ room: EnxRoom?, didConnectionInterrupted data: [Any]?) {
        guard let dataDict = data![0] as? [String : Any], data!.count > 0 else{
            return
        }
        self.emitEvent(event: "room:didConnectionInterrupted", data:dataDict)
    }
    
    func room(_ room: EnxRoom?, didConnectionLost data: [Any]?) {
        guard let dataDict = data![0] as? [String : Any], data!.count > 0 else{
            return
        }
        self.emitEvent(event: "room:didConnectionLost", data:dataDict)
    }
    
    func room(_ room: EnxRoom?, didPublishStream stream: EnxStream?) {
        if(localStreamId == nil){
            localStreamId = ""
        }
        let resultDict : [String : Any] = ["result" : 0 ,"message" : "Stream has been published." ,"streamId" :localStreamId!]
        
        self.emitEvent(event: "room:didPublishedStream", data: resultDict)
    }
    
    func room(_ room: EnxRoom?, didAddedStream stream: EnxStream?) {
        
        guard stream != nil else{
            return
        }
        EnxRN.sharedState.subscriberStreams.updateValue(stream!, forKey: stream!.streamId!)
        let resultDict : [String : Any] = ["streamId" : stream!.streamId! ,"hasData" : stream!.hasData()   ,"hasScreen" :stream!.screen]
        self.emitEvent(event: "room:didStreamAdded", data: resultDict)
    }
    
    func room(_ room: EnxRoom?, didRemovedStream stream: EnxStream?) {
        guard stream != nil else{
            return
        }
        guard let subscribeStream = EnxRN.sharedState.subscriberStreams[(stream?.streamId)!] else {
            return
        }
        let resultDict : NSDictionary = ["streamId" : subscribeStream.streamId as Any,"msg": "Stream has removed."]
        self.emitEvent(event: "room:didRemoveStream", data: resultDict)
         EnxRN.sharedState.subscriberStreams.removeValue(forKey: subscribeStream.streamId!)

    }
    
    func room(_ room: EnxRoom?, didSubscribeStream stream: EnxStream?) {
        guard let player = EnxRN.sharedState.players[(stream?.streamId)!] else {
            return
        }
        stream?.attachRenderer(player)
        self.emitEvent(event: "room:didSubscribedStream", data: "")
    }
    
    func room(_ room: EnxRoom?, didActiveTalkerList Data: [EnxStream]?) {
        var activeStreamArray: [Any] = [];
        for (_,active) in (Data?.enumerated())! {
            let stream = active
            let shareDict : NSDictionary = ["streamId" : stream.streamId! ,"name": stream.name!,"clientId": stream.clientId!]
            activeStreamArray.append(shareDict)
            let remoteStreamDict = EnxRN.sharedState.room!.streamsByStreamId
                if let  remoteStream = remoteStreamDict[stream.streamId!]{
                    if let player = EnxRN.sharedState.players[stream.streamId!]{
                        remoteStream.attachRenderer(player)
                    }
                }
        }
         self.emitEvent(event: "room:didActiveTalkerList", data: activeStreamArray)
    }
    //Screen Share Delegates
    func room(_ room: EnxRoom?, didScreenShareStarted stream: EnxStream?) {
        let shareDict : [String : Any] = ["streamId" : stream!.streamId!,"name": stream!.name!,"clientId": stream!.clientId!,"result":0]
        self.emitEvent(event: "room:didScreenSharedStarted", data:shareDict)
        let streamId = stream!.streamId!
        guard let shareStream = EnxRN.sharedState.room!.streamsByStreamId[streamId] else{
            return
        }
        guard let player = EnxRN.sharedState.players[streamId] else{
            return
        }
        shareStream.attachRenderer(player)
    }
    
    func room(_ room: EnxRoom?, didScreenShareStopped stream: EnxStream?) {
        let streamId = stream!.streamId!
        guard EnxRN.sharedState.players[streamId] != nil else{
            return
        }
        EnxRN.sharedState.players.removeValue(forKey: streamId)
        let shareDict : NSDictionary = ["streamId" : stream!.streamId as Any,"name": stream!.name!,"clientId": stream!.clientId!,"result":0]
        self.emitEvent(event: "room:didScreenShareStopped", data: shareDict)
    }
    
    /*
    //Screen Share Delegates
    func room(_ room: EnxRoom?, screenSharedStarted Data: [Any]?) {
        guard let shareDict = Data?[0] as? [String : Any], Data!.count > 0 else{
            return
        }
        self.emitEvent(event: "room:didScreenSharedStarted", data:shareDict)
        let streamId = String (shareDict["streamId"] as! Int)
        guard let shareStream = EnxRN.sharedState.room!.streamsByStreamId![streamId] as? EnxStream else{
            return
        }
        guard let player = EnxRN.sharedState.players[streamId] else{
            return
        }
        shareStream.attachRenderer(player)
        
    }
    
    func room(_ room: EnxRoom?, screenShareStopped Data: [Any]?) {
        guard let shareDict = Data?[0] as? [String : Any], Data!.count > 0 else{
            return
        }
        let streamId = String (shareDict["streamId"] as! Int)
        guard EnxRN.sharedState.players[streamId] != nil else{
            return
        }
        EnxRN.sharedState.players.removeValue(forKey: streamId)
        self.emitEvent(event: "room:didScreenShareStopped", data: shareDict)
    }
     */
    
     //Canvas Delegates
    func room(_ room: EnxRoom?, didCanvasStarted stream: EnxStream?) {
        let canvasDict : NSDictionary = ["streamId" : stream!.streamId as Any,"name": stream!.name!,"clientId": stream!.clientId!,"result":0]
        self.emitEvent(event: "room:didCanvasStarted", data:canvasDict)
        let streamId = stream!.streamId!
        guard let canvasStream = EnxRN.sharedState.room!.streamsByStreamId[streamId] else{
            return
        }
        guard let player = EnxRN.sharedState.players[streamId] else{
            return
        }
        canvasStream.attachRenderer(player)
    }
    
    func room(_ room: EnxRoom?, didCanvasStopped stream: EnxStream?) {
        let streamId = stream!.streamId!
        guard EnxRN.sharedState.players[streamId] != nil else{
            return
        }
        EnxRN.sharedState.players.removeValue(forKey: streamId)
        let canvasDict : NSDictionary = ["streamId" : stream!.streamId as Any,"name": stream!.name!,"clientId": stream!.clientId!,"result":0]
        self.emitEvent(event: "room:didCanvasStopped", data: canvasDict)
    }
    
    func didRoomDisconnect(_ response: [Any]?) {
     self.emitEvent(event: "room:didRoomDisconnect", data: response as Any)
    }
    
    /* Recording Delegate */
    /* This delegate called when recording started by the moderator. */
    func startRecordingEvent(_ response: [Any]?) {
        guard let responseDict = response?[0] as? [String : Any], response!.count > 0 else{
            return
        }
        self.emitEvent(event: "room:didStartRecordingEvent", data: responseDict)
    }
    /* This delegate called when recording stopped by the moderator. */
    func stopRecordingEvent(_ response: [Any]?) {
        guard let responseDict = response?[0] as? [String : Any], response!.count > 0 else{
            return
        }
        self.emitEvent(event: "room:didStopRecordingEvent", data: responseDict)
    }
    /* When recording is started in the room, (either implicitly or explicitly), all connected users are notified that room is being recorded.(For Participant) */
    func roomRecord(on Data: [Any]?) {
        guard let responseDict = Data?[0] as? [String : Any], Data!.count > 0 else{
            return
        }
        self.emitEvent(event: "room:didRoomRecordStart", data: responseDict)
    }
    
    /* When the recording is turned off (either implicitly or explicitly), all connected users are notified that recording has been stopped in the room.(For Participant) */
    func roomRecordOff(_ Data: [Any]?) {
        guard let responseDict = Data?[0] as? [String : Any], Data!.count > 0 else{
            return
        }
        self.emitEvent(event: "room:didRoomRecordStop", data: responseDict)
    }
    
    /* Chair control Delegates */
    //Participant receives on the success of requestFloor. This is for participant only.
    func didFloorRequested(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didFloorRequested", data: dataDict)
    }
    
    /* Participant receives when the moderator performs action grantFloor. */
    func didGrantedFloorRequest(_ Data: [Any]?) {
      guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didGrantedFloorRequest", data: dataDict)
    }
   
    /* Participant receives when the moderator performs action denyFloor. */
    func didDeniedFloorRequest(_ Data: [Any]?) {
       guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didDeniedFloorRequest", data: dataDict)
    }
    
    
    /* Participant receives when the moderator performs action releaseFloor. */
    func didReleasedFloorRequest(_ Data: [Any]?) {
      guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didReleasedFloorRequest", data: dataDict)
    }
    
    /* Moderator receives any Floor Request raised by the participant. This is for Moderator only. */
    func didFloorRequestReceived(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didFloorRequestReceived", data: dataDict)
    }
    
    /* Moderator receives acknowledgment on performing actions like grantFloor, denyFloor, releaseFloor. */
    func didProcessFloorRequested(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didProcessFloorRequested", data: dataDict)
    }
    

 /*
 This is an acknowledgment method for the inviteToFloor to the moderator.
 */
    func didACKInvite(toFloorRequested Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didACKInviteToFloorRequested", data: dataDict)
    }
   /*
 This event method will notify to all moderator in the same session (including the owner of the event), that invitation received by participant
 **/
    func didInvite(toFloorRequested Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didInviteToFloorRequested", data: dataDict)
    }
    
 /*
 This delegate method for Participant , How or she will receive handover floor access.
 */
    func didInvited(forFloorAccess Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didInvitedForFloorAccess", data: dataDict)
    }

   /*
 This is an event method for the all  moderator including owner of the API and participant which has received handover floor request .
 */
    func didCanceledFloorInvite(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didCanceledFloorInvite", data: dataDict)
    }

    /*
 This is an event method for the all  moderator including owner of the API and participant which has received handover floor request .
 */
    func didRejectedInviteFloor(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didRejectedInviteFloor", data: dataDict)
    }

    
/*
 This is an event method for the all  moderator including owner of the API and invitee participant,  once invitee has accept the invite floor  .
 */
    func didAcceptedFloorInvite(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didAcceptedFloorInvite", data: dataDict)
    }


    /*
       This delegate method will notify to all available moderator, Once any participant has finished there floor request
    */
   func didFinishedFloorRequest(_ Data: [Any]?) {
     guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
           return
       }
       self.emitEvent(event: "room:didFinishedFloorRequest", data: dataDict)
   }
    
    /*
    This ACK method for Participant , When he/she will finished their request floor after request floor accepted by any moderator */
   func didFloorFinished(_ Data: [Any]?) {
    guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
          return
       }
       self.emitEvent(event: "room:didFloorFinished", data: dataDict)
   }
    
    /*
       This delegate method will notify to all available moderator, Once any participant has canceled there floor request
    */
   func didCancelledFloorRequest(_ Data: [Any]?) {
    guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
           return
        }
        self.emitEvent(event: "room:didCancelledFloorRequest", data: dataDict)
   }
    
    /*
    This ACK method for Participant , When he/she will cancel their request floor*/
   func didFloorCancelled(_ Data: [Any]?) {
    guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
           return
        }
        self.emitEvent(event: "room:didFloorCancelled", data: dataDict)
    }

    
    //Room mute Delegates
    /* This delegate called when the room is muted by the moderator. Available to Moderator only. */
    func didhardMute(_ Data: [Any]?) {
    guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didMutedAllUser", data: dataDict)
    }
    
    /* This delegate called when the room is unmuted by the moderator. Available to Moderator only. */
    func didhardUnMute(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didUnMutedAllUser", data: dataDict)
        
    }
    
    /* Participants notified when room is muted by any moderator. */
    func didHardMuteRecived(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didHardMutedAll", data: dataDict)
    }
    
    /*  */
    func didHardunMuteRecived(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didHardUnMuteAllUser", data: dataDict)
    }
    
    /* This delegate called when a user is connected to a room, all other connected users are notified about the new user. */
    func room(_ room: EnxRoom?, userDidJoined Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:userDidConnected", data: dataDict)
    }
    
    /* When a user is disconnected from a room, all other connected users are notified about the users exit. */
    func room(_ room: EnxRoom?, userDidDisconnected Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:userDidDisconnected", data: dataDict)
    }
    
    //logs upload delegate
    func didLogUpload(_ data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didLogUpload", data: dataDict)
    }
    
    
    //Set and Get Active talker Delegates.
    /* Client endpoint receives when the user set number of active talker. */
    func room(_ room: EnxRoom?, didSetTalkerCount Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didSetTalkerCount", data: dataDict)
    }
    
    /* Client endpoint will get the maximum number of allowed Active Talkers in the connected room. */
    func room(_ room: EnxRoom?, didGetMaxTalkers Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didGetMaxTalkers", data: dataDict)
    }
    
    /* Client endpoint receives when the user request to get opted active talker streams set by them. */
    func room(_ room: EnxRoom?, didGetTalkerCount Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "room:didGetTalkerCount", data: dataDict)
    }
    
    /**
     This delegate Method Will Notify app user for any Audio media changes happen recentaly(Like :- New device connected/Doisconnected).
     */
    func didNotifyDeviceUpdate(_ updates: String) {
        self.emitEvent(event: "room:didNotifyDeviceUpdate", data: updates)
      
    }
    
    /*
     This method will update once stats enable and update to app user for stats
     @param statsData has all stats information.
     */
    func didStatsReceive(_ statsData: [Any]) {
        self.emitEvent(event: "room:didStatsReceive", data: statsData)
    }
    
    func didAcknowledgeStats(_ subUnSubResponse: [Any]?) {
        self.emitEvent(event: "room:didAcknowledgeStats", data: subUnSubResponse!)
    }
    
    //ABWD delegates
    func room(_ room: EnxRoom?, didBandWidthUpdated data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didBandWidthUpdated", data: Data)
    }
    
    func room(_ room: EnxRoom?, didCanvasStreamEvent data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didCanvasStreamEvent", data: Data)
    }
    
    func room(_ room: EnxRoom?, didShareStreamEvent data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didShareStreamEvent", data: Data)
    }
    
    func room(_ room: EnxRoom, didMessageReceived data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didMessageReceived", data: Data)
    }
    
    func room(_ room: EnxRoom, didUserDataReceived data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didUserDataReceived", data: Data)
    }
    
    func room(_ room: EnxRoom?, didAcknowledgSendData data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didAcknowledgSendData", data: Data)
    }
    
    func room(_ room: EnxRoom?, didAdvanceOptionsUpdate data: [AnyHashable : Any]? = nil) {
        self.emitEvent(event: "room:didAdvanceOptionsUpdate", data: data as Any)

    }
    
    func room(_ room: EnxRoom?, didGetAdvanceOptions data: [Any]?) {
        if(data!.count > 0){
            print(data![0])
            self.emitEvent(event: "room:didGetAdvanceOptions", data: data![0] )
            
        }
    }
    
    func room(_ room: EnxRoom?, didSwitchUserRole data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didSwitchUserRole", data: Data)
    }
    
    func room(_ room: EnxRoom?, didUserRoleChanged data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didUserRoleChanged", data: Data)
    }
    
    /*
     This delegate method called When any of the user in same room will start sharing file.
     */
    func room(_ room: EnxRoom, didFileUploadStarted data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didFileUploadStarted", data: Data)
    }
    
    /*
     This delegate method called When self user will start sharing file.
     */
    func room(_ room: EnxRoom, didInitFileUpload data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didInitFileUpload", data: Data)
    }
    
    /*
     This delegate method called When File available to download.
     */
    func room(_ room: EnxRoom, didFileAvailable data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didFileAvailable", data: Data)
    }
    
    /*
     This delegate method called upload file is success.
     */
    func room(_ room: EnxRoom, didFileUploaded data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didFileUploaded", data: Data)
    }
   
    /*
     This delegate method called upload file is failed.
     */
    func room(_ room: EnxRoom, didFileUploadFailed data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didFileUploadFailed", data: Data)
    }
    
    /*
     This delegate method called When download of file success.
     */
    func room(_ room: EnxRoom, didFileDownloaded data: String?) {
//        guard let data == nil else {
//            return
//        }
        self.emitEvent(event: "room:didFileDownloaded", data: data!)
    }
    
    /*
     This delegate method called When file download failed.
     */
    func room(_ room: EnxRoom, didFileDownloadFailed data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didFileDownloadFailed", data: Data)
    }
    
    func room(_ room: EnxRoom, didFileUploadCancelled data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didFileUploadCancelled", data: Data)
    }
    
    func room(_ room: EnxRoom, didFileDownloadCancelled data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didFileDownloadCancelled", data: Data)
    }
    
    func room(_ room: EnxRoom, didInitFileDownload data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didInitFileDownload", data: Data)
    }
    
    func room(_ room: EnxRoom?, didLockRoom data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didLockRoom", data: Data)
    }
    
    func room(_ room: EnxRoom?, didUnlockRoom data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didUnlockRoom", data: Data)
    }
    
    func room(_ room: EnxRoom?, didAckLockRoom data: [Any]?) {
       guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didAckLockRoom", data: Data)
    }
    
    func room(_ room: EnxRoom?, didAckUnlockRoom data: [Any]?) {
       guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didAckUnlockRoom", data: Data)
    }
    
    func room(_ room: EnxRoom?, didOutBoundCallInitiated data: [Any]?)
    {
        guard let Data = data?[0] as? [String : Any] else {
            return
        }
        self.emitEvent(event: "room:didOutBoundCallInitiated", data: Data)
    }
    
    func room(_ room: EnxRoom?, didDialStateEvents state: EnxOutBoundCallState) {
        var eventState = "Initiated"
        if(state == .Ringing){
            eventState = "Ringing"
        }else if(state == .Connected){
            eventState = "Connected"
        }else if(state == .Failed){
            eventState = "Failed"
        }else if(state == .Disconnected){
            eventState = "Disconnected"
        }else if(state == .Timeout){
            eventState = "Timeout"
        }
      self.emitEvent(event: "room:didDialStateEvents", data: eventState)
    }

     func didDialStateEvents(_ data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
                return
            }
          self.emitEvent(event: "room:didDialStateWithInfo", data: Data)
    }

    func room(_ room: EnxRoom?, didDTMFCollected data: String?) {
        self.emitEvent(event: "room:didDTMFCollected", data: data ?? "")
    }
     func room(_ room: EnxRoom?, didOutBoundCallSendDtmf data: [Any]?) {
         guard let Data = data?[0] as? [String : Any] else {
        return
      }
        self.emitEvent(event: "room:didOutBoundCallSendDtmf", data: Data )
    }
    
    func room(_ room: EnxRoom?, didAckDropUser data: [Any]?) {
     guard let Data = data?[0] as? [String : Any] else {
        return
      }
      self.emitEvent(event: "room:didAckDropUser", data: Data)
    }
    
    func room(_ room: EnxRoom?, didAckDestroy data: [Any]?) {
     guard let Data = data?[0] as? [String : Any] else {
          return
     }
      self.emitEvent(event: "room:didAckDestroy", data: Data)
    }
    
    
    func room(_ room: EnxRoom?, didAnnotationStarted stream: EnxStream?) {
        let shareDict : [String : Any] = ["streamId" : stream!.streamId!,"name": stream!.name!,"clientId": stream!.clientId!,"result":0]
      self.emitEvent(event: "room:didAnnotationStarted", data: shareDict)
    }
    
    func room(_ room: EnxRoom?, didStartAnnotationACK Data: [Any]?) {
     guard let data = Data?[0] as? [String : Any] else {
       return
     }
     self.emitEvent(event: "room:didStartAnnotationACK", data: data)
    }
    
    func room(_ room: EnxRoom?, didAnnotationStopped stream: EnxStream?) {
        let shareDict : [String : Any] = ["streamId" : stream!.streamId!,"name": stream!.name!,"clientId": stream!.clientId!,"result":0]
      self.emitEvent(event: "room:didAnnotationStopped", data: shareDict)
    }
    
    func room(_ room: EnxRoom?, didStoppedAnnotationACK Data: [Any]?) {
      guard let data = Data?[0] as? [String : Any] else {
        return
      }
      self.emitEvent(event: "room:didStoppedAnnotationACK", data: data)
    }
    
    func room(_ room: EnxRoom?, didConferencessExtended data: [Any]?) {
     guard let Data = data?[0] as? [String : Any] else {
        return
     }
    self.emitEvent(event: "room:didConferencessExtended", data: Data)
    }
    
    func room(_ room: EnxRoom?, didConferenceRemainingDuration data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
            return
         }
        self.emitEvent(event: "room:didConferenceRemainingDuration", data: Data)
    }
    
    func room(_ channel: EnxRoom?, didACKAddPinUser data: [Any]?) {
     guard let Data = data?[0] as? [String : Any] else {
        return
     }
     self.emitEvent(event: "room:didACKAddPinUser", data: Data)
    }
    
    func room(_ channel: EnxRoom?, didACKRemovePinUser data: [Any]?) {
     guard let Data = data?[0] as? [String : Any] else {
        return
     }
     self.emitEvent(event: "room:didACKRemovePinUser", data: Data)
    }
    
    func room(_ channel: EnxRoom?, didpinnedUsers data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didpinnedUsers", data: Data)
    }


//Knock-Knock Room /wait for moderator
 func room(_ channel: EnxRoom?, didRoomAwated data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didRoomAwated", data: Data)
    
    }

    func room(_ channel: EnxRoom?, didAckForApproveAwaitedUser data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didAckForApproveAwaitedUser", data: Data)
    }
    
    func room(_ channel: EnxRoom?, didAckForDenyAwaitedUser data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didAckForDenyAwaitedUser", data: Data)
    }
    
    func room(_ channel: EnxRoom?, diduserAwaited data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:diduserAwaited", data: Data)
    }
    
 func room(_ room: EnxRoom?, didRoomBandwidthAlert data: [Any]?) {
          guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didRoomBandwidthAlert", data:Data)
    }
    // Add Callbacks to handle event for subscribe talker notification
     func room(_ room: EnxRoom?, didAckSubscribeTalkerNotification data:  [Any]?) {
         guard let Data = data?[0] as? [String : Any] else {
        return
     }
        self.emitEvent(event: "room:didAckSubscribeTalkerNotification", data:Data)
    }

    func room(_ room: EnxRoom?, didAckUnsubscribeTalkerNotification data:  [Any]?) {
         guard let Data = data?[0] as? [String : Any] else {
        return
     }
        self.emitEvent(event: "room:didAckUnsubscribeTalkerNotification", data:Data)
    }

    func room(_ room: EnxRoom?, didTalkerNotification data: [Any]?) {
          guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didTalkerNotification", data:Data)
    }

    
    
   //  Add call back to handle event of Breakout room
    
    func room(_ room: EnxRoom?, didAckCreateBreakOutRoom data: [Any]?) {
           guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didAckCreateBreakOutRoom", data: Data)
    }

    func room(_ room: EnxRoom?, didAckCreateAndInviteBreakOutRoom data: [Any]?) {
             guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didAckCreateAndInviteBreakOutRoom", data:Data)
    }

    func room(_ room: EnxRoom?, didAckInviteBreakOutRoom data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didAckInviteBreakOutRoom", data:Data)
    }

    func room(_ room: EnxRoom?, didAckPause data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didAckPause", data:Data)
    }
    func room(_ room: EnxRoom?, didAckResume data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didAckResume", data:Data)
    }
    func room(_ room: EnxRoom?, didAckMuteRoom data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didAckMuteRoom", data:Data)
    }
    func room(_ room: EnxRoom?, didAckUnmuteRoom data: [Any]?) {
        
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        self.emitEvent(event: "room:didAckUnmuteRoom", data:Data)
    }

    func room(_ room: EnxRoom?, didFailedJoinBreakOutRoom data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didFailedJoinBreakOutRoom", data:Data)
    }

    func room(_ room: EnxRoom?, didConnectedBreakoutRoom data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didConnectedBreakoutRoom", data:Data)
    }
    func room(_ room: EnxRoom?, didDisconnectedBreakoutRoom data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didDisconnectedBreakoutRoom", data:Data)
    }

    func room(_ room: EnxRoom?, didUserJoinedBreakoutRoom data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didUserJoinedBreakoutRoom", data:Data)
    }

    func room(_ room: EnxRoom?, didInvitationForBreakoutRoom data: [Any]?) {
        
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        self.emitEvent(event: "room:didInvitationForBreakoutRoom", data:Data)
    }

    func room(_ room: EnxRoom?, didDestroyedBreakoutRoom data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didDestroyedBreakoutRoom", data:Data)
    }

    func room(_ room: EnxRoom?, didUserDisconnectedFromBreakoutRoom data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didUserDisconnectedFromBreakoutRoom", data:Data)
    }

    func room(_ room: EnxRoom?, didAckRejectBreakoutRoom data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didAckRejectBreakoutRoom", data:Data)
    }


    func room(_ room: EnxRoom?, didBreakoutRoomCreated data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didBreakoutRoomCreated", data:Data)
    }

    func room(_ room: EnxRoom?, didBreakoutRoomInvited data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didBreakoutRoomInvited", data:Data)
    }
    func room(_ room: EnxRoom?, didBreakoutRoomInviteRejected data: [Any]?) {
            guard let Data = data?[0] as? [String : Any] else {
        return
     }
        
        self.emitEvent(event: "room:didBreakoutRoomInviteRejected", data:Data)
    }
    
    
    

    // Add call back to handle pre call test



    //Add callback to handle SpotLight user
    func room(_ channel: EnxRoom?, didAckAddSpotlightUsers data: [Any]?) {
     guard let Data = data?[0] as? [String : Any] else {
        return
     }
     self.emitEvent(event: "room:didAckAddSpotlightUsers", data: Data)
    }
    
    func room(_ channel: EnxRoom?, didAckRemoveSpotlightUsers data: [Any]?) {
     guard let Data = data?[0] as? [String : Any] else {
        return
     }
     self.emitEvent(event: "room:didAckRemoveSpotlightUsers", data: Data)
    }
    
    func room(_ channel: EnxRoom?, didUpdatedSpotlightUsers data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didUpdatedSpotlightUsers", data: Data)
    }

    //Switch Room callback
    func room(_ channel: EnxRoom?, didAckSwitchedRoom data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didAckSwitchedRoom", data: Data)
    }

     func room(_ channel: EnxRoom?, didRoomModeSwitched data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didRoomModeSwitched", data: Data)
    }

    // Live Recording
    func room(_ channel: EnxRoom?, didACKStartLiveRecording data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didACKStartLiveRecording", data: Data)
    }
    func room(_ channel: EnxRoom?, didACKStopLiveRecording data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didACKStopLiveRecording", data: Data)
    }
    func room(_ channel: EnxRoom?, didLiveRecordingNotification data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didLiveRecordingNotification", data: Data)
    }
    func room(_ room : EnxRoom?, didRoomLiveRecordingOn data : [Any]?){
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didRoomliverecordOn", data: Data)
    }

    //Live Streaming
     func room(_ channel: EnxRoom?, didAckStartStreaming data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didAckStartStreaming", data: Data)
    }
    func room(_ channel: EnxRoom?, didAckStopStreaming data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didAckStopStreaming", data: Data)
    }
    func room(_ channel: EnxRoom?, didStreamingStarted data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didStreamingStarted", data: Data)
    }
    func room(_ room : EnxRoom?, didStreamingStopped data : [Any]?){
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didStreamingStopped", data: Data)
    }

   func room(_ room : EnxRoom?, didStreamingFailed data : [Any]?){
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didStreamingFailed", data: Data)
    }
    func room(_ room : EnxRoom?, didStreamingUpdated data : [Any]?){
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didStreamingUpdated", data: Data)
    }

    // Cancel OutBoundCall
    func room(_ channel: EnxRoom?, didOutBoundCallCancel data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didOutBoundCallCancel", data: Data)
    }

    // mute-unmute audio
    func room(_ channel: EnxRoom?, didAckHardMuteUserAudio data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didAckHardMuteUserAudio", data: Data)
    }
    func room(_ channel: EnxRoom?, didAckHardunMuteUserAudio data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didAckHardunMuteUserAudio", data: Data)
    }

    // mute-unmute video
    func room(_ channel: EnxRoom?, didAckHardMuteUserVideo data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didAckHardMuteUserVideo", data: Data)
    }
    func room(_ channel: EnxRoom?, didAckHardUnMuteUserVideo data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didAckHardUnMuteUserVideo", data: Data)
    }

    // Stop Sharing
    func room(_ channel: EnxRoom?, didStopAllSharingACK data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didStopAllSharingACK", data: Data)
    }

    // update in breakout room
    func room(_ channel: EnxRoom?, didBreakoutroomjoining data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didBreakoutroomjoining", data: Data)
    }
    func room(_ channel: EnxRoom?, didUserPaused data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didUserPaused", data: Data)
    }
    func room(_ channel: EnxRoom?, didUserResumed data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didUserResumed", data: Data)
    }
    //Speech to Text (LiveTranscriptions)
    /**Acknowledgment callback for stratLive Transcription**/
     func room(_ channel: EnxRoom?, didACKStartLiveTranscription data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didACKStartLiveTranscription", data: Data)
    }
    /**Acknowledgment callback for stopLive Transcription**/
     func room(_ channel: EnxRoom?, didACKStopLiveTranscription data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didACKStopLiveTranscription", data: Data)
    }
    /**Acknowledgment callback for subscribe/unsubscribe live Transcription**/
    func room(_ channel: EnxRoom?, didACKSubscribeForLiveTranscription data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didACKSubscribeForLiveTranscription", data: Data)
    }
    /**Event  callback for Live Transcription**/
     func room(_ channel: EnxRoom?, didTranscriptionEvents data: [Any]?) {
      guard let Data = data?[0] as? [String : Any] else {
        return
      }
     self.emitEvent(event: "room:didTranscriptionEvents", data: Data)
    }
    /**Event callback for Room Transcription on**/
    func room(_ channel: EnxRoom?, didRoomTranscriptionOn data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didRoomTranscriptionOn", data: Data)
    }
    /**Event callback for Room Transcription Off**/
    func room(_ channel: EnxRoom?, didRoomTranscriptionOff data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didRoomTranscriptionOff", data: Data)
    }
    /**Event callback for Self Transcription on**/
    func room(_ channel: EnxRoom?, didSelfTranscriptionOn data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didSelfTranscriptionOn", data: Data)
    }
    /**Event callback for Self Transcription Off**/
    func room(_ channel: EnxRoom?, didSelfTranscriptionOff data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didSelfTranscriptionOff", data: Data)
    }

    //Share Privacy
    func room(_ channel: EnxRoom?, didACKSetSharePermissionMode data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didACKSetSharePermissionMode", data: Data)
    }
    func room(_ channel: EnxRoom?, didACKGrantSharePermission data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didACKGrantSharePermission", data: Data)
    }
    func room(_ channel: EnxRoom?, didACKDenySharePermission data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didACKDenySharePermission", data: Data)
    }
    func room(_ channel: EnxRoom?, didACKReleaseSharePermission data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didACKReleaseSharePermission", data: Data)
    }
    func room(_ channel: EnxRoom?, didACKRequestSharePermission data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didACKRequestSharePermission", data: Data)
    }
    func room(_ channel: EnxRoom?, didACKCancelSharePermission data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didACKCancelSharePermission", data: Data)
    }
    func room(_ channel: EnxRoom?, didSharePermissionsModeChanged data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didSharePermissionsModeChanged", data: Data)
    }
    func room(_ channel: EnxRoom?, didSharePermissionRequested data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didSharePermissionRequested", data: Data)
    }
    func room(_ channel: EnxRoom?, didSharePermissionReleased data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didSharePermissionReleased", data: Data)
    }
    func room(_ channel: EnxRoom?, didSharePermissionDeny data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didSharePermissionDeny", data: Data)
    }
    func room(_ channel: EnxRoom?, didSharePermissionCancled data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didSharePermissionCancled", data: Data)
    }
    func room(_ channel: EnxRoom?, didSharePermissionGranted data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didSharePermissionGranted", data: Data)
    }
    //HLS Callback
     func room(_ channel: EnxRoom?, didHlsStarted data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didHlsStarted", data: Data)
    }
     func room(_ channel: EnxRoom?, didHlsWaiting data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didHlsWaiting", data: Data)
    }
     func room(_ channel: EnxRoom?, didHlsFailed data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didHlsFailed", data: Data)
    }
     func room(_ channel: EnxRoom?, didHlsStopped data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didHlsStopped", data: Data)
    }
    //data storage
    func room(_ channel: EnxRoom?, didCustomDataSaved data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didCustomDataSaved", data: Data)
    }
    func room(_ channel: EnxRoom?, didCustomDataUpdated data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didCustomDataUpdated", data: Data)
    }
    func room(_ channel: EnxRoom?, didGetCustomData data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didGetCustomData", data: Data)
    }
     func room(_ channel: EnxRoom?, didACKCustomDataUpdated data: [Any]?) {
        guard let Data = data?[0] as? [String : Any] else {
          return
        }
       self.emitEvent(event: "room:didACKCustomDataUpdated", data: Data)
    }
}
//EnxStream Delegate
extension EnxRoomManager :  EnxStreamDelegate{
    /* Stream Delegates */
    func didAudioEvents(_ data: [String : Any]?) {
        self.emitEvent(event: "stream:didAudioEvent", data: data as Any)
    }
    func didVideoEvents(_ data: [String : Any]?) {
        self.emitEvent(event: "stream:didVideoEvent", data: data as Any)
    }
    //Receive all other users
    func stream(_ stream: EnxStream?, didRemoteStreamAudioMute data: [Any]?) {
      guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didRemoteStreamAudioMute", data: dataDict)
    }
     //Receive all other users
    func stream(_ stream: EnxStream?, didRemoteStreamAudioUnMute data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didRemoteStreamAudioUnMute", data: dataDict)
    }
    //Receive all other users
    func stream(_ stream: EnxStream?, didRemoteStreamVideoMute data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didRemoteStreamVideoMute", data: dataDict)
    }
    // Receive all other users
    func stream(_ stream: EnxStream?, didRemoteStreamVideoUnMute data: [Any]?) {
       guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didRemoteStreamVideoUnMute", data: dataDict)
    }
    //Hard mute Delegate
    /* On Success of single user mute by moderator. This delegate method is for moderator.*/
    func didhardMuteAudio(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didhardMuteAudio", data: dataDict)
    }
    /*On Success of single user unmute by moderator. This delegate method is for moderator.*/
    func didhardUnMuteAudio(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didhardUnmuteAudio", data: dataDict)
    }
    /*On Success of single user mute by moderator. This delegate method is for participant.*/
    func didRecievedHardMutedAudio(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didRecievedHardMutedAudio", data: dataDict)
        
    }
    /*On Success of single user unmute by moderator. This delegate method is for participant.*/
    func didRecievedHardUnmutedAudio(_ Data: [Any]?) {
        guard let dataDict = Data?[0] as? [String : Any], Data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didRecievedHardUnmutedAudio", data: dataDict)
    }
    //For Video
    /* This delegate called when a hard mute video alert moderator received from server. This delegate is for moderator. */
    func stream(_ stream: EnxStream?, didHardVideoMute data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didHardVideoMute", data: dataDict)
    }
    /* This delegate called when a hard unmute video alert moderator received from server. This delegate is for moderator. */
    func stream(_ stream: EnxStream?, didHardVideoUnMute data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didHardVideoUnMute", data: dataDict)
    }
    /* This delegate called when a hard mute video alert participant received from server. */
    func stream(_ stream: EnxStream?, didReceivehardMuteVideo data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didReceivehardMuteVideo", data: dataDict)
    }
    /* This delegate called when a hard unmute video alert participant received from server. */
    func stream(_ stream: EnxStream?, didRecivehardUnmuteVideo data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
            return
        }
        self.emitEvent(event: "stream:didRecivehardUnmuteVideo", data: dataDict)
    }
    //Receive data API
    func didReceiveData(_ data: [String : Any]?) {
        if data != nil{
            self.emitEvent(event: "stream:didReceiveData", data: data as Any)
        }
    }
  }
//EnxPlayer Delegates
extension EnxRoomManager : EnxPlayerDelegate{
    func didPlayerStats(_ data: [String : Any]) {
        self.emitEvent(event: "stream:didPlayerStats", data: data)
    }
    func didCapturedView(_ snapShot: UIImage?) {
        guard let imageData = snapShot!.pngData() else {
            return;
        }
        let base64String = imageData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
        self.emitEvent(event: "room:didCapturedView", data: base64String)
    }
}
//Pree call test CallBack -- TroubleShoot
extension EnxRoomManager:EnxTroubleShooterDelegate{
    func didClientDiagnosisFailed(_ data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
         return
     }
     self.emitEvent(event: "room:didClientDiagnosisFailed", data: dataDict)
    }
    
    func didClientDiagnosisFinished(_ data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
         return
     }
     self.emitEvent(event: "room:didClientDiagnosisFinished", data: dataDict)
    }
    
    func didClientDiagnosisStatus(_ data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
         return
     }
     self.emitEvent(event: "room:didClientDiagnosisStatus", data: dataDict)
    }
    
    func didClientDiagnosisStopped(_ data: [Any]?) {
        guard let dataDict = data?[0] as? [String : Any], data!.count>0 else {
         return
     }
     self.emitEvent(event: "room:didClientDiagnosisStopped", data: dataDict)
    }
}
