// Scripting by Oleg Okhotnikov, contact - svoboda200786@gmail.com
let editor_multiplier = 1;
let auto_save_flag = true;
let file_loaded = true;
let board =  document.querySelector("#intro-canvas");
var canvas = new fabric.Canvas('intro-canvas', {
    targetFindTolerance: 2,
    selectionBorderColor: "black",
    selectionDashArray: [10, 10],
    selectionLineWidth: 2,
    selectionColor: "rgba(100, 100, 255, 0)",
    cornerSize: 6
});

let state;
canvas.objectCaching = false;
fabric.Object.prototype.objectCaching = false;
// canvas.backgroundColor = 'rgba(256, 256, 256, 1)';
canvas.freeDrawingBrush.width = 1;

canvas.renderAll();

let btn_save = document.querySelector("#btnSave");
let btn_saveBitmap = document.querySelector("#btnSaveBitmap"); 

if(top_panel_display == "none"){
    document.body.appendChild(btn_saveBitmap);
    btn_saveBitmap.classList.add("save-btn-preview");
}   


let input_filename = document.querySelector("#inputFilename");
function beforeSave(filename, callback, auto_save_flag){
    array = canvas.getObjects();
    for(i in array){
        array[i].excludeFromExport = !array[i].visible;
        let shape_type = /shape_group.*/.test(array[i].groupName)
        if(shape_type){
            array[i].excludeFromExport = false;
        }                 
    } 
    board.style.pointerEvents = "none";
    canvas.backgroundImage.setCoords();
    var coords = canvas.backgroundImage.oCoords;

    let tl = coords.tl;
    let bl = coords.bl; 
    let br = coords.br;                    
    let x = tl.x;
    let y = tl.y;

    let w = br.x - bl.x;
    let h =  bl.y - tl.y; 

    editor_multiplier = 2;
    let img = canvas.toDataURL({
        format: 'png',
        multiplier: editor_multiplier,
        left: x,
        top: y,
        width: w,
        height: h
    }).replace(/^data:image\/[a-z]+;base64,/,'');
    editor_multiplier = 1;    
    // img = img.replace(new RegExp("\n", "g"), ""); // убираем переносы
    let canvas_obj = canvas.toJSON(['groupName', 'name', 'pointType', 'hasBorders', 'hasControls', 'originX', 'originY', 'lockScalingX', 'lockScalingY', 'fontWeight', 'perPixelTargetFind', 'visible', 'caption', 'caption_type', "scaleConstX", "scaleConstY", "length", "oldX", "oldY", "direction", "firstWidth", "firstHeight", "firstLeft", "firstTop", "zoom_size"]);
    canvas_obj.width = canvas.width;
    let data = JSON.stringify(canvas_obj);
    data = data.replace(new RegExp("\\+", "g"), "%2B"); // заменяем на кодированный знак плюса,
    //чтобы php скрипт не менял его на пробел   
    save(filename, data, img, callback, auto_save_flag);
}
function save(filename, data, img, callback, auto_save_flag){
    formData = new FormData;
    formData.append("data", data);
    formData.append("filename", filename);    
    formData.append("img", img);       
    let sender = new XMLHttpRequest();
    sender.open('POST', 'save.php', true);
    sender.onreadystatechange = function() {
        if(sender.readyState == 4)
        {
            if(sender.status == 200)
            {
                if(typeof window.connected != "undefined" && !window.connected){
                    alert("Соединение восстановлено");
                }
                if(callback != undefined){
                    callback();
                }
                else{
                    if(!auto_save_flag){
                        alert(sender.responseText);
                    }
                    else{
                        console.log("Сохранено");                        
                    }
                    let array = canvas.getObjects();
                    // board.style.cssText = "";
                    for(i in array){
                        array[i].excludeFromExport = !array[i].visible;                 
                    }                    
                }
                window.connected = true;
            }
            else{
                if(typeof window.connected != "undefined" && window.connected){
                    alert("Соединение потеряно");                    
                    window.connected = false;                    
                }
            }
        }
    }
    sender.send(formData);        
}
// function checkState(destination_filename, callback, auto_save_flag)
// {
//     if(destination_filename != filename){
//         let sender = new XMLHttpRequest();
//         sender.open('POST', 'check_state.php', true);
//         sender.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
//         sender.onreadystatechange = function() {
//             if(sender.readyState == 4)
//             {
//                 if(sender.status == 200)
//                 {
//                     if(sender.responseText != 1){
//                         beforeSave(destination_filename, callback, auto_save_flag);
//                     }
//                     else{
//                         newName(destination_filename, function(result){doubleSource(result)});
//                     }
//                 }
//             }
//         }
//         sender.send('filename=' + destination_filename);        
//     }
//     else{
//         beforeSave(destination_filename, callback, auto_save_flag);
//     }
// }
// function newName(destination_filename, callback){
//     let result = prompt("Файл с именем " + destination_filename + " редактируется другим пользователем. Введите другое имя (используйте буквы латинского и кириллического алфавита и знак подчеркивания)", "New_name");
//     if (/[0-9A-Za-zА-Яа-я\_]+/.test(result) && result != null){
//         callback(result);
//     }
//     else if(result != null){
//         newName(destination_filename, callback);
//     }
// }
// function saveBitmap(filename, img)
// {
//     let sender = new XMLHttpRequest();
//     sender.open('POST', 'saveBitmap.php', true);
//     sender.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
//     sender.onreadystatechange = function() {
//         if(sender.readyState == 4 )
//         {
//             if(sender.status == 200)
//             {
//                 document.querySelector("#download").href=sender.responseText;
//                 document.querySelector("#download").click();

//             }
//         }
//     }
//     sender.send('img=' + img +  '&filename=' + filename);
// }
function load(filename, data){
    var form_data = new FormData();
    form_data.append('filename', filename);    
    const promise = new Promise((resolve, reject) => {
        sendData(form_data, address="load.php", resolve)
    });
    promise.then((response) => {
            if(response != "Нет такого файла."){
                let json = JSON.parse(response); 
                canvas.loadFromJSON(json, function(){
                    if(start_double_file){
                        doubleSource(input_filename.value + "_double", function(){
                            location.replace("editor.php?file_name="+filename+"_double");
                        });
                    }
                    file_loaded = true;
                    window.scene_loaded = true;
                    loadObjects();
                    shape_change_flag = false;
                    hideLens();
                    canvas.renderAll();
                });                                          
            }
            if(start_double_file){
                board.style.display = "none";
            }
    })
}
if (editable_flag == 1){
    file_loaded = false;
    load(background_image);        
}
else{
    saveBackgroundImageToBase64(background_image);
}
async function saveBackgroundImageToBase64(background_image)
{
    var res = await fetch(background_image, {})
    var fileobj = await res.blob();
    blobToBase64(fileobj).then(res => {
        editor_obj.change_source(res);
        if(top_panel_display != "none"){
            add_legend_back(legend_back);                    
        }
    });
}
btn_save.addEventListener("click", function(){
    var edited_path = input_filename.value;
    edited_path = edited_path.replace(new RegExp("\\s", "g"), "_");
    beforeSave(edited_path);
    // checkState(edited_path);
});

setInterval(function(){
    if(auto_save_flag){
        var edited_path = input_filename.value;
        edited_path = edited_path.replace(new RegExp("\\s", "g"), "_");
        beforeSave(edited_path, undefined, auto_save_flag);        
    }
}, 20000);
// function saveInCicle(){
//     checkState(input_filename.value, undefined, true);
// }
// setInterval(saveInCicle, 1000); 
function doubleSource(filename, callback){
    let double = true;
    let array = canvas.getObjects();
    for(var i = 0; i < array.length; i++){
        array[i].excludeFromExport = true;                 
    }
    beforeSave(filename);  
}
btn_saveBitmap.addEventListener("click", function(){//
    if(top_panel_display != "none"){
        let img = new Image();

        canvas.backgroundImage.setCoords();
        var coords = canvas.backgroundImage.oCoords;

        let tl = coords.tl;
        let bl = coords.bl; 
        let br = coords.br;                    
        let x = tl.x;
        let y = tl.y;

        let w = br.x - bl.x;
        let h =  bl.y - tl.y; 

        editor_multiplier = 2;
        img.src = canvas.toDataURL({
            format: 'png',
            multiplier: editor_multiplier,
            left: x,
            top: y,
            width: w,
            height: h
        })
        editor_multiplier = 1;

        document.querySelector("#download").download = input_filename.value + ".png";
        document.querySelector("#download").href = img.src;
        document.querySelector("#download").click();        
    }
    else{
        document.querySelector("#download").download = input_filename.value.slice(0, -4) + ".png";
        document.querySelector("#download").href = "images/preview/" + input_filename.value + ".png";
        document.querySelector("#download").click();         
    }
});
let objects_arr = []; // массив составных объектов
// Составные объекты - это не группы fabric. Здесь каждый составной элемент перемещатся отдельно, либо вместе с ключевым,
// который записывается в массив shape
// Далее идет функция для создания составных объектов. Она сортирует все, что возвращает fabric по группам
// и создает составные объекты через методы editor_obj - это необходимо, потому что составной объект содержит в себе
// события, которые нельзя сохранить в файл и их нужно заново навешивать при создании объекта
function loadObjects(array){
    let flag = false;
    let legend_back;  
    if(array == undefined){
        array = canvas.getObjects(); // получаем все объекты канваса
        flag = true;
    } 
    let param = [ // тип составных объектов, число объектов внутри составного объекта и метод, который его создает
        {
           regexp: /arrow.*/, // слово в названии группы составного объекта
           amount: 3, // число объектов в составном объекте
           event: add_arrow // метод, который его создаст и навесит события
        },
        {
           regexp: /line.*/, // слово в названии группы составного объекта
           amount: 3, // число объектов в составном объекте
           event: add_line // метод, который его создаст и навесит события
        },        
        {
           regexp: /size.*/,
           amount: 4,
           event: add_size
        },
        {
           regexp: /geometry.*/,
           amount: 8,
           event: add_geometry
        },        
        {
           regexp: /cap.*/,
           amount: 3,
           event: add_cap
        },
        {
           regexp: /socket.*/,
           amount: 8,
           event: add_socket
        }                     
    ]
    // проверяем элементы массива array на соотвествие одному из типов param
    let length = [];  
    for(let j = 0; j < param.length; j++){      
        for(let i = 0; i < array.length; i++){
            setTimeout(function(){
                array[i].setCoords();
            }, 100)   
            if (array[i].groupName == "back-1"){
                legend_back = array[i];
            }
            var id = param[j].regexp.exec(array[i].groupName); // узнаем имя группы объекта канваса - это будет id            
            if(length[id] == undefined){
                length[id] = 0;
            }
            length[id]++;           
            if(Boolean(id)){ // если false, то объект не составной, а примитив fabric
                if(objects_arr[id[0]] == undefined){ // делаем каждый элемент масссивом
                    objects_arr[id[0]] = []; // массив частей объекта, будет передаваться в метод отрисовки
                    // array[i].setCoords();                        
                }

                objects_arr[id[0]][array[i].name] = array[i]; // пушим найденный элемент в элмемент массива и называем его по id,
                // дальше будем пушить туда все элементы array с тем же id
                if(length[id] == param[j].amount){ // если набрали в массив столько элементов,
                    // сколько должно быть в составном объекте этого типа, создаем объект
                    let e = { // технический параметр с координатами мыши - нужен просто, чтобы вызвать метод
                        pointer: {
                            x: 0,
                            y: 0
                        }
                    };
                    param[j].event(e, objects_arr[id[0]]);
                }                                                      
            }                
        }
    }
    if(flag){
        if(legend_back != undefined){
            add_legend_back(legend_back);
        }
        else{
            add_legend_back();    
        }
        canvas.setWidth(canvas.width);
        editor_obj.add_legend();         
    }
};