Map.js


Wyg.Map = class {

    constructor(map = []){
        this.map = map;
    }

    reset(map = []){
        this.map = map;
    }

    emptyObject(){
        return {
        "node":undefined,
        "templateNode":undefined,
        "fields":[],
        "code":undefined,
        };
    }
    removeWhere(key,value){
        for (const index in this.map){
            const ref = this.map[index];
            if (key=='field'){
                for (const childField of ref.fields){
                    if (value===childField){
                        //delete(this.map[index]);
                        this.map.splice(index,1);
                    }
                }
            } else {
                if (ref[key]===value){
                    //delete(this.map[index]);
                    this.map.splice(index,1);
                }
            }
        }
    }
    push(key,value,siblingKey=undefined,siblingValue=undefined){
        const ref = this.refFrom(key,value);

        if (siblingKey===undefined
            ||siblingValue===undefined){
                if (ref!==undefined)return ref;

                const emptyObj = this.emptyObject();
                if (key=='field'){
                    emptyObj['fields'].push(value);
                } else {
                    emptyObj[key] = value;
                }
                this.map.push(emptyObj);
                return emptyObj;
            } 
        else {
            const fromSibling = this.refFrom(siblingKey,siblingValue);
            
            if (ref!==undefined
                &&ref!==fromSibling){
                    if (key=='field'){
                        for (let index in ref.fields){
                            if (ref.fields[index]===value){
                                ref.fields.splice(index,1);
                            }
                        }
                    } else {
                        ref[key] = undefined;
                    }
            }
            if (key=='field'){
                fromSibling['fields'].push(value);
            } else {
                fromSibling[key] = value;
            }
            return fromSibling;
        }
    }

    refFrom(key,value){
        for (const ref of this.map){
            if (key=='field'){
                for (const childField of ref.fields){
                    if (value===childField){
                        return ref;
                    }
                }
            } else {
                if (ref[key]==value){
                    return ref;
                }
            }
        }
    }
    
    /*
    {"node":nodeObject,
     "fields":[fieldList],
     "code":initialNodeTemplateCode
    }

    */

    refFromField(field){
        for (const ref of this.map){
            for (const childField of ref.fields){
                if (field===childField){
                    return ref;
                }
            }
        }
    }
    refFromNode(node){
        for (const ref of this.map){
            if (ref.node===node){
                return ref;
            }
        }
        return this.push('node',node);
    }

    fieldFromParam(fieldKey,fieldValue){
        for (const ref of this.map){
            for (const field of ref.fields){
                if (field[fieldKey]===fieldValue){
                    return field;
                }
            }
        }
    }
    fieldFromKey(key){
        return this.fieldFromParam('key',key);
    }
    fieldsFromNode(node){
        const ref = this.refFromNode(node);
        return ref.fields;
    }
    fieldsFromParam(fieldParamKey,fieldParamValue){
        const fields = [];
        for (const ref of this.map){
            for (const field of ref.fields){
                if (field[fieldParamKey]===fieldParamValue){
                    fields.push(field);
                }
            }
        }
        return fields;
    }
    fieldFromNode(node,index){
        const fields = this.fieldsFromNode(node);
        return fields[index];
    }


    nodeFromFieldKey(fieldKey){
        const field = this.fieldFromParam('key',fieldKey);
        const ref = this.refFromField(field);
        return ref.node;
    }
    fieldFromCode(fieldCode){
        let field = this.fieldFromParam('code',fieldCode);
        if (field===undefined){
            field = new Wyg.Field(fieldCode);
            this.push('field',field);
        }
        return field;
    }
}