
function ar_open_tab(evt, tabName, target) {
  // Declare all variables
  var i, ar_tabcontent, ar_tablinks;
  // Get all elements with class="tabcontent" and hide them
  ar_tabcontent = document.getElementsByClassName("ar_tabcontent");
  for (i = 0; i < ar_tabcontent.length; i++) {
    ar_tabcontent[i].style.display = "none";
  }
  var ar_option = document.getElementById("ar_admin_options");
  if (ar_option) {
    ar_option.style.display = "none";
  }
  var ar_modelviewer = document.getElementById("ar_admin_modelviewer");
  if (ar_modelviewer) {
    ar_modelviewer.style.display = "none";
  }
  
  // Get all elements with class="ar_tablinks" and remove the class "active"
  ar_tablinks = document.getElementsByClassName("ar_tablinks");
  for (i = 0; i < ar_tablinks.length; i++) {
    ar_tablinks[i].className = ar_tablinks[i].className.replace(" active", "");
  }
var tabElement = document.getElementById(tabName);
  // Show the current tab, and add an "active" class to the button that opened the tab
  document.getElementById(tabName).style.display = "block";
  //evt.currentTarget.className += " active";
  document.getElementById(target).className += " active";
  
if (tabElement && (tabElement.id.startsWith("model_files_content") || tabElement.id.startsWith("asset_builder_content"))) {
  if (ar_option) {
    ar_option.style.display = "block";
  }
  if (ar_modelviewer) {
    ar_modelviewer.style.display = "block";
  }
}
}

function ar_activeclass(divId) {
  var element = document.getElementById(divId);
  if (element) {
    element.className += " active";
  }
}



jQuery(document).ready(function(){
    
    //Accordian Content

    jQuery(document).on('click','.ar_accordian', function(event){
                    
        jQuery(this).toggleClass("ar_active");

        var panel = jQuery(this).next();
        //console.log(panel[0].scrollHeight);
        /*if (panel.style.display === "block") {
          panel.style.display = "none";
        } else {
          panel.style.display = "block";
        }*/
        if (panel[0].style.maxHeight) {
          panel[0].style.maxHeight = null;
        } else {
          panel[0].style.maxHeight = panel[0].scrollHeight + "px";
        }
    }); 


    jQuery(document).on('click','#toggle-model-fields', function(event){
        event.preventDefault();
        //console.log(jQuery(this).data('status'));
        if(jQuery(this).data('status') == 'hidden'){
            jQuery('#_usdz_file').attr('type','text');
            jQuery('#_glb_file').attr('type','text');
            jQuery(this).data('status','visible');
            jQuery(this).text('Hide Model Fields');
        } else {
            jQuery('#_usdz_file').attr('type','hidden');
            jQuery('#_glb_file').attr('type','hidden');
            jQuery(this).data('status','hidden');
            jQuery(this).text('Show Model Fields');
        }

    });
});  

//

 const modelTexturesArray = {}; 
 let modelLastSrc = {};     

//

function ARModelFields(containerId, options, autoInit = true) {
    // Default options to an empty object if not provided
    options = options || {};

    // Initialize instance properties
    this.modelid = containerId;
    this.options = Object.assign({}, options);  // Object.assign is ES6, so replaced with manual copying in ES5
    this.suffix = options.suffix || '';
    this.modelViewer = null;

    // Initialize AR Model Fields
    if (autoInit) {
        this.initARModelFields();
    } else{
        this.setMaterials();
    }
}

// Add methods to the prototype
ARModelFields.prototype.initARModelFields = function() {
    if(this.modelid != 'user_upload')
        this.uploadButtonScript();

    this.animationSelector();
    this.hotSpot();
    this.cameraRotation();
    this.assetBuilder();
    this.setMaterials();

    if (this.options.wc_model === '0') {
        this.modelFields();
        // console.log('arwp');
    } else {
        // console.log('arwc');
    }
};

ARModelFields.prototype.uploadButtonScript = function() {
    var options = this.options;
    jQuery(function($) {    
        var custom_uploader;
        var button_clicked;

        
        $(document).on('click','.upload_usdz_button, .upload_glb_button, .upload_skybox_button, .upload_environment_button, .upload_poster_button, .upload_qr_image_button, .upload_asset_texture_button, .upload_asset_texture_button_0, .upload_asset_texture_button_1, .upload_asset_texture_button_2, .upload_asset_texture_button_3, .upload_asset_texture_button_4, .upload_asset_texture_button_5, .upload_asset_texture_button_6, .upload_asset_texture_button_7, .upload_asset_texture_button_8, .upload_asset_texture_button_9', function(e) {
            window.button_clicked = $(this).attr('class');
            e.preventDefault();

            var variation_id = '';
            var model_idd = '';
            var suffix = '';

            //console.log('buttonclicked');

            if(e.target.hasAttribute('data-variation')){
                variation_id = '_var_' + e.target.getAttribute('data-variation');
                model_idd = e.target.getAttribute('data-variation');
                suffix = variation_id;
            } else {
                model_idd = options.product_parent;
            }

            $('#uploader_modelid').val(model_idd.replace(/"/g, ''));
        
            //If the uploader object has already been created, reopen the dialog
            if (custom_uploader) {
                custom_uploader.open();
                return;
            }
    
            //Extend the wp.media object
            custom_uploader = wp.media.frames.file_frame = wp.media({
                title: options.uploader_title,
                button: {
                    text: options.uploader_title
                },
                multiple: true
            });
    
            //When a file is selected, grab the URL and set it as the text field value
            custom_uploader.on('select', function() {
                var attachments = custom_uploader.state().get('selection').map( 
                   function( attachment ) {
                       attachment.toJSON();
                       return attachment;
                  });

                  //console.log(window.button_clicked);

                 $.each(attachments, function( index, attachement ) {
                      
                    var fileurl=attachments[index].attributes.url;
                    var filetype = fileurl.substring(fileurl.length - 4, fileurl.length).toLowerCase();
                    var modl_id = $('#uploader_modelid').val();
                    var sffx = '';

                    if (fileurl.startsWith('http://')) {
                        fileurl = fileurl.replace('http://', 'https://');
                    }

                    if(modl_id != options.product_parent){
                        sffx = '_var_' + modl_id;
                    }
                    //.reality files = lity (last 4 chars)
                    if ((filetype === 'usdz') || (filetype === 'USDZ') || (filetype === 'lity') || (filetype === 'LITY')){
                        
                        $('#_usdz_file' + sffx).attr('value',fileurl);
                        var usdz_filename = fileurl.substring(fileurl.lastIndexOf('/') + 1);
                        document.getElementById("usdz_filename"  + sffx).innerHTML= usdz_filename;
                        document.getElementById("usdz_thumb_img").src = options.usdz_thumb;
                        document.getElementById('usdz_thumb_img').classList.add('ar_file_icons_pulse');

                    }else if ((filetype === '.glb')||(filetype === 'gltf')||(filetype === '.zip')||(filetype === '.dae')){
                        
                        $('#_glb_file'  + sffx).attr('value',fileurl);
                        var glb_filename = fileurl.substring(fileurl.lastIndexOf('/') + 1);
                        document.getElementById("glb_filename"  + sffx).innerHTML=glb_filename;
                        document.getElementById("glb_thumb_img").src = options.glb_thumb;
                        var element = document.getElementById("model_" + modl_id);
                        
                        var element2 = document.getElementById("ar_admin_model_" + modl_id);
                        if (element2) {
                            element2.style.display = "block";
                        }
                        element.setAttribute("src", fileurl);


                    } else if ((filetype === '.hdr') || (filetype === '.jpg') || (filetype === '.png') || (filetype === 'webp')){

                        if (window.button_clicked.indexOf('upload_skybox_button') != -1){
                            $('#_skybox_file' + sffx).val(fileurl).trigger('change'); 
                        }
                        else if (window.button_clicked.indexOf('upload_environment_button') != -1){
                            $('#_ar_environment' + sffx).val(fileurl).trigger('change');
                        }
                        else if (window.button_clicked.indexOf('upload_poster_button') != -1){
                            $('#_ar_poster' + sffx).val(fileurl).trigger('change');
                        }
                        else if (window.button_clicked.indexOf('upload_qr_image_button') != -1){
                            $('#_ar_qr_image' + sffx).val(fileurl); 
                            $('#_ar_qr_image' + sffx).trigger('change'); 
                        }
                        
                        //Asset Builder Textures
                        $( ".upload_asset_texture_button" ).each(function( index ) {
                            if (window.button_clicked.indexOf('upload_asset_texture_button_' + index) != -1){
                                $('#_asset_texture_file_' + index).val(fileurl).trigger('input');
                                if ($('#_ar_asset_file').val()) {
                                    $('#ar_asset_builder_submit_container').css('display', 'block');
                                }
                                $('#ar_asset_builder_texture_done').html('&#10003;');
                            }
                        });
                    }
                        
                        
                    else{
                       
                
                            //$js_alert =__('Invalid file type. Please choose a USDZ, REALITY, GLB, GLTF, ZIP, HDR, JPG, PNG, DAE, DXF, 3DS, OBJ, PLY or STL file.', $ar_plugin_id );
                            alert(options.js_alert);
                        }

                        $('supports-drag-drop').hide();
                 });
     
            });
            //Open the uploader dialog
            custom_uploader.open();

            e.stopPropagation();
        });  
    });

    /*document.querySelector('._glb_file_field').addEventListener('change', function(e) {
        var model_id = this.getAttribute('data-model');
        var element = document.getElementById("model_" + model_id);
        element.setAttribute("src", this.value);
        var element2 = document.getElementById("ar_admin_model_" + model_id);
        element2.style.display = "block";
    }); */     
    
};


ARModelFields.prototype.animationSelector = function(){
    const modelViewer = document.querySelector('#model_' + this.modelid);
    
    if (!modelViewer) {
        //console.warn('Model viewer not found for model ID:', this.modelid);
        return;
    }
    
    const animationSelector = document.getElementById('_ar_animation_selection' + this.suffix);
    const animationDiv = document.getElementById('animationDiv');

    if (!animationSelector ) {
        //console.warn('Animation selector or animation div not found for model ID:', this.modelid);
        return;
    }

    // Load the model and retrieve animation names
    modelViewer.addEventListener('load', () => {
        const names = modelViewer.availableAnimations;

        if (names && names.length > 0) {
            names.forEach((animationName, index) => {
                const option = document.createElement('option');
                option.value = animationName;
                option.text = animationName || `Animation ${index + 1}`;
                animationSelector.appendChild(option);
                // Preselect an option if it matches the PHP variable value
                if (animationName === this.ar_animation_selection) {
                    option.selected = true;
                    modelViewer.animationName = animationName;
                   
                }
            });
            // Set the display style to "block" if animations exist
            animationDiv.style.display = 'block';

            // Add event listener to change animations
            animationSelector.addEventListener('change', () => {
                const selectedAnimationName = animationSelector.value;
                modelViewer.animationName = selectedAnimationName;
            });
        }
    });

    const arAnimationCheckbox = document.getElementById('_ar_animation' + this.suffix);
    if (arAnimationCheckbox) {
        arAnimationCheckbox.addEventListener('change', function() {
            const element = document.getElementById("ar-button-animation_");
            if (arAnimationCheckbox.checked) {
                element.style.display = "block";
            } else {
                element.style.display = "none";
            }
        });
    } else {
        //console.warn('Animation checkbox not found for suffix:', this.suffix);
    }
};


ARModelFields.prototype.hotSpot = function(){
    document.body.addEventListener( 'keyup', function ( event ) {
        //Hotspots update on change 
        if( event.target.id.startsWith('_ar_hotspots' )) {
            var hotspot_name = event.target.getAttribute("hotspot_name");
            var hotspot_link = event.target.getAttribute("hotspot_link");
            var match = event.target.id.match(/\[([0-9]+)\]/);
            var index = match ? match[1] : null;
            if (hotspot_name){
                var hotspot_content = document.getElementById(event.target.getAttribute("hotspot_name")).innerHTML;
                // Extract the index from the currentId
                if (index !== null) {
                    // Replace "annotation" with "link" and construct the new id
                    var newId = event.target.id.replace('annotation', 'link');
                    var inputlink = document.getElementById(newId).value;
                }
                var inputtext = event.target.value;
            }
            if (hotspot_link){
                var inputlink = event.target.value;
                // Replace "link" with "annotation" and construct the new id
                var newId = event.target.id.replace('link', 'annotation');
                var inputtext = document.getElementById(newId).value;
                var hotspot_name = hotspot_link;
            }
                
            if (inputlink){
                inputtext = '<a href="'+inputlink+'" target="_blank">'+inputtext+'</a>';
            }
            document.getElementById(hotspot_name).innerHTML='<div class="annotation">'+inputtext+'</div>';
        
        };
        //CTA update on change 
        if( event.target.id=='_ar_cta') {
            document.getElementById("ar-cta-button-container").style="display:block";
            document.getElementById("ar-cta-button").innerHTML=event.target.value;
        };
    });
};


ARModelFields.prototype.cameraRotation = function() {

    // Rotation Limits Compass
    const modelViewer = document.querySelector('#model_' + this.modelid);
    
    if (!modelViewer) {
        //console.warn('Model viewer not found for model ID:', this.modelid);
        return;
    }

    const ar_compass_buttons = document.getElementsByClassName('ar-compass-button');
    const ar_compass_image = document.getElementById('ar-compass-image');
    const ar_rotate_limit = document.getElementById('_ar_rotate_limit');
    
    if (!ar_compass_image || !ar_rotate_limit) {
        //console.warn('Compass image or rotation limit elements not found');
        return;
    }

    ar_rotate_limit.addEventListener('change', function() {
        const min_orbit_arr = modelViewer.getAttribute("min-camera-orbit").split(" ");
        const max_orbit_arr = modelViewer.getAttribute("max-camera-orbit").split(" ");
        const element = document.getElementById("ar_rotation_limits");

        if (!element) {
            //console.warn('Rotation limits element not found');
            return;
        }

        if (ar_rotate_limit.checked) {
            element.style.display = "block";
            element.style.borderColor = "#49848f";
        } else {
            element.style.display = "none";
            modelViewer.setAttribute("min-camera-orbit", 'auto auto ' + min_orbit_arr[2]);
            modelViewer.setAttribute("max-camera-orbit", 'Infinity auto ' + max_orbit_arr[2]);
            document.getElementById("_ar_compass_top_value").value = '';
            document.getElementById("_ar_compass_bottom_value").value = '';
            document.getElementById("_ar_compass_left_value").value = '';
            document.getElementById("_ar_compass_right_value").value = '';
            document.getElementById("ar-compass-top").style.backgroundColor = '#e2e2e2';
            document.getElementById("ar-compass-bottom").style.backgroundColor = '#e2e2e2';
            document.getElementById("ar-compass-left").style.backgroundColor = '#e2e2e2';
            document.getElementById("ar-compass-right").style.backgroundColor = '#e2e2e2';
        }
    });

    // Add a click event listener to each compass button
    if (ar_compass_buttons.length > 0) {
        for (let i = 0; i < ar_compass_buttons.length; i++) {
            ar_compass_buttons[i].addEventListener('mouseenter', function() {
                const id = this.id;
                if (id === 'ar-compass-top') {
                    ar_compass_image.style.transform = 'rotate(0deg)';
                } else if (id === 'ar-compass-bottom') {
                    ar_compass_image.style.transform = 'rotate(180deg)';
                } else if (id === 'ar-compass-right') {
                    ar_compass_image.style.transform = 'rotate(90deg)';
                } else if (id === 'ar-compass-left') {
                    ar_compass_image.style.transform = 'rotate(270deg)';
                }
            });

            ar_compass_buttons[i].addEventListener('click', function() {
                const id = this.id;
                const orbit = modelViewer.getCameraOrbit();
                const min_orbit_arr = modelViewer.getAttribute("min-camera-orbit").split(" ");
                const max_orbit_arr = modelViewer.getAttribute("max-camera-orbit").split(" ");

                let orbitString;
                if (id === 'ar-compass-top') {
                    if (!document.getElementById("_ar_compass_top_value").value) {
                        orbitString = `${orbit.phi}rad`;
                        document.getElementById("_ar_compass_top_value").value = orbitString;
                        document.getElementById(id).style.backgroundColor = '#f37a23';
                    } else {
                        orbitString = 'auto';
                        document.getElementById(id).style.backgroundColor = '#e2e2e2';
                        document.getElementById("_ar_compass_top_value").value = '';
                    }
                    modelViewer.setAttribute("min-camera-orbit", min_orbit_arr[0] + ' ' + orbitString + ' ' + min_orbit_arr[2]);

                } else if (id === 'ar-compass-bottom') {
                    if (!document.getElementById("_ar_compass_bottom_value").value) {
                        orbitString = `${orbit.phi}rad`;
                        document.getElementById("_ar_compass_bottom_value").value = orbitString;
                        document.getElementById(id).style.backgroundColor = '#f37a23';
                    } else {
                        orbitString = 'auto';
                        document.getElementById(id).style.backgroundColor = '#e2e2e2';
                        document.getElementById("_ar_compass_bottom_value").value = '';
                    }
                    modelViewer.setAttribute("max-camera-orbit", max_orbit_arr[0] + ' ' + orbitString + ' ' + max_orbit_arr[2]);

                } else if (id === 'ar-compass-right') {
                    if (!document.getElementById("_ar_compass_right_value").value) {
                        orbitString = `${orbit.theta}rad`;
                        document.getElementById("_ar_compass_right_value").value = orbitString;
                        document.getElementById(id).style.backgroundColor = '#f37a23';
                    } else {
                        orbitString = 'Infinity';
                        document.getElementById(id).style.backgroundColor = '#e2e2e2';
                        document.getElementById("_ar_compass_right_value").value = '';
                    }
                    modelViewer.setAttribute("max-camera-orbit", orbitString + ' ' + max_orbit_arr[1] + ' ' + max_orbit_arr[2]);

                } else if (id === 'ar-compass-left') {
                    if (!document.getElementById("_ar_compass_left_value").value) {
                        orbitString = `${orbit.theta}rad`;
                        document.getElementById("_ar_compass_left_value").value = orbitString;
                        document.getElementById(id).style.backgroundColor = '#f37a23';
                    } else {
                        orbitString = 'auto';
                        document.getElementById(id).style.backgroundColor = '#e2e2e2';
                        document.getElementById("_ar_compass_left_value").value = '';
                    }
                    modelViewer.setAttribute("min-camera-orbit", orbitString + ' ' + min_orbit_arr[1] + ' ' + min_orbit_arr[2]);
                }

                modelViewer.removeAttribute("auto-rotate");
                document.getElementById("_ar_rotate").checked = true;
            });

            // Set up camera orbit button click handlers once
            jQuery(document).on('click','#camera_view_button_wp, #camera_view_button_wp_second', function() {
                const orbit = modelViewer.getCameraOrbit();
                const orbitString = `${orbit.theta}rad ${orbit.phi}rad ${orbit.radius}m`;
                
                document.getElementById("_ar_camera_orbit_set").style.display = 'block';
                document.getElementById("_ar_camera_orbit").value = orbitString;
            });
        }
    } else {
        //console.warn('No compass buttons found');
    }
};

ARModelFields.prototype.assetBuilder = function(){
     var self = this;

    var asset_JsonList = {"asset_Table" : 
        [
                {"modelMakeID" : "1","modelMake" : "1.0"},
                {"modelMakeID" : "2","modelMake" : "1.4142"},
                {"modelMakeID" : "3","modelMake" : "1.25"},
                {"modelMakeID" : "4","modelMake" : "1.5"},
                {"modelMakeID" : "5","modelMake" : "1.33"},
                {"modelMakeID" : "5","modelMake" : "3.1"}
        ]};
    var modelTypeJsonList = {"1.0" : 
        [
                {"modelTypeID" : "0.8","modelType" : "20.3 x 20.3cm / 8 x 8in"},
                {"modelTypeID" : "1","modelType" : "25.4 x 25.4cm / 10 x 10in"},
                {"modelTypeID" : "1.2","modelType" : "30.5 x 30.5cm / 12 x 12in"},
                {"modelTypeID" : "1.6","modelType" : "40.6 x 40.6cm / 16 x 16in"},
                {"modelTypeID" : "2.4","modelType" : "61.0 x 61.0cm / 24 x 24in"},
                {"modelTypeID" : "3.6","modelType" : "91.4 x 91.4cm / 36 x 36in"}
        ],
        "1.4142" : 
        [
                {"modelTypeID" : "1","modelType" : "A4 21.0 x 29.7cm / 8.3 x 11.7in"},
                {"modelTypeID" : "1.41","modelType" : "A3 29.7 x 42cm / 11.7 x 16.5in"},
                {"modelTypeID" : "2","modelType" : "A2 42 x 59.4cm / 16.5 x 23.4in"},
                {"modelTypeID" : "2.83","modelType" : "A1 59.4 x 84.1cm / 23.4 x 33.1in"}
        ],
        "1.25" : 
        [
                {"modelTypeID" : "1","modelType" : "20 x 25cm / 8 x 10in"},
                {"modelTypeID" : "1.5","modelType" : "30.5 x 38.0cm / 12 x 15in"},
                {"modelTypeID" : "2","modelType" : "41 x 51cm /16 x 20in"},
                {"modelTypeID" : "3","modelType" : "61 x 76cm / 24 x 30in"}
        ],
        "1.5" : 
        [
                {"modelTypeID" : "1","modelType" : "20 x 30cm"},
                {"modelTypeID" : "1","modelType" : "20 x 30cm / 8 x 12in"},
                {"modelTypeID" : "1.5","modelType" : "30 x 46cm / 12 x 18in"},
                {"modelTypeID" : "2","modelType" : "41 x 51cm / 16 x 24in"},
                {"modelTypeID" : "2.5","modelType" : "51 x 76cm / 20 x 30in"}
        ],
        "1.33" : 
        [
                {"modelTypeID" : "1","modelType" : "23 x 30cm / 9 x 12in"},
                {"modelTypeID" : "1.3","modelType" : "30 x 41cm/ 12 x 16in"},
                {"modelTypeID" : "1.6","modelType" : "38 x 51cm/ 15 x 20in"},
                {"modelTypeID" : "2","modelType" : "46 x 61cm / 18 x 24in"}
        ],
        "3.1": [
                {"modelTypeID": "1", "modelType": "12 x 38cm / 5 x 15in"},
                {"modelTypeID": "2", "modelType": "25 x 76cm/ 10 x 30in"},
                {"modelTypeID": "3", "modelType": "38 x 114cm/ 15 x 45in"},
                {"modelTypeID": "4", "modelType": "50 x 152cm / 20 x 60in"}
        ]
    };
    var ModelListItems= "";
    for (var i = 0; i < asset_JsonList.asset_Table.length; i++){
        ModelListItems+= "<option value='" + asset_JsonList.asset_Table[i].modelMakeID + "'>" + asset_JsonList.asset_Table[i].modelMake + "</option>";
    }
    jQuery("#makeSelectionBox").html(ModelListItems);

    var updatear_asset_size_options = function(ratio) {
        if (ratio === '1') {
            ratio = '1.0';
        }
        //console.log('updating with here ', ratio);
        var listItems = "";
        if (ratio in modelTypeJsonList) {
    
        } else {
    
            ratio = '1.0';
        }
        if (ratio in modelTypeJsonList) {
            var ar_asset_default_size = parseFloat(document.querySelector("#_ar_asset_default_size").value).toFixed(2); // Round to 2 decimals

            for (var i = 0; i < modelTypeJsonList[ratio].length; i++) {
                var modelTypeID = parseFloat(modelTypeJsonList[ratio][i].modelTypeID).toFixed(2); // Round to 2 decimals
                var selected = (ar_asset_default_size === modelTypeID) ? "selected" : ""; // Check if they match
                listItems += "<option value='" + modelTypeJsonList[ratio][i].modelTypeID + "' " + selected + ">" + modelTypeJsonList[ratio][i].modelType + "</option>";
                // If selected, also set the value of #_ar_x to modelTypeID
                if (selected) {
                    document.getElementById("_ar_x").value = modelTypeJsonList[ratio][i].modelTypeID;
                }
            }
            jQuery("select#ar_asset_size").html(listItems);
            jQuery('#ar_asset_size_container').css('display', 'block');
            //jQuery('#ar_asset_builder_message').css('display', 'none');
            
            /*if (jQuery('#_ar_asset_file').val()) {
                jQuery('#ar_asset_builder_model_done').html('&#10003;');
                jQuery('#ar_asset_builder_submit_container').css('display', 'block');
            }*/
            if (document.getElementById("_asset_texture_file_0").value) {
                // Check if we're in user upload context
                var isUserUploadContext = document.querySelector('#model_user_upload') !== null;
                
                if (isUserUploadContext) {
                    console.log('User upload context: updating size options and model viewer with new ratio');
                    // In user upload context, update size options AND update model viewer with new ratio
                    jQuery('#_ar_asset_ratio_select').val(document.getElementById("_ar_asset_ratio").value);
                    
                    // IMPORTANT: We need to update the model viewer with the new ratio dimensions
                    // Get the current model viewer and update it with new ratio while preserving the image
                    var modelViewer = document.querySelector('#model_user_upload');
                    if (modelViewer && modelViewer.src) {
                        var currentSrc = modelViewer.src;
                        var baseUrl = currentSrc.split('?')[0];
                        
                        // Extract current parameters
                        var urlParams = new URLSearchParams(currentSrc.split('?')[1] || '');
                        var currentImageUrl = urlParams.get('url');
                        var currentNonce = urlParams.get('_wpnonce') || '';
                        
                        // Get new ratio and orientation values
                        var newRatio = document.getElementById("_ar_asset_ratio").value;
                        var newOrientation = document.getElementById("_ar_asset_orientation").value;
                        
                        // Calculate new dimensions based on ratio
                        var newWidth, newHeight;
                        if (newRatio === '1.0') {
                            newWidth = '300'; newHeight = '300'; // Square
                        } else if (newRatio === '1.4142') {
                            newWidth = '300'; newHeight = '212'; // A4 ratio
                        } else if (newRatio === '1.25') {
                            newWidth = '300'; newHeight = '240'; // 5:4 ratio
                        } else if (newRatio === '1.5') {
                            newWidth = '300'; newHeight = '200'; // 3:2 ratio
                        } else if (newRatio === '1.33') {
                            newWidth = '300'; newHeight = '225'; // 4:3 ratio
                        } else if (newRatio === '1.27') {
                            newWidth = '300'; newHeight = '236'; // Custom ratio
                        } else {
                            // Default to 2:3 ratio
                            newWidth = '300'; newHeight = '200';
                        }
                        
                        // Get current frame settings
                        var framedValue = document.querySelector("#_ar_framed") ? document.querySelector("#_ar_framed").value : "0";
                        var frameColor = document.getElementById("_ar_frame_color") ? document.getElementById("_ar_frame_color").value.replace('#', '') : "f8f8f8";
                        var opacity = document.getElementById("_ar_frame_opacity") ? document.getElementById("_ar_frame_opacity").value : "1.0";
                        
                        // Build new URL with updated ratio dimensions
                        var newUrl = baseUrl + '?url=' + encodeURIComponent(currentImageUrl) + 
                            '&ratio=' + newRatio + '&f=' + framedValue + '&fc=' + frameColor + '&opacity=' + opacity;
                        
                        if (currentNonce) {
                            newUrl += '&_wpnonce=' + currentNonce;
                        }
                        
                        // Update the model viewer with new ratio dimensions
                        modelViewer.src = newUrl;
                        console.log('Updated model viewer with new ratio dimensions:', newUrl);
                    }
                    
                    // Build the size options list based on ratio and orientation
                    var ratio = document.getElementById("_ar_asset_ratio").value;
                    var orientation = document.getElementById("_ar_asset_orientation").value;
                    
                    // Build the size options list based on ratio and orientation
                    var listItems = '';
                    if (ratio === '1.0') {
                        listItems = '<option value="0.8">20.3 x 20.3cm / 8 x 8in</option><option value="1">25.4 x 25.4cm / 10 x 10in</option><option value="1.2">30.5 x 30.5cm / 12 x 12in</option><option value="1.6">40.6 x 40.6cm / 16 x 16in</option><option value="2.4">61.0 x 61.0cm / 24 x 24in</option><option value="3.6">91.4 x 91.4cm / 36 x 36in</option>';
                    } else if (ratio === '1.4142') {
                        listItems = '<option value="1">A4 21.0 x 29.7cm / 8.3 x 11.7in</option><option value="1.41">A3 29.7 x 42cm / 11.7 x 16.5in</option><option value="2">A2 42 x 59.4cm / 16.5 x 23.4in</option><option value="2.83">A1 59.4 x 84.1cm / 23.4 x 33.1in</option>';
                    } else if (ratio === '1.25') {
                        listItems = '<option value="1">20 x 25cm / 8 x 10in</option><option value="1.5">30.5 x 38.0cm / 12 x 15in</option><option value="2">41 x 51cm /16 x 20in</option><option value="3">61 x 76cm / 24 x 30in</option>';
                    } else if (ratio === '1.5') {
                        listItems = '<option value="1">20 x 30cm / 8 x 12in</option><option value="1.5">30 x 46cm / 12 x 18in</option><option value="2">40 x 60cm / 16 x 24in</option><option value="2.5">50 x 75cm / 20 x 30in</option>';
                    } else if (ratio === '1.33') {
                        listItems = '<option value="1">20 x 26.7cm / 8 x 10.5in</option><option value="1.5">30 x 40cm / 12 x 16in</option><option value="2">40 x 53.3cm / 16 x 21in</option><option value="2.5">50 x 66.7cm / 20 x 26.3in</option>';
                    } else if (ratio === '1.27') {
                        listItems = '<option value="1">20 x 25.4cm / 8 x 10in</option><option value="1.5">30 x 38.1cm / 12 x 15in</option><option value="2">40 x 50.8cm / 16 x 20in</option><option value="2.5">50 x 63.5cm / 20 x 25in</option>';
                    } else if (ratio === '3.1') {
                        listItems = '<option value="1">12 x 38cm / 5 x 15in</option><option value="1.5">18 x 57cm / 7.5 x 22.5in</option><option value="2">24 x 76cm / 10 x 30in</option><option value="2.5">30 x 95cm / 12.5 x 37.5in</option>';
                    } else {
                        // Default ratio options
                        listItems = '<option value="1">100%</option><option value="1.5">150%</option><option value="2">200%</option><option value="2.5">250%</option>';
                    }
                    
                    // Update the size options dropdown
                    jQuery("select#ar_asset_size").html(listItems);
                    jQuery('#ar_asset_size_container').css('display', 'block');
                    
                } else {
                    // In gallery context, update everything normally
                    var framedValue = document.querySelector("#_ar_framed").value;
                    // Get the value of the input field
                    var frameColor = document.getElementById("_ar_frame_color").value;
                    // Remove the '#' character if it exists
                    frameColor = frameColor.replace('#', '');
                    var ar_asset_gallery = document.getElementById("_ar_asset_url").value + '?url=' + document.getElementById("_asset_texture_file_0").value + '&ratio=' + document.getElementById("_ar_asset_ratio").value+ '&o=' + document.getElementById("_ar_asset_orientation").value+ '&f=' + framedValue+ '&fc=' + frameColor+ '&opacity=' + document.getElementById("_ar_frame_opacity").value + '&_wpnonce=' + document.getElementById("_ar_wpnonce").value;
                    const modelViewer = document.querySelector('#model_'+self.modelid);
                    modelViewer.setAttribute("src", ar_asset_gallery);
                    //calculateImageRatio();
                    jQuery('#_ar_asset_ratio_select').val(document.getElementById("_ar_asset_ratio").value);
                    jQuery('#_glb_file').val(ar_asset_gallery);
                }
            }
        }
    }
    jQuery(document).ready(function($) {
        var ratio = $('#_ar_asset_ratio_select').val(); // Or set it to the desired ratio
        // Check if the ratio exists and is valid
        if (ratio) {
            updatear_asset_size_options(ratio); // Call the function with the ratio on page load
            var scale = $('#_ar_x').val();
            if (scale) {
                $('#ar_asset_size').val(scale).change();
            }
        }
    });
    // Light Color - initialize the WordPress color picker
    jQuery(document).ready(function($) {
        // Initialize the Iris color picker with custom palettes for #_ar_light_color
        $('#_ar_light_color').iris({
            palettes: ['#ff0000', '#00ff00', '#0000ff', '#ffffff', '#000000', '#cccccc'],
            change: function(event, ui) {
                // Detect color change and update the model viewer
                var modelViewer = document.querySelector('#model_' + self.modelid);
                modelViewer.setAttribute("light-color", ui.color.toString());
            },
            clear: function() {
                // Handle color clear event
                var modelViewer = document.querySelector('#model_' + self.modelid);
                modelViewer.setAttribute("light-color", "");
            }
        });
    
        // Toggle Iris color picker on #_ar_light_color input field click
        $('#_ar_light_color').on('click', function(event) {
            event.stopPropagation(); // Prevent this click from triggering the document click event
            if ($('.iris-picker').is(':visible')) {
                $('#_ar_light_color').iris('hide');
            } else {
                $('#_ar_light_color').iris('show');
            }
        });
    
        // Close the color picker when clicking outside of it
        $(document).on('click', function(event) {
            if (!$(event.target).closest('#_ar_light_color, .iris-picker').length) {
                $('#_ar_light_color').iris('hide'); // Hide the Iris color picker if clicking outside
            }
        });
    });
    
    
    jQuery(document).ready(function($) {
    
    // Ensure the script runs after the DOM is fully loaded
        $(document).ready(function() {
            // Get the current value of the color input field or default to black
            var currentColor; 

            if($('#_ar_frame_color').val()){
                currentColor = $('#_ar_frame_color').val().trim(); // Default to black if empty
            } else {        
            // Check if the color value is correctly set            
                currentColor = '#000000'; // Fallback to black if still empty, null, or falsy
            }
        
            // Initialize the color picker with the current color
            $('#_ar_frame_color').iris({
                color: currentColor,
                change: function(event, ui) {
                    // Handle color change event for frame color
                    updateModelViewer();
                }
            });
        
            // Toggle Iris color picker on input field click
            $('#_ar_frame_color').on('click', function(event) {
                event.stopPropagation(); // Prevent this click from triggering the document click event
                if ($('.iris-picker').is(':visible')) {
                    $('#_ar_frame_color').iris('hide');
                } else {
                    $('#_ar_frame_color').iris('show');
                }
            });
        
            // Close the color picker when clicking outside of it
            $(document).on('click', function(event) {
                if (!$(event.target).closest('#_ar_frame_color, .iris-picker').length) {
                    $('#_ar_frame_color').iris('hide'); // Hide the Iris color picker if clicking outside
                }
            });
        });
            // Function to update the model viewer URL
            

        // Event listeners for color and framed fields
        $('#_ar_framed, #_ar_frame_opacity, #_asset_texture_file_0').on('change', function() {
            updateModelViewer();
        });
    // Detect manual input in the color field (for users who type the color value)
        $('#_ar_frame_color').on('input', function() {
            // You can trigger the model update or other actions here
            //console.log('Manual color input:', $(this).val());
            updateModelViewer();
        });
        
    

    });
    
    function updateModelViewer() {            
        var textureFileElement = document.getElementById("_asset_texture_file_0");
        if (!textureFileElement || !textureFileElement.value) {
            return; // No texture file to process
        }
        
        var textureValue = textureFileElement.value;
        
        // Check if we're in user upload context
        var isUserUploadContext = document.querySelector('#model_user_upload') !== null;
        
        // Skip processing if this is a base64 data URL (user upload context)
        if (textureValue.startsWith('data:image/') || textureValue.startsWith('blob:')) {
            console.log('Skipping updateModelViewer for base64/blob data - this is user upload context');
            return;
        }
        
        // If we're in user upload context and have a processed image URL, update frame effects
        if (isUserUploadContext && textureValue.includes('ar_temp')) {
            console.log('User upload context detected - updating frame effects');
            
            // Get frame values with safety checks and fallbacks
            var framedElement = document.querySelector("#_ar_framed");
            var framedValue = framedElement ? framedElement.value : "0";
            
            var frameColorElement = document.getElementById("_ar_frame_color");
            var frameColor = frameColorElement ? frameColorElement.value : "f8f8f8";
            // Remove the '#' character if it exists
            frameColor = frameColor.replace('#', '');
            
            var opacityElement = document.getElementById("_ar_frame_opacity");
            var opacity = opacityElement ? opacityElement.value : "1.0";
            
            // Update the existing model viewer URL with new frame parameters
            var modelViewer = document.querySelector('#model_user_upload');
            if (modelViewer && modelViewer.src) {
                var currentSrc = modelViewer.src;
                var baseUrl = currentSrc.split('?')[0];
                
                // Extract width and height from current URL if available
                var urlParams = new URLSearchParams(currentSrc.split('?')[1] || '');
                var width = urlParams.get('width') || '300';
                var height = urlParams.get('height') || '144';
                var nonce = urlParams.get('_wpnonce') || '';
                
                // IMPORTANT: Extract the actual image URL from textureValue if it's a gallery URL
                var imageUrl = textureValue;
                if (textureValue.includes('ar-gallery.php') && textureValue.includes('url=')) {
                    try {
                        var galleryUrlParams = new URLSearchParams(textureValue.split('?')[1] || '');
                        var extractedImageUrl = galleryUrlParams.get('url');
                        if (extractedImageUrl) {
                            imageUrl = decodeURIComponent(extractedImageUrl);
                            console.log('Extracted image URL from gallery URL:', imageUrl);
                        }
                    } catch (e) {
                        console.log('Failed to extract image URL from gallery URL:', e);
                    }
                }
                
                var newUrl = baseUrl + '?url=' + encodeURIComponent(imageUrl) + 
                           '&width=' + width + '&height=' + height + 
                           '&f=' + framedValue + '&fc=' + frameColor + '&opacity=' + opacity;
                           
                if (nonce) {
                    newUrl += '&_wpnonce=' + nonce;
                }
                
                // Update the model viewer with new frame effects
                modelViewer.src = newUrl;
                console.log('Updated user upload model viewer with new frame effects:', newUrl);
                
                // Also update the thumbnail if it exists
                var thumbnailElement = document.querySelector('#asset_thumb_img');
                if (thumbnailElement) {
                    thumbnailElement.src = imageUrl;
                    console.log('Updated thumbnail with:', imageUrl);
                }
            }
            
            return; // Exit early - don't run the gallery context code
        }
        
        // Get frame values with safety checks and fallbacks
        var framedElement = document.querySelector("#_ar_framed");
        var framedValue = framedElement ? framedElement.value : "0";
        
        var frameColorElement = document.getElementById("_ar_frame_color");
        var frameColor = frameColorElement ? frameColorElement.value : "f8f8f8";
        // Remove the '#' character if it exists
        frameColor = frameColor.replace('#', '');
        
        var opacityElement = document.getElementById("_ar_frame_opacity");
        var opacity = opacityElement ? opacityElement.value : "1.0";
        
        // Get ratio and orientation with fallbacks
        var ratioElement = document.getElementById("_ar_asset_ratio");
        var ratio = ratioElement ? ratioElement.value : "2";
        
        var orientationElement = document.getElementById("_ar_asset_orientation");
        var orientation = orientationElement ? orientationElement.value : "portrait";
        
        // Get asset URL with fallback - check if we're in gallery context
        var assetUrlElement = document.getElementById("_ar_asset_url");
        var assetUrl = "";
        
        if (assetUrlElement && assetUrlElement.value) {
            // We're in gallery context, use the asset URL
            assetUrl = assetUrlElement.value;
        } else {
            // We're in user upload context, construct URL from current model viewer
            var userUploadModel = document.querySelector('#model_user_upload');
            if (userUploadModel && userUploadModel.src) {
                // Extract the base URL from the current model viewer
                var currentSrc = userUploadModel.src;
                var urlMatch = currentSrc.match(/^(.+?)\?url=/);
                if (urlMatch) {
                    assetUrl = urlMatch[1];
                } else {
                    // Fallback to a default gallery URL
                    assetUrl = window.location.origin + "/wp-content/plugins/ar-for-wordpress/includes/ar-gallery.php";
                }
            } else {
                // Fallback to a default gallery URL
                assetUrl = window.location.origin + "/wp-content/plugins/ar-for-wordpress/includes/ar-gallery.php";
            }
        }
        
        // Get nonce with fallback
        var nonceElement = document.getElementById("_ar_wpnonce");
        var nonce = nonceElement ? nonceElement.value : "";
        
        var ar_asset_gallery = assetUrl 
            + '?url=' + textureValue
            + '&ratio=' + ratio 
            + '&o=' + orientation 
            + '&f=' + framedValue
            + '&fc=' + frameColor
            + '&opacity=' + opacity;
        
        // Add nonce if available
        if (nonce) {
            ar_asset_gallery += '&_wpnonce=' + nonce;
        }

        // Update model viewer if it exists
        const galleryModelViewer = document.querySelector('#model_' + self.modelid);
        if (galleryModelViewer) {
            galleryModelViewer.setAttribute("src", ar_asset_gallery);
            
            // Update other elements if they exist
            var ratioSelect = jQuery('#_ar_asset_ratio_select');
            if (ratioSelect.length) {
                ratioSelect.val(ratio);
            }
            
            var glbFile = jQuery('#_glb_file');
            if (glbFile.length) {
                glbFile.val(ar_asset_gallery);
            }
            
            calculateImageRatio();
        }
    }
    

    function ar_update_size_fn(){ 
        var ratio = jQuery('#_ar_asset_ratio').val();

        if (ratio === '1') {
            ratio = '1.0';
        }
        jQuery('#_ar_asset_ratio_select').val(ratio);
        
        
        updatear_asset_size_options(ratio); 
        jQuery('#ar_asset_builder_texture_done').html('&#10003;');
    }  

    //var ar_update_size_function = ar_update_size_fn();
    jQuery("select#_ar_asset_ratio_select, select#_ar_asset_orientation").on('change', function() {
        var selectedRatio = jQuery('#_ar_asset_ratio_select option:selected').val();
        jQuery('#_ar_asset_ratio').val(selectedRatio);
        
        // Check if we're in user upload context
        var isUserUploadContext = document.querySelector('#model_user_upload') !== null;
        
        if (isUserUploadContext) {
            console.log('Ratio changed in user upload context - updating size options only');
            // In user upload context, just update the size options without changing the model
            updatear_asset_size_options(selectedRatio);
            
            // IMPORTANT: Don't trigger any model viewer updates in user upload context
            // The model viewer should keep its current image and just update the size options
        } else {
            // In gallery context, update everything normally
            updatear_asset_size_options(selectedRatio);
        }
    });  
    
    //Update the scale of the model
    jQuery("select#ar_asset_size").on('change',function(){
        this.suffix ='';
        var selectedSize = jQuery('#ar_asset_size option:selected').val();
        if (selectedSize != null){
            //console.log(selectedSize + ' selected asset size');
            jQuery('#_ar_x' + this.suffix).val(selectedSize);
            jQuery('#_ar_y' + this.suffix).val(selectedSize);
        }
         
        jQuery('#ar_asset_builder_size_done').html('&#10003;');
        const modelViewer = document.querySelector('#model_'+self.modelid);
        var x = document.getElementById('_ar_x') ? document.getElementById('_ar_x').value : '1';
        var y = document.getElementById('_ar_y') ? document.getElementById('_ar_y').value : '1';
        var z = document.getElementById('_ar_z') ? document.getElementById('_ar_z').value : '1';

        const updateScale = () => {
          modelViewer.scale = x +' '+ y +' '+ z;
        };
        updateScale();
        
    });


    function calculateImageRatio() {
      var imageUrl = jQuery('#_asset_texture_file_0').val();
    // Decode the URL-encoded blob URL
        var decodedImageUrl = decodeURIComponent(imageUrl); // Decode the URL-encoded blob URL
        
        // Create an image element dynamically
        var img = new Image();
        
        // Check if the decoded URL is a blob URL
        if (decodedImageUrl && decodedImageUrl.startsWith('blob:')) {
            // If it's a blob URL, use it directly
            img.src = decodedImageUrl;  // Blob URL
        } else {
            img.src = imageUrl;
        }
      // Wait for the image to load
      img.onload = function() {
        // Calculate aspect ratio (always width/height for consistency)
        var raw_ratio = img.width / img.height;
        var aspect_ratio = parseFloat(raw_ratio.toFixed(2));
        
        // Determine orientation
        var orientation = 'landscape'; // default to landscape
        if (img.width < img.height) {
            orientation = 'portrait';
            // For portrait images, invert the ratio to match available models
            aspect_ratio = parseFloat((img.height / img.width).toFixed(2));
        } else if (img.width == img.height) {
            orientation = 'square';
            aspect_ratio = 1.0;
        }

        // Update the select field with the orientation
        jQuery('#_ar_asset_orientation').val(orientation);
        
        // Define the target ratios - must match models.json
        var targetRatios = [1.0, 1.4142, 1.25, 1.5, 1.33, 3.1];

        // Find the closest ratio
        var closestRatio = findClosestRatio(aspect_ratio, targetRatios);
        
        // Ensure closestRatio is properly formatted as string for form fields
        if (closestRatio === 1 || closestRatio === 1.0) {
            closestRatio = '1.0';
        } else {
            closestRatio = closestRatio.toString();
        }

        // Output the result
        jQuery('#_ar_asset_ratio').val(closestRatio);
        //console.log('Closest Ratio: ' + closestRatio);
         // Execute the ar_update_size_fn function to sync dropdown and update sizes
        ar_update_size_fn();
      };
    }

    // Function to find the closest ratio
    function findClosestRatio(actualRatio, targetRatios) {
      var closestRatio = targetRatios[0];
      var minDifference = Math.abs(actualRatio - targetRatios[0]);

      for (var i = 1; i < targetRatios.length; i++) {
        var difference = Math.abs(actualRatio - targetRatios[i]);
        if (difference < minDifference) {
          minDifference = difference;
          closestRatio = targetRatios[i];
        }
      }

      return closestRatio;
    }
    function asset_display_thumb() {
        
        var imageUrl = jQuery('#_asset_texture_file_0').val();
        jQuery('#asset_thumb_img').attr('src', imageUrl);
    }
    
    // Trigger the function when the value of _asset_texture_file_0 changes (on file selection or clearing)
    jQuery('#_asset_texture_file_0').on('change', function() {
        // Check if we're in user upload context
        var isUserUploadContext = document.querySelector('#model_user_upload') !== null;
        
        if (isUserUploadContext) {
            console.log('User upload context: skipping automatic ratio calculation');
            // In user upload context, just update the thumbnail without changing ratios
            asset_display_thumb();
        } else {
            // In gallery context, calculate ratio and update thumbnail
            calculateImageRatio();
            asset_display_thumb();
        }
    });
    
    // Also trigger the function on text input (useful if this applies to non-file fields)
    jQuery('#_asset_texture_file_0').on('input', function() {
        // Check if we're in user upload context
        var isUserUploadContext = document.querySelector('#model_user_upload') !== null;
        
        if (isUserUploadContext) {
            console.log('User upload context: skipping automatic ratio calculation on input');
            // In user upload context, just update the thumbnail without changing ratios
            asset_display_thumb();
        } else {
            // In gallery context, calculate ratio and update thumbnail
            calculateImageRatio();
            asset_display_thumb();
        }
    }); 
};


ARModelFields.prototype.modelFields = function(){
    const modelViewer = document.querySelector('#model_'+this.modelid);
    const modelid = this.modelid;

    document.getElementById('_ar_disable_zoom').addEventListener('change', function() {
        if (document.getElementById("_ar_disable_zoom").checked == true){
            modelViewer.setAttribute("disable-zoom",true);
        }else{
            modelViewer.removeAttribute("disable-zoom");
        }
    });

    document.getElementById('_ar_resizing').addEventListener('change', function() {
        if (document.getElementById("_ar_resizing").checked == true){
            modelViewer.setAttribute("ar-scale","fixed");
        }else{
            modelViewer.setAttribute("ar-scale","auto");
        }
    });

    document.getElementById('_ar_rotate').addEventListener('change', function() {
        if (document.getElementById("_ar_rotate").checked == true){
            modelViewer.removeAttribute("auto-rotate");
        }else{
            modelViewer.setAttribute("auto-rotate",true);
        }
    });
    if(this.options.public != 'y'){
        document.getElementById('_glb_file').addEventListener('change', function() {
            
            modelViewer.setAttribute("src", this.value);
            var element2 = document.getElementById("ar_admin_model");
            if (element2) {
                element2.style.display = "block";
            }
        });

        jQuery(document).on('change','#_skybox_file', function(e) {
            //console.log('skybox changed' + jQuery(this).val());
            
            modelViewer.setAttribute("skybox-image", jQuery(this).val());
        });

       jQuery(document).on('change','#_ar_environment', function(e) {
            
            modelViewer.setAttribute("environment-image", jQuery(this).val());
        });
        jQuery(document).on('change','#_ar_emissive', function(e) {
           
            var value = this.value;
            
            if (value === 'False') {
                modelViewer.removeAttribute("emissive");
            } else {
                modelViewer.setAttribute("emissive", "True");
            }
        });
    
        document.getElementById('_ar_placement').addEventListener('change', function() {
            
            if (this.value == 'floor'){
                modelViewer.setAttribute("ar-placement", '');
            }else{
                modelViewer.setAttribute("ar-placement", this.value);
            }
        });
    }

    document.getElementById('_ar_zoom_in').addEventListener('change', function() {
        
        if (this.value == 'default'){
            modelViewer.setAttribute("min-camera-orbit", 'auto auto 20%');
        }else{
            const min_orbit_arr = modelViewer.getAttribute("min-camera-orbit").split(" ");
            modelViewer.setAttribute("min-camera-orbit", min_orbit_arr[0]+' '+min_orbit_arr[1]+' '+(100 - this.value) +'%');
            
        }
    });
    document.getElementById('_ar_zoom_out').addEventListener('change', function() {            
        if (this.value == 'default'){
            modelViewer.setAttribute("max-camera-orbit", 'Infinity auto 300%');
        }else{
            const max_orbit_arr = modelViewer.getAttribute("max-camera-orbit").split(" ");
            modelViewer.setAttribute("max-camera-orbit", max_orbit_arr[0]+' '+max_orbit_arr[1]+' '+(((this.value/100)*400)+100) +'%');
        }
    });
    document.getElementById('_ar_field_of_view').addEventListener('change', function() {            
        if (this.value == 'default'){
            modelViewer.setAttribute("field-of-view", '');
        }else{
            modelViewer.setAttribute("field-of-view", this.value +'deg');
        }
    });
    document.getElementById('_ar_environment_image').addEventListener('change', function() {            
        if (document.getElementById("_ar_environment_image").checked == true){
            modelViewer.setAttribute("environment-image", 'legacy');
        }else{
            modelViewer.setAttribute("environment-image", '');
        }
    });
    document.getElementById('_ar_emissive').addEventListener('change', function() {
        
        var isChecked = document.getElementById("_ar_emissive").checked;
    
        if (isChecked) {
            modelViewer.setAttribute("emissive", "True");
        } else {
            modelViewer.removeAttribute("emissive");
        }
    });
    document.getElementById('_ar_exposure').addEventListener('change', function() {
        
        modelViewer.setAttribute("exposure", this.value);
    });
    document.getElementById('_ar_shadow_intensity').addEventListener('change', function() {
        
        modelViewer.setAttribute("shadow-intensity", this.value);
    });
    document.getElementById('_ar_shadow_softness').addEventListener('change', function() {
       
        modelViewer.setAttribute("shadow-softness", this.value);
    });
    document.getElementById('_ar_light_color').addEventListener('change', function() {
        
        modelViewer.setAttribute("light-color", this.value);
    });

                
    document.getElementById('_ar_view_hide').addEventListener('change', function() {
        var element = document.getElementById("ar-button_"+modelid);
        if (document.getElementById("_ar_view_hide").checked == true){
            element.style.display = "none";
        }else{
            element.style.display = "block";
        }
    });
    
    document.getElementById('_ar_qr_hide').addEventListener('change', function() {
        var element = document.getElementById("ar-qrcode_"+modelid);
        if (document.getElementById("_ar_qr_hide").checked == true){
            element.style.display = "none";
        }else{
            element.style.display = "block";
        }
    });
    
    document.getElementById('_ar_hide_dimensions').addEventListener('change', function() {
        var element = document.getElementById("controls");
        var element_checkbox = document.getElementById("show-dimensions_"+modelid);

        jQuery('.ar-dimension-control').toggleClass('nodisplay');

        if (document.getElementById("_ar_hide_dimensions").checked == true){
            element.style.display = "none";
            element_checkbox.checked = false;
            
            modelViewer.querySelectorAll('button').forEach((hotspot) => {
              if ((hotspot.classList.contains('dimension'))||(hotspot.classList.contains('dot'))){
                    hotspot.classList.add('nodisplay');
              }
            });
        }else{
            element.style.display = "block";
        }
    });
    
    document.getElementById('_ar_hide_reset').addEventListener('change', function() {
        var element = document.getElementById("ar-reset_"+modelid);
        if (document.getElementById("_ar_hide_reset").checked == true){
            element.style.display = "none";
        }else{
            element.style.display = "block";
        }
    });
    
    [ _ar_x, _ar_y, _ar_z ].forEach(function(element) {
        element.addEventListener('change', function() {
            var x = document.getElementById('_ar_x').value;
            var y = document.getElementById('_ar_y').value;
            var z = document.getElementById('_ar_z').value;

            const updateScale = () => {
              modelViewer.scale = x +' '+ y +' '+ z;
            };
            updateScale();
        });
    });
    document.getElementById('_ar_animation').addEventListener('change', function() {
        var element = document.getElementById("ar-button-animation");
        if (document.getElementById("_ar_animation").checked == true){
            element.style.display = "block";
        }else{
            element.style.display = "none";
        }
    });
};


/** UPDATE FOR TEXTURES AND MATERIALS **/

ARModelFields.prototype.setMaterials = function(){

    const self = this;
      
    //console.log('ctexpicker: ' + "color_texture_grid" + this.suffix)

    let modelViewer = document.querySelector("#model_" + this.modelid);
    const materialSelect = document.querySelector("#_ar_material" + this.suffix);
    const colortexturePicker = document.getElementById("color_texture_grid" + this.suffix);
    const metallictexturePicker = document.getElementById("metallic_texture_grid" + this.suffix);
    const blankTexture = document.getElementById("blank-texture" + this.suffix);
    const metallicBlankTexture = document.getElementById("metallic-blank-texture" + this.suffix);
    let materialStates = {};
    let texturesArray = {}; // array to hold textures
    let baseColorTextureUri = '';
    let baseColorTextureName = '';
    let metallicRoughnessTextureUri = '';
    let metallicRoughnessTextureName = '';
    const textureHiddenInput = jQuery('#_ar_textures' + this.suffix);
    let materialStatesHiddenInput = jQuery('#_ar_material_states' + this.suffix);

    texturesArray = getTexturesArrayValue();

    jQuery('#_ar_basecolor' + self.suffix).iris({
        palettes: ['#ff0000', '#00ff00', '#0000ff', '#ffffff', '#000000', '#cccccc'],
        change: function(event, ui) {
            // Detect color change and update the model viewer
            applyBaseColor(ui.color.toString());
            updateTexturesField();
        },
        clear: function() {
            // Handle color clear event
            applyBaseColor([1,1,1,1]); // reset to white
        }
    });

    // Toggle Iris color picker on #_ar_light_color input field click
    jQuery('#_ar_basecolor' + self.suffix).on('click', function(event) {
        event.stopPropagation(); // Prevent this click from triggering the document click event
        if (jQuery('.iris-picker').is(':visible')) {
            jQuery('#_ar_basecolor' + self.suffix).iris('hide');
        } else {
            jQuery('#_ar_basecolor' + self.suffix).iris('show');
        }
    });

    // Close the color picker when clicking outside of it
    jQuery(document).on('click', function(event) {
        if (!jQuery(event.target).closest('#_ar_basecolor' + self.suffix + ', .iris-picker').length) {
            jQuery('#_ar_basecolor' + self.suffix).iris('hide'); // Hide the Iris color picker if clicking outside
        }
    });


    function applyBaseColor(color) {
        if (!modelViewer.model) return;

        const selectedIndex = parseInt(materialSelect.value, 10);
        const material = modelViewer.model.materials[selectedIndex];

        if (material && material.pbrMetallicRoughness) {                
            // Get current alpha and alphaMode before applying color
            const currentAlpha = material.pbrMetallicRoughness.baseColorFactor 
              ? material.pbrMetallicRoughness.baseColorFactor[3] 
              : 1.0;
            const currentAlphaMode = material.alphaMode || (currentAlpha < 1.0 ? 'BLEND' : 'OPAQUE');
            
            // Apply color while preserving alpha
            material.pbrMetallicRoughness.setBaseColorFactor(
              hexToRgbaArray(color, currentAlpha)
            );
            
            // Preserve alphaMode for transparent materials
            if (currentAlpha < 1.0 && material.alphaMode !== 'BLEND') {
              material.alphaMode = 'BLEND';
            } else if (currentAlphaMode === 'BLEND' && material.alphaMode !== 'BLEND') {
              material.alphaMode = 'BLEND';
            }
            
            materialStates[selectedIndex].basecolor = color;                                
        }
    }

    function hexToRgbaArray(hex, alpha = 1) {
      hex = hex.replace(/^#/, '');
      if (hex.length === 3) {
        hex = hex.split('').map(x => x + x).join('');
      }
      const bigint = parseInt(hex, 16);
      const r = ((bigint >> 16) & 255) / 255;
      const g = ((bigint >> 8) & 255) / 255;
      const b = (bigint & 255) / 255;
      return [r, g, b, alpha];
    }


    modelViewer.addEventListener("load", async () => {
        if (!modelViewer.model || !modelViewer.model.materials) {
            console.warn("Model or materials not available yet");
            return;
        }
        const materials = modelViewer.model.materials;
    

        try {
            materialStates = JSON.parse(materialStatesHiddenInput.val());
        } catch (err) {
            materialStates = {};
        }

        await Promise.all(materials.map((mat) => mat.ensureLoaded()));
        
        let newMaterialStates = {};

        if (materialSelect) {
            materialSelect.innerHTML = "";

            if (materials.length === 0) return;

            const seenNames = new Set();

            materials.forEach((mat, index) => {
                const matName = mat.name || `Material ${index + 1}`;

                // Skip duplicates by name
                if (seenNames.has(matName)) {                    
                    return;
                }

                seenNames.add(matName);

                baseColorTextureUri = mat.pbrMetallicRoughness.baseColorTexture?.texture?.source?.uri || mat.pbrMetallicRoughness.baseColorTexture?.texture?.image?.src || null;
                baseColorTextureName = mat.pbrMetallicRoughness.baseColorTexture?.texture?.name || baseColorTextureUri?.split('/').pop() || "none";
                metallicRoughnessTextureUri = mat.pbrMetallicRoughness.metallicRoughnessTexture?.texture?.source?.uri || mat.pbrMetallicRoughness.metallicRoughnessTexture?.texture?.image?.src || null;
                metallicRoughnessTextureName = mat.pbrMetallicRoughness.metallicRoughnessTexture?.texture?.name || metallicRoughnessTextureUri?.split('/').pop() || "none";
                const basecolorFactor = mat.pbrMetallicRoughness.baseColorFactor;
                const metallicFactor = mat.pbrMetallicRoughness.metallicFactor;
                const roughnessFactor = mat.pbrMetallicRoughness.roughnessFactor;

                if (!materialStates || Object.keys(materialStates).length === 0 || !materialStates[index]) {
                    // Detect if material has transparency
                    const hasTransparency = basecolorFactor && basecolorFactor[3] < 1.0;
                    const alphaMode = mat.alphaMode || (hasTransparency ? 'BLEND' : 'OPAQUE');
                    
                    newMaterialStates[index] = {
                        texture: baseColorTextureName,
                        texture_url: baseColorTextureUri,
                        texture_uploaded: 0,
                        basecolor: rgbaArrayToHex(basecolorFactor),
                        metallic: metallicFactor,
                        roughness: roughnessFactor,
                        metallic_texture: metallicRoughnessTextureName,
                        metallic_texture_url: metallicRoughnessTextureUri,
                        metallic_texture_uploaded: 0,
                        alphaMode: alphaMode, // Save alphaMode for later restoration
                    };
                } else {
                    newMaterialStates[index] = materialStates[index];
                }

                // Add dropdown option
                const option = document.createElement("option");
                option.value = index;
                option.textContent = matName;
                materialSelect.appendChild(option);
            });

            materialStates = newMaterialStates;
            updateTexturesField(); // make sure this does not reset materialStates
        }

        materialsListener(modelViewer);
        clearTextureImagesGrid();

        if (blankTexture) {
            blankTexture.style.outline = '2px solid #00f'; 
        }
        if (metallicBlankTexture) {
            metallicBlankTexture.style.outline = '2px solid #00f';
        } 

        if (colortexturePicker) {
            getTextureImages(materials, colortexturePicker);
        }
    });


    function clearTextureImagesGrid(){
        if (colortexturePicker) {
            [...colortexturePicker.querySelectorAll("img")].forEach(img => {
                if (img !== blankTexture) {
                    img.remove();
                }
            });
        }

        if (metallictexturePicker) {
            [...metallictexturePicker.querySelectorAll("img")].forEach(img2 => {
                if (img2 !== metallicBlankTexture) {
                    img2.remove();
                }
            });
        }
    }

          

    function getMaterialStatesValue(){
        const materialStatesHiddenInput = document.getElementById('_ar_material_states' + self.suffix);

        if (!materialStatesHiddenInput || !materialStatesHiddenInput.value) return {};

        savedStates = JSON.parse(materialStatesHiddenInput.value);

        return savedStates;
    }

    function getTexturesArrayValue(){
        const texturesArrayHiddenInput = document.getElementById('_ar_textures' + self.suffix);

        if (!texturesArrayHiddenInput || !texturesArrayHiddenInput.value) return {};

        texturesArray = JSON.parse(texturesArrayHiddenInput.value);

        return texturesArray;
    }

    function updateTexturesField() {
        textureHiddenInput.val(JSON.stringify(texturesArray));
        materialStatesHiddenInput.val(JSON.stringify(materialStates));
    }

    function rgbaArrayToHex(rgba){
        const [r,g,b] = rgba;
        return "#" + [r,g,b].map(c => {
            const hex = Math.round(c * 255).toString(16).padStart(2,"0");
            return hex;
        }).join("");
    }

    function loadDefaultValues(){
        const selectedIndex = parseInt(materialSelect.value, 10);
        let values = materialStates[selectedIndex];
        let textureName = values.texture;
        let metalicTextureName = values.metallic_texture;

        const metallicSlider = document.getElementById("_ar_metallic" + self.suffix);
        const roughnessSlider = document.getElementById("_ar_roughness" + self.suffix);
        const metallicValue = document.getElementById("_ar_metallic_value" + self.suffix);
        const roughnessValue = document.getElementById("_ar_roughness_value" + self.suffix);

        setTimeout(() => {
            document.querySelectorAll('#color_texture_picker' + self.suffix + ' img').forEach(i => i.style.outline = '');
            document.querySelectorAll('#metallic_texture_picker' + self.suffix + ' img').forEach(i => i.style.outline = '');

            document.querySelector(`#color_texture_picker${self.suffix} img[data-texture="${textureName}"]`).style.outline = '2px solid #00f';
            document.querySelector(`#metallic_texture_picker${self.suffix} img[data-texture="${metalicTextureName}"]`).style.outline = '2px solid #00f';
        }, 1000);

        metallicSlider.value = values.metallic;
        roughnessSlider.value = values.roughness;
        metallicValue.textContent = values.metallic.toFixed(2);
        roughnessValue.textContent = values.roughness.toFixed(2);
    }

    function getTextureImages(mats, element){         
        
        const selectedIndex = parseInt(materialSelect.value, 10);
        const currentMaterial = modelViewer.model.materials[selectedIndex];
        const metallicGrid = document.getElementById("metallic_texture_grid" + self.suffix);
        const metallicSlider = document.getElementById("_ar_metallic" + self.suffix);
        const roughnessSlider = document.getElementById("_ar_roughness" + self.suffix);
        const metallicValue = document.getElementById("_ar_metallic_value" + self.suffix);
        const roughnessValue = document.getElementById("_ar_roughness_value" + self.suffix);
        //console.log(currentMaterial);

        const currentBaseColorTexture = currentMaterial.pbrMetallicRoughness.baseColorTexture?.texture;
        const currentMetallicTexture = currentMaterial.pbrMetallicRoughness.metallicRoughnessTexture?.texture;
        //console.log('herer');
        //console.log(currentMetallicTexture);

        var metallic = currentMaterial.pbrMetallicRoughness.metallicFactor || 0;
        var roughness = currentMaterial.pbrMetallicRoughness.roughnessFactor || 0;
        var factor = currentMaterial.pbrMetallicRoughness.baseColorFactor || [1,1,1,1];
        var hex = rgbaArrayToHex(factor);
        
        jQuery('#_ar_basecolor' + self.suffix).iris('color', hex);  
        metallicSlider.value = metallic;
        roughnessSlider.value = roughness;

        metallicValue.textContent = metallic.toFixed(2);
        roughnessValue.textContent = roughness.toFixed(2);

        if (!element) return;
        
        (async () => {
               let modelTextures = modelTexturesArray[self.modelid];
               
              //for (const texture of Object.entries(modelTextures)) {                
              for (const { info, texture, type } of Object.values(modelTextures)) {
                
                const texUri = texture?.source?.uri || texture?.image?.src || '';
                const textureName = texture?.name || texUri.split('/').pop() || 'none';

                if (texture && info.texture.source?.createThumbnail) {
                  try {
                    const thumbnail = await info.texture.source.createThumbnail(100, 100);

                    const exists = document.querySelector(`#color_texture_picker${self.suffix} img[data-texture="${textureName}"]`);
                    if (exists) {                       
                        continue;
                    }

                    const img = document.createElement('img');
                    img.src = thumbnail;                    
                    img.style.width = '40px';
                    img.style.height = '40px';
                    img.style.objectFit = 'cover';
                    img.style.border = '1px solid #ccc';
                    img.style.borderRadius = '3px';
                    img.style.marginRight = '3px';
                    img.dataset.texture = textureName; 

                    //duplicate image for metallic texture
                    let img2 = img.cloneNode(true);

                    if (textureName === baseColorTextureName) {                        
                        img.style.outline = '2px solid #00f';  
                        if (blankTexture) {
                            blankTexture.style.outline = '';
                        }                                             
                    }  

                    img.addEventListener('click', () => {
                        
                        var selectedIndex = parseInt(materialSelect.value, 10);
                        var currentMaterial = modelViewer.model.materials[selectedIndex];
                                              
                        var newTexture = texture;
                        var factor = currentMaterial.pbrMetallicRoughness.baseColorFactor || [1,1,1,1];
                        var hex = rgbaArrayToHex(factor);
                        jQuery('#_ar_basecolor' + self.suffix).iris('color', hex);
                        currentMaterial.pbrMetallicRoughness.baseColorTexture.setTexture(newTexture);
                        materialStates[selectedIndex].texture = textureName;
                        materialStates[selectedIndex].texture_url = img.src;
                        materialStates[selectedIndex].texture_uploaded = 0;
                        updateTexturesField();

                        // Optional: highlight the selected texture
                        document.querySelectorAll('#color_texture_picker' + self.suffix + ' img').forEach(i => i.style.outline = '');
                        img.style.outline = '2px solid #00f';
                    });

                    if (element && blankTexture) {
                        element.insertBefore(img, blankTexture);
                    } else if (element) {
                        element.appendChild(img);
                    }

                    if (textureName === metallicRoughnessTextureName) {
                        //set sliders for metallic roughness and factor
                        img2.style.outline = '2px solid #00f'; 
                        if (metallicBlankTexture) {
                            metallicBlankTexture.style.outline = '';
                        }                      
                    }

                    //add event listener for metallic texture image
                    img2.addEventListener('click', () => {
                   
                        var selectedIndex = parseInt(materialSelect.value, 10);
                        var currentMaterial = modelViewer.model.materials[selectedIndex];                                              
                        var newMetallicTexture = texture; 
                        var metallicFactor = currentMaterial.pbrMetallicRoughness.metallicFactor || 0;
                        var roughnessFactor = currentMaterial.pbrMetallicRoughness.roughnessFactor || 0; 

                        currentMaterial.pbrMetallicRoughness.metallicRoughnessTexture.setTexture(newMetallicTexture);
                        materialStates[selectedIndex].metallic_texture = textureName;
                        materialStates[selectedIndex].metallic_texture_url = img2.src;
                        materialStates[selectedIndex].metallic_texture_uploaded = 0;
                        updateTexturesField();               

                        // Optional: highlight the selected texture
                        document.querySelectorAll('#metallic_texture_picker' + self.suffix + ' img').forEach(i => i.style.outline = '');
                        img2.style.outline = '2px solid #00f';
                    });

                    if (metallicGrid) {
                        metallicGrid.insertBefore(img2, metallicBlankTexture);
                    }

                  } catch (err) {
                    console.warn(`Failed to create thumbnail for ${type}:`, err);
                  }
                }
              }



              getUploadedTextures();                

        })(); 

         

    }

    function getUploadedTextures(){
        if (Object.keys(texturesArray).length > 0) {
            Object.entries(texturesArray).forEach(([key, tex]) => {
                const img = document.createElement('img');
                img.src = tex.url;
                img.style.width = '40px';
                img.style.height = '40px';
                img.style.objectFit = 'cover';
                img.style.border = '1px solid #ccc';
                img.style.borderRadius = '3px';
                img.style.marginRight = '3px';

                // dataset.id = object key (your index)
                img.dataset.id = key;
                img.dataset.texture = tex.name;

                let img2 = img.cloneNode(true);

                img.addEventListener('click', async () => {
                    const selectedIndex = parseInt(materialSelect.value, 10);
                    const currentMaterial = modelViewer.model.materials[selectedIndex];

                    try {
                        // Create a <model-viewer> Texture from uploaded image URL
                        const newTexture = await modelViewer.createTexture(tex.url);

                        // Apply as baseColorTexture
                        currentMaterial.pbrMetallicRoughness.baseColorTexture.setTexture(newTexture);
                        const textureName = tex.name || tex.url.split('/').pop();
                        
                        materialStates[selectedIndex].texture = textureName;
                        materialStates[selectedIndex].texture_url = img.src;
                        materialStates[selectedIndex].texture_uploaded = 1;

                        // Highlight selected
                        colortexturePicker.querySelectorAll('img').forEach(i => i.style.outline = '');
                        img.style.outline = '2px solid #00f';

                        updateTexturesField();

                    } catch (err) {
                        console.error("Failed to apply uploaded texture:", err);
                    }
                });


                colortexturePicker.insertBefore(img, blankTexture);


                img2.addEventListener('click', async () => {
                    const selectedIndex = parseInt(materialSelect.value, 10);
                    const currentMaterial = modelViewer.model.materials[selectedIndex];

                    try {
                        // Create a <model-viewer> Texture from uploaded image URL
                        const newTexture = await modelViewer.createTexture(tex.url);

                        // Apply as baseColorTexture
                        currentMaterial.pbrMetallicRoughness.metallicRoughnessTexture.setTexture(newTexture);
                        const textureName = tex.name || tex.url.split('/').pop();
                        
                        materialStates[selectedIndex].metallic_texture = textureName;
                        materialStates[selectedIndex].metallic_texture_url = img2.src;
                        materialStates[selectedIndex].metallic_texture_uploaded = 1;

                        // Highlight selected
                        metallictexturePicker.querySelectorAll('img').forEach(i => i.style.outline = '');
                        img2.style.outline = '2px solid #00f';

                        updateTexturesField();

                    } catch (err) {
                        console.error("Failed to apply uploaded texture:", err);
                    }
                });

                metallictexturePicker.insertBefore(img2, metallicBlankTexture);    
            });

            loadDefaultValues();
        }
    }

    function getTextureName(str){
        
        try {
            const url = new URL(str); // throws if not a valid URL
            return url.pathname.split('/').pop() || str;
        } catch {
            // not a URL → return original string
            return str;
        }

    }

    function materialsListener(model){
        const picker = document.getElementById("color_texture_picker" + self.suffix);
        const mainImg = document.getElementById("texture-img" + self.suffix);
        const hiddenInput = document.getElementById("_ar_basecolor_texture" + self.suffix);
        const metallicSlider = document.getElementById("_ar_metallic" + self.suffix);
        const roughnessSlider = document.getElementById("_ar_roughness" + self.suffix);
        const metallicValue = document.getElementById("_ar_metallic_value" + self.suffix);
        const roughnessValue = document.getElementById("_ar_roughness_value" + self.suffix);

        //const body = picker.closest('.ar_accordian_panel');
        var frame;
        // Toggle picker on main image click
        
        const modelViewer = model;
        const materialSelect = document.querySelector("#_ar_material" + self.suffix);
        console.log("material-select: #_ar_material" + self.suffix);

        // Handle texture selection
        // Check if materialSelect exists before adding event listener
        if (!materialSelect) {
            console.warn("Material select element not found: #_ar_material" + self.suffix);
            return;
        }
        
        materialSelect.addEventListener("change", () => {
            const selectedIndex = parseInt(materialSelect.value, 10);
            const currentMaterial = modelViewer.model.materials[selectedIndex];

            if (!currentMaterial) return;

            // --- Sync texture highlight ---
            const currentTex = currentMaterial.pbrMetallicRoughness.baseColorTexture?.texture;
            const texUri = currentTex?.source?.uri || currentTex?.image?.src || '';
            let textureName = currentTex?.name || texUri.split('/').pop() || 'none';
            textureName = getTextureName(textureName);
            

            document.querySelectorAll('#color_texture_picker' + self.suffix + ' img').forEach(img => {
                img.style.outline = '';
                if (img.dataset.texture && textureName === img.dataset.texture) {
                    img.style.outline = '2px solid #00f';
                }
            });


            const currentMetallicTex = currentMaterial.pbrMetallicRoughness.metallicRoughnessTexture?.texture;
            const metallicTexUri = currentMetallicTex?.source?.uri || currentMetallicTex?.image?.src || '';
            let metallicTextureName = currentMetallicTex?.name || metallicTexUri.split('/').pop() || 'none';
            metallicTextureName = getTextureName(metallicTextureName);
           

            document.querySelectorAll('#metallic_texture_picker' + self.suffix + ' img').forEach(img2 => {
                img2.style.outline = '';
                if (img2.dataset.texture && metallicTextureName === img2.dataset.texture) {
                    img2.style.outline = '2px solid #00f';
                }
            });

            // --- Sync color picker ---
            const factor = currentMaterial.pbrMetallicRoughness.baseColorFactor || [1,1,1,1];
            const hex = rgbaArrayToHex(factor);
            jQuery('#_ar_basecolor' + self.suffix).iris('color', hex);
            materialStates[selectedIndex].basecolor = hex;

            var metallicFactor = currentMaterial.pbrMetallicRoughness.metallicFactor;
            var roughnessFactor = currentMaterial.pbrMetallicRoughness.roughnessFactor;
            materialStates[selectedIndex].metallic = metallicFactor;
            materialStates[selectedIndex].roughness = roughnessFactor;
            metallicSlider.value = metallicFactor;
            roughnessSlider.value = roughnessFactor;
            metallicValue.textContent = metallicFactor.toFixed(2);
            roughnessValue.textContent = roughnessFactor.toFixed(2);
            
            updateTexturesField();
        });



        if (blankTexture) {
          blankTexture.addEventListener("click", () => {
       
            const selectedIndex = parseInt(materialSelect.value, 10);
            const currentMaterial = modelViewer.model.materials[selectedIndex];

            currentMaterial.pbrMetallicRoughness.baseColorTexture.setTexture(null);
            materialStates[selectedIndex].texture = 'none';
            materialStates[selectedIndex].texture_url = '';
            materialStates[selectedIndex].texture_uploaded = 0;
            updateTexturesField();
            document.querySelectorAll('#color_texture_picker' + self.suffix + ' img').forEach(i => i.style.outline = '');
            blankTexture.style.outline = "2px solid #00f";
          });
        }

        if (metallicBlankTexture) {
          metallicBlankTexture.addEventListener("click", () => {
                        
            const selectedIndex = parseInt(materialSelect.value, 10);
            const currentMaterial = modelViewer.model.materials[selectedIndex];

            currentMaterial.pbrMetallicRoughness.metallicRoughnessTexture.setTexture(null);
            materialStates[selectedIndex].metallic_texture = 'none';
            materialStates[selectedIndex].metallic_texture_url = '';
            materialStates[selectedIndex].metallic_texture_uploaded = 0;
            updateTexturesField();
            document.querySelectorAll('#metallic_texture_picker'  + self.suffix + ' img').forEach(i => i.style.outline = '');
            metallicBlankTexture.style.outline = "2px solid #00f";
          });
        }


        /* metallic factor and roughness */
          metallicSlider.addEventListener("input", () => {
            //metallicValue.textContent = metallicSlider.value;
            const selectedIndex = parseInt(materialSelect.value, 10);
            const currentMaterial = modelViewer.model.materials[selectedIndex];
            materialStates[selectedIndex].metallic = parseFloat(metallicSlider.value);
            currentMaterial.pbrMetallicRoughness.setMetallicFactor(parseFloat(metallicSlider.value));
            updateTexturesField();
          });

          roughnessSlider.addEventListener("input", () => {
            //roughnessValue.textContent = roughnessSlider.value;
            const selectedIndex = parseInt(materialSelect.value, 10);
            const currentMaterial = modelViewer.model.materials[selectedIndex];
            materialStates[selectedIndex].roughness = parseFloat(roughnessSlider.value);
            currentMaterial.pbrMetallicRoughness.setRoughnessFactor(parseFloat(roughnessSlider.value));   
            updateTexturesField();    
          });


        
               
    
        jQuery(document).on('click', '.upload_texture_btn' + self.suffix, function (e) {
            e.preventDefault();
            console.log('.upload_texture_btn' + self.suffix);
            const msuffix = jQuery(this).data('suffix');
            const baseColorImageGrid = document.getElementById("color_texture_grid" + msuffix);
            const metallicImageGrid = document.getElementById("metallic_texture_grid" + msuffix);
            const baseColorBlank = document.getElementById("blank-texture" + msuffix);
            const metallicBlank = document.getElementById("metallic-blank-texture" + msuffix);
            // If the media frame already exists, reopen it
            if (frame) {
                frame.open();
                return;
            }

            // Create new media frame
            frame = wp.media({
                title: 'Select or Upload Texture',
                button: {
                    text: 'Add this texture'
                },
                multiple: false // change to true if you want multiple
            });

            // When an image is selected
            frame.on('select', function () {
                const attachment = frame.state().get('selection').first().toJSON();

                texturesArray[attachment.id] = {
                    url: attachment.url,
                    name: attachment.filename
                };

                frame.close();

                const img = document.createElement('img');
                img.src = attachment.url;
                img.style.width = '40px';
                img.style.height = '40px';
                img.style.objectFit = 'cover';
                img.style.border = '1px solid #ccc';
                img.style.borderRadius = '3px';
                img.style.marginRight = '3px';

                let img2 = img.cloneNode(true);

                img.addEventListener('click', async () => {
                    const selectedIndex = parseInt(materialSelect.value, 10);
                    const currentMaterial = modelViewer.model.materials[selectedIndex];

                    try {
                        // Create a <model-viewer> Texture from uploaded image URL
                        const newTexture = await modelViewer.createTexture(attachment.url);

                        // Apply as baseColorTexture
                        currentMaterial.pbrMetallicRoughness.baseColorTexture.setTexture(newTexture);
                        const textureName = attachment.filename || attachment.url.split('/').pop();
                        
                        materialStates[selectedIndex].texture = textureName;
                        materialStates[selectedIndex].texture_url = img.src;
                        materialStates[selectedIndex].texture_uploaded = 1;

                        // Highlight selected
                        baseColorImageGrid.querySelectorAll('img').forEach(i => i.style.outline = '');
                        img.style.outline = '2px solid #00f';

                        updateTexturesField();

                    } catch (err) {
                        console.error("Failed to apply uploaded texture:", err);
                    }
                });

                baseColorImageGrid.insertBefore(img, baseColorBlank);


                img2.addEventListener('click', async () => {
                    const selectedIndex = parseInt(materialSelect.value, 10);
                    const currentMaterial = modelViewer.model.materials[selectedIndex];

                    try {
                        // Create a <model-viewer> Texture from uploaded image URL
                        const newTexture = await modelViewer.createTexture(attachment.url);

                        // Apply as baseColorTexture
                        currentMaterial.pbrMetallicRoughness.metallicRoughnessTexture.setTexture(newTexture);
                        const textureName = attachment.filename || attachment.url.split('/').pop();
                        
                        materialStates[selectedIndex].metallic_texture = textureName;
                        materialStates[selectedIndex].metallic_texture_url = img2.src;
                        materialStates[selectedIndex].metallic_texture_uploaded = 1;

                        // Highlight selected
                        metallicImageGrid.querySelectorAll('img').forEach(i => i.style.outline = '');
                        img2.style.outline = '2px solid #00f';

                        updateTexturesField();

                    } catch (err) {
                        console.error("Failed to apply uploaded texture:", err);
                    }
                });

                metallicImageGrid.insertBefore(img2, metallicBlank);
                
                // Update hidden field
                updateTexturesField();



            });

            // Open the media frame
            frame.open();

        // Close picker on outside click
        });
    }

    
};

/** END UPDATE FOR TEXTURES AND MATERIALS **/


/*
jQuery(function($) { 
    //Asset Builder
    // Initialize a flag to track whether the action has been triggered
    // Find the "Update" button in the Gutenberg editor
    const updateButton = $('.editor-post-save-draft');

    // Find your custom button by its class or ID
    const customButton = $('#ar_asset_builder_submit');

    // Add a click event handler to your custom button
    customButton.on('click', function() {
    
        var asset_file = $('#_ar_asset_file').val();
        var asset_orientation = $('#_ar_asset_orientation').val();
        var asset_ratio = $('#ar_asset_ratio').val();
        var m = asset_file.lastIndexOf('.');
        
        //console.log(\'Asset File:\', asset_file);
        //console.log(\'Last Index of Dot:\', m);
        
        if (m !== -1) {
            var asset_file_result = asset_file.substring(0, m);
            console.log('Result:', asset_file_result);
        } else {
            console.log("No dot found in asset_file");
        }
        //console.log(\'Asset Ratio:\', asset_ratio);
        //console.log(\'Asset Orientation:\', asset_orientation);
        var asset_file_result = asset_file.substring(0, m) + '_' + asset_ratio + '_' + asset_orientation + '.zip' ;
        $('#_ar_asset_file').val(asset_file_result);
        $('#_ar_placement').val('wall');
        //alert (asset_file_result);
        
        wp.data.dispatch('core/editor').savePost();
        // Reload the page after a short delay to ensure the save action completes
        setTimeout(function() {
            location.reload();
        }, 1000); 
    });
    //asset_builder_button
    $( "#asset_builder_tab, #asset_builder_button" ).click(function() {
            $("#asset_builder_iframe").html('<iframe src="https://augmentedrealityplugins.com/asset_builder/gallery.php?referrer='+ options.site_url +'" style="width:100%;min-height:180px" id="asset_builder_iframe"></iframe>');
    });
});   */ 

    /*$( "#ar_asset_iframe_acc" ).click(function() {
        if ($("#asset_builder_iframe").html() === \'\') {
            $("#asset_builder_iframe").html(\'<iframe src="https://augmentedrealityplugins.com/asset_builder/gallery.php?referrer='.urlencode(get_site_url()).'" style="width:100%;height:160px" id="asset_builder_iframe"></iframe>\');
        }
    });*/
//});
//List for Events from the Asset Builder iFrame
var eventMethod = window.addEventListener
        ? "addEventListener"
        : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod === "attachEvent"
    ? "onmessage"
    : "message";

eventer(messageEvent, function (e) {
    if (e.origin !== 'https://augmentedrealityplugins.com') return;
    if (e.data.substring(0, 5)==='https'){
    //alert (e.data);
        document.getElementById('_ar_asset_file').value = e.data;
        if (document.getElementById('_asset_texture_file_0').value) {
            document.getElementById('ar_asset_builder_model_done').innerHTML = '&#10003;';
            document.getElementById('ar_asset_builder_submit_container').style.display = 'block';
        }
        //ar_update_size_function();
    }else{
        //Show texture input fields and update their labels
        var details = e.data.split(',');
        document.getElementById('_asset_texture_flip').value = '';
        var i;
        for (i = 0; i < 1; i++) { //Previously 10 - Cube will require 6
          var texture = 'texture_' + i;
          var label = 'texture_label_' + i;
          var btn = 'upload_asset_texture_button_' + i;
          var field = '_asset_texture_file_' + i;
          var field_id = '_asset_texture_id_' + i;
          var element = document.getElementById('texture_container_' + i);
          element.classList.add("nodisplay");
          if(details[i] === undefined){
              document.getElementById(field).value = '';
              document.getElementById(field_id).value = '';
          }else if (details[i] ==='flip'){
              //alert(details[i]);
              document.getElementById('_asset_texture_flip').value = 'flip';
          }else{
              //element.classList.remove("nodisplay");
              element.classList.remove("nodisplay");
              //document.getElementById(\'texture_\' + i).classList.remove("nodisplay");
              
              var label_contents = details[i].charAt(0).toUpperCase() + details[i].slice(1);
              label_contents=label_contents.substring(0,(label_contents.length -4));
              document.getElementById(field_id).value = details[i];
              document.getElementById(btn).value = label_contents.replace('_',' ');
          }
        
        }
    }
    
});

jQuery(document).ready(function($) {
    
    // Ensure the script runs after the DOM is fully loaded
        $(document).ready(function() {
            // Get the current value of the color input field or default to black
            if($('#_ar_frame_color').val()){
                currentColor = $('#_ar_frame_color').val().trim(); // Default to black if empty
            }else if($('#ar_progress_bar_color').val()){
                currentColor = $('#ar_progress_bar_color').val().trim(); // Default to black if empty
            } else {        
            // Check if the color value is correctly set            
                currentColor = '#666666'; // Fallback to black if still empty, null, or falsy
            }

            // Initialize the color picker with the current color
            $('#ar_progress_bar_color').iris({
                color: currentColor,
                change: function(event, ui) {
                    // Handle color change event for frame color
                    //updateModelViewer();
                }
            });
        
            // Toggle Iris color picker on input field click
            $('#ar_progress_bar_color').on('click', function(event) {
                
                event.stopPropagation(); // Prevent this click from triggering the document click event
                if ($('.iris-picker').is(':visible')) {
                    $('#ar_progress_bar_color').iris('hide');
                } else {
                    $('#ar_progress_bar_color').iris('show');
                }
            });
        
            // Close the color picker when clicking outside of it
            $(document).on('click', function(event) {
                if (!$(event.target).closest('#ar_progress_bar_color, .iris-picker').length) {
                    $('#ar_progress_bar_color').iris('hide'); // Hide the Iris color picker if clicking outside
                }
            });
            
            
            
            
        });
        
    

    });