var $=function(id) { return document.getElementById(id); };
function IsJsonString(str) { try { JSON.parse(str); } catch(e) { return false; } return true; }
String.prototype.replaceAt=function(index,replacement) { return this.substr(0,index)+replacement+this.substr(index+replacement.length); }

function rndMinMax(min,max) { // min and max included
  return Math.floor(Math.random()*(max-min+1)+min);
}

function b64Enc(str,s=1) {
    var str=btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,function(match,p1) {
        return String.fromCharCode(parseInt(p1,16));
    }));
    if(s==0) str=str.replace(/\=/g,'');
    return str;
}

function b64Dec(str) {
    try {
        return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
            return '%'+('00'+c.charCodeAt(0).toString(16)).slice(-2);
        }).join(''));
    } catch(e) {
        return str;
    }
}

function sleep(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

var enableLS=false;
if(typeof(Storage)!=="undefined") {
    enableLS=true;
}

function selectText() {
    var element=document.getElementById('code');
    if (element) {
        if (element && window.getSelection) {
            // marking
            const selection = window.getSelection();
            selection.removeAllRanges();
            const range = document.createRange();
            range.selectNodeContents(element);
            selection.addRange(range);
            // copying
            //document.execCommand('copy') // old way
            //navigator.clipboard.writeText(element.textContent); // new way
        }
    }
}

var zT;
function zindex(id) {
    clearTimeout(zT);

    if(id=="chat") {
        if($('text')) $('text').style.zIndex=9;
        $(id).style.zIndex=10;
    } else {
        zT=setTimeout(function() {
            if($('chat')) $('chat').style.zIndex=9;
            $(id).style.zIndex=10;
        },500);
    }
}

var nShow;
function showNotification(nt,nc) {
    var nc1=nc.substring(nc.indexOf("<b>")+3,nc.indexOf("</b>"));
    var nc2=nc.substring(nc.indexOf("</b>")+12,nc.indexOf("<br>"));
    nc2=nc2.replace(/<(a\s+.*?|\/a)>/g,'');

    if(window.Notification && Notification.permission!=="denied") {
        Notification.requestPermission(function(status) {
            nShow=new Notification('Twily.info ('+nt+')', {
                body: nc1+' '+nc2,
                icon: '/favicon.ico'
            });
        });

        nShow.close();
    }
}

var n=0,fI,fT=false,fL=false;
window.addEventListener('message',function(event) {
	data=event.data;
	if(IsJsonString(data)) data=JSON.parse(data);

    var title=document.title;
    var link=document.createElement('link');
    link.id="favicon";
    link.type="image/x-icon";
    link.rel="shortcut icon";

    if(data[0]=="notify") {
        if(!fL) {
            fL=true;

            fI=setInterval(function() {
                fT=!fT;

                if(fT) link.href="/favicon_red.ico";
                else   link.href="/favicon.ico";

                document.getElementsByTagName('head')[0].removeChild($('favicon'));
                document.getElementsByTagName('head')[0].appendChild(link);
            },500);
        }

        if(title.substr(0,1)!="(") {
            n=1;
        } else {
            n+=parseInt(data[1]);
            title=title.substr(title.indexOf(" ")+1);
        }
        document.title="("+n+") "+title;

		showNotification(n,data[2]);
    } else {
        clearInterval(fI);
        fT=false;
        fL=false;

        link.href="/favicon.ico";

        document.getElementsByTagName('head')[0].removeChild($('favicon'));
        document.getElementsByTagName('head')[0].appendChild(link);

        n=0;
        if(title.substr(0,1)=="(") document.title=title.substr(title.indexOf(" ")+1);
    }
});

window.addEventListener('scroll',function() {
    if($('text')) {
        var eT,wY;
        eT=$('text').offsetTop;
        eB=$('text').offsetTop+$('text').offsetHeight;
        wY=window.pageYOffset;
        wH=window.innerHeight;

        if(wY>eT) {
            $('top_arrow').style.display="block";
        } else {
            $('top_arrow').style.display="none";
        }
        if((wY+wH)<eB) {
            $('bot_arrow').style.display="block";
        } else {
            $('bot_arrow').style.display="none";
        }
    }
});

var rzC;
function loadCmt(x,f) {
    clearInterval(rzC);

    //$(x).contentWindow.postMessage(f,'*');

    rzC=setInterval(function() {
        //$(x).style.height=0;
        $(x).style.height=$(x).contentWindow.document.body.scrollHeight+"px";
    },100);
}

async function ajaxThumbs(name, idx, cb) {
    var xhr;
    if(window.XMLHttpRequest) xhr=new XMLHttpRequest();
    else                      xhr=new ActiveXObject("Microsoft.XMLHTTP");

    var data;
    xhr.onreadystatechange=function() {
        if(xhr.readyState==4 && xhr.status==200) {
            cb(xhr.responseText);
        }
    }

    xhr.open("GET","/ffthumber.php?p="+name+"&i="+idx,true);
    xhr.send(null);
}

var mfiles=[];
var mcount=0;
var mindex=[];
var mstring=[];
async function checkThumbs() {
    mfiles=document.getElementsByClassName('file');
    mcount=0;
    var host=location.hostname;

    for(var i=0;i<mfiles.length;i++) {
        //console.log(mfiles[i].className);
        if(mfiles[i].className.includes("mimg") || mfiles[i].className.includes("mvid")) {
            var src=mfiles[i].getElementsByTagName('img')[0].src;
            src=src.substring(src.indexOf('/') + host.length + 3);
            src=src.substring(0, src.lastIndexOf('/') + 1);
            //console.log(src);
            if(src=="img/") { // defalt icon loaded only
                mcount++; // ready generate thumb first time
                mindex.push(i);
                var href=mfiles[i].href.split("#")[0];
                href=href.substring(href.indexOf('/') + host.length + 3);
                mstring.push(href);
                //console.log(decodeURI(mstring[(mstring.length-1)]));
            }
        }
    }
    //console.log(mcount);
    for(var i=0;i<mindex.length;i++) {
        var name=mstring[i];
        var idx=mindex[i];
        // ajax name w callback ?
        //console.log("/ffthumber.php?p="+name+"&i="+idx);

        await ajaxThumbs(name,idx,function(data) {
            // callback
            //console.log(data);
            if(data!="") {
                //console.log(data);
                if(IsJsonString(data)) {
                    var json=JSON.parse(data);
                    var targetidx=json['idx'];
                    var targetfile=mfiles[targetidx];
                    if(typeof targetfile!=='undefined') {
                        var targetthumb=json['thumb'];
                        targetfile.getElementsByTagName('img')[0].src="/"+targetthumb;
                    } else {
                        console.log("empty json");
                    }
                }
            }
        });
    }
}

function init() {
    win_resize();

    checkThumbs();

    if(window.location.hash) {
        setTimeout(function() {
            var view=window.location.hash.substr(1);
            if($(view)) {
                $(view).scrollIntoView();
                //alert(window.location.hash);
            }
        },100);
    }
}

function win_resize() {
    var winWidth=window.innerWidth;
    var winHeight=window.innerHeight;

    //alert(winWidth);
    if(typeof smallscreen!=='undefined') {
    if(winWidth<770) {
        if(!smallscreen) {
       		var style=document.createElement('style');
       		style.type="text/css";
       		var styhtm="/* smallscreen css */";
       		styhtm+=".file, .dir { min-width: 64px; width: 64px; }";
       		styhtm+=".statsf { display: block; }";
       		styhtm+=".statsf2 { display: none; }";
       		styhtm+="#chat, #backdrop { width: 200px; }";
            //styhtm+="#container { padding: 64px 8px;  }";
            styhtm+=".embed { width: calc(100% - 200px) !important; margin-left: 200px; padding: 64px 8px !important; }";
            styhtm+="#dirbtn2 { display: none; }";
            styhtm+="#dirbtn { display: block; }";
       		style.innerHTML=styhtm;
       		document.getElementsByTagName('head')[0].appendChild(style);

            smallscreen=true;

            if($('comment')) {
                if($('comment').contentWindow) {
                    if(typeof $('comment').contentWindow.set_size==='function') {
                        $('comment').contentWindow.set_size('small');
                    }
                }
            }
        }
    } else {
        if(smallscreen) {
			var styles=document.getElementsByTagName('style');
       		for(var i=0;i<styles.length;i++) {
           		if(styles[i].innerHTML.indexOf('/* smallscreen css */')!=-1) {
               		styles[i].parentNode.removeChild(styles[i]);
               		break;
           		}
       		}
            
            smallscreen=false;

            if($('comment')) {
                if($('comment').contentWindow) {
                    if(typeof $('comment').contentWindow.set_size==='function') {
                        $('comment').contentWindow.set_size('big');
                    }
                }
            }
        }
    }
    }
}

var wrT;
window.onresize=function() {
    clearTimeout(wrT);
    wrT=setTimeout(function() { win_resize(); },100);
}

window.onscroll=function() {
    currentScroll=window.scrollY;
}

function bodytouch() {
    if(autoscrollOn) {
        if(scrollSpeed<0) {
            toggleScroll('Up');
        } else if(scrollSpeed>0) {
            toggleScroll('Down');
        }
    }
}

var aST;
var autoscrollOn=false;
var scrollSpeed=1.0;
var currentScroll=0;
function autoscroll() {
    clearTimeout(aST);

    if(autoscrollOn) {
        currentScroll+=scrollSpeed;

        window.scrollTo(0,currentScroll);

        if(scrollSpeed<0) {
            if(currentScroll+window.innerHeight<=0) {
                toggleScroll('Up');
                scrollSpeed=-1.0;
            }
         } else if(scrollSpeed>0) {
             if(currentScroll+window.innerHeight>=$('container').scrollHeight) {
                toggleScroll('Down');
                scrollSpeed=1.0;
             }
         }

        aST=setTimeout(function() { autoscroll(); },1000/60);
    }
}
function toggleScroll(x="") {
	var btnsel="";
	var btnoth="";
	var directionRunning=false;
	
	currentScroll=window.scrollY;
	
	if(x=="Up") {
	    //
	    btnsel="btnScrollU";
	    btnoth="btnScrollD";
	
	    $(btnoth).value="Down";
	
	    if(autoscrollOn && scrollSpeed<0) directionRunning=true;
	
	    if(scrollSpeed>0) scrollSpeed=0-scrollSpeed;
	    //scrollSpeed=-1.0;
	} else if(x=="Down") {
	    //
	    btnsel="btnScrollD";
	    btnoth="btnScrollU";
	
	    $(btnoth).value="Up";
	
	    if(autoscrollOn && scrollSpeed>0) directionRunning=true;
	
	    if(scrollSpeed<0) scrollSpeed=Math.abs(scrollSpeed);
	    //scrollSpeed=1.0;
	}
    if(directionRunning) {
        $(btnsel).value=x;
        $('scrollSpeed').style.display="none";
        autoscrollOn=false;
    } else {
        $(btnsel).value="Stop";
        $('scrollSpeed').innerHTML=scrollSpeed;
        $('scrollSpeed').style.display="inline-block";
        autoscrollOn=true;
        autoscroll();
    }
}
var scrollSpeedInc=[0.2,0.4,0.8,1.6,2.4];
var scrollSpeedIdx=0;
var lastchangeSpeedX=0;
var sSIT;
function changeSpeed(x) {
    var step=0.5;

    if(autoscrollOn) {
        //step=scrollSpeedInc[scrollSpeedIdx];
        //console.log('x: '+x+' , step: '+step);

        //if(lastchangeSpeedX==x) {
        //    if(scrollSpeedIdx<scrollSpeedInc.length-1) scrollSpeedIdx++;

        //    clearTimeout(sSIT);
        //    sSIT=setTimeout(function() {
        //        scrollSpeedIdx=0;
        //    },250);
        //}
        //
        //lastchangeSpeedX=x;
        step=1.0;

        if(x==1) { // increaseA (+)
            if(scrollSpeed>0) { // down active
                if(scrollSpeed<1.0) step=0.1;

                scrollSpeed=Math.round((scrollSpeed+step)*100)/100;
            } else if(scrollSpeed<0) { // up active
                if(scrollSpeed>-1.0) step=0.1;

                scrollSpeed=Math.round((scrollSpeed-step)*100)/100;
            }
        } else if(x==-1) { // decrease (-)
            if(scrollSpeed>0) { // down active
                if(scrollSpeed<=1.0) step=0.1;

                if((Math.round((scrollSpeed-step)*100)/100)>0) {
                    scrollSpeed=Math.round((scrollSpeed-step)*100)/100;
                }
            } else if(scrollSpeed<0) { // up active
                if(scrollSpeed>=-1.0) step=0.1;

                if((Math.round((scrollSpeed+step)*100)/100)<0) {
                    scrollSpeed=Math.round((scrollSpeed+step)*100)/100;
                }
            }
        }
        $('scrollSpeed').innerHTML=scrollSpeed;
    }
}
function showBar() {
    if($('control')) {
        $('control').style.opacity="1";
    }
}
function hideBar() {
    if($('control')) {
        $('control').style.opacity="0";
    }
}

function saveVol(id,typ) {
    if(enableLS) {
        var obj={vol: $(id).volume, mut: $(id).muted};
        //console.dir(obj);
        localStorage.setItem('twily-volume-'+typ,JSON.stringify(obj));
    }
}
function loadVol(id,typ) {
    var obj={vol: 1, mut: 1};
    if(enableLS) {
        if(localStorage.getItem('twily-volume-'+typ)) {
            dat=localStorage.getItem('twily-volume-'+typ);
            if(IsJsonString(dat)) {
                obj=JSON.parse(dat);
            }
        }
    }
    $(id).volume=obj['vol'];
    $(id).muted=obj['mut']; // can't autoplay unmuted*
    // requires a user interact before play with unmute
    // means even a timer will not work as unmute pauses~
    // however sometimes it just works .. x)
}
