 /*
 * GTVRModule.js
 * 
 * This file is part of the "gotoviar" project.
 * See "LICENSE" for license information.
 */

class GTVRModule {

    constructor(options) {
        this.options = {
            wasm_url: options.wasm_url && options.wasm_name ? options.wasm_url + options.wasm_name + '.wasm' : options.wasm_url,
            wasm_js_url: options.wasm_js_url ? options.wasm_js_url : options.wasm_url + options.wasm_name + '.js',
            canvas: options ? options.canvas : null
        };

        window.shutdownGTVR = (function () {
            document.body.style.overflow = window.Module.gtvr.scrollbars;
            delete window.Module;
            delete window.shutdownGTVR;
        });

        this.microIsOK = false;
        this.isXrSupported = false;
    }

    detectSystem(){
        if (this.system_name) {
            this.setCallbacks();
        }
        else {
            var xhttp = new XMLHttpRequest();
            xhttp.open("GET", window.location.origin + '/gotoviar/system_name', true);
            xhttp.responseType = 'json';
            xhttp.onload = function(e) {
                if (xhttp.readyState === 4){
                    if (xhttp.status === 200){
                        this.system_name = xhttp.response.system_name;
                        this.setSallbacks();
                    }
                    else{
                        xhttp.open("GET", window.location.origin + '?rest_route=/gotoviar/system_name', true);
                        xhttp.onload = function(e) {
                            if (xhttp.readyState === 4){
                                if (xhttp.status === 200){
                                    this.system_name = xhttp.response.system_name;
                                    this.setSallbacks();
                              }
                            }
                      }.bind(this);
                      xhttp.send();                    
                    }
                }
          }.bind(this);
          xhttp.send();
        }
    }

    setSallbacks(){
        this.shop_integration = {};
        this.shop_integration.items_count_in_cart = 0;
      
        if (this.system_name === 'woocommerce')
        {
            this.shop_integration.get_items_count_in_cart = function()
            {
                var xhttp = new XMLHttpRequest();
                xhttp.open("GET", window.location.origin + '?rest_route=/gotoviar/v1/items_count_in_cart/', true);
                xhttp.onload = function(e) {
                    if (xhttp.readyState === 4){
                        if (xhttp.status === 200){                            
                            this.shop_integration.items_count_in_cart = parseInt(xhttp.responseText, 10);
                        }
                    }
                }.bind(this);
                xhttp.send();
            }.bind(this);

            this.shop_integration.get_products = function()
            {
                var xhttp = new XMLHttpRequest();
                xhttp.open("GET", window.location.origin + '?rest_route=/gotoviar/v1/products/', true);
                xhttp.responseType = 'json';
                xhttp.onload = function(e) {
                    if (xhttp.readyState === 4){
                        if (xhttp.status === 200){                            
                            this.shop_integration.products = xhttp.response;
                        }
                    }
                }.bind(this);
                xhttp.send();
            }.bind(this);

            this.shop_integration.add_in_basket = function(product_id, quantity)
            {
                var xhttp = new XMLHttpRequest();
                xhttp.open("GET", window.location.origin + '?add-to-cart=' + product_id + "&quantity=" + quantity, true);
                xhttp.onload = function(e) {
                    if (xhttp.readyState === 4){
                        if (xhttp.status === 200){
                            window.Module.gtvr.shop_integration.items_count_in_cart++;
                            window.Module.gtvr.shop_integration.set_items_count_in_menu();
                        }
                    }
                };
                xhttp.send();                    
            };
        }
        else if (this.system_name === 'shopify')
        {
            this.shop_integration.get_items_count_in_cart = function()
            {
                fetch(window.location.origin + '/cart.json').then((response) => {
                  if (response.ok)
                    return response.json();
                })
                .then((responseJson) => {
                    this.shop_integration.items_count_in_cart = parseInt(responseJson.item_count, 10);
                })
                .catch((error) => {
                }); 
            }.bind(this);
          
            this.shop_integration.get_products = function()
            {
                this.shop_integration.products = this.shop_integration_shopify.products;
            }.bind(this);
          
            this.shop_integration.add_in_basket = function(product_id, quantity)
            {
                fetch(window.location.origin + '/cart/add', {
                  method: "POST", 
                  headers: {
                      "Content-Type": "application/json",
                      "Accept": "application/json"
                  },            
                  body: JSON.stringify({'items': [{'id': product_id,'quantity': quantity}]}) }).then((response) => {
                  if (response.ok) {
                    return response.json();
                  }
                })
                .then((responseJson) => {
                    window.Module.gtvr.shop_integration.items_count_in_cart++;
                    window.Module.gtvr.shop_integration.set_items_count_in_menu();
                })
                .catch((error) => {
                }); 
            };          
        }

        this.shop_integration.get_items_count_in_cart();
        this.shop_integration.get_products();
      
        this.shop_integration.set_items_count_in_menu = function()
        {
            window.Module.MenuSentEvent("/home/main_win/basket", "label", "Click to Proceed to Checkout (" + window.Module.gtvr.shop_integration.items_count_in_cart + ")");
        };

        this.shop_integration.init = function()
        {
            this.shop_integration.set_items_count_in_menu();
            window.Module.MenuSentEvent("/home/main_win/basket", "action", window.location.origin + "/cart/");
        }.bind(this);      
    }

    createCanvas() {
        let canvas = document.createElement('canvas');
        canvas.id = 'gvrcanvas';
        //canvas.style = {"backgroundColor": "rgba(0, 0, 0, 1.0)", "zIndex": "1000", "position": "fixed", "top": 0, "bottom": 0, "overflow": "hidden"};
        canvas.style.backgroundColor = "rgba(0, 0, 0, 1.0)"; 
        canvas.style.zIndex = "1000";
        canvas.style.position = "fixed";
        canvas.style.top = "0";
        canvas.style.bottom = "0";
        canvas.style.overflow = "hidden";
        document.body.appendChild(canvas);
        return canvas;
    }

    hideScrollBars() {
        window.scrollTo(0, 0);
        this.scrollbars = document.body.style.overflow;
        document.body.style.overflow = "hidden";
    }

    run(project) {        
        if (this.isXrSupported === false)
        {
            this.showNotVRDevice();
            return;
        }

        try {
            this.detectSystem();
            this.askForMicrophonePermision(project);
        } catch(err) {
                console.log(err);
        }
    }

    askForMicrophonePermision(project)
    {
        let disableButton = false;
        let noAcces = false;
        navigator.mediaDevices.getUserMedia({ audio: true, video: false })
        .then(function (stream) {
            this.microIsOK = true;
            document.getElementById('gtvr_microphone_ok_button')?.removeAttribute("disabled");
        }.bind(this))
        .catch(function (err) {
            document.getElementById('gtvr_message')?.close();
            noAcces = true;
            this.showNoMicroAcces();
        }.bind(this));

        setTimeout(function() {
            if (this.microIsOK === false)
            {
                if ((disableButton === false) && (noAcces === false))
                    this.showMicrophoneDialog(project);
            }
            else
                this.__runModule(project);
        }.bind(this), 800);
    }
  
    download() {         
        if (navigator.xr)
        {
            navigator.xr.isSessionSupported("immersive-vr").then((isSupported) => {
            if (isSupported) {
                this.isXrSupported = true;
                this.__downloadModule();
            }
          });
        }
    }

    async __downloadModule() {
        const wasm_response = await fetch(this.options.wasm_url);
        if (!wasm_response.ok)
            throw new Error("Network response was not OK for wasm module.");
        else
            this.wasm_data = await wasm_response.arrayBuffer();

        const js_response = await fetch(this.options.wasm_js_url);
        if (!js_response.ok)
            throw new Error("Network response was not OK for js wasm module.");
        else            
            this.js_data = await js_response.text();             
    }

    async __runModule(project) {
        window.Module =
        {
            gtvr: this,
            wasmBinary: this.wasm_data,
            preRun: (function () {
                window.ENV.PROJECT_PATH = project.url + '/' + project.name;
            }).bind(this),
            canvas: (function () {
                var canvas = typeof this.options.canvas === "string" ? document.getElementById(this.options.canvas) : this.createCanvas();
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;
                canvas.addEventListener("webglcontextlost", function (e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
                canvas.focus();
                return canvas;
            }).bind(this)()
        };

        this.hideScrollBars();
        
        const script = document.createElement("script");
        const scriptText = document.createTextNode(this.js_data);
        script.appendChild(scriptText);
        document.body.appendChild(script);

        window.addEventListener('resize', function () {
            window.Module.canvas.width = window.innerWidth;
            window.Module.canvas.height = window.innerHeight;
            window.Module.canvas.dispatchEvent(new Event('resize'));
        }, false);

        window.Module.canvas.dispatchEvent(new Event('resize'));
    }

    addStyle(styleString) {
        
        let css_style = document.getElementById('gtvr_css');
        if (css_style)
            return;

        const style = document.createElement('style');
        style.id = 'gtvr_css';
        style.textContent = styleString;
        document.head.append(style);
    }
        
    addGTVRCSSStyle()
    {
        /*
        text-align:center; 
        vertical-align: middle;
        display: table-cell;

        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        */

        this.addStyle(`
        .gtvr_center {
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }

        #gtvr_message::backdrop {
            opacity: 1;
            backdrop-filter: blur(5px);
        }

        #gtvr_message {
            border:none;     
            outline: none;
            box-shadow: 5px 5px #888888;
            border-radius: 20px;
            background: #083358;
            color: #fdfdfd;
            padding: 25px 25px 25px 25px;
        }

        #gtvr_message header {
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
        }

        #gtvr_message h3, section{
            margin:0;
            text-align: center;
            color: white;
        }

        #gtvr_message button {
            background-color: #4CAF50;
            border: none;
            color: white;
            padding: 15px 32px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 16px;
            margin: 4px 2px;
            cursor: pointer;
        }

        #gtvr_message button:disabled, input[type="submit"]:disabled {
            background-color: #80af82;
            color: #666666;
        }

        #gtvr_message footer{
            display: flex;
            justify-content: center;
            align-items: center;
        }

        #gtvr_message p {
            line-height: 200%;
        }
        `);
    }

    showNotVRDevice()
    {
        let diag = document.getElementById('gtvr_message');
        if (diag)
            document.body.removeChild(diag);

        this.addGTVRCSSStyle();

        let str = `
        <dialog id="gtvr_message" class="gtvr_center">
            <header>
                <h3 class="header">Accessing GOTOVIAR's VR Environment</h3>
            </header>
            <section>      
                <p>
                You're about to step into the immersive world of GOTOVIAR! Please note that this feature is specially<br> crafted for VR devices and isn't compatible with laptops, or PCs.<br>
                For the ultimate VR experience and guidance on how to dive into the GOTOVIAR universe, feel free to<br> contact us. Our team is always ready and excited to assist you in starting your extraordinary VR<br> journey!<br>
                </p>
            </section>
            <footer>
                <button onclick="gtvr_message.close()" class="pure-button pure-button-primary">
                    Go Back
                </button>
            </footer>
        </dialog>
        `;
        document.body.insertAdjacentHTML( 'afterbegin', str);
        document.getElementById('gtvr_message').showModal();
    }

    showNoMicroAcces()
    {
        let diag = document.getElementById('gtvr_message');
        if (diag)
            document.body.removeChild(diag);

        this.addGTVRCSSStyle();

        let str = `
        <dialog id="gtvr_message" class="gtvr_center">
            <header>
                <h3 class="header">Oops! Microphone Access Needed</h3>
            </header>
            <section>      
                <p>
                <b>Hey there!</b> It looks like you didn't agree to enable your microphone. To fully enjoy the interactive and<br> social aspects of the GOTOVIAR experience, microphone access is essential.<br>
                <b>Quick Fix: Clear Your Cache</b><br>
                Before revisiting the previous step, please clear your browser's cache. This simple action often<br> resolves access issues. After that, click 'Agree' to enable your microphone and unlock the full<br> potential of your VR adventure.<br>
                </p>
            </section>
            <footer>
                <button onclick="gtvr_message.close()" class="pure-button pure-button-primary">
                    Go Back
                </button>
            </footer>
        </dialog>
        `;
        document.body.insertAdjacentHTML( 'afterbegin', str);
        document.getElementById('gtvr_message').showModal();
    }

    showMicrophoneDialog(project)
    {
        let diag = document.getElementById('gtvr_message');
        if (diag)
            document.body.removeChild(diag);

        this.addGTVRCSSStyle();

        let str = `
        <dialog id="gtvr_message" class="gtvr_center">
            <header>
                <h3 class="header">Welcome to Your GOTOVIAR Adventure!</h3>
            </header>
            <section>
            <p>
            <b>Step 1:</b> Activate Your Microphone<br>
            Click 'Agree' on the popup below to enable your microphone. This lets you chat and make friends in<br> VR!<br>
            <b>Step 2:</b> Dive into the VR World<br>
            Click on Start step 2 and hit 'Agree' on the next browser popup to enter our immersive VR<br> environment.<br>
            <b>(Prepare to Click Quickly!</b> - Your next immersive popup awaits your swift click!)<br>
            </p>
            </section>
            <footer>
            <button id="gtvr_microphone_ok_button" disabled class="pure-button pure-button-primary">
                Start Step 2
            </button>
            </footer>
            <section>
            <p>
            <b>If you face any issues loading, just refresh the page. Don't worry, it's a one-time deal.<br>Once you're set, you're all set for all your future visits.</br>
            </p>
            </section>            
        </dialog>
        `;
        document.body.insertAdjacentHTML( 'afterbegin', str);
        diag = document.getElementById('gtvr_message');
        diag.showModal();
        document.getElementById('gtvr_microphone_ok_button').onclick = function() {
            diag.close();
            if (this.microIsOK === true)
                this.__runModule(project);
        }.bind(this);
        
    }
}
  
export default GTVRModule;
