/* global Bdf,Ficheform,$$ */

Ficheform.AddendaInclude.Manager = function (entryKey, addendaName) {
    this.entryKey = entryKey;
    this.addendaName = addendaName;
    this.infoMap = new Map();
    this.documentInfoMap = new Map();
    this.creationInfoMap = new Map();
    this.addInfoMap = new Map();
    this.orderArray = null;
    this.toolsId = null;
};

Ficheform.AddendaInclude.Manager.map = new Map();

Ficheform.AddendaInclude.Manager.prototype.putInfo = function (info) {
    var divId = info.divId;
    this.infoMap.set(divId, info);
    switch(info.type) {
        case "document":
            this.documentInfoMap.set(divId, info);
            break;
        case "creation":
            this.creationInfoMap.set(divId, info);
            break;
        case "add":
            this.addInfoMap.set(divId, info);
            break;
    }
    return this;
};

Ficheform.AddendaInclude.Manager.prototype.deleteInfo = function (divId) {
    $$(divId).remove();
    this.infoMap.delete(divId);
    this.documentInfoMap.delete(divId);
    this.creationInfoMap.delete(divId);
    this.addInfoMap.delete(divId);
    return this;
};

Ficheform.AddendaInclude.Manager.prototype.checkOrder = function (force) {
    if((!force) && (!this.orderArray)) {
        return this;
    }
    var manager = this;
    var entry = Ficheform.entry(this.entryKey);
    var array = new Array();
    $$(entry, {ficheformRole: "document-list"}).children().each(function (index, element) {
        array.push(manager.infoMap.get(element.id));
    });
    this.orderArray = array;
    return this;
};

Ficheform.AddendaInclude.Manager.prototype.sort = function (desc) {
    var entry = Ficheform.entry(this.entryKey);
    var array = new Array();
    var basenameArray = new Array();
    $$(entry, {ficheformRole: "document-list"}).children().each(function (index, element) {
        let basename = $$(element, {ficheformRole: "document-basename"}).text();
        basenameArray.push(basename);
        array.push({
            basename: basename,
            element: element
        });
    });
    var length = array.length;
    if (length < 2) {
        return false;
    }
    array = array.sort(function (obj1, obj2) {
        let sortValue = _sort(obj1, obj2);
        if (desc) {
            sortValue = -sortValue;
        }
        return sortValue;
    });
    if (!_hasChange()) {
        return false;
    }
    let $current = $(array[0].element);
    $$(entry, {ficheformRole: "document-list"}).prepend($current);
    for(let i = 1; i < length; i++) {
        let $next = $(array[i].element);
        $current.after($next);
        $current = $next;
    }
    this.checkOrder(true);
    return true;
    
    function _sort(obj1, obj2) {
        if (obj1.basename < obj2.basename) {
            return -1;
        }
        if (obj1.basename > obj2.basename) {
            return 1;
        }
        return 0;
    }
    
    function _hasChange() {
        for(let i = 0; i < length; i++) {
            if (basenameArray[i] !== array[i].basename) {
                return true;
            }
        }
        return false;
    }
};

Ficheform.AddendaInclude.Manager.prototype.removeDocument = function (documentDivId) {
    var $documentDiv = $$(documentDivId).addClass("ficheform-document-Removed");
    $$($documentDiv, {showState: "active"}).addClass("hidden");
    $$($documentDiv, {showState: "restore"}).removeClass("hidden");
    this.documentInfoMap.get(documentDivId).isRemoved = true;
    return this;
};

Ficheform.AddendaInclude.Manager.prototype.restoreDocument = function (documentDivId) {
    var $documentDiv = $$(documentDivId).removeClass("ficheform-document-Removed");
    $$($documentDiv, {showState: "active"}).removeClass("hidden");
    $$($documentDiv, {showState: "restore"}).addClass("hidden");
    this.documentInfoMap.get(documentDivId).isRemoved = false;
    return this;
};

Ficheform.AddendaInclude.Manager.prototype.openDocumentChange = function (documentDivId, callback) {
    var manager = this;
    var entryKey = this.entryKey;
    var addendaName = this.addendaName;
    var appelant = entryKey + "/" + documentDivId;
    var documentInfo = this.documentInfoMap.get(documentDivId);
    Bdf.putAppelantCallback(appelant, _callbackChange);
    var url = "addenda?page=document-change&addenda=" + addendaName + "&changetype=" + Ficheform.AddendaInclude.DOCUMENT_CHANGETYPE + "&appelant=" + appelant;
    url = documentInfo.completeUrl(url);
    Ficheform.openDialog(url,"pioche_"+ entryKey, 620, 580);
    
    
    function _callbackChange(appelantResponse) {
        documentInfo.changeObject = appelantResponse;
        manager.checkExtensions(appelantResponse, documentDivId);
        if (callback) {
            callback();
        }
    }
};

Ficheform.AddendaInclude.Manager.prototype.openNewCreation = function (callback) {
    var manager = this;
    var entryKey = this.entryKey;
    var entry = Ficheform.entry(entryKey);
    var addendaName = this.addendaName;
    var appelant = entryKey;
    Bdf.putAppelantCallback(appelant, _callback);
    var url = "addenda?page=document-upload-new&addenda=" + addendaName  + "&appelant=" + appelant;
    Ficheform.openDialog(url, "pioche_" + entryKey, 620, 580);
    
    
    function _callback(appelantResponse) {
        let extensionMap = appelantResponse.extensionMap;
        let extensionText = "";
        let next = false;
        for(let extension in extensionMap) {
            let extensionObj = extensionMap[extension];
            let state = extensionObj.state;
            if ((state === Ficheform.AddendaInclude.UPDATE_STATE) || (state === Ficheform.AddendaInclude.CREATE_STATE)) {
                if (next) {
                    extensionText += " / ";
                } else {
                    next = true;
                }
                extensionText += "." + extension;
            }
        }
        let divId = Bdf.generateId();
        $$(entry, {ficheformRole: "document-list"}).append(Bdf.render("ficheform:addenda/new", {
            documentDivId: divId,
            basename: appelantResponse.basename,
            extensionText: extensionText,
            noTab: Ficheform.getOption("noTab")
        }));
        manager.putInfo(new Ficheform.AddendaInclude.CreationInfo(divId, appelantResponse)).checkOrder(false).initOrderButtons(divId);
        $$(divId, "change").click(function () {
            manager.openCreationChange(divId);
        });
        $$(divId, "remove").click(function () {
            let ok = confirm(Bdf.Loc.get("_ warning.edition.documentremove_creation"));
            if (ok) {
                manager.deleteInfo(divId).update();
            }
        });
        if (callback) {
            callback();
        }
    }
};

Ficheform.AddendaInclude.Manager.prototype.openCreationChange = function (divId) {
    var manager = this;
    var entryKey = this.entryKey;
    var addendaName = this.addendaName;
    var appelant = entryKey + "/" + divId;
    Bdf.putAppelantCallback(appelant, _callback);
    var creationInfo = manager.creationInfoMap.get(divId);
    var url = "addenda?page=document-change&addenda=" + addendaName + "&changetype=" + Ficheform.AddendaInclude.CREATION_CHANGETYPE + "&appelant=" + appelant
        + "&originalname=" + encodeURIComponent(creationInfo.originalName)
        + "&change=" + encodeURIComponent(Ficheform.AddendaInclude.changeObjectToString(creationInfo.changeObject));
    Ficheform.openDialog(url,"pioche_"+ entryKey, 620, 580);
    
    
    function _callback(appelantResponse) {
        creationInfo.changeObject = appelantResponse;
        manager.checkExtensions(appelantResponse, divId).checkOrder(false).update();
    }
};

Ficheform.AddendaInclude.Manager.prototype.pioche = function (inputId) {
    var manager = this;
    var entry = Ficheform.entry(this.entryKey);
    var limit = entry.dataset.ficheformLimit;
    if (!limit) {
        limit = -1;
    }
    var subsets = this.addendaName;
    var url = "pioche?page=document&subsets=" + subsets + "&appelant=" + inputId + "&limit=" + limit;
    Bdf.putAppelantCallback(inputId, _callback);
    Ficheform.openDialog(url,"pioche_" + this.entryKey, 430, 510);
    
    
    function _callback(selectionArray) {
        var $documentList = $$(entry, {ficheformRole: "document-list"});
        for(let jsonItem of selectionArray) {
            let code = jsonItem.code;
            let existing = $$($documentList, {addCode: code});
            if (existing.length === 0) {
                let divId = Bdf.generateId();
                $documentList.append(Bdf.render("ficheform:addenda/add", {
                    documentDivId: divId,
                    id: jsonItem.id,
                    code: code,
                    title: jsonItem.title,
                    basename: jsonItem.basename,
                    extensions: jsonItem.extensions,
                    noTab: Ficheform.getOption("noTab")
                }));
                $$(divId, "remove").click(function () {
                    manager.deleteInfo(divId).update();
                });
                manager.putInfo(new Ficheform.AddendaInclude.AddInfo(divId, jsonItem.id))
                        .initOrderButtons(divId);
            } 
        }
        manager.update();
    }
};

Ficheform.AddendaInclude.Manager.prototype.checkHidden = function () {
    var entry = Ficheform.entry(this.entryKey);
    var toolsId = this.toolsId;
    var length = $$(entry, {ficheformRole: "document-list"}).children().length;
    Ficheform.checkEnumerationCell(entry, length);
    if (length > 1) {
        $$(toolsId, "sort_asc").removeClass("hidden");
        $$(toolsId, "sort_desc").removeClass("hidden");
    } else {
        $$(toolsId, "sort_asc").addClass("hidden");
        $$(toolsId, "sort_desc").addClass("hidden");
    }
    return this;
};

Ficheform.AddendaInclude.Manager.prototype.checkExtensions = function (changeObject, divId) {
    var addenda = this.addendaName;
    var $document = $$(divId);
    if (changeObject.basename) {
        var $basename = $$($document, {ficheformRole: "document-basename"});
        $basename.html(changeObject.basename);
        if (changeObject.changeType === Ficheform.AddendaInclude.DOCUMENT_CHANGETYPE) {
            $basename.addClass("ficheform-document-NameChanged");
        }
    }
    var extensionMap = changeObject.extensionMap;
    var extensionArray = new Array();
    for(let extension in extensionMap) {
        let extensionObj = extensionMap[extension];
        let cssClass, href;
        let state = extensionObj.state;
        if (state === Ficheform.AddendaInclude.UPDATE_STATE) {
            href = Bdf.toTmpPath(extensionObj.tmpFileName);
            cssClass = "ficheform-document-VersionChanged";
        } else if (state === Ficheform.AddendaInclude.CREATE_STATE) {
            href =  Bdf.toTmpPath(extensionObj.tmpFileName);
            cssClass = "ficheform-document-VersionAdded";
        } else if (state === Ficheform.AddendaInclude.REMOVE_STATE) {
            if (extensionObj.previousState === Ficheform.AddendaInclude.CREATE_STATE) {
                continue;
            }
            if (extensionObj.tmpFileName) {
                href =  Bdf.toTmpPath(extensionObj.tmpFileName);
            } else {
                href = "documents/" + addenda + "/" + extensionObj.currentFileName;
            }
            cssClass = "ficheform-document-VersionRemoved";
        } else {
            href = "documents/" + addenda + "/"  + extensionObj.currentFileName;
            cssClass = false;
        }
        extensionArray.push({
            href: href,
            cssClass: cssClass,
            extension: extension
        });
    }
    $$($document, {ficheformRole: "document-extensions"}).html(Bdf.render("ficheform:addenda/extensions", {
        extensionArray: extensionArray,
        noTab: Ficheform.getOption("noTab")
    }));
    return this;
};

Ficheform.AddendaInclude.Manager.prototype.update = function () {
    var manager = this;
    manager.checkHidden();
    var entry = Ficheform.entry(this.entryKey);
    _updateOrder();
    _updateChange();
    _updateRemove();
    _updateCreate();
    _updateAdd();
    Ficheform.signalChange();
    
    function _updateOrder() {
        if (!manager.orderArray) {
            return;
        }
        let order = "";
        for(let obj of manager.orderArray) {
            if (obj.type === "document") {
                if (!obj.isRemoved) {
                    order += "id=" + obj.itemId + ";";
                }
            } else if (obj.type === "add") {
                order += "id=" + obj.itemId + ";";
            } else {
                order += "bn=" + obj.changeObject.basename + ";";
            }
        }
        $$(entry, {ficheformRole: "orderfield"}).val(order);
    }
    
    function _updateRemove() {
        let remove = "";
        for(let documentInfo of manager.documentInfoMap.values()) {
            if (documentInfo.isRemoved) {
                remove += documentInfo.itemId + ";";
            }
        }
        $$(entry, {ficheformRole: "removefield"}).val(remove);
    }
    
    function _updateChange() {
        let change = "";
        for(let documentInfo of manager.documentInfoMap.values()) {
            if ((documentInfo.changeObject) && (!documentInfo.isRemoved)) {
                change += documentInfo.itemId + ":" + Ficheform.AddendaInclude.changeObjectToString(documentInfo.changeObject) + ";";
            }
        }
        $$(entry, {ficheformRole: "changefield"}).val(change);
    }
    
    function _updateCreate() {
        let create = "";
        for(let creationInfo of manager.creationInfoMap.values()) {
            create += Ficheform.AddendaInclude.changeObjectToString(creationInfo.changeObject) + ";";
        }
        $$(entry, {ficheformRole: "createfield"}).val(create);
    }
    
    function _updateAdd() {
        let add = "";
        for(let addInfo of manager.addInfoMap.values()) {
            add += addInfo.itemId + ";";
        }
        $$(entry, {ficheformRole: "addfield"}).val(add);
    }
};

Ficheform.AddendaInclude.Manager.prototype.initOrderButtons = function (divId) {
    var manager = this;
    Ficheform.initOrderButtons(divId, $$.one(divId), function () {
        manager.checkOrder(true).update();
    });
    return this;
};


Ficheform.AddendaInclude.Manager.init = function (entry) {
    var entryKey = entry.dataset.ficheformKey;
    var addendaName = entry.dataset.subsetName;
    var manager = new Ficheform.AddendaInclude.Manager(entryKey, addendaName);
    $$(entry, {ficheformRole: "document"}).each(function (index2, documentDiv) {
        let divId = documentDiv.id;
        manager.putInfo(new Ficheform.AddendaInclude.DocumentInfo(divId, documentDiv.dataset.subsetItemId));
        $$(divId).append(Bdf.render("ficheform:addenda/document", {
            documentDivId: divId,
            noTab: Ficheform.getOption("noTab")
        }));
        $$(divId, "change").click(function () {
            manager.openDocumentChange(divId, function () {
                manager.update();
            });
        });
        $$(divId, "remove").click(function () {
            let ok = confirm(Bdf.Loc.get("_ warning.edition.documentremove_existing"));
            if (ok) {
                manager.removeDocument(divId).update();
            }
        });
        $$(divId, "restore").click(function () {
            manager.restoreDocument(divId).update();
        });
        manager.initOrderButtons(divId);
    });
    let $addInput = $$(entry, {ficheformRole: "addfield"});
    let addAllowed = ($addInput.length > 0);
    let toolsId = Bdf.generateId();
    manager.toolsId = toolsId;
    $$(entry, {ficheformRole: "document-input"}).append(Bdf.render("ficheform:addenda/tools", {
        toolsId: toolsId,
        addAllowed: addAllowed,
        addendaTitle: Bdf.Loc.get("subset:addenda_" + addendaName),
        noTab: Ficheform.getOption("noTab")
    }));
    $$(toolsId, "create").click(function () {
        manager.openNewCreation(function () {
            manager.update();
        });
    });
    if (addAllowed) {
        $$(toolsId, "add").click(function () {
            manager.pioche($addInput.attr("id"));
        });
    }
    $$(toolsId, "sort_asc").click(function () {
        if (manager.sort(false)) {
            manager.update();
        }
    });
    $$(toolsId, "sort_desc").click(function () {
        if (manager.sort(true)) {
           manager.update();
        }
    });
    manager.checkHidden();
    Ficheform.AddendaInclude.Manager.map.set(entryKey, manager);
    return manager;
};

Ficheform.AddendaInclude.DocumentInfo = function (divId, itemId) {
    this.type = "document";
    this.divId = divId;
    this.itemId = itemId;
    this.changeObject = null;
    this.isRemoved = false;
};

Ficheform.AddendaInclude.DocumentInfo.prototype.completeUrl = function (url) {
    url += "&id=" + this.itemId;
    if (this.changeObject) {
        url += "&change=" + encodeURIComponent(Ficheform.AddendaInclude.changeObjectToString(this.changeObject));
    }
    return url;
};

Ficheform.AddendaInclude.CreationInfo = function (divId, changeObject) {
    this.type = "creation";
    this.divId = divId;
    this.changeObject = changeObject;
    this.originalName = changeObject.originalName;
    this.isRemoved = false;
};

Ficheform.AddendaInclude.AddInfo = function (divId, itemId) {
    this.type = "add";
    this.divId = divId;
    this.itemId = itemId;
};
