<template>
    <v-container>
        <v-btn @click="deviceSelectDialog = true">change</v-btn>
        <v-btn @click="screenShare">share a screen</v-btn>
        <PdfShare :username="username"  :opaque-id="opaqueId" :room="room" :janus-init="janusInit" ></PdfShare>

        <v-dialog
                v-model="mozillaAlert"
                max-width="290"
        >
            <v-card>
                <v-card-title class="headline">Share whole screen or a window?</v-card-title>

                <v-card-text>
                    Firefox handles screensharing in a different way: are you going to share the whole screen, or would you rather pick a single window/application to share instead?
                </v-card-text>
                <v-card-actions>
                    <v-btn @click="shareScreenStart('screen')">Share a screen</v-btn>
                    <v-btn @click="shareScreenStart('window')">Share a window</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog><v-dialog
                v-model="chromeAlert"
                max-width="290"
        >
            <v-card>
                <v-card-title class="headline">Chrome Extension Error</v-card-title>

                <v-card-text>
                    You're using Chrome but don't have the screensharing extension installed: click <b><a href='https://chrome.google.com/webstore/detail/janus-webrtc-screensharin/hapfgfdkleiggjjpfpenajgdnfckjpaj' target='_blank'>here</a></b> to do so
                </v-card-text>
            </v-card>
        </v-dialog>

        <v-dialog
                v-model="deviceSelectDialog"
                max-width="290"
        >
            <v-card>
                <v-card-title class="headline">Configuration</v-card-title>

                <v-card-text>
                    <v-row>
                        <v-col md="12" cols="12">
                            <v-select
                                    label="Please select video device"
                                    v-model="selectedVideo"
                                    :items="videoDevices"
                                    item-value="deviceId"
                                    item-text="label"
                            ></v-select>
                            <v-checkbox label="No Video" v-model="noVid"></v-checkbox>
                        </v-col>
                        <v-col md="12" cols="12">
                            <v-select
                                    label="Please select audio device"
                                    :items="audioDevices"
                                    v-model="selectedAudio"
                                    item-value="deviceId"
                                    item-text="label"
                            ></v-select>
                        </v-col>
                    </v-row>
                </v-card-text>

                <v-card-actions>
                    <v-spacer></v-spacer>

                    <v-btn
                            color="green darken-1"
                            text
                            @click="deviceSelectDialog = false"
                    >
                        Disagree
                    </v-btn>

                    <v-btn
                            color="green darken-1"
                            text
                            @click="selectDevice"
                    >
                        Agree
                    </v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>
        <v-row>
            <v-col cols="12" md="3">
                    <video ref="ownstream" class="rounded centered" id="myvideo" width="100%" height="100%" autoplay
                           playsinline muted="muted"/>
            </v-col>
            <v-col cols="12" md="3" style="display: none">
                <video ref="ownstreamscreen" class="rounded centered" id="myvideo2" width="100%" height="100%" autoplay
                       playsinline muted="muted"/>
            </v-col>
            <v-col cols="12" md="3" v-for="remoteStream in remoteStreams" :key="remoteStream.id">
                    <RemoteFeed :opaqueId="opaqueId" :mypvtid="mypvtid" :feedid="remoteStream.id" :janusInit="janusInit" :room="room" ></RemoteFeed>
            </v-col>
        </v-row>
    </v-container>
</template>

<script>
    import RemoteFeed from "@/lib/RemoteFeed";
    import PdfShare from "@/lib/PdfShare";
    export default {
        components: {PdfShare, RemoteFeed},
        props: {
            server: String,
            room: Number,
            username: String
        },
        data() {
            return {
                janusInit: null,
                opaqueId: null,
                pluginHandle: null,
                mystream: null,
                myid: '',
                mypvtid: '',
                selectedVideo: null,
                selectedAudio: null,
                started: false,
                mozillaAlert: false,
                janusScreenShareHandle: null,
                chromeAlert: false,
                videoDevices: [],
                capture: '',
                audioDevices: [],
                deviceSelectDialog: false,
                noVid: false,
                shareScreenId: null,
                remoteStreams: []
            }
        },
        name: "VueJanus",
        mounted() {
            this.janusInit = new this.$janus({
                success: this.janusSuccess,
                server: this.server,
                error: function (error) {
                    this.$janus.error(error);
                },
                destroyed: function () {
                    window.location.reload();
                }
            })

        },
        methods: {
            janusPluginSuccessScreen (pluginHandle) {
                this.janusScreenShareHandle = pluginHandle
                this.$janus.log("Plugin attached! (" + this.pluginHandle.getPlugin() + ", id=" + this.pluginHandle.getId() + ")");
                this.$janus.log("  -- This is a publisher/manager");
                var register = { "request": "join", "room": this.room, "ptype": "publisher", "display": this.username + " - Share Screen" };
                pluginHandle.send({"message": register});
            },
            castStart(jsep) {
                var publish = { "request": "configure", "audio": false, "video": true };
                this.janusScreenShareHandle.send({"message": publish, "jsep": jsep});
            },
            janusMessageScreen (msg, jesp) {
                var event = msg["videoroom"]
                console.log(jesp)
                if(event === "joined") {
                    this.janusScreenShareHandle.createOffer(
                        {
                            media: { video: this.capture, audioSend: false, videoRecv: false},	// Screen sharing Publishers are sendonly
                            success: this.castStart,
                            error: function(error) {
                                console.log("WebRTC error:", error);
                                // bootbox.alert("WebRTC error... " + JSON.stringify(error));
                            }
                        });
                }
                if(jesp !== undefined && jesp !== null) {
                    // Janus.debug("Handling SDP as well...");
                    // Janus.debug(jsep);
                    this.janusScreenShareHandle.handleRemoteJsep({jsep: jesp});
                }
            },
            onlocalstreamScreen (stream) {
                this.$refs.ownstreamscreen.srcObject = stream
            },
            shareScreenStart (capture) {
                this.capture = capture
                this.janusInit.attach(
                    {
                        plugin: "janus.plugin.videoroom",
                        opaqueId: this.opaqueId,
                        success: this.janusPluginSuccessScreen,
                        consentDialog: this.consentDialog,
                        error: this.janusPluginError,
                        mediaState: this.mediaState,
                        webrtcState: this.webrtcState,
                        onmessage: this.janusMessageScreen,
                        onlocalstream: this.onlocalstreamScreen
                    }
                )

            },
            screenShare () {
                if(!this.$janus.isExtensionEnabled()) {
                    this.chromeAlert = true
                    return;
                }

                if(navigator.mozGetUserMedia) {
                    // Firefox needs a different constraint for screen and window sharing
                    this.mozillaAlert = true
                    return;
                }
                this.shareScreenStart('screen')

            },
            janusPluginError (error) {
                console.log(error)
            },
            consentDialog (on) {
                // this.$janus.debug("Consent dialog should be " + (on ? "on" : "off") + " now");
                console.log(on)
            },
            janusPluginSuccess (pluginHandle) {
                this.pluginHandle = pluginHandle
                this.$janus.log("Plugin attached! (" + this.pluginHandle.getPlugin() + ", id=" + this.pluginHandle.getId() + ")");
                this.$janus.log("  -- This is a publisher/manager");

                this.$janus.listDevices(this.initDevices);


            },
            initDevices (devices) {
                console.log(devices)
                devices.forEach(device => {
                    if (device.kind === 'videoinput') {
                        this.videoDevices.push(device)
                    }
                    if (device.kind === 'audioinput') {
                        this.audioDevices.push(device)
                    }

                })
                this.deviceSelectDialog = true
            },
            genRemoteFeed () {
                this.remoteStreams.forEach(item => {
                    this.createRemoteFeed(item)
                })
            },
            offerSend (jsep) {
                console.log('vid offer')
                var publish = {"request": "configure", "audio": true, "video": true};

                this.pluginHandle.send({"message": publish, "jsep": jsep});
            },
            controlPublishers(msg) {
                msg["publishers"].forEach(item => {
                    var has = false
                    this.remoteStreams.forEach(rm => {
                        if (item.id === rm.id) has = true
                    })
                    if (!has) {
                        if (this.username + " - Share Screen" !== item.display) this.remoteStreams.push(item)
                    }

                })
            },
            janusMessage (msg, jsep) {
                console.log(msg);
                var event = msg["videoroom"];
                if (event !== undefined) {
                    if (event === "joined") {
                        this.myid = msg["id"];
                        this.mypvtid = msg["private_id"];
                        this.$janus.log("Successfully joined room " + msg["room"] + " with ID " + this.myid);
                        this.restartDevices()
                        if (msg["publishers"] !== undefined && msg["publishers"] !== null) {
                            this.controlPublishers(msg)
                        }
                    } else if(event === "event") {
                        if (msg["publishers"] !== undefined && msg["publishers"] !== null) {
                            this.controlPublishers(msg)

                        } else if(msg["leaving"] !== undefined && msg["leaving"] !== null) {
                            console.log("leaving")
                            this.remoteStreams.forEach(item => {
                                if (item.id === msg['leaving']) this.remoteStreams.splice(this.remoteStreams.indexOf(item),1)
                            })
                        }
                    }
                }
                if (jsep !== undefined && jsep !== null) {

                    console.log("Handling SDP as well...");
                    console.log(jsep);
                    this.pluginHandle.handleRemoteJsep({jsep: jsep});
                    var audio = msg["audio_codec"];
                    if (this.mystream && this.mystream.getAudioTracks() && this.mystream.getAudioTracks().length > 0 && !audio) {
                        console.log("Our audio stream has been rejected, viewers won't hear us");
                    }
                }
            },
            onlocalstream (stream) {
                this.mystream = stream
                console.log(this.$refs)
                console.log(this.$refs["ownstream"])
                this.$refs.ownstream.srcObject = this.mystream

            },
            restartDevices () {
                this.deviceSelectDialog = false

                var media = {
                    audioRecv: false, videoRecv: false, audioSend: true, videoSend: !this.noVid,
                    audio: {
                        deviceId: {
                            exact: this.selectedAudio
                        }
                    },
                    replaceAudio: true,	// This is only needed in case of a renegotiation
                    video: {
                        deviceId: {
                            exact: this.selectedVideo
                        }
                    },
                    replaceVideo: true,
                };


                this.pluginHandle.createOffer(
                    {
                        media: media,
                        success: this.offerSend,
                        error: function (error) {
                            // An error has occurred ...
                            console.log(error)
                        }
                    })
            },
            webrtcState (on) {
                this.$janus.log("Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now");
            },
            mediaState (medium, on) {
                this.$janus.log("Janus " + (on ? "started" : "stopped") + " receiving our " + medium);
            },
            changeDevice () {
                this.$refs.ownstream.setSinkId(this.selectedVideo)
                this.$refs.ownstream.setSinkId(this.selectedAudio)
            },
            selectDevice () {
                if (!this.started) {
                    console.log(this.selectedVideo)
                    console.log(this.selectedAudio)
                    this.started = true
                    var register = {
                        "request": "join",
                        "room": this.room,
                        "ptype": "publisher",
                        "display": this.username
                    };
                    this.pluginHandle.send({"message": register});
                } else {
                    this.restartDevices()
                }
            },
            janusSuccess () {
                this.opaqueId = "videoroomtest-" + this.$janus.randomString(12);

                this.janusInit.attach(
                    {
                        plugin: "janus.plugin.videoroom",
                        opaqueId: this.opaqueId,
                        success: this.janusPluginSuccess,
                        consentDialog: this.consentDialog,
                        error: this.janusPluginError,
                        mediaState: this.mediaState,
                        webrtcState: this.webrtcState,
                        onmessage: this.janusMessage,
                        onlocalstream: this.onlocalstream
                    }
                )
            }
        }
    }
</script>

<style scoped>

</style>
