<script>
import Slider from 'vue3-slider';

export default {
    props: {
        localVideo: Boolean,  // is our local webcam (not other's camera)
        poppedOut: Boolean,   // Video is popped-out and draggable
        username: String,     // username related to this video
        isExplicit: Boolean,  // camera is marked Explicit
        isMuted: Boolean,     // camera is muted on our end
        isSourceMuted: Boolean, // camera is muted on the broadcaster's end
        isWatchingMe: Boolean, // other video is watching us back
        isFrozen: Boolean,     // video is detected as frozen
        isSpeaking: Boolean,   // video is registering audio
        watermarkImage: Image, // watermark image to overlay (nullable)
    },
    components: {
        Slider,
    },
    data() {
        return {
            // Volume slider
            volume: 100,

            // Volume change debounce
            volumeDebounce: null,

            // Mouse over status
            mouseOver: false,
        };
    },
    computed: {
        containerID() {
            return this.videoID + '-container';
        },
        videoID() {
            return this.localVideo ? 'localVideo' : `videofeed-${this.username}`;
        },
        textColorClass() {
            return this.isExplicit ? 'has-text-camera-red' : 'has-text-camera-blue';
        },
        muteButtonClass() {
            let classList = [
                'button is-small ml-1 p-2',
            ]

            if (this.isMuted) {
                classList.push('is-danger');
            } else {
                classList.push('is-success is-outlined');
            }

            if (!this.mouseOver) {
                classList.push('seethru');
            }

            return classList.join(' ');
        },
        muteIconClass() {
            if (this.localVideo) {
                return this.isMuted ? 'fa-microphone-slash' : 'fa-microphone';
            }
            return this.isMuted ? 'fa-volume-xmark' : 'fa-volume-high';
        }
    },
    methods: {
        closeVideo() {
            // Note: closeVideo only available for OTHER peoples cameras.
            // Closes the WebRTC connection as the offerer.
            this.$emit('close-video', this.username, 'offerer');
        },

        reopenVideo() {
            // Note: goes into openVideo(username, force)
            this.$emit('reopen-video', this.username, true);
        },

        openProfile() {
            this.$emit('open-profile', this.username);
        },

        // Toggle the Mute button
        muteVideo() {
            this.$emit('mute-video', this.username);
        },

        popoutVideo() {
            this.$emit('popout', this.username);
        },

        fullscreen(force=false) {
            // If we are popped-out, pop back in before full screen.
            if (this.poppedOut && !force) {
                this.popoutVideo();
                window.requestAnimationFrame(() => {
                    this.fullscreen(true);
                });
                return;
            }

            let $elem = document.getElementById(this.containerID);
            if ($elem) {
                if (document.fullscreenElement) {
                    document.exitFullscreen();
                } else if ($elem.requestFullscreen) {
                    $elem.requestFullscreen();
                } else {
                    window.alert("Fullscreen not supported by your browser.");
                }
            }
        },

        volumeChanged() {
            if (this.volumeDebounce !== null) {
                clearTimeout(this.volumeDebounce);
            }
            this.volumeDebounce = setTimeout(() => {
                this.$emit('set-volume', this.username, this.volume);
            }, 200);
        },

        // Show info about the watermark when the corner one is clicked.
        showWatermarkInfo() {
            this.$emit('modal-alert', {
                icon: "fa-solid fa-qrcode",
                title: "What are the QR codes on webcams?",
                message: "This QR code is a safety feature to deter people from wanting to screen record webcams on chat. " +
                    "The QR code contains the current viewer's username, the website's name, and the current date/time. The " +
                    "idea is that if a webcam is recorded and then leaked online, the QR code would connect it directly back to who exactly " +
                    "recorded it, and when.\n\n" +
                    "There are two QR codes on each video: the one in the bottom-right corner is intentionally made visible and obvious " +
                    "to everybody, and a second (subtle) copy of the code spans across the center/middle of the video and pulsates in " +
                    "transparency over time.",
            });
        }
    }
}
</script>

<template>
    <div class="feed" :id="containerID" :class="{
        'popped-out': poppedOut,
        'popped-in': !poppedOut,
    }" @mouseover="mouseOver = true" @mouseleave="mouseOver = false">
        <video
            :id="videoID"
            autoplay
            disablepictureinpicture
            playsinline
            oncontextmenu="return false;"
            :muted="localVideo"></video>

        <!-- Watermark layer -->
        <div v-if="watermarkImage">
            <img :src="watermarkImage" class="watermark" oncontextmenu="return false">
            <img :src="watermarkImage" class="corner-watermark seethru invert-color" @click="showWatermarkInfo()" oncontextmenu="return false">
        </div>

        <!-- Caption -->
        <div class="caption" :class="textColorClass">
            <i class="fa fa-microphone-slash mr-1 has-text-grey" v-if="isSourceMuted"></i>
            <a href="#" @click.prevent="openProfile" :class="textColorClass">{{ username }}</a>
            <i class="fa fa-people-arrows ml-1 has-text-grey is-size-7" :title="username + ' is watching your camera too'"
                v-if="isWatchingMe"></i>

            <!-- Frozen stream detection -->
            <a class="fa fa-mountain ml-1" href="#" v-if="!localVideo && isFrozen" style="color: #00FFFF"
                @click.prevent="reopenVideo()" title="Frozen video detected!"></a>

            <!-- Is speaking -->
            <span v-if="isSpeaking" class="ml-1" title="Speaking">
                <i class="fa fa-volume-high has-text-info"></i>
            </span>
        </div>

        <!-- Close button (others' videos only) -->
        <div class="close" v-if="!localVideo" :class="{'seethru': !mouseOver}">
            <a href="#" class="button is-small is-danger is-outlined px-2" title="Close video" @click.prevent="closeVideo()">
                <i class="fa fa-close"></i>
            </a>
        </div>

        <!-- Controls -->
        <div class="controls">
            <!-- Mute Button -->
            <button type="button" :class="muteButtonClass"
                @click="muteVideo()">
                <i class="fa" :class="muteIconClass"></i>
            </button>

            <!-- Pop-out Video -->
            <button type="button" class="button is-small is-light is-outlined p-2 ml-2" title="Pop out"
                :class="{'seethru': !mouseOver}"
                @click="popoutVideo()">
                <i class="fa fa-up-right-from-square"></i>
            </button>

            <!-- Full screen. -->
            <button type="button" class="button is-small is-light is-outlined p-2 ml-2" title="Go full screen"
                :class="{'seethru': !mouseOver}"
                @click="fullscreen()">
                <i class="fa fa-expand"></i>
            </button>
        </div>

        <!-- Volume slider -->
        <div class="volume-slider" v-show="!localVideo && !isMuted && mouseOver">
            <Slider v-model="volume" color="#00FF00" track-color="#006600" :min="0" :max="100" :step="1" :height="7"
                orientation="vertical" @change="volumeChanged">

            </Slider>
        </div>
    </div>
</template>

<style scoped>
.volume-slider {
    position: absolute;
    left: 18px;
    top: 30px;
    bottom: 44px;
}

/* A background image behind video elements in case they don't load properly */
video {
    background-image: url(/static/img/connection-error.png);
    background-position: center center;
    background-repeat: no-repeat;
}

/* Translucent controls until mouse over */
.seethru {
    opacity: 0.4;
}

/* Watermark image */
.watermark {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    width: 40%;
    height: 40%;
    opacity: 0.02;
    animation-name: subtle-pulsate;
    animation-duration: 10s;
    animation-iteration-count: infinite;
}
.corner-watermark {
    position: absolute;
    right: 4px;
    bottom: 4px;
    width: 20%;
    min-width: 32px;
    min-height: 32px;
    max-height: 20%;
    cursor: pointer;
}
.invert-color {
    filter: invert(100%);
}

/* Animate the primary watermark to pulsate in opacity */
@keyframes subtle-pulsate {
    0% { opacity: 0.02; }
    50% { opacity: 0.06; }
    100% { opacity: 0.02; }
}
</style>
