var about = {
    init: function (loadPageFunc) {
        nav.setTitle('О сайте');
        loadPageFunc();
        home.actions.init();
        validation('#contactForm', about.contact);

    },
    contact: function () {
        var text = e('message').value.trim();
        var email = e('email').value.trim();
        var name = e('name').value.trim();

        j.post(['about', 'contact'], function (data) {
            var frm = e('contactForm');
            empty(frm);
            // if (data.mgr.http_response_code == 200) e('alert', frm, 'div', 'alert alert-success').innerHTML = 'Спасибо! Ваше сообщение успешно отправлено.';
            if (data.result == 1) e('alert', frm, 'div', 'alert alert-success').innerHTML = 'Спасибо! Ваше сообщение успешно отправлено.';
            else e('alert', frm, 'div', 'alert alert-warning').innerHTML = 'К сожалению произошла ошибка, сообщите об этом по адресу - blago.web@outlook.com';
        }, {text: text, name: name, email: email, history: clk.debugPushedHistory});

    }
};var home = {
    init: function (callback){

        if (isDefined(getUrlParameter('editor'))) {
            if (getUrlParameter('editor') === 'true') localStorage.editor = true;
            nav.goTo('/');
            return false;
        }

        callback();

        document.querySelector('#home .btnsBox').innerHTML = document.querySelector('#navbarNav .btnsBox').innerHTML;
        forEachArray(document.getElementsByName('searchForm'), function (form) {form.reset();});

        this.actions.init();
    },
    actions: {
        init: function () {
            let inpts = document.getElementsByClassName('searchInput');
            let btns = document.getElementsByClassName('searchBtn');
            forEachArray(document.querySelectorAll('.btnsBox select'),function (slct) {
                slct.onchange = home.actions.selector;
            });

            forEachArray(inpts, function (inpt) {
                inpt.onkeydown = home.actions.input;
            });
            forEachArray(btns, function (btn) {
                btn.onclick = home.actions.button;
            });

        },
        button: function (ev) {
            const searchText = ev.target.closest('.input-group').querySelector('input').value;
            if(searchText.length > 2 || parseInt(searchText))nav.goTo('search', {word:searchText});
            else alert('Введите три и больше символов или введите номер песни для начала поиска');
        },
        input: function (ev) {
            if (ev.key == "Enter") {
                ev.preventDefault();
                ev.stopImmediatePropagation();
                const searchText = ev.target.value;
                if(searchText.length > 2 || parseInt(searchText))nav.goTo('search', {word:searchText});
                else alert('Введите три и больше символов или введите номер песни для начала поиска');
            }
        },
        selector: function (ev) {
            nav.goTo('search?'+ev.target.name+'=' + ev.target.value);
        }
    }
};
var presentation = {
    init: function (callback) {
        if (callback) callback();
        window.page = 'presentation';
        this.receiver.init();
    },
    showSlide: function (slideText) {
        document.getElementById('textBox').innerHTML = slideText;
        presentation.fontResize();
    },
    fontResize: function (isDelay) {
        if (isDelay) {
            setTimeout(presentation.fontResize, 500);
            return false;
        }
        let slide = document.getElementById('slideBox');
        let slText = document.getElementById('textBox');
        let f = 10;
        slText.style.fontSize = f + 'px';

        const isFullScr = !!document.body.classList.contains('fullscreen');

        if (page != 'presentation' && !isFullScr) slide = slide.parentElement;
        let maxW = page != 'presentation' && !isFullScr ? slide.offsetWidth - 30 : slide.offsetWidth;
        let maxH = page != 'presentation' && !isFullScr ? window.innerHeight * 0.5 : slide.offsetHeight;

        while (maxW > slText.offsetWidth + 40 && maxH > slText.offsetHeight + 40 && (page == 'presentation' || isFullScr || f < 45)) {
            slText.style.fontSize = f + 'px';
            f++;
        }

    },
    receiver: {
        connectionIdx: 0,
        init: function () {
            if (navigator.presentation.receiver) {
                navigator.presentation.receiver.connectionList.then(list => {
                    list.connections.map(connection => presentation.receiver.initConnection(connection));
                    list.addEventListener('connectionavailable', function (event) {
                        presentation.receiver.initConnection(event.connection);
                    });
                });
            }
        },
        initConnection: function (connection) {
            connection.connectionId = ++presentation.receiver.connectionIdx;
            connection.send('connected');
            console.log('New connection #' + connection.connectionId);

            connection.addEventListener('message', function (event) {
                // const data = JSON.parse(event.data);
                let data = event.data;
                if (data.indexOf('settings') == 0) {
                    const params = JSON.parse(data.replace(/^[^:]+:/gi, ''));
                    if(params.bgColorOpacity)document.getElementById('bgColor').style.opacity = params.bgColorOpacity;
                    if(params.bgColor)document.getElementById('bgColor').style.backgroundColor = params.bgColor;
                    if(params.txtColor)document.getElementById('textBox').style.color = params.txtColor;
                    if(params.imgSrc)document.body.style.backgroundImage = 'url("' + params.imgSrc + '")';
                    if(params.firstSlide)data = params.firstSlide;
                    else data = false;
                }
                if(data) switch (data) {
                    case 'stop': {
                        document.getElementById('textBox').innerText = '';
                        document.getElementById('bgColor').hidden = true;
                        connection.send('stoped');
                        break;
                    }
                    case 'close': {
                        window.close();
                        break;
                    }
                    default:
                        presentation.showSlide(data);
                        document.getElementById('bgColor').hidden = false;
                        break;
                }
                console.log(data);
            });
        }
    }
};


// oinclose present page clear localstorage id
var search = {
    init: function (callback) {
        home.actions.init();

        let word = getUrlParameter('word');
        let colId = getUrlParameter('collections');
        let letter = getUrlParameter('alphabet');
        let kw = getUrlParameter('tags');
        let path = '';
        forEachArray(document.getElementsByName('searchForm'), function (form) {
            form.reset();
        });

        callback();
        this.build.template = document.querySelector('#searchList>div').cloneNode(true);

        if (word) {
            let slcts = document.getElementsByClassName('searchInput');
            forEachArray(slcts, function (slct) {
                slct.value = word;
            });
            path = 'init';
        } else if (colId) {
            let slcts = document.getElementsByClassName('collections');
            forEachArray(slcts, function (slct) {
                slct.value = colId;
            });
            path = 'collection';
        } else if (kw) {
            let slcts = document.getElementsByClassName('tags');
            forEachArray(slcts, function (slct) {
                slct.value = kw;
            });
            path = 'tags';
        } else if (letter) {
            let inpts = document.getElementsByClassName('alphabet');
            forEachArray(inpts, function (inpt) {
                inpt.value = letter;
            });
            path = 'alphabet';
        }

        j.post(['search', path], function (data) {
            search.pagination.initNav(data.searchCount);
            if (data.searchCount) search.build.results(data);
            let title;
            if (colId) title = 'Сборник - ' + searchParams.collections[colId];
            else if (letter) title = 'Алфавитный указатель "' + letter + '"';
            else if (kw) title = 'Поиск по метке "' + kw + '"';
            else title = 'Поиск "' + word + '"';

            nav.setTitle(title);
        }, {sw: word, colId: colId, letter: letter, kw: kw});

    },
    collNum: {
        openPopup: function () {
            $('#modalMsg').modal('show');
            e('modalMsg').querySelector('.modal-title').innerText = 'Перейти на песню';
            e('modalMsg').querySelector('.msgText').innerHTML = '<div class="input-group">' + e('srchByNumBox').innerHTML +
                '</div><button type="button" class="btn btn-outline-success mt-2 float-right" onclick="search.collNum.goTo()">Перейти</button>';
            document.forms.modalForm.collections.onchange = search.collNum.collSaver;
            if(localStorage.collId) document.forms.modalForm.collections.value = localStorage.collId;
        },
        goTo: function () {
            event.preventDefault();
            event.stopImmediatePropagation();
            const songNum = document.forms.modalForm.songNum.value;
            const collId = document.forms.modalForm.collections.value;
            j.post(['search', 'byNum'], function (data) {
                if(data.info){
                    nav.goTo('/song/'+toUrl(data.info.title) + '/' + data.info.sId);
                    $('#modalMsg').modal('hide');
                }
                else {alert("Песни под этим номером нету в сборнике, или она выключена. \n\nЕсли вы считаете что это ошибка, напишите нам через контактную форму (справа вверху кнопка \"О нас\")");}
            }, {songNum: songNum, collId: collId});
        },
        collSaver: function (ev) {
            console.log(ev);
            localStorage.collId = ev.target.value;
        },

    },
    build: {
        template: false,
        results: function (data) {
            search.pagination.reInitNav();
            let startPos = (search.pagination.curPage - 1) * search.pagination.perPage;
            let endPos = startPos + search.pagination.perPage;
            let par = e('searchList');
            par.innerHTML = '';

            for (let i = startPos; i < data.searchList.order.length && i < endPos; i++) {
                let div, el, val, curBlock, imgBlk, k = data.searchList.order[i], line = data.searchList[k];

                div = this.template.cloneNode(true);
                div.removeAttribute('hidden');
                el = par.appendChild(div);

                el.dataset.list = k;

                for (var l in line) {
                    curBlock = el.querySelector('[data-name="' + l + '"]');
                    val = line[l];
                    if (l == 'imgId' && (imgBlk = el.querySelector('img'))) {
                        imgBlk.src = img.url(val, 150, 150, line.collectionName);
                        imgBlk.alt = line.title;
                    } else if (l == 'title') {
                        curBlock.href = '/song/' + toUrl(val) + '/' + line.sid;
                        curBlock.innerHTML = val;
                    } else if (curBlock) curBlock.innerHTML = val;
                }
            }
            if (isDefined(data.search)) highlight(data.search, 'searchList');
        }
    },
    pagination: {
        curPage: 1,
        perPage: 20,
        pages: 0,
        total: 0,
        initNav: function (total) {
            this.totalLines = total;
            if (isDefined(total)) {
                if (getUrlParameter('page')) search.pagination.curPage = getUrlParameter('page');
                else this.curPage = 1;
                this.pages = Math.ceil(total / this.perPage);

                e('searchPagesInfo').innerHTML = 'Всего найдено ' + (total > 100 ? '100+' : total) + ' результатов. Страница ' + this.curPage + ' из ' + this.pages;
                let par = e('searchPagination').querySelector('ul');
                par.innerHTML = '';

                e(null, e(null, par, 'li', 'page-item'), 'a', 'page-link').t('&laquo;').onclick = this.prev;
                var mobileSelect = e(null, e(null, par, 'li', 'page-item'), 'select', 'page-link d-lg-none form-control');
                mobileSelect.onchange = this.initPage;

                for (let p = 1; p <= this.pages; p++) {
                    let isActive = p == this.curPage ? 'active' : '';
                    let plink = e(null, e(null, par, 'li', 'page-item ' + isActive), 'a', 'page-link d-none d-lg-block').t(p);
                    plink.onclick = this.initPage;
                    plink.dataset.page = p;
                    mobileSelect[p] = new Option(p, p, p == this.curPage, p == this.curPage);
                }

                e(null, e(null, par, 'li', 'page-item'), 'a', 'page-link').t('&raquo;').onclick = this.next;
            } else e('searchPagesInfo').innerHTML = 'По вашему запросу ничего не найдено, попробуйте изменить параметры поиска';
        },
        reInitNav: function () {
            if (isDefined(this.totalLines)) {
                e('searchPagesInfo').innerHTML = 'Всего найдено ' + (this.totalLines > 100 ? '100+' : this.totalLines) + ' результатов. Страница ' + this.curPage + ' из ' + this.pages;
                e('searchPagination').querySelector('.active').classList.remove('active');
                e('searchPagination').querySelector('a[data-page="' + this.curPage + '"]').closest('li').classList.add('active');
                e('searchPagination').querySelector('select').value = this.curPage;
                this.changeUrl();
            } else e('searchPagesInfo').innerHTML = 'По вашему запросу ничего не найдено, попробуйте изменить параметры поиска';
        },
        initPage: function (ev) {
            search.pagination.curPage = (ev.target.dataset.page ? ev.target.dataset.page : ev.target.value);
            search.build.results(loadedData);
        },
        prev: function () {
            if (search.pagination.curPage > 0) search.pagination.curPage--;
            search.build.results(loadedData);
        },
        next: function () {
            if (search.pagination.curPage < search.pagination.pages) search.pagination.curPage++;
            search.build.results(loadedData);
        },
        changeUrl: function () {
            const url = new URL(window.location.href);
            url.searchParams.set('page', this.curPage);
            clk.historyPushedHref = url;
            window.history.replaceState(null, null, url);
        }
    }
};var song = {
    id: false,
    languages: {
        'ru': 'Русский',
        'en': 'Английский',
        'uk': 'Украинский',
        'be': 'Белорусский',
        'de': 'Немецкий'
    },
    playing: false,
    currentBodyFontSize: false,
    init: function (callback) {
        for (var i in path) if (path[i].search(/^\d{5,6}$/i) >= 0) song.id = path[i];

        j.post(['song', 'init'], function (data) {
            callback();
            document.body.classList.remove('presentation');

            song.clientSettings.init();
            song.build.tones();
            song.build.couplets();
            song.build.coupletNums();
            song.build.keywords(data.keywords);
            song.build.info(data.details);
            song.build.videos(data.videoLinks);
            song.build.files(data.files);
            if (isDefined(data.couplets[0])) song.slideShow.init();
            home.actions.init();
            song.actions.init();

            nav.setTitle(data.details.title);
            e('songBody').style.fontSize = song.currentBodyFontSize + "px";
        }, {sid: song.id});
    },
    build: {
        couplets: function () {
            const list = loadedData.couplets;
            let cNum = 1;
            e('couplets').innerHTML = '';
            let repeatChorus = e('repeatChorus').checked;
            for (let k in list) {
                loadedData.couplets[k].subTitle = list[k].isChorus == 1 ? "Припев: \n" : ((cNum++) + '. ');
                let chrds = list[k].hasChords == 1 ? ' hasChords ' : '';
                let chorus = list[k].isChorus == 1 ? ' chorus ' : '';
                let txt = chrds != '' ? this.rebuildText(list[k].body) : list[k].body;
                if (repeatChorus || !list[k].repeat) {
                    const cpl = e(null, e('couplets'), 'div', chorus + chrds).t(txt);
                    cpl.dataset.couplet = k;
                    cpl.dataset.coupletAbsnum = list[k].sort;
                    cpl.dataset.bodyLength = list[k].body.length;
                }
                if (list[k].isChorus == 1) document.querySelector('.repeatChorusBox').hidden = false;
            }
            this.chords();
        },
        rebuildText: function (txt) {
            let nTxt = '';
            for (let i = 0; i < txt.length; i++) {
                nTxt += '<span data-pos="' + i + '">' + txt[i] + '</span>';
            }
            return nTxt;
        },
        coupletNums: function () {
            const list = loadedData.couplets;
            let cNum = 1;
            for (let k in list) {
                let chorus = list[k].isChorus == 1;
                e(null, e('coupletNums'), 'a').t((chorus ? '*' : cNum)).a('onclick', 'song.actions.numSlide(' + k + ')')
                    .title = chorus ? 'Припев' : ("Куплет " + (cNum++));
            }
        },
        keywords: function (list) {
            if (typeof list === 'object' && !Array.isArray(list)) e('keywords').closest('.card').hidden = false;
            for (let k in list) {
                e(null, e('keywords'), 'button', 'btn btn-secondary m-1').t('<i class="fas fa-tag"></i> ' + list[k])
                    .onclick = function (ev) {
                    nav.goTo('/search', {kw: ev.target.innerText});
                };
            }
        },
        info: function (data) {
            let el, val;

            for (let k in data) {
                val = data[k];

                if (k == 'title') e('songTitle').innerHTML = val;
                else if ((el = e('generalInfo').querySelector('[data-name="' + k + '"]')) && val != null && val != "") {
                    if (k == 'language') val = song.languages[val];
                    if (el.querySelector('span')) el.querySelector('span').innerHTML = val;
                    el.hidden = false;
                }
                else if(k == 'note' && val !=''){
                    e('historyBox').hidden = false;
                    e('note').innerText = val;
                }
            }

        },
        videos: function (data) {
            for(let k in data){
                // console.log(k,);
                e(null, e('videos'), 'iframe').a('allowfullscreen', 'true').a('frameborder', '0').src = data[k];
            }
        },
        files: function (data) {
            if (!isDefined(data.length) && loadedData.details.dirMid) {
                e('zipLink').closest('div').hidden = false;
                e('zipLink').href = zipServer + loadedData.details.dirMid + '/';
            }
            for (let k in data) {
                let file = data[k];

                if (file.ext == 'mp3' && file.role != null) {
                    let role = file.role;
                    let src = playServer + file.id + '/' + toUrl(loadedData.details.title) + '.' + file.ext;
                    let block = document.querySelector('div[data-role="' + role + '"]');
                    let a = new Audio(src);
                    a.controls = true;
                    a.preload = "metadata";
                    block.closest('.card').hidden = false;
                    block.appendChild(a);
                } else {
                    let src = (file.ext == 'pdf' ? pdfServer : dwnldServer) + file.id + '/' + toUrl(file.name) + '.' + file.ext;
                    let block = document.querySelector('div[data-role="otherFiles"]');
                    let a = document.createElement('a');
                    let iconCls = file.ext == 'pdf' ? 'fa-file-pdf' : file.role == 'musicxml' ? 'fa-file-audio' : file.role == 'sheetimg' ? 'fa-file-image' : 'fa-file';
                    let icon = '<i class="far ' + iconCls + '"></i> ';
                    a.href = src;
                    a.target = "_blank";
                    a.innerHTML = icon + file.name + ' (' + (file.roleName != null ? file.roleName : file.ext) + ')';//.' + file.ext;
                    block.closest('.card').hidden = false;
                    block.appendChild(a);
                }
            }

            forEachArray(document.querySelectorAll('.tracks  audio'), function (aud) {
                aud.onplay = song.actions.playAudio;
            });
        },
        chords: function (toneChange) {
            for (let s in loadedData.chordsRefs) {
                let cplt = loadedData.chordsRefs, id;

                let lvl = parseInt(cplt[s].level);
                let bassLvl = parseInt(cplt[s].bassLevel);
                if (isDefined(toneChange)) {
                    toneChange = parseInt(toneChange);
                    lvl = lvl + toneChange;
                    lvl = lvl < 0 ? lvl + 12 : lvl > 11 ? lvl - 12 : lvl;
                    if(bassLvl){
                        bassLvl = bassLvl + toneChange;
                        bassLvl = bassLvl < 0 ? bassLvl + 12 : bassLvl > 11 ? bassLvl - 12 : bassLvl;
                    }
                }

                const curChord = loadedData.chords[cplt[s].type][lvl][cplt[s].step];

                let chrdPlace = false;
                const curCoupl = document.querySelector('div[data-couplet-absnum="' + cplt[s].coupletSort + '"]');
                const bodyLength = parseInt(curCoupl.dataset.bodyLength);
                let curLett = curCoupl.querySelector('span[data-pos="' + cplt[s].pos + '"]');
                if(!curLett) curLett = curCoupl.querySelector('span[data-pos="' + (bodyLength - 1) + '"]');
                chrdPlace = curLett.querySelector('span.chordPlace');

                const bassCode = bassLvl ? loadedData.chords[cplt[s].bassType][bassLvl][cplt[s].bassStep].code : false;

                const chord = this.getChordElement(curChord.code, curChord.id, cplt[s].addLabel, bassCode);

                if (!chrdPlace) {
                    const sp = document.createElement('span');
                    sp.dataset.curToneId = song.curToneId;
                    sp.className = 'chordPlace';
                    curLett.prepend(sp);
                    chrdPlace = curLett.querySelector('span.chordPlace');
                }
                else if(chrdPlace.dataset.curToneId != song.curToneId) {
                    chrdPlace.innerHTML = '';
                    chrdPlace.dataset.curToneId = song.curToneId;
                }
                chrdPlace.prepend(chord);
            }
        },
        tones: function () {
            const select = e('tone');
            select.hidden = false;
            let sel = false;

            for (let a in loadedData.tones) {
                sel = loadedData.details.defTonality == loadedData.tones[a].id;
                select[select.options.length] = new Option(loadedData.tones[a].code + (sel ? ' (оригинал)' : ''), loadedData.tones[a].id, sel, sel);
            }
            select.onchange = song.actions.chords.changeTonality;

            song.curToneId = loadedData.details.defTonality;
        },
        getChordElement: function (code, id, addLabel, bassCode) {
            const chord = document.createElement('chord');
            chord.innerHTML = code + (addLabel?addLabel:'') +
                (bassCode? '/' + bassCode : '')+
                "<span>" +
                "<img src='/chords/images/" + id + ".gif'/>" +
                "<audio src='/chords/audio/" + id + ".mp3' preload='none' controls onpause='this.currentTime = 0;' onplay='song.actions.playAudio(this)'></audio>" +
                "</span>";
            return chord;
        }
    },
    actions: {
        init: function () {
            e('presentationBtn').onclick = function () {
                song.slideShow.startData = loadedData.couplets[0].subTitle + loadedData.couplets[0].body;

                if (!localStorage.presentationId) {
                    const disabled = song.slideShow.presentationAvailable ? '' : 'disabled';

                    $('#modalMsg').modal('show');
                    e('modalMsg').querySelector('.modal-title').innerText = 'Выберите экран';
                    e('modalMsg').querySelector('.msgText').innerHTML =
                        '<button class="btn w-100 mb-2" type="button" onclick="$(\'#modalMsg\').modal(\'hide\');song.actions.fullScr.slide();">Показать на этом экране</button><br>' +
                        '<button class="btn btn-secondary w-100"  type="button"onclick="song.slideShow.actions.start();$(\'#modalMsg\').modal(\'hide\');"' + disabled + '>Показать на другом экране</button>';
                } else song.slideShow.actions.start();
            };
            if (Object.isEmpty(loadedData.chordsRefs)) e('chordsSwitch').hidden = true;
            e('slideBox').addEventListener('fullscreenchange', (event) => {
                event.preventDefault();
                event.stopImmediatePropagation();
                if (!document.fullscreenElement) song.slideShow.reactions.onstop();
            });
            e('songBody').addEventListener('fullscreenchange', song.actions.fullScr.body);
        },
        prevSlide: function () {
            if (song.slideShow.curSlide > 0) song.slideShow.curSlide--;
            const newData = loadedData.couplets[song.slideShow.curSlide].subTitle + loadedData.couplets[song.slideShow.curSlide].body;
            song.slideShow.sendData(newData);
            presentation.showSlide(newData);
        },
        nextSlide: function () {
            if (song.slideShow.curSlide < loadedData.couplets.length - 1) song.slideShow.curSlide++;
            else {
                song.slideShow.actions.stop();
                return false;
            }
            let newData = loadedData.couplets[song.slideShow.curSlide].subTitle + loadedData.couplets[song.slideShow.curSlide].body;
            if (song.slideShow.curSlide == loadedData.couplets.length - 1) newData += "\n*  *  *";
            song.slideShow.sendData(newData);
            presentation.showSlide(newData);
        },
        numSlide: function (num) {
            if (isDefined(loadedData.couplets[num])) song.slideShow.curSlide = parseInt(num);
            let newData = loadedData.couplets[song.slideShow.curSlide].subTitle + loadedData.couplets[song.slideShow.curSlide].body;
            if (song.slideShow.curSlide == loadedData.couplets.length - 1) newData += "\n*  *  *";
            song.slideShow.sendData(newData);
            presentation.showSlide(newData);
        },
        stopSlides: function () {
            song.slideShow.actions.stop();
            if (document.fullscreenElement) document.exitFullscreen();
            else if (document.body.classList.contains('fullscreen')) song.slideShow.reactions.onstop();
        },
        share: function () {
            var link = baseUrl, title;

            link += "song/" + toUrl(loadedData.details.title) + "/" + loadedData.details.id;
            title = loadedData.details.title;

            if (isMobile && navigator.share) {
                navigator.share({
                    title: title,
                    url: link
                });
            } else {
                // if(!isShared) {
                if (Clipboard.copy(link)) {
                    $('#modalMsg').modal('show');
                    e('modalMsg').querySelector('.modal-title').innerText = 'Поделиться';
                    e('modalMsg').querySelector('.msgText').innerText = 'Ссылка скопирована успешно';
                    setTimeout(function () {
                        $('#modalMsg').modal('hide');
                    }, 3000);
                }
            }
        },
        copyText: function () {
            let txt = '';
            for (let k in loadedData.couplets){
                txt += (txt ? "\n\n" : '') + loadedData.couplets[k].subTitle + loadedData.couplets[k].body;
            }
            if (Clipboard.copy(txt)) {
                $('#modalMsg').modal('show');
                e('modalMsg').querySelector('.modal-title').innerText = 'Копирование текста';
                e('modalMsg').querySelector('.msgText').innerText = 'Текст песни успешно скопирован';
                setTimeout(function () {
                    $('#modalMsg').modal('hide');
                }, 3000);
            }
        },
        playAudio: function (ev) {
            if (isDefined(ev.target)) ev = ev.target;
            if (song.playing && !song.playing.paused && song.playing != ev) song.playing.pause();
            song.playing = ev;
        },
        fullScr: {
            body: function (ev) {
                if (!ev && e('songBody').requestFullscreen) {
                    if (document.fullscreenElement) document.exitFullscreen();
                    else e('songBody').requestFullscreen();
                } else document.body.classList.toggle('fullscreenCouplets');
            },
            slide: function () {
                document.body.classList.add('fullscreen');
                if (e('slideBox').requestFullscreen) e('slideBox').requestFullscreen().then(function () {
                    song.slideShow.enabled = true;
                    song.slideShow.reactions.onstart();
                });
                else {
                    song.slideShow.enabled = true;
                    song.slideShow.reactions.onstart();
                }
            }
        },

        text: {
            increaseTxt: function () {
                e('songBody').style.fontSize = song.currentBodyFontSize + 1 + "px";
                song.currentBodyFontSize++;
                song.clientSettings.set('fontSize', song.currentBodyFontSize);
            },
            decreaseTxt: function () {
                e('songBody').style.fontSize = song.currentBodyFontSize - 1 + "px";
                song.currentBodyFontSize--;
                song.clientSettings.set('fontSize', song.currentBodyFontSize);

            },
            twoColumnsSw: function () {
                e('songBody').classList.toggle('twoColumns');
                song.clientSettings.set('twoColumns', !song.clientSettings.data.twoColumns);
            },
            chordVisibilitySw: function () {
                e('songBody').classList.toggle('chordsVisible');
                song.clientSettings.set('chords', !song.clientSettings.data.chords);
            },
            lightSw: function () {
                e('songBody').classList.toggle('light');
                song.clientSettings.set('fullscreenLight', !song.clientSettings.data.fullscreenLight);
            },
            chorusRptSw: function () {
                song.build.couplets(loadedData.couplets);
                song.clientSettings.set('chorusRepeat', !song.clientSettings.data.chorusRepeat);
            }
        },

        chords: {
            changeTonality: function () {
                const d = loadedData.tones[e('tone').value].level - loadedData.tones[loadedData.details.defTonality].level;
                song.curToneId = e('tone').value;
                song.build.chords(d);
            }
        }
    },
    slideShow: {
        enabled: false,
        request: false,
        startData: false,
        curSlide: 0,
        presentationAvailable: false,
        init: function () {
            const url = '/presentation.html';

            if (!isOS() && isDefined(PresentationRequest)) {
                this.request = new PresentationRequest(url);

                navigator.presentation.defaultRequest = this.request;

                // Доступность презентации в браузере + наличие других мониторов
                this.request.getAvailability().then(function (availability) {
                    song.slideShow.availabilityChange(availability.value);
                    availability.onchange = function () {
                        song.slideShow.availabilityChange(this.value);
                    };
                }).catch(function () {
                    song.slideShow.availabilityChange(true);
                });

                this.request.addEventListener('connectionavailable', function (event) {
                    console.log(event);
                    localStorage.presentationId = event.connection.id;
                    song.slideShow.connection = event.connection;
                    song.slideShow.connection.addEventListener('close', function () {
                        console.log('> Connection closed.');
                        song.slideShow.reactions.oncloseConnect();
                    });
                    song.slideShow.connection.addEventListener('terminate', function () {
                        console.log('> Connection terminated.');
                        song.slideShow.reactions.oncloseConnect();
                    });
                    song.slideShow.connection.addEventListener('message', function (event) {
                        console.log('> ' + event.data);
                        if (event.data == 'connected') song.slideShow.reactions.onstart();
                        if (event.data == 'stoped') song.slideShow.reactions.onstop();
                    });
                });
            }


        },
        availabilityChange: function (available) {
            this.presentationAvailable = !!available;
        },
        actions: {
            start: function (mode) {
                console.log(mode);
                console.log('onstartpresentation', !localStorage.presentationId);

                if (!localStorage.presentationId) {
                    console.log('presstart');
                    song.slideShow.request.start().then(connection => {
                        console.log(connection);
                        song.slideShow.reactions.onstart(connection);
                    }).catch(error => {
                        song.slideShow.enabled = false;
                        console.log('> ' + error.name + ': ' + error.message);
                    });
                }
                else song.slideShow.request.reconnect(localStorage.presentationId).then(connection => {
                    song.slideShow.reactions.onstart(connection);
                }).catch(error => {
                    song.slideShow.enabled = false;
                    console.log('> ' + error.name + ': ' + error.message);
                    localStorage.removeItem('presentationId');
                    if (mode != 'tech') song.slideShow.actions.start();
                });
            },
            stop: function () {
                if (!song.slideShow.sendData('stop')) {
                    song.slideShow.startData = 'stop';
                    this.start('tech');
                }
            },
            close: function () {
                if (!song.slideShow.sendData('close')) {
                    song.slideShow.startData = 'close';
                    this.start('tech');
                }
            },
            loadImg: {
                sett: function () {
                    $('#presentSettModal').modal('show');
                    if (localStorage.presentationBgColorOpacity) {
                        e('presentationBgTransp').value = localStorage.presentationBgColorOpacity;
                        e('presentationBgTransp').nextSibling.innerText = localStorage.presentationBgColorOpacity;
                    }
                    if (localStorage.presentationBgColor)
                        e('presentationBgColor').value = localStorage.presentationBgColor;
                    if (localStorage.presentationTxtColor)
                        e('presentationTxtColor').src = localStorage.presentationTxtColor;
                    if (localStorage.presentationImgSrc)
                        e('presentationImgPrev').src = localStorage.presentationImgSrc;
                },
                transparency: function (ev) {
                    const val = ev.value;
                    ev.nextSibling.innerText = val;
                    localStorage.presentationBgColorOpacity = val;
                    song.slideShow.sendData('settings:{"bgColorOpacity":"' + val + '"}');
                },
                bgColor: function (ev) {
                    const val = ev.value;
                    localStorage.presentationBgColor = val;
                    song.slideShow.sendData('settings:{"bgColor":"' + val + '"}');
                },
                txtColor: function (ev) {
                    const val = ev.value;
                    localStorage.presentationTxtColor = val;
                    song.slideShow.sendData('settings:{"txtColor":"' + val + '"}');
                },
                getImg: function (ev) {
                    const files = ev.files[0];
                    if (files) {
                        const fileReader = new FileReader();
                        fileReader.readAsDataURL(files);
                        fileReader.addEventListener("load", function () {
                            localStorage.presentationImgSrc = this.result;
                            e('presentationImgPrev').src = this.result;

                            if (!localStorage.presentationBgColorOpacity || localStorage.presentationBgColorOpacity > 0.8) {
                                e('presentationBgTransp').value = 0.7;
                                song.slideShow.actions.loadImg.transparency(e('presentationBgTransp'));
                            }

                            song.slideShow.sendData('settings:{"imgSrc":"' + this.result + '"}');
                        });
                    }
                }
            }
        },
        reactions: {
            onstop: function () {
                song.slideShow.enabled = false;
                document.body.classList.remove('presentation');
                document.body.classList.remove('fullscreen');
                if (!!document.fullscreenElement) document.exitFullscreen();

                window.removeEventListener('keyup', this.onKeyup, false);
                window.removeEventListener('orientationchange', presentation.fontResize);
                window.removeEventListener('onresize', presentation.fontResize);
                localStorage.presentationStatus = 'stoped';
            },
            onstart: function (connection) {
                if (connection) {
                    song.slideShow.enabled = true;
                    console.log('> Connected to ' + connection.url + ', id: ' + connection.id);
                    document.body.classList.add('presentationOpened');
                    localStorage.presentationStatus = 'started';
                }
                document.body.classList.add('presentation');
                song.slideShow.curSlide = 0;
                presentation.showSlide(song.slideShow.startData);

                //send settings & first couplet
                const sett = {
                    bgColorOpacity: localStorage.presentationBgColorOpacity,
                    bgColor: localStorage.presentationBgColor,
                    txtColor: localStorage.presentationTxtColor,
                    imgSrc: localStorage.presentationImgSrc,
                    firstSlide: song.slideShow.startData
                }
                song.slideShow.sendData('settings:' + JSON.stringify(sett));

                window.addEventListener('keyup', this.onKeyup, false);
                window.addEventListener('orientationchange', presentation.fontResize);
                window.addEventListener('onresize', presentation.fontResize);
            },
            oncloseConnect: function () {
                song.slideShow.reactions.onstop();
                localStorage.removeItem('presentationId');
                document.body.classList.remove('presentationOpened');
            },
            onKeyup: function (ev) {
                console.log(ev);
                if (ev.key == 'ArrowRight') song.actions.nextSlide();
                if (ev.key == 'ArrowLeft') song.actions.prevSlide();
                if (ev.key == 'Escape') song.actions.stopSlides();
            }
        },
        sendData: function (slideText) {
            if (song.slideShow.connection && song.slideShow.connection.state == "connected") {
                song.slideShow.connection.send(slideText);
                return true;
            }
            return false;
        },
    },
    clientSettings: {
        data: {
            fontSize: 16,
            twoColumns: false,
            chords: false,
            chorusRepeat: false,
            fullscreenLight: false
        },
        init: function () {
            if (localStorage.clientSettings) this.data = JSON.parse(localStorage.clientSettings);

            song.currentBodyFontSize = song.clientSettings.data.fontSize;
            if (this.data.twoColumns) e('songBody').classList.add('twoColumns');
            if (this.data.chords && loadedData.chordsRefs.length) e('songBody').classList.add('chordsVisible');
            if (this.data.chorusRepeat) e('repeatChorus').checked = true;
            if (this.data.fullscreenLight) e('songBody').classList.add('light');
        },
        set: function (param, value) {
            song.clientSettings.data[param] = value;
            localStorage.clientSettings = JSON.stringify(song.clientSettings.data);
        }
    },
    onstorage: function (ev) {
        if (ev.key == 'presentationId') {
            if (ev.newValue == null) document.body.classList.remove('presentationOpened');
            else document.body.classList.add('presentationOpened');
        }
    }
};