/* global Bdf,$$,Fql,FqlEditor */

/**
 * 
 * @param {type} subsetTrees
 * @constructor
 */
FqlEditor.Model = function (subsetTrees) {
    this.subsetTrees = subsetTrees;
    this.ficheQueryArray = new Array();
    this.motcleQueryArray = new Array();
};

FqlEditor.Model.FICHE_EDITENTRIES = [
    {
        name: "range",
        titleKey: "_ label.selection.id"
    },
    {
        name: "content",
        titleKey: "_ label.selection.fieldcontent"
    },
    {
        name: "period",
        titleKey: "_ label.selection.period"
    },
    {
        name: "user",
        titleKey: "_ label.selection.users"
    },
    {
        name: "discard",
        titleKey: "_ label.selection.discardfilter"
    },
    {
        name: "geoloc",
        titleKey: "_ label.selection.geoloc"
    },
    {
        name: "satellite",
        titleKey: "_ label.selection.satellite",
        noroot: true
    },
    {
        name: "junction",
        titleKey: "_ label.selection.junction",
        noroot: true
    }
];
FqlEditor.Model.MOTCLE_EDITENTRIES = [
    {
        name: "range",
        titleKey: "_ label.selection.id"
    },
    {
        name: "level",
        titleKey: "_ label.selection.level"
    },
    {
        name: "content",
        titleKey: "_ label.selection.motclecontent"
    },
    {
        name: "status",
        titleKey: "_ label.selection.status"
    },
    {
        name: "master",
        titleKey: "_ label.selection.master",
        noroot: true
    },
    {
        name: "junction",
        titleKey: "_ label.selection.junction",
        noroot: true
    }
];

FqlEditor.Model.prototype.createRootFicheQuery = function (data) {
    let ficheQuery = new Fql.FicheQuery(data);
    ficheQuery.custom.queryNumber = (this.ficheQueryArray.length + 1);
    this.initFicheQuery(ficheQuery, true);
    this.ficheQueryArray.push(ficheQuery);
    return ficheQuery;
};

FqlEditor.Model.prototype.createRootMotcleQuery = function (data) {
    let motcleQuery = new Fql.MotcleQuery(data);
    motcleQuery.custom.queryNumber = (this.motcleQueryArray.length + 1);
    this.initMotcleQuery(motcleQuery, true);
    this.motcleQueryArray.push(motcleQuery);
    return motcleQuery;
};

FqlEditor.Model.prototype.initFicheQuery = function (ficheQuery, root) {
    ficheQuery.custom.jsId = Bdf.generateId();
    this.updateCorpusCondition(ficheQuery);
    this.updateMotcleCondition(ficheQuery);
    this.updateFicheCondition(ficheQuery);
    ficheQuery.custom.editEntries = [];
    for(let entryInit of FqlEditor.Model.FICHE_EDITENTRIES) {
        if ((root) && (entryInit.noroot)) {
            continue;
        }
        let editEntry = new FqlEditor.Model.EditEntry(entryInit.name, entryInit.titleKey);
        ficheQuery.custom.editEntries.push(editEntry);
        this.updateFicheQueryEditEntry(ficheQuery, entryInit.name);
    }
    if (ficheQuery.motcleCondition) {
        for(let motcleQuery of ficheQuery.motcleCondition.motcleQueryArray) {
            this.initMotcleQuery(motcleQuery, false);
        }
    }
    if (ficheQuery.ficheCondition) {
        for(let childFicheQuery of ficheQuery.ficheCondition.ficheQueryArray) {
            this.initFicheQuery(childFicheQuery, false);
        }
    }
};

FqlEditor.Model.prototype.initMotcleQuery = function (motcleQuery, root) {
    motcleQuery.custom.jsId = Bdf.generateId();
    this.updateThesaurusCondition(motcleQuery);
    this.updateFicheCondition(motcleQuery);
    motcleQuery.custom.editEntries = [];
    for(let entryInit of FqlEditor.Model.MOTCLE_EDITENTRIES) {
        if ((root) && (entryInit.noroot)) {
            continue;
        }
        let editEntry = new FqlEditor.Model.EditEntry(entryInit.name, entryInit.titleKey);
        motcleQuery.custom.editEntries.push(editEntry);
        this.updateMotcleQueryEditEntry(motcleQuery, entryInit.name);
    }
    if (motcleQuery.ficheCondition) {
        for(let ficheQuery of motcleQuery.ficheCondition.ficheQueryArray) {
            this.initFicheQuery(ficheQuery, false);
        }
    }
};

FqlEditor.Model.prototype.appendFicheQuery = function (parentQuery, ficheQuery) {
    parentQuery.addFicheQueries(ficheQuery);
    this.updateFicheCondition(parentQuery);
    this.initFicheQuery(ficheQuery, false);
};

FqlEditor.Model.prototype.appendMotCleQuery = function (ficheQuery, motcleQuery) {
    ficheQuery.addMotcleQueries(motcleQuery);
    this.updateMotcleCondition(ficheQuery);
    this.initMotcleQuery(motcleQuery, false);
};

FqlEditor.Model.prototype.addCorpusToQuery = function (ficheQuery, corpusName) {
    let corpus = this.subsetTrees.getCorpus(corpusName);
    if (corpus) {
        ficheQuery.addCorpus(corpusName);
        ficheQuery.custom.corpusArray.push(corpus);
        ficheQuery.custom.all = false;
        return corpus;
    } else {
        return false;
    }
};

FqlEditor.Model.prototype.addThesaurusToQuery = function (motcleQuery, thesaurusName) {
    let thesaurus = this.subsetTrees.getThesaurus(thesaurusName);
    if (thesaurus) {
        motcleQuery.addThesaurus(thesaurusName);
        motcleQuery.custom.thesaurusArray.push(thesaurus);
        motcleQuery.custom.all = false;
        return thesaurus;
    } else {
        return false;
    }
};

FqlEditor.Model.prototype.setCorpusCondition = function (ficheQuery, corpusCondition) {
    ficheQuery.setCorpusCondition(corpusCondition);
    return this.updateCorpusCondition(ficheQuery);
};

FqlEditor.Model.prototype.setFicheJunctionCondition = function (ficheQuery, junctionCondition) {
    ficheQuery.setJunctionCondition(junctionCondition);
    return this.updateMotcleQueryEditEntry(ficheQuery, "junction");
};

FqlEditor.Model.prototype.setMotcleOperator = function (ficheQuery, newOperator) {
    if (ficheQuery.motcleCondition) {
        ficheQuery.motcleCondition.operator = newOperator;
    }
    return this.updateMotcleCondition(ficheQuery);
};

FqlEditor.Model.prototype.setSatelliteValue = function (ficheQuery, satelliteValue) {
   ficheQuery.withSatellite = satelliteValue;
    return this.updateFicheQueryEditEntry(ficheQuery, "satellite");
};

FqlEditor.Model.prototype.setFieldContentCondition = function (ficheQuery, fieldContentCondition) {
    ficheQuery.setFieldContentCondition(fieldContentCondition);
    return this.updateFicheQueryEditEntry(ficheQuery, "content");
};

FqlEditor.Model.prototype.setPeriodCondition = function (ficheQuery, periodCondition) {
    ficheQuery.setPeriodCondition(periodCondition);
    return this.updateFicheQueryEditEntry(ficheQuery, "period");
};

FqlEditor.Model.prototype.setRangeCondition = function (ficheQuery, rangeCondition) {
    ficheQuery.setRangeCondition(rangeCondition);
    return this.updateFicheQueryEditEntry(ficheQuery, "range");
};

FqlEditor.Model.prototype.setUserCondition = function (ficheQuery, userCondition) {
    ficheQuery.setUserCondition(userCondition);
    return this.updateFicheQueryEditEntry(ficheQuery, "user");
};

FqlEditor.Model.prototype.setGeoloc = function (ficheQuery, withGeoloc) {
    ficheQuery.withGeoloc = withGeoloc;
    return this.updateFicheQueryEditEntry(ficheQuery, "geoloc");
};

FqlEditor.Model.prototype.setDiscardFilter = function (ficheQuery, discardFilter) {
    ficheQuery.setDiscardFilter(discardFilter);
    return this.updateFicheQueryEditEntry(ficheQuery, "discard");
};

FqlEditor.Model.prototype.setThesaurusCondition = function (motcleQuery, thesaurusCondition) {
    motcleQuery.setThesaurusCondition(thesaurusCondition);
    return this.updateThesaurusCondition(motcleQuery);
};

FqlEditor.Model.prototype.setMotcleContentCondition = function (motcleQuery, contentCondition) {
    motcleQuery.setContentCondition(contentCondition);
    return this.updateMotcleQueryEditEntry(motcleQuery, "content");
};

FqlEditor.Model.prototype.setMotcleJunctionCondition = function (motcleQuery, junctionCondition) {
    motcleQuery.setJunctionCondition(junctionCondition);
    return this.updateMotcleQueryEditEntry(motcleQuery, "junction");
};

FqlEditor.Model.prototype.setFicheOperator = function (query, newOperator) {
    if (query.ficheCondition) {
        query.ficheCondition.operator = newOperator;
    }
    return this.updateFicheCondition(query);
};

FqlEditor.Model.prototype.setMasterValue = function (motcleQuery, masterValue) {
    motcleQuery.withMaster = masterValue;
    return this.updateMotcleQueryEditEntry(motcleQuery, "master");
};

FqlEditor.Model.prototype.setIdRangeCondition = function (motcleQuery, rangeCondition) {
    motcleQuery.setIdRangeCondition(rangeCondition);
    return this.updateMotcleQueryEditEntry(motcleQuery, "range");
};

FqlEditor.Model.prototype.setLevelRangeCondition = function (motcleQuery, rangeCondition) {
    motcleQuery.setLevelRangeCondition(rangeCondition);
    return this.updateMotcleQueryEditEntry(motcleQuery, "level");
};

FqlEditor.Model.prototype.setStatusCondition = function (motcleQuery, statusCondition) {
    motcleQuery.setStatusCondition(statusCondition);
    return this.updateMotcleQueryEditEntry(motcleQuery, "status");
};

FqlEditor.Model.prototype.toXml = function () {
    var result = "";
    for(let ficheQuery of this.ficheQueryArray) {
        result += ficheQuery.toXml(-1);
        result += "\n";
    }
    for(let motcleQuery of this.motcleQueryArray) {
        result += motcleQuery.toXml(-1);
        result += "\n";
    }
    return result;
};

FqlEditor.Model.prototype.updateCorpusCondition = function (ficheQuery) {
    let corpusArray = new Array();
    for(let name of ficheQuery.corpusCondition.nameArray) {
        let corpus = this.subsetTrees.getCorpus(name);
        if (corpus) {
            corpusArray.push(corpus);
        } else {
            corpusArray.push({node: "unknown", name: name});
        }
    }
    ficheQuery.custom.all = ficheQuery.corpusCondition.isAll();
    ficheQuery.custom.corpusArray = corpusArray;
};

FqlEditor.Model.prototype.updateMotcleCondition = function (ficheQuery) {
    let motcleCondition = ficheQuery.motcleCondition;
    let length = 0;
    let operator = {
        value: Fql.LOGICALOPERATOR_AND,
        title: ""
    };
    if (motcleCondition) {
        let numberPrefix = ficheQuery.custom.queryNumber + ".";
        length = motcleCondition.motcleQueryArray.length;
        let p = 1;
        for(let motcleQuery of motcleCondition.motcleQueryArray) {
            motcleQuery.custom.queryNumber = numberPrefix + p;
            p++;
        }
        operator.value = motcleCondition.operator;
    }
    operator.title = Bdf.Loc.get(FqlEditor.getMatchingLocKey(operator.value));
    ficheQuery.custom.withMotcle = (length > 0);
    ficheQuery.custom.motcleLength = length;
    ficheQuery.custom.motcleOperator = operator;
};

FqlEditor.Model.prototype.updateFicheQueryEditEntry = function (ficheQuery, name) {
    var editEntry = this.getEditEntry(ficheQuery, name);
    if (!editEntry) {
        Bdf.log("Unknown editEntry: " + name);
        return;
    }
    switch(name) {
        case "content":
            _updateContent();
            break;
        case "junction":
            _updateJunction();
            break;
        case "discard":
            _updateDiscard();
            break;
        case "geoloc":
            _updateGeoloc();
            break;
        case "period":
            _updatePeriod();
            break;
        case "range":
            _updateRange();
            break;
        case "satellite":
            _updateSatellite();
            break;
        case "user":
            _updateUser();
            break;
    }
    return editEntry;

    function _updateContent() {
        if (ficheQuery.fieldContentCondition) {
            _enableEntry(ficheQuery.fieldContentCondition.toText());
        } else {
            _disableEntry();
        }
    }
    
    function _updateJunction() {
        if (ficheQuery.junctionCondition) {
            _enableEntry(ficheQuery.junctionCondition.toText());
        } else {
            _disableEntry();
        }
    }
    
    function _updateDiscard() {
        if (ficheQuery.discardFilter === Fql.DISCARDFILTER_ALL) {
            _disableEntry();
        } else {
            _enableEntry(Bdf.Loc.get(FqlEditor.getMatchingLocKey(ficheQuery.discardFilter)));
        }
    }

    function _updateGeoloc() {
        if (ficheQuery.withGeoloc) {
            _enableEntry(Bdf.Loc.get("_ label.fqleditor.geoloc"));
        } else {
            _disableEntry();
        }
    }
    
    function _updatePeriod() {
        if (ficheQuery.periodCondition) {
            _enableEntry(ficheQuery.periodCondition.toText());
        } else {
            _disableEntry();
        }
    }
    
    function _updateRange() {
        if (ficheQuery.rangeCondition) {
            _enableEntry(ficheQuery.rangeCondition.toText(true));
        } else {
            _disableEntry();
        }
    }
    
    function _updateSatellite() {
        if (ficheQuery.withSatellite) {
            _enableEntry(Bdf.Loc.get("_ label.fqleditor.satellite"));
        } else {
            _disableEntry();
        }
    }
    
    function _updateUser() {
        if (ficheQuery.userCondition) {
            _enableEntry(ficheQuery.userCondition.toText());
        } else {
            _disableEntry();
        }
    }
    
    function _enableEntry(value) {
        editEntry.value = value;
        editEntry.newdisabled = true;
        editEntry.hidden = false;
    }
    
    function _disableEntry() {
        editEntry.value = "";
        editEntry.newdisabled = false;
        editEntry.hidden = true;
    }
};

FqlEditor.Model.prototype.updateThesaurusCondition = function (motcleQuery) {
    let thesaurusArray = new Array();
    for(let name of motcleQuery.thesaurusCondition.nameArray) {
        let thesaurus = this.subsetTrees.getThesaurus(name);
        if (thesaurus) {
            thesaurusArray.push(thesaurus);
        } else {
            thesaurusArray.push({node: "unknown", name: name});
        }
    }
    motcleQuery.custom.all = motcleQuery.thesaurusCondition.isAll();
    motcleQuery.custom.thesaurusArray = thesaurusArray;
};

FqlEditor.Model.prototype.updateFicheCondition = function (query) {
    let ficheCondition = query.ficheCondition;
    let length = 0;
    let operator = {
        value: Fql.LOGICALOPERATOR_AND,
        title: ""
    };
    if (ficheCondition) {
        let numberPrefix = query.custom.queryNumber + ".";
        length = ficheCondition.ficheQueryArray.length;
        let p = 1;
        for(let ficheQuery of ficheCondition.ficheQueryArray) {
            ficheQuery.custom.queryNumber = numberPrefix + p;
            p++;
        }
        operator.value = ficheCondition.operator;
    }
    operator.title = Bdf.Loc.get(FqlEditor.getMatchingLocKey(operator.value));
    query.custom.withFiche = (length > 0);
    query.custom.ficheLength = length;
    query.custom.ficheOperator = operator;
};

FqlEditor.Model.prototype.updateMotcleQueryEditEntry = function (motcleQuery, name) {
    var editEntry = this.getEditEntry(motcleQuery, name);
    if (!editEntry) {
        Bdf.log("Unknown editEntry: " + name);
        return;
    }
    switch(name) {
        case "content":
             _updateContent();
            break;
        case "junction":
            _updateJunction();
            break;
        case "level":
            _updateLevel();
            break;
        case "status":
            _updateStatus();
            break;
        case "master":
            _updateMaster();
            break;
        case "range":
            _updateRange();
            break;
    }
    return editEntry;
    
    function _updateContent() {
        if (motcleQuery.contentCondition) {
            _enableEntry(motcleQuery.contentCondition.toText());
        } else {
            _disableEntry();
        }
    }
    
    function _updateJunction() {
        if (motcleQuery.junctionCondition) {
            _enableEntry(motcleQuery.junctionCondition.toText());
        } else {
            _disableEntry();
        }
    }
    
    function _updateLevel() {
        if (motcleQuery.levelRangeCondition) {
            _enableEntry(motcleQuery.levelRangeCondition.toText(true));
        } else {
            _disableEntry();
        }
    }
    
    function _updateStatus() {
        if (motcleQuery.statusCondition) {
            _enableEntry(motcleQuery.statusCondition.toText());
        } else {
            _disableEntry();
        }
    }
    
    function _updateMaster() {
        if (motcleQuery.withMaster) {
            _enableEntry(Bdf.Loc.get("_ label.fqleditor.motclemaster"));
        } else {
            _disableEntry();
        }
    }
    
    function _updateRange() {
        if (motcleQuery.idRangeCondition) {
            _enableEntry(motcleQuery.idRangeCondition.toText(true));
        } else {
            _disableEntry();
        }
    }
    
    function _enableEntry(value) {
        editEntry.value = value;
        editEntry.newdisabled = true;
        editEntry.hidden = false;
    }
    
    function _disableEntry() {
        editEntry.value = "";
        editEntry.newdisabled = false;
        editEntry.hidden = true;
    }
};

FqlEditor.Model.prototype.getEditEntry = function (query, name) {
    for(let editEntry of query.custom.editEntries) {
        if (editEntry.name === name) {
            return editEntry;
        }
    }
    return null;
};

FqlEditor.Model.EditEntry = function (name, titleKey) {
    this.name = name;
    this.titleKey = titleKey;
    this.hidden = true;
    this.newdisabled = false;
    this.value = "";
};
