#include forum/forum.js

Misuzu.Forum.Editor = {};
Misuzu.Forum.Editor.allowWindowClose = false;
Misuzu.Forum.Editor.init = function() {
    const postingForm = $q('.js-forum-posting');
    if(!postingForm)
        return;

    const postingButtons = postingForm.querySelector('.js-forum-posting-buttons'),
        postingText = postingForm.querySelector('.js-forum-posting-text'),
        postingParser = postingForm.querySelector('.js-forum-posting-parser'),
        postingPreview = postingForm.querySelector('.js-forum-posting-preview'),
        postingMode = postingForm.querySelector('.js-forum-posting-mode'),
        previewButton = document.createElement('button'),
        bbcodeButtons = $q('.forum__post__actions--bbcode'),
        markdownButtons = $q('.forum__post__actions--markdown'),
        markupButtons = $qa('.forum__post__action--tag');

    // Initialise EEPROM, code sucks ass but it's getting nuked soon again anyway
    if(typeof peepPath === 'string')
        document.body.appendChild($e({
            tag: 'script',
            attrs: {
                src: peepPath + '/eeprom.js',
                charset: 'utf-8',
                type: 'text/javascript',
                onload: function() {
                    const eepromClient = new EEPROM(peepApp, peepPath + '/uploads', '');

                    const eepromHistory = $e({
                        attrs: {
                            className: 'eeprom-widget-history-items',
                        },
                    });

                    const eepromHandleFileUpload = function(file) {
                        const uploadElemNameValue = $e({
                            attrs: {
                                className: 'eeprom-widget-file-name-value',
                                title: file.name,
                            },
                            child: file.name,
                        });

                        const uploadElemName = $e({
                            tag: 'a',
                            attrs: {
                                className: 'eeprom-widget-file-name',
                                target: '_blank',
                            },
                            child: uploadElemNameValue,
                        });

                        const uploadElemProgressText = $e({
                            attrs: {
                                className: 'eeprom-widget-file-progress',
                            },
                            child: 'Please wait...',
                        });

                        const uploadElemProgressBarValue = $e({
                            attrs: {
                                className: 'eeprom-widget-file-bar-fill',
                                style: {
                                    width: '0%',
                                },
                            },
                        });

                        const uploadElem = $e({
                            attrs: {
                                className: 'eeprom-widget-file',
                            },
                            child: [
                                {
                                    attrs: {
                                        className: 'eeprom-widget-file-info',
                                    },
                                    child: [
                                        uploadElemName,
                                        uploadElemProgressText,
                                    ],
                                },
                                {
                                    attrs: {
                                        className: 'eeprom-widget-file-bar',
                                    },
                                    child: uploadElemProgressBarValue,
                                },
                            ],
                        });

                        if(eepromHistory.children.length > 0)
                            $ib(eepromHistory.firstChild, uploadElem);
                        else
                            eepromHistory.appendChild(uploadElem);

                        const explodeUploadElem = function() {
                            $r(uploadElem);
                        };

                        const uploadTask = eepromClient.createUpload(file);

                        uploadTask.onProgress = function(progressInfo) {
                            const progressValue = progressInfo.progress.toString() + '%';
                            uploadElemProgressBarValue.style.width = progressValue;
                            uploadElemProgressText.textContent = progressValue + ' (' + (progressInfo.total - progressInfo.loaded).toString() + ' bytes remaining)';
                        };

                        uploadTask.onFailure = function(errorInfo) {
                            if(!errorInfo.userAborted) {
                                let errorText = 'Was unable to upload file.';

                                switch(errorInfo.error) {
                                    case EEPROM.ERR_INVALID:
                                        errorText = 'Upload request was invalid.';
                                        break;
                                    case EEPROM.ERR_AUTH:
                                        errorText = 'Upload authentication failed, refresh and try again.';
                                        break;
                                    case EEPROM.ERR_ACCESS:
                                        errorText = 'You\'re not allowed to upload files.';
                                        break;
                                    case EEPROM.ERR_GONE:
                                        errorText = 'Upload client has a configuration error or the server is gone.';
                                        break;
                                    case EEPROM.ERR_DMCA:
                                        errorText = 'This file has been uploaded before and was removed for copyright reasons, you cannot upload this file.';
                                        break;
                                    case EEPROM.ERR_SERVER:
                                        errorText = 'Upload server returned a critical error, try again later.';
                                        break;
                                    case EEPROM.ERR_SIZE:
                                        if(errorInfo.maxSize < 1)
                                            errorText = 'Selected file is too large.';
                                        else {
                                            const _t = ['bytes', 'KB', 'MB', 'GB', 'TB'],
                                                _i = parseInt(Math.floor(Math.log(errorInfo.maxSize) / Math.log(1024))),
                                                _s = Math.round(errorInfo.maxSize / Math.pow(1024, _i), 2);

                                            errorText = 'Upload may not be larger than %1 %2.'.replace('%1', _s).replace('%2', _t[_i]);
                                        }
                                        break;
                                }

                                uploadElem.classList.add('eeprom-widget-file-fail');
                                uploadElemProgressText.textContent = errorText;
                                Misuzu.showMessageBox(errorText, 'Upload Error');
                            }
                        };

                        uploadTask.onComplete = function(fileInfo) {
                            uploadElem.classList.add('eeprom-widget-file-done');
                            uploadElemName.href = fileInfo.url;
                            uploadElemProgressText.textContent = '';

                            const insertTheLinkIntoTheBoxEx2 = function() {
                                const parserMode = parseInt(postingParser.value);
                                let insertText = location.protocol + fileInfo.url;

                                if(parserMode == 1) { // bbcode
                                    if(fileInfo.isImage())
                                        insertText = '[img]' + fileInfo.url + '[/img]';
                                    else if(fileInfo.isAudio())
                                        insertText = '[audio]' + fileInfo.url + '[/audio]';
                                    else if(fileInfo.isVideo())
                                        insertText = '[video]' + fileInfo.url + '[/video]';
                                } else if(parserMode == 2) { // markdown
                                    if(fileInfo.isMedia())
                                        insertText = '![](' + fileInfo.url + ')';
                                }

                                $insertTags(postingText, insertText, '');
                                postingText.value = postingText.value.trim();
                            };

                            uploadElemProgressText.appendChild($e({
                                tag: 'a',
                                attrs: {
                                    href: 'javascript:void(0);',
                                    onclick: function() { insertTheLinkIntoTheBoxEx2(); },
                                },
                                child: 'Insert',
                            }));
                            uploadElemProgressText.appendChild($t(' '));
                            uploadElemProgressText.appendChild($e({
                                tag: 'a',
                                attrs: {
                                    href: 'javascript:void(0);',
                                    onclick: function() {
                                        eepromClient.deleteUpload(fileInfo).start();
                                        explodeUploadElem();
                                    },
                                },
                                child: 'Delete',
                            }));

                            insertTheLinkIntoTheBoxEx2();
                        };

                        uploadTask.start();
                    };

                    const eepromFormInput = $e({
                        tag: 'input',
                        attrs: {
                            type: 'file',
                            multiple: 'multiple',
                            className: 'eeprom-widget-form-input',
                            onchange: function(ev) {
                                const files = this.files;
                                for(const file of files)
                                    eepromHandleFileUpload(file);
                                this.value = '';
                            },
                        },
                    });

                    const eepromForm = $e({
                        tag: 'label',
                        attrs: {
                            className: 'eeprom-widget-form',
                        },
                        child: [
                            eepromFormInput,
                            {
                                attrs: {
                                    className: 'eeprom-widget-form-text',
                                },
                                child: 'Select Files...',
                            }
                        ],
                    });

                    const eepromWidget = $e({
                        attrs: {
                            className: 'eeprom-widget',
                        },
                        child: [
                            eepromForm,
                            {
                                attrs: {
                                    className: 'eeprom-widget-history',
                                },
                                child: eepromHistory,
                            },
                        ],
                    });
                    postingForm.appendChild(eepromWidget);

                    postingText.addEventListener('paste', function(ev) {
                        if(ev.clipboardData && ev.clipboardData.files.length > 0) {
                            ev.preventDefault();

                            const files = ev.clipboardData.files;
                            for(const file of files)
                                eepromHandleFileUpload(file);
                        }
                    });

                    document.body.addEventListener('dragenter', function(ev) {
                        ev.preventDefault();
                        ev.stopPropagation();
                    });
                    document.body.addEventListener('dragover', function(ev) {
                        ev.preventDefault();
                        ev.stopPropagation();
                    });
                    document.body.addEventListener('dragleave', function(ev) {
                        ev.preventDefault();
                        ev.stopPropagation();
                    });
                    document.body.addEventListener('drop', function(ev) {
                        ev.preventDefault();
                        ev.stopPropagation();
                        if(ev.dataTransfer && ev.dataTransfer.files.length > 0) {
                            const files = ev.dataTransfer.files;
                            for(const file of files)
                                eepromHandleFileUpload(file);
                        }
                    });
                },
                onerror: function(ev) {
                    console.error('Failed to initialise EEPROM: ', ev);
                },
            },
        }));

    // hack: don't prompt user when hitting submit, really need to make this not stupid.
    postingButtons.firstElementChild.addEventListener('click', function() {
        Misuzu.Forum.Editor.allowWindowClose = true;
    });

    window.addEventListener('beforeunload', function(ev) {
        if(!Misuzu.Forum.Editor.allowWindowClose && postingText.value.length > 0) {
            ev.preventDefault();
            ev.returnValue = '';
        }
    });

    for(var i = 0; i < markupButtons.length; ++i)
        (function(currentBtn) {
            currentBtn.addEventListener('click', function(ev) {
                $insertTags(postingText, currentBtn.dataset.tagOpen, currentBtn.dataset.tagClose);
            });
        })(markupButtons[i]);

    Misuzu.Forum.Editor.switchButtons(parseInt(postingParser.value));

    var lastPostText = '',
        lastPostParser = null;

    postingParser.addEventListener('change', function() {
        var postParser = parseInt(postingParser.value);
        Misuzu.Forum.Editor.switchButtons(postParser);

        if(postingPreview.hasAttribute('hidden'))
            return;

        // dunno if this would even be possible, but ech
        if(postParser === lastPostParser)
            return;

        postingParser.setAttribute('disabled', 'disabled');
        previewButton.setAttribute('disabled', 'disabled');
        previewButton.classList.add('input__button--busy');

        Misuzu.Forum.Editor.renderPreview(postParser, lastPostText, function(success, text) {
            if(!success) {
                Misuzu.showMessageBox(text);
                return;
            }

            postingPreview.classList[postParser == 2 ? 'add' : 'remove']('markdown');

            lastPostParser = postParser;
            postingPreview.innerHTML = text;
            MszEmbed.handle($qa('.js-msz-embed-media'));

            previewButton.removeAttribute('disabled');
            postingParser.removeAttribute('disabled');
            previewButton.classList.remove('input__button--busy');
        });
    });

    previewButton.className = 'input__button';
    previewButton.textContent = 'Preview';
    previewButton.type = 'button';
    previewButton.value = 'preview';
    previewButton.addEventListener('click', function() {
        if(previewButton.value === 'back') {
            postingPreview.setAttribute('hidden', 'hidden');
            postingText.removeAttribute('hidden');
            previewButton.value = 'preview';
            previewButton.textContent = 'Preview';
            postingMode.textContent = postingMode.dataset.original;
            postingMode.dataset.original = null;
        } else {
            var postText = postingText.value,
                postParser = parseInt(postingParser.value);

            if(lastPostText === postText && lastPostParser === postParser) {
                postingPreview.removeAttribute('hidden');
                postingText.setAttribute('hidden', 'hidden');
                previewButton.value = 'back';
                previewButton.textContent = 'Edit';
                postingMode.dataset.original = postingMode.textContent;
                postingMode.textContent = 'Previewing';
                return;
            }

            postingParser.setAttribute('disabled', 'disabled');
            previewButton.setAttribute('disabled', 'disabled');
            previewButton.classList.add('input__button--busy');

            Misuzu.Forum.Editor.renderPreview(postParser, postText, function(success, text) {
                if(!success) {
                    Misuzu.showMessageBox(text);
                    return;
                }

                postingPreview.classList[postParser == 2 ? 'add' : 'remove']('markdown');

                lastPostText = postText;
                lastPostParser = postParser;
                postingPreview.innerHTML = text;
                MszEmbed.handle($qa('.js-msz-embed-media'));

                postingPreview.removeAttribute('hidden');
                postingText.setAttribute('hidden', 'hidden');
                previewButton.value = 'back';
                previewButton.textContent = 'Back';
                previewButton.removeAttribute('disabled');
                postingParser.removeAttribute('disabled');
                previewButton.classList.remove('input__button--busy');
                postingMode.dataset.original = postingMode.textContent;
                postingMode.textContent = 'Previewing';
            });
        }
    });

    postingButtons.insertBefore(previewButton, postingButtons.firstChild);
};
Misuzu.Forum.Editor.switchButtons = function(parser) {
    var bbcodeButtons = $q('.forum__post__actions--bbcode'),
        markdownButtons = $q('.forum__post__actions--markdown');

    bbcodeButtons.hidden = parser != 1;
    markdownButtons.hidden = parser != 2;
};
Misuzu.Forum.Editor.renderPreview = function(parser, text, callback) {
    if(!callback)
        return;
    parser = parseInt(parser);
    text = text || '';

    var xhr = new XMLHttpRequest,
        formData = new FormData;

    formData.append('post[mode]', 'preview');
    formData.append('post[text]', text);
    formData.append('post[parser]', parser.toString());

    xhr.addEventListener('readystatechange', function() {
        if(xhr.readyState !== XMLHttpRequest.DONE)
            return;
        if(xhr.status === 200)
            callback(true, xhr.response);
        else
            callback(false, 'Failed to render preview.');
    });
    // need to figure out a url registry system again, current one is too much overhead so lets just do this for now
    xhr.open('POST', '/forum/posting.php');
    xhr.withCredentials = true;
    xhr.send(formData);
};
