/*
Copyright 2022 James D. Miller

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

// Page Stuff (pS) module
// pageStuff.js
   console.log('pS _*-*_');
// 11:11 AM Sat May 27, 2023

/*

*/

window.pS = (function() {
   "use strict";
   
   // Globals
   var m_closer, m_opener;
   var m_navMenu;
   var m_scrollAdjust;
   var m_dialog, m_cookieLink;
   
   console.log('pS _*-*_');
   
   function scroll( targetID, mode='jump') {
      //var container = $('#helpScroller'); // see html tag
      // Ended up using the method below to reference the full page. This works in all three
      // browsers: Chrome, Firefox, and Edge. The method above, using the helpScroller id, does not
      // work in Edge.
      var container = $('html, body');
      
      // Find the position of the anchor named TOP. This varies with browser, so this sets
      // a position baseline.
      let topAnchor = $('a[name=TOP]');
      // If found a "TOP", set a non-zero offset.
      let topPosition = (topAnchor.length) ? topAnchor.offset().top : 0;
      
      // Search for ID 
      var scrollTarget  = $('#' + targetID);
      
      // If can't find ID, search for a named anchor element
      if (scrollTarget.length == 0) {
         var anchorSearchString = 'a[name=' + targetID + ']';
         var scrollTarget = $( anchorSearchString);
         if (scrollTarget.length == 0) {
            console.log('found nothing');
            return null;
         } else {
            console.log('found name');
         }
      } else {
         console.log('found ID');
      }

      // Must have found the ID. Now, scroll the page.
      if (scrollTarget.offset()) {
         let scroll_px = scrollTarget.offset().top - topPosition;
         let totalScroll_px = (['top','TOP'].includes( targetID)) ? scroll_px : (scroll_px + m_scrollAdjust);
         
         if (mode == 'pageReload') {
            console.log('jump to top');
            // Jump to top, wait, then slowly scroll to the target.
            container.animate( {scrollTop:'0px'}, 0);
            window.setTimeout( function() {
               console.log('slowly scroll to target');
               container.animate( { scrollTop: totalScroll_px }, 300); // 1000
            }, 700);         

         } else if (mode == 'jump') {
            // This mode is used for scrolling to targets on the same page.
            // e.g. put this in the anchor element: onclick="pS.scroll('pygame');"
            container.animate( { scrollTop: totalScroll_px }, 300); // 1000
         }
      } else {
         console.log("scrollTarget.offset() not found or defined");
      }
      
      // Prevent default behavior that scrolls to the top.
      return false;
   }
   
   function logEntry( eventDescription, mode='normal') {
      // If this page is coming from the production server...
      var pageURL = window.location.href;
      if (pageURL.includes("timetocode")) {
         var sheetURL = 'https://script.google.com/macros/s/AKfycby8j...SL0BkBI/exec';
         // AJAX
         var xhttp = new XMLHttpRequest();
         xhttp.open('GET', sheetURL + '?mode=' + mode + '&eventDesc=' + eventDescription, true);
         xhttp.send();
      } else {
         console.log("Event = " + eventDescription);
      }
   }
   
   function openNav() {
      m_navMenu.style.height = "100%";
   }
   function closeNav() {
      m_navMenu.style.height = "0%";
   }
   
   // https://javascript.info/cookie
   // https://www.w3schools.com/js/js_cookies.asp
   // https://github.com/js-cookie/js-cookie/tree/latest
   function cookieSet() {
      // 2592000 = 30 * 24 * 3600 (30 days in seconds)
      // 7776000 = 90 * 24 * 3600 (90 days in seconds)
      document.cookie = "youtube-consent=accept; max-age=7776000; samesite=strict";
   }
   function cookieRemove() {
      document.cookie = "youtube-consent=reject; max-age=0; samesite=strict";
   }
   function cookieCheck() {
      return document.cookie.includes("youtube-consent");
   }
   
   function viewDialog( pars={}) {
      let alwaysShowDialog = uT.setDefault( pars.alwaysShowDialog, true);
      let statusMessage;
      if (m_dialog) {
         if (alwaysShowDialog) m_dialog.showModal();
         if ( cookieCheck()) {
            statusMessage = " \u2713"; // a check mark
         } else {
            statusMessage = "";
            if ( ! alwaysShowDialog) m_dialog.showModal();
         }
         jQuery("#dialog-status").text( statusMessage);
      }
      document.getElementById("firstDialogButton").blur();
   }
   
   function getTopicTitle( videoDivElement) {
      // Find the sibling <p> elements containing the <strong> element with class "title_2"
      var siblingParagraphs = videoDivElement.siblings("p").filter(function() {
         return $(this).find("strong.title_2").length > 0;
      });

      // Get the text within the <strong> element of the first matching sibling <p> element
      var title = siblingParagraphs.first().find("strong.title_2").text();
      
      return title;
   }
   
   function loadLargeImage( img, fileName=null) {
      if (fileName) {
         img.src = "screenshots/" + fileName;
      } else {
         let srcString = img.src;
         img.src = srcString.replace("_550w","");
      }
   }   
      
   function initialize( pars={}) {
      /*  */
      let dialogOptions = uT.setDefault( pars.dialogOptions, false);
      let navMenu = uT.setDefault( pars.navMenu, true);
      let navDivName = uT.setDefault( pars.navDiv, "navDiv");
      let pageDesc = uT.setDefault( pars.pageDesc, null);
      let pathSiteMap = uT.setDefault( pars.pathSiteMap, "sitemap.html?v2"); // changing the version overrides cache
      let scrollAtLoad = uT.setDefault( pars.scrollAtLoad, true);
      m_scrollAdjust = uT.setDefault( pars.scrollAdjust, 0);
      
      // Take note...
      logEntry( pageDesc);
      
      if (navMenu) {
         // put the navigation menu into the div
         let navDiv = document.getElementById( navDivName);
         
         var xhr = new XMLHttpRequest();
         xhr.onreadystatechange = function() {
            if ((xhr.readyState === 4) && (xhr.status === 200)) {
               navDiv.innerHTML = xhr.responseText;
               
               m_navMenu = document.getElementById("myNav");
            
               m_closer = document.getElementById("closer");
               m_closer.addEventListener("click", function(event) {
                  event.preventDefault();
                  closeNav();
               });               
               // Note that the opener is not an anchor element, so no need for preventDefault.
               m_opener = document.getElementById("opener");
               m_opener.addEventListener('click', openNav);
               m_opener.title = "Site Menu";
            }
         };
         
         function handleXHR_error() {
            let theMessage = "The navigation menu (hamburger icon) depends on a webserver. " + 
                 "If you're opening this page directly, without a webserver, try navigating using any available links.";
            window.alert( theMessage);
         }
         xhr.addEventListener('error', handleXHR_error);
         
         xhr.open("GET", pathSiteMap, true);
         xhr.send();
      }
      
      if (scrollAtLoad) {
         // This zero delay seems necessary for Chrome to behave as expected on page refresh (should jump to the top, then scroll to the target)
         window.setTimeout( function() {
            // The ready approach does not work well with a page having many auto-sizing images. Rather, better to wait
            // until EVERYTHING is done loading, including images, as is done in the 'load' method above.
            //$(document).ready( function() {});
            
            // Bailed on using hash parameter in URL. Native jumps to anchors are confusing. So sidestepping that mess by using query parameters.
            //var hashID = window.location.hash;
            
            // Discard everything after the "&".
            var queryStringInURL = window.location.search.split("&")[0];
            // Then use the part after the "?".
            var queryID = queryStringInURL.slice(1);
            if (queryID) {
               console.log("queryID=" + queryID);
               scroll( queryID, 'pageReload');
            };
            
         }, 0);
      }
        
      // event handler for scroll links
      $('.scroll-link').click( function( event) {
         event.preventDefault();
         let target = $(this).attr('data-scroll-target');
         scroll( target);
      })
      
      // dialogOptions is True for all the pages with YouTube videos.
      if (dialogOptions) {
         m_dialog = document.getElementById("cookieConsent");
         m_cookieLink = document.getElementById("cookieLink");
         
         // Check for prior consent. If not there, display the dialog.
         viewDialog({'alwaysShowDialog':false});
         
         m_dialog.addEventListener("close", function() {
            const value = m_dialog.returnValue;
            if (value == "accept") {
               cookieSet();
               //console.log("cookie = " + document.cookie);
            } else if (value == "reject")  {
               cookieRemove();
            } else if (value == "close") {
               console.log('Cookies stay the same.');
            }
         });
         
         m_cookieLink.addEventListener("click", function(event) {
            event.preventDefault();
            viewDialog();
         });
         
         // Define event handlers for each video container.
         $('.video-container').click( function() {
            logEntry( "Video: " + getTopicTitle($(this)) );
           
            if ( ! cookieCheck()) { // (Cookies.get('youtube-consent') == 'accept')
               console.log('url = ' + "https://youtu.be/" + $(this).attr('data-videoID'));
               window.open( "https://youtu.be/" + $(this).attr('data-videoID'), '_blank');
            } else {
               if ( ! $(this).children("img.playButton").is(":hidden")) {
                  // ?autoplay=1&mute=1     an autoplay with mute works, but apparently YouTube does not count these as user-initiated plays.
                  // ?rel=0                 limit the follow-up videos to the same youtube channel
                  var video = '<iframe src="' +  '//www.youtube.com/embed/' + $(this).attr('data-videoID') + '?rel=0' + '"' + 
                                     ' width="' +  $(this).children("img.frameCapture").width()      + '"' + 
                                     ' height="' + $(this).children("img.frameCapture").height()     + '"' + 
                                     ' frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>';
                                                       
                  $(this).find("img").hide();
                  $(this).append( video);
               }
            }      
            
         }).mouseenter( function() {
            $(this).children("img.playButton").css('opacity', "1.0");
         }).mouseleave( function() {
            $(this).children("img.playButton").css('opacity', "0.7");
         });
         
         // Loop through all the video containers...
         $('.video-container').each( function(i, item) {
            var imageSource = $(item).children("img.frameCapture").attr('src');
            // Use the YouTube default image if an src for a screen-shot isn't given.
            if (imageSource == "") {
               var linkToYTImage = "https://i.ytimg.com/vi/" + $(this).attr('data-videoID') + "/hqdefault.jpg";   // mqdefault hqdefault maxresdefault 
               $(item).children("img.frameCapture").attr('src', linkToYTImage);
            }
            // Add an alt attribute to the image.
            $(item).children("img.frameCapture").attr('alt', getTopicTitle($(this)) );
            
            // Add a play-button image as an overlay.
            $(item).append('<img class="playButton" src="screenshots/play_button.png" alt="play button">');
         });         
      }
   }
   
   return {
      // Objects
      
      // Variables

      // Methods
      'init': initialize,
      'scroll': scroll,
      'viewDialog': viewDialog,
      'loadLargeImage': loadLargeImage,
      
   };

})();