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

FqlEditor.subsetTrees = null;
FqlEditor.jsonData = null;
FqlEditor.currentModel = null;

FqlEditor.update = function (jsonData, overlayId) {
    FqlEditor.jsonData = jsonData;
    FqlEditor.testReady();
};

FqlEditor.getResult = function () {
    if (FqlEditor.currentModel) {
        return FqlEditor.currentModel.toXml();
    } else {
        return "";
    }
};

FqlEditor.testReady = function () {
    if (_isReady()) {
        FqlEditor.init();
    }
    
    function _isReady() {
        if (!FqlEditor.subsetTrees) {
            return false;
        }
        if (!FqlEditor.jsonData) {
            return false;
        }
        return true;
    }
};

FqlEditor.init = function () {
    var editorId = Bdf.generateId();
    var jsonData = FqlEditor.jsonData;
    var html = "";
    var currentModel;
    if ((jsonData.commandMessage) && (jsonData.commandMessage.type === "error")) {
        html = Bdf.render("bdf:commandmessage", jsonData.commandMessage);
    } else {
        currentModel = new FqlEditor.Model(FqlEditor.subsetTrees);
        if (jsonData.fql.fiche) {
             for(let data of jsonData.fql.fiche) {
                 currentModel.createRootFicheQuery(data);
             }
        }
        if (jsonData.fql.motcle) {
             for(let data of jsonData.fql.motcle) {
                 currentModel.createRootMotcleQuery(data);
             }
        }
        html = Bdf.render("fqleditor:main", {
            model: currentModel,
            editorId: editorId
        });
    }
    $$("fqleditor").html(html);
    if (currentModel) {
        FqlEditor.currentModel = currentModel;
        FqlEditor.initActions(currentModel, editorId);
    }

};

FqlEditor.initActions = function (currentModel, editorId) {
    for(let ficheQuery of currentModel.ficheQueryArray) {
        _initFicheQueryAction(ficheQuery);
    }
    for(let motcleQuery of currentModel.motcleQueryArray) {
        _initMotcleQueryAction(motcleQuery);
    }
    $$(editorId, "button_addquery_fiche").click(function () {
        let ficheQuery = currentModel.createRootFicheQuery();
        $$(editorId, "area_list_fiche").append(Bdf.render("fqleditor:fichequery-unit", ficheQuery));
        _initFicheQueryAction(ficheQuery);
    });
    $$(editorId, "button_addquery_motcle").click(function () {
        let motcleQuery = currentModel.createRootMotcleQuery();
        $$(editorId, "area_list_motcle").append(Bdf.render("fqleditor:motclequery-unit", motcleQuery));
        _initMotcleQueryAction(motcleQuery);
    });
    
   
    function _initFicheQueryAction(ficheQuery) {
        var jsId = ficheQuery.custom.jsId;
        $$(jsId, "button_corpusedit").click(function () {
            FqlEditor.Overlay.showCorpusEdit(ficheQuery.corpusCondition, currentModel, function (corpusCondition) {
                currentModel.setCorpusCondition(ficheQuery, corpusCondition);
                $$(jsId, "corpuscondition").html(Bdf.render("fqleditor:corpuscondition", ficheQuery));
            });
        });
        for(let editEntry of ficheQuery.custom.editEntries) {
            $$(jsId, "button_entryedit", editEntry.name).click(function () {
                 __editEntry(editEntry.name);
            });
        }
        $$(jsId, "button_motcleoperatoredit").click(function () {
            FqlEditor.Overlay.showLogicalOperatorEdit(ficheQuery.custom.motcleOperator.value, "_ label.selection.motclelogicaloperator", function (newValue) {
                currentModel.setMotcleOperator(ficheQuery, newValue);
                $$(jsId, "motcleoperatortitle").html(ficheQuery.custom.motcleOperator.title);
            });
        });
        $$(jsId, "button_addentry").click(function () {
           let availableSelect = $$.one(jsId, "available_entries");
           let selectedIndex = availableSelect.selectedIndex;
           if (selectedIndex > -1) {
               let option = availableSelect.options[selectedIndex];
               switch(option.value) {
                    case "motcle":
                        __addMotcle();
                        break;
                    case "fiche":
                        _addFiche(jsId, ficheQuery);
                       break;
                    default:
                        __editEntry(option.value);
               }
           }
        });
        if (ficheQuery.custom.withMotcle) {
             for(let motcleQuery of ficheQuery.motcleCondition.motcleQueryArray) {
                 _initMotcleQueryAction(motcleQuery);
             }
        }
        if (ficheQuery.custom.withFiche) {
             for(let childFicheQuery of ficheQuery.ficheCondition.ficheQueryArray) {
                 _initFicheQueryAction(childFicheQuery);
             }
        }
        
        function __addMotcle() {
            $$(jsId, "motclearea").removeClass("hidden");
            let motcleQuery = new Fql.MotcleQuery();
            currentModel.appendMotCleQuery(ficheQuery, motcleQuery);
            $$(jsId, "motclequerylist").append(Bdf.render("fqleditor:motclequery-unit", motcleQuery));
            _initMotcleQueryAction(motcleQuery);
            if (ficheQuery.custom.motcleLength > 1) {
                $$(jsId, "motcleoperator").removeClass("hidden");
            }
        }
        
        function __editEntry(name) {
            switch(name) {
                case "range":
                    FqlEditor.Overlay.showRangeEdit(ficheQuery.rangeCondition, '_ label.selection.id', function (rangeCondition) {
                        let updatedEditEntry = currentModel.setRangeCondition(ficheQuery, rangeCondition);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                    break;
                case "content":
                   FqlEditor.Overlay.showFieldContentEdit(ficheQuery.fieldContentCondition, function (newfieldContentCondition) {
                        let updatedEditEntry = currentModel.setFieldContentCondition(ficheQuery, newfieldContentCondition);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                   break;
                case "croisement":
                    FqlEditor.Overlay.showCroisementEdit(ficheQuery.croisementCondition, function (newCroisementCondition) {
                        let updatedEditEntry = currentModel.setFicheCroisementCondition(ficheQuery, newCroisementCondition);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                   break;
                case "discard":
                   FqlEditor.Overlay.showDiscardEdit(ficheQuery.discardFilter, function (newDiscardFilter) {
                        let updatedEditEntry = currentModel.setDiscardFilter(ficheQuery, newDiscardFilter);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                   break;
                case "period":
                   FqlEditor.Overlay.showPeriodEdit(ficheQuery.periodCondition, function (newPeriodCondition) {
                        let updatedEditEntry = currentModel.setPeriodCondition(ficheQuery, newPeriodCondition);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                    break;
                case "geoloc":
                   FqlEditor.Overlay.showCheckEdit(ficheQuery.withGeoloc, '_ label.fqleditor.geoloc', function (newChecked) {
                        let updatedEditEntry = currentModel.setGeoloc(ficheQuery, newChecked);
                         _updateEditEntry(jsId, updatedEditEntry);
                    });
                   break;
                case "user":
                   FqlEditor.Overlay.showUserEdit(ficheQuery.userCondition, function (newUserCondition) {
                        let updatedEditEntry = currentModel.setUserCondition(ficheQuery, newUserCondition);
                         _updateEditEntry(jsId, updatedEditEntry);
                    });
                   break;
                case "satellite":
                    FqlEditor.Overlay.showCheckEdit(ficheQuery.withSatellite, '_ label.fqleditor.satellite', function (newSatelliteValue)  {
                        let updatedEditEntry = currentModel.setSatelliteValue(ficheQuery, newSatelliteValue);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                    break;
            }
        }

    }
    
    function _initMotcleQueryAction(motcleQuery) {
        var jsId = motcleQuery.custom.jsId;
        $$(jsId, "button_thesaurusedit").click(function () {
            FqlEditor.Overlay.showThesaurusEdit(motcleQuery.thesaurusCondition, currentModel, function (thesaurusCondition) {
                currentModel.setThesaurusCondition(motcleQuery, thesaurusCondition);
                $$(jsId, "thesauruscondition").html(Bdf.render("fqleditor:thesauruscondition", motcleQuery));
            });
        });
        for(let editEntry of motcleQuery.custom.editEntries) {
            $$(jsId, "button_entryedit", editEntry.name).click(function () {
                 __editEntry(editEntry.name);
            });
        }
        $$(jsId, "button_ficheoperatoredit").click(function () {
            FqlEditor.Overlay.showLogicalOperatorEdit(motcleQuery.custom.ficheOperator.value, "_ label.selection.fichelogicaloperator", function (newValue) {
                currentModel.setFicheOperator(motcleQuery, newValue);
                $$(jsId, "ficheoperatortitle").html(motcleQuery.custom.ficheOperator.title);
            });
        });
        $$(jsId, "button_addentry").click(function () {
           let availableSelect = $$.one(jsId, "available_entries");
           let selectedIndex = availableSelect.selectedIndex;
           if (selectedIndex > -1) {
               let option = availableSelect.options[selectedIndex];
               switch(option.value) {
                    case "fiche":
                        _addFiche(jsId, motcleQuery);
                       break;
                    default:
                        __editEntry(option.value);
               }
           }
        });
        if (motcleQuery.custom.withFiche) {
             for(let ficheQuery of motcleQuery.ficheCondition.ficheQueryArray) {
                 _initFicheQueryAction(ficheQuery);
             }
        }
        
        function __editEntry(name) {
            switch(name) {
                case "content":
                   FqlEditor.Overlay.showMotcleContentEdit(motcleQuery.contentCondition, function (newContentCondition) {
                        let updatedEditEntry = currentModel.setMotcleContentCondition(motcleQuery, newContentCondition);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                   break;
                case "croisement":
                    FqlEditor.Overlay.showCroisementEdit(motcleQuery.croisementCondition, function (newCroisementCondition) {
                        let updatedEditEntry = currentModel.setMotcleCroisementCondition(motcleQuery, newCroisementCondition);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                   break;
                case "master":
                    FqlEditor.Overlay.showCheckEdit(motcleQuery.withMaster, '_ label.fqleditor.motclemaster', function (newMasterValue)  {
                        let updatedEditEntry = currentModel.setMasterValue(motcleQuery, newMasterValue);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                    break;
                case "range":
                    FqlEditor.Overlay.showRangeEdit(motcleQuery.idRangeCondition, '_ label.selection.id', function (rangeCondition) {
                        let updatedEditEntry = currentModel.setIdRangeCondition(motcleQuery, rangeCondition);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                    break;
                case "level":
                    FqlEditor.Overlay.showRangeEdit(motcleQuery.levelRangeCondition, '_ label.selection.level', function (rangeCondition) {
                        let updatedEditEntry = currentModel.setLevelRangeCondition(motcleQuery, rangeCondition);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                    break;
                case "status":
                    FqlEditor.Overlay.showStatusEdit(motcleQuery.statusCondition, '_ label.selection.status', function (statusCondition) {
                        let updatedEditEntry = currentModel.setStatusCondition(motcleQuery, statusCondition);
                        _updateEditEntry(jsId, updatedEditEntry);
                    });
                    break;
            }
        }
    }
    
    function _addFiche(jsId, parentQuery) {
        $$(jsId, "fichearea").removeClass("hidden");
        let ficheQuery = new Fql.FicheQuery();
        currentModel.appendFicheQuery(parentQuery, ficheQuery);
        $$(jsId, "fichequerylist").append(Bdf.render("fqleditor:fichequery-unit", ficheQuery));
        _initFicheQueryAction(ficheQuery);
        if (parentQuery.custom.ficheLength > 1) {
            $$(jsId, "ficheoperator").removeClass("hidden");
        }
    }
    
    function _updateEditEntry(jsId, editEntry) {
        if (editEntry.hidden) {
            $$(jsId, "entryrow", editEntry.name).addClass("hidden");
        } else {
            $$(jsId, "entryrow", editEntry.name).removeClass("hidden");
            $$(jsId, "entryvalue", editEntry.name).html(editEntry.value);
        }
        __checkOption(editEntry.name, editEntry.newdisabled);
        
        function __checkOption(name, disabled) {
            let select = $$.one(jsId, "available_entries");
            let selectedIndex = select.selectedIndex;
            let changeSelected = false;
            let optionLength = select.options.length;
            for(let i = 0; i < optionLength; i++) {
                if (select.options[i].value === name) {
                    select.options[i].disabled = disabled;
                    if ((i === selectedIndex) && (disabled)) {
                        changeSelected = true;
                    }
                    break;
                }
            }
            if (changeSelected) {
                for(let i = 0; i < optionLength; i++) {
                    if ((i !== selectedIndex) && (!select.options[i].disabled)) {
                        select.options[i].selected = true;
                        break;
                    }
                }
            }
        }
    }
    
};

FqlEditor.getMatchingLocKey = function (fqlConstant) {
    switch(fqlConstant) {
        case Fql.DISCARDFILTER_ALL:
            return "_ label.selection.discardfilter_all";
        case Fql.DISCARDFILTER_NONE:
            return "_ label.selection.discardfilter_none";
        case Fql.DISCARDFILTER_ONLY:
            return "_ label.selection.discardfilter_only";
        case Fql.LOGICALOPERATOR_OR:
            return "_ label.global.or";
        case Fql.LOGICALOPERATOR_AND:
            return "_ label.global.and";
    }
};

FqlEditor.getSubsetArray = function (category, subsetCondition, model) {
    var array = new Array();
    var existingMap = new Map();
    for(let name of subsetCondition.nameArray) {
        existingMap.set(category + "_" + name, true);
    }
     _convert(array, model.subsetTrees.getTree(category));
    return array;
    
    function _convert(currentArray, nodeArray) {
        for(let obj of nodeArray) {
            var nodeType = obj.node;
            if (nodeType === "group") {
                let label = obj.indent + obj.title;
                let subArray = new Array();
                _convert(subArray, obj.array);
                currentArray.push({
                    type: "group",
                    label: label,
                    array: subArray
                });
            } else if (nodeType === "subset") {
                let value, label, checked;
                value = obj.name;
                if (obj.title) {
                    label = obj.title + " [" + obj.name + "]";
                } else {
                    label = "[" + obj.name + "]";
                }
                if (existingMap.has(obj.key)) {
                    checked = true;
                } else {
                    checked = false;
                }
                currentArray.push({
                    type: "subset",
                    value: value,
                    label: label,
                    checked: checked
                });
            }
        }
    }
};


$(function () {
    Bdf.initTemplates();
    Bdf.runSerialFunctions(
        _initSubsetTrees,
        FqlEditor.testReady
    );
    
    function _initSubsetTrees(callback) {
        Bdf.SubsetTrees.load(function (subsetTrees) {
            FqlEditor.subsetTrees = subsetTrees;
            if (callback) {
                callback();
            }
        });

    }
});

