/* global Bdf,$$,Overlay */
/**
 * Objet global définissant l'espace de nom Pane
 * 
 * @namespace Pane
 */
var Pane = {};

Pane.CHECK_FUNCTION_ARRAY = new Array();

Pane.registerCheckFunction = function (checkFunction) {
    Pane.CHECK_FUNCTION_ARRAY.push(checkFunction);
};

Pane.getEntry = function (entryName) {
    return $$({role: "entry", name: entryName});
};

Pane.insertEntry = function ($entryParent, entryName, entryHtml) {
    var $entryList = $entryParent.children($$.toCssSelector({role: "entry"}));
    var currentLength = $entryList.length;
    var p = 0;
    while(true) {
        if (p >= currentLength) {
            $entryParent.append(entryHtml);
            break;
        } else {
            let currentEntry = $entryList[p];
            let currentName = currentEntry.dataset.name;
            if (entryName < currentName) {
                $(currentEntry).before(entryHtml);
                break;
            } else {
                p++;
            }
        }
    }
    if (Bdf.Deploy) {
        Bdf.Deploy.init($entryParent);
    }
    return $$({role: "entry", name: entryName});
};

Pane.removeEntry = function ($entryParent, entryName) {
    var $entry = $entryParent.children($$.toCssSelector({role: "entry", name: entryName}));
    $entry.remove();
};

Pane.getEntryName = function (element) {
    if (element.dataset.role === "entry") {
        return element.dataset.name;
    }
    return Bdf.getMandatoryAncestor(element, {role: "entry"}).dataset.name;
};

Pane.updateContentList = function (prefix, $contentUl, contentArray) {
    if (contentArray.length === 0) {
        $contentUl.empty();
        return;
    }
    var $currentLis = $contentUl.children("li");
    var currentLength = $currentLis.length;
    var p = 0;
    for(let newContentObj of contentArray) {
        let newContentPath = newContentObj.path;
        while(true) {
            if (p >= currentLength) {
                $contentUl.append(Bdf.render(prefix + ":list/content", newContentObj));
                break;
            } else {
                let currentContent = $currentLis[p];
                let currentContentPath = currentContent.dataset.contentPath;
                if (newContentPath === currentContentPath) {
                    Pane.updateContentState(prefix, currentContent, newContentObj);
                    p++;
                    break;
                } else if (newContentPath < currentContentPath) {
                    $(currentContent).before(Bdf.render(prefix + ":list/content", newContentObj));
                    break;
                } else {
                    $(currentContent).remove();
                    p++;
                }
            }
        }
    }
    if (p < currentLength) {
        for(let i = p; i < currentLength; i++) {
            $($currentLis[i]).remove();
        }
    }
};

Pane.updateContentState = function (prefix, element, newContentObj) {
    Pane.updateStateClass($(element), prefix + "-contentstate-" + newContentObj.state);
    $$(element, {role: "linelogarray"}).remove();
    if ((newContentObj.lineLogArray) && (newContentObj.lineLogArray.length > 0)) {
        $(element).append(Bdf.render("bdf:linelogarray", newContentObj));
    }
};

Pane.updateStateClass = function ($element, newClassName) {
    $element.removeClass(function (index, className) {
        let result = /([-a-z]+)state-([-_a-zA-Z]+)/.exec(className);
        if (result) {
            return result[0];
        } else {
            return "";
        }
    });
    $element.addClass(newClassName);
};

Pane.setLayoutVisible = function (visible) {
  if (visible) {
      $$("layout").removeClass("hidden");
  } else {
      $$("layout").addClass("hidden");
  }
};

Pane.initLayout = function (options) {
    var withStock = true;
    var withClipboard = true;
    var hiddenAtStart = false;
    if (options) {
        if (options.ignoreStock) {
            withStock = false;
            withClipboard = false;
        }
        if (options.ignoreClipboard) {
            withClipboard = false;
        }
        if (options.hiddenAtStart) {
            hiddenAtStart = true;
        }
    }    
    if (hiddenAtStart) {
        Pane.setLayoutVisible(false);
    }
    $$("layout").html(Bdf.render("pane:layout", {
        withStock: withStock
    }));
    $$("layout_tool_list_onoff").click(function () {
        _onoff("layout_list");
    });
    $$("layout_tool_list_decrease").click(function () {
        _resize("layout_list", -100);
    });
    $$("layout_tool_list_increase").click(function () {
        _resize("layout_list", 100);
    });
    if (withStock) {
        $$("layout_tool_stock_onoff").click(function () {
            _onoff("layout_stock");
        });
        $$("layout_tool_stock_decrease").click(function () {
            _resize("layout_stock", -100);
        });
        $$("layout_tool_stock_increase").click(function () {
            _resize("layout_stock", 100);
        });
    }
    if (withClipboard) {
        _addClipboardUnit();
    }
    
    
    function _onoff(layoutId) {
        let $layout = $$(layoutId);
        if ($layout.hasClass("hidden")) {
            $layout.removeClass("hidden");
        } else {
            $layout.addClass("hidden");
        }
    }
    
    function _resize(layoutId, widthDiff) {
        let $layout = $$(layoutId);
        let newWidth = $layout.width() + widthDiff;
        if (newWidth > 199) {
            $layout.width(newWidth);
        }
    }
    
    function _addClipboardUnit() {
        let clipboardId = Pane.addHelpUnit(Bdf.Loc.get("_ title.stock.clipboard"), true);
        $$(clipboardId, "content").html(Bdf.render("pane:clipboard", {}));
    }
};

Pane.initQueryDetails = function (formId) {
    var queryxmlCodeMirror = Bdf.toCodeMirror($$.one(formId, "queryxml"), {
        lineWrapping: false,
        lineNumbers: false,
        indentUnit: 4,
        theme: 'bdf',
        mode: "xml"
    });
    queryxmlCodeMirror.on("change", function () {
        Pane.setChange(true);
    });
    $$(formId, "button_queryparser").click(function () {
        Bdf.Overlay.showFqlEditor(queryxmlCodeMirror.getDoc().getValue(), function (result) {
            queryxmlCodeMirror.getDoc().setValue(result);
        });
    });
    return queryxmlCodeMirror;
};

Pane.initAttributesDetails = function (formId) {
    var attributesCodeMirror = Bdf.toCodeMirror($$.one(formId, "attributes"), {
        lineWrapping: false,
        lineNumbers: false,
        indentUnit: 4,
        theme: 'bdf',
        mode: "attributes"
    });
    attributesCodeMirror.on("change", function () {
        Pane.setChange(true);
    });
    return attributesCodeMirror;
};

Pane.moveMainToStock = function ($anchor) {
    var $mainBody =  $$("layout_main");
    var $children = $mainBody.children();
    var done = false;
    $children.fadeOut(function () {
        if (!done) {
            done = true;
            Pane.addStockUnit($children, $anchor);
            Pane.clearMain();
            Pane.checkState();
        }
    });
};

Pane.addStockUnit = function (jqArgument, $anchor) {
    var $elements = $$.convert(jqArgument);
    var contentKey = $elements.data("contentKey");
    if (contentKey) {
        let state = Pane.State.build();
        if (state.getLoadLocation(contentKey) === "stock") {
            return;
        }
    } else {
        contentKey = "";
    }
    var unitId = Bdf.generateId();
    var bodyId = unitId + "_body";
    if ($anchor) {
        $anchor.after(Bdf.render("pane:stockunit", {
            unitId: unitId,
            contentKey: contentKey
        }));
    } else {
        $$("layout_stock").prepend(Bdf.render("pane:stockunit", {
            unitId: unitId,
            contentKey: contentKey
        }));
    }
    var $bodyUnit = $$(bodyId);
    $elements.appendTo($bodyUnit).fadeIn(function () {
        $$("layout_stock").animate({
            scrollTop: 0
        }, 1000);
        Bdf.refreshCodeMirror($bodyUnit);
    });
    $$(unitId + "_title").html($$($elements, {stockRole: "title"}).html());
    _checkStockHandler($bodyUnit, true);
    $$(unitId, "button_stock_remove").click(function () {
        $$(unitId).fadeOut(function () {
            $$(unitId).remove();
            Pane.checkState();
        });
    });
    $$(unitId, "button_destock").click(function () {
        if (!Bdf.confirmUnload()) {
            return;
        }
        let $stockChildren = $$(bodyId).children();
        $$(unitId).fadeOut(function () {
            Pane.clearMain();
            let $mainBody =  $$("layout_main");
            $stockChildren.appendTo($mainBody).fadeIn(function () {
                Bdf.refreshCodeMirror($mainBody);
            });
            _checkStockHandler($mainBody, false);
            $$(unitId).remove();
            Pane.checkState();
        });

    });
    $$(unitId, "button_switch").click(function () {
        if (Bdf.hasChange()) {
            return;
        }
        Pane.moveMainToStock($$(unitId));
        $$(unitId, "button_destock").click();
    });
    $$(unitId, "button_stock_down").click(function () {
        let $next = $$(unitId).next();
        if ($next.length > 0) {
            $$(unitId).fadeOut(function () {
                $$(unitId).insertAfter($next).fadeIn();
            });
        }
    });
    $$(unitId, "button_stock_up").click(function () {
        let $prev = $$(unitId).prev();
        if ($prev.length > 0) {
            $$(unitId).fadeOut(function () {
                $$(unitId).insertBefore($prev).fadeIn();
            });
        }
    });
    
    function _checkStockHandler($parent, inStock) {
        $$($parent, {stockRole: "handler"}).each(function (index, element) {
        let stockHandler = $(element).data("stockHandler");
        if (stockHandler) {
                stockHandler(inStock);
            }
        });
    }
    
};

Pane.clearMain = function () {
    $$("layout_main").empty();
    Pane.setChange(false);
    Bdf.clearTimer();
    $(".pane-list-ActiveItem").removeClass("pane-list-ActiveItem");
};

Pane.destock = function (contentKey) {
    var $children = $$("layout_stock").children($$.toCssSelector({contentKey: contentKey}));
    if ($children.length > 0) {
        var unitId = $children[0].id;
        $$(unitId, "button_destock").click();
    }
};

Pane.loadOrDestock = function (contentKey, loadCallback) {
    let state = Pane.State.build();
    if (state.getLoadLocation(contentKey) === "stock") {
        Pane.destock(contentKey);
    } else {
        Pane.clearMain();
        loadCallback();
    }
};

Pane.testFormSubmit = function (array, $form, options) {
    if ($form.data("layoutLocation") === "stock") {
        return false;
    } else {
        return true;
    }
};

Pane.setReadOnly = function ($form, readOnly) {
    $$($form, {_element: "input"}).prop("disabled", readOnly);
    $$($form, {_element: "input", _type: "text"}).prop("disabled", false).prop("readonly", readOnly);
    $$($form, {_element: "textarea"}).prop("readonly", readOnly); 
};

Pane.removeContents = function (contentKeyRoot, separatorChar) {
    if (!separatorChar) {
        separatorChar = "/";
    }
    var state = Pane.State.build();
    if (_test(state.mainContentKey)) {
        Pane.clearMain();
    }
    for(let contentKey of state.stockContentKeyArray) {
        if (_test(contentKey)) {
            $$("layout_stock").children($$.toCssSelector({contentKey: contentKey})).remove();
        }
    }
    Pane.checkState();
    
    function _test(contentKey) {
        if (contentKey === contentKeyRoot) {
            return true;
        }
        if (contentKey.indexOf(contentKeyRoot + separatorChar) === 0) {
            return true;
        }
        return false;
    }
};

Pane.setChange = function (change) {
    Bdf.setChange(change);
    Pane.checkState();
};

Pane.checkState = function () {
    var state = Pane.State.build();
    $$({stateEnable: true}).each(function (index, element) {
        let $element = $(element);
        let tokens = $element.data("stateEnable").split(" ");
        let disabled = false;
        let contentKey = _getContentKey(element);
        for(let token of tokens) {
            let opposite = false;
            let ok = false;
            if (token.indexOf("!") === 0) {
                opposite = true;
                token = token.substring(1);
            }
            switch(token) {
                case "loaded":
                    ok = state.isLoaded(contentKey);
                    break;
                case "with_main":
                    ok = state.withMain();
                    break;
                case "change":
                    ok = state.mainChange;
                    break;
                case "change-current":
                    ok = (state.mainChange && state.isMain(contentKey));
                    break;
            }
            if (opposite)  {
                ok = !ok;
            }
            if (!ok) {
                disabled = true;
                break;
            }
        }
        $element.prop("disabled", disabled);
    });
    for(let checkFunction of Pane.CHECK_FUNCTION_ARRAY) {
        checkFunction(state);
    }
    
    function _getContentKey(element) {
        var contentKey = element.dataset.contentKey;
        if (!contentKey) {
            try {
                contentKey = Bdf.getMandatoryAncestor(element, {role: "content-reference"}).dataset.contentKey;
            } catch(e) {
                return "";
            } 
        }
        if (contentKey) {
            return contentKey;
        } else {
            return "";
        }
    }
};

Pane.State = function (mainContentKey, stockContentKeyArray, mainChange) {
    this.mainContentKey = mainContentKey;
    this.stockContentKeyArray = stockContentKeyArray;
    this.mainChange = mainChange;
};

Pane.State.prototype.withMain = function () {
    return (this.mainContentKey.length > 0);
};

Pane.State.prototype.isMain = function (contentKey) {
    return (contentKey === this.mainContentKey);
};

Pane.State.prototype.isLoaded = function (contentKey) {
    return (this.getLoadLocation(contentKey) !== false);
};

Pane.State.prototype.getLoadLocation = function (contentKey) {
    if (contentKey === this.mainContentKey) {
        return "main";
    }
    if (this.stockContentKeyArray.indexOf(contentKey) !== -1) {
        return "stock";
    }
    return false;
};

Pane.State.build = function () {
    var $mainChildren = $$("layout_main").children($$.toCssSelector({contentKey: true}));
    var change = Bdf.hasChange();
    var mainContentKey = $mainChildren.data("contentKey");
    if (!mainContentKey) {
        mainContentKey = "";
    }
    var stockContentKeyArray = new Array();
    var $stockChildren = $$("layout_stock").children($$.toCssSelector({contentKey: true}));
    $stockChildren.each(function (index, element) {
        stockContentKeyArray.push($(element).data("contentKey"));
    });
    _initTimer();
    var state = new Pane.State(mainContentKey, stockContentKeyArray, change);
    return state;
    
    
    function _initTimer() {
        let timerType = $mainChildren.data("timerType");
        if (timerType === "form") {
            if (change) {
                Bdf.clearTimer();
            } else {
                if (!Bdf.hasTimer()) {
                    Bdf.startTimer(function () {
                        if (Bdf.checkFormChange($mainChildren)) {
                            Pane.setChange(true);
                        }
                    }, 1000);
                }
            }
        } else {
            Bdf.clearTimer();
        }
    }
};

Pane.loadSubsetTrees = function (callback) {
    if (Bdf.SubsetTrees) {
        Bdf.SubsetTrees.load(function (subsetTrees) {
            _addUnit(subsetTrees, "corpus", "_ title.subsettrees.corpusfields");
            _addUnit(subsetTrees, "thesaurus", "_ title.subsettrees.thesaurusfields");
            if (callback) {
                callback(subsetTrees);
            }
        });
    } else {
        Bdf.log("Bdf.SubsetTrees not loaded");
    }
    
    function _addUnit(subsetTrees, category, titleKey) {
        let nodeArray = subsetTrees.getTree(category);
        if (nodeArray.length > 0) {
            let unitId = Pane.addHelpUnit(Bdf.Loc.get(titleKey), false);
            $$(unitId, "content").html(Bdf.render("pane:subsettree-root", {array: nodeArray}));
        }
    }
};

Pane.loadMemento = function (mementoPath, callback) {
    Bdf.Ajax.loadMementoUnit(mementoPath, function (mementoUnit) {
        let unitId = Pane.addHelpUnit(Bdf.Loc.get("_ link.misc.memento") + " – " + mementoUnit.title, false);
         _completeNodes(mementoUnit.subnodeArray);
        $$(unitId, "content").html(Bdf.render("pane:memento", {subnodeArray: mementoUnit.subnodeArray}));
        if (callback) {
            callback(mementoUnit);
        }
    });
    
    
    function _completeNodes(nodeArray) {
        for(let node of nodeArray) {
            node.generatedId = Bdf.generateId();
            if (!node.leaf) {
                __completeNodes(node.subnodeArray);
            }
        }
    }
        
};

Pane.addHelpUnit = function (title, showAtStart) {
    var unitId = Bdf.generateId();
    $$("layout_stock").append(Bdf.render("pane:stockunit_help", {
        unitId: unitId,
        title: title,
        open: showAtStart
    }));
    $$(unitId, "button_stock_down").click(function () {
        let $next = $$(unitId).next();
        if ($next.length > 0) {
            $$(unitId).fadeOut(function () {
                $$(unitId).insertAfter($next).fadeIn();
            });
        }
    });
    $$(unitId, "button_stock_up").click(function () {
        let $prev = $$(unitId).prev();
        if ($prev.length > 0) {
            $$(unitId).fadeOut(function () {
                $$(unitId).insertBefore($prev).fadeIn();
            });
        }
    });
    return unitId;
};

Pane.ensureVisibility = function ($element) {
    $element.parents(".hidden").each(function (index, element) {
        if (element.id) {
            let $deployLink = $$({deployRole: "link", deployTarget: "#" + element.id});
            Bdf.Deploy.ensureLinkVisibility($deployLink, true);
        }
    });
};

Pane.initShortcuts = function () {
    Bdf.Shortcut.init();
    Bdf.Shortcut.putEventFunction(Bdf.Shortcut.MOD_S, function (event) {
        _clickButton("savebutton");
    });
    Bdf.Shortcut.putEventFunction(Bdf.Shortcut.F1, function (event) {
        _clickButton("testbutton");
    });
    
    function _clickButton(name) {
        if (!_testOverlay()) {
            let $button = _getMainButton(name);
            if (!$button.prop("disabled")) {
                $button.click();
            }
        }
    }
    
    function _testOverlay() {
        if (!Overlay) {
            return false;
        }
        let lastOverlayInfo = Overlay.getLastOverlayInfo();
        return (lastOverlayInfo !== null);
    }
    
    
    function _getMainButton(name) {
        return $$("layout_main", {role: name});
    }
    
};

Pane.checkTooltip = function (jqArgument) {
    if (!Bdf.Shortcut) {
        Bdf.log("Bdf.Shorcut is missing");
        return;
    }
    Bdf.Shortcut.checkTooltip(jqArgument);
};
