/* global Bdf,$$, Ficheframe */

Ficheframe.Positions = function (positionArray) {
  this.positionArray = positionArray; 
  this.currentIndex = -1;
  this.currentPosition = null;
  this.isCurrentActive = false;
};

Ficheframe.Positions.prototype.isChanged = function (pageY) {
    var currentPosition = this.currentPosition;
    if ((currentPosition) && (currentPosition.containsWithMargin(pageY))) {
        return false;
    }
    return true;
};

Ficheframe.Positions.prototype.activateCurrent = function () {
    this.isCurrentActive = true;
};

Ficheframe.Positions.prototype.clear = function () {
    if (this.currentPosition) {
        this.currentPosition.setBackground(null);
        this.currentPosition = null;
        this.currentIndex = -1;
        this.isCurrentActive = false;
    }
};

Ficheframe.Positions.prototype.updatePosition = function (pageY) {
    this.clear();
    let length = this.positionArray.length;
    for(let i = 0; i < length; i++) {
        let position = this.positionArray[i];
        let comp = position.compare(pageY);
        if (comp === 0) {
            this.currentPosition = position;
            this.currentIndex = i;
            break;
        } else if (comp < 0) {
            break;
        }
    }
    return this.currentPosition;
};

Ficheframe.Positions.prototype.highlightCurrent = function (highlight) {
    if (this.currentPosition) {
        let backgroundColor = null;
        if (highlight) {
            backgroundColor = Ficheframe.backgroundColor;
        }
        this.currentPosition.setBackground(backgroundColor);
    }
};

Ficheframe.Positions.build = function (document) {
    var positionArray = new Array();
    $(document).find($$.toCssSelector({bdfField: true})).each(function (index, element) {
        let fieldType = element.dataset.bdfField;
        let gotoObject = _getGotoObject(element);
        if (gotoObject) {
            let done = false;
            if (fieldType === "section") {
                let firstDim;
                $$(element, {bdfPosition: true}).each(function (index, ficheblock) {
                    let dim = _getDim(ficheblock);
                    if (!firstDim) {
                        firstDim = dim;
                    }
                    let ficheblockGotoObject = Object.assign({}, gotoObject);
                    ficheblockGotoObject.goto = ficheblockGotoObject.goto + "@" + ficheblock.dataset.bdfPosition;
                    positionArray.push(new Ficheframe.Position(ficheblock, ficheblockGotoObject , dim));
                });
                if (firstDim) {
                    done = true;
                    let dim = _getDim(element);
                    dim[1] = firstDim[0] - 1;
                    positionArray.push(new Ficheframe.Position(element, gotoObject, dim));
                }
            }
            if (!done) {
                let dim = _getDim(element);
                positionArray.push(new Ficheframe.Position(element, gotoObject, dim));
            }
        }
    });
    positionArray.sort(function (p1, p2) {
        if (p1.startY < p2.startY) {
            return -1;
        }
        if (p1.startY > p2.startY) {
            return 1;
        }
        if (p1.endY < p2.endY) {
            return -1;
        }
        if (p1.endY > p2.endY) {
            return 1;
        }
        return 0;
    });
    let length = positionArray.length;
    let marginMax = 12;
    for(let i = 0; i < length; i++) {
        let currentPosition = positionArray[i];
        if (i === 0) {
            currentPosition.startMargin = Math.max(0, currentPosition.startY -  marginMax);
        } else {
            let previous = positionArray[i -1];
            let margin = Math.min(marginMax, (currentPosition.startY - previous.endY) / 2);
            if (margin < 0) {
                margin = 0;
            }
            currentPosition.startMargin = currentPosition.startY -  margin;
        }
        if (i === (length - 1)) {
            currentPosition.endMargin = Math.min($(document).height(), currentPosition.endY +  marginMax);
        } else {
            let next = positionArray[i + 1];
            let margin = Math.min(marginMax, (next.startY - currentPosition.endY) / 2);
            if (margin < 0) {
                margin = 0;
            }
            currentPosition.endMargin = Math.max(Math.min(positionArray[i + 1].startY - 1, currentPosition.endY +  margin), currentPosition.endY);
        }
    }
    return new Ficheframe.Positions(positionArray);
    
    function _getDim(element) {
        let $element = $(element);
        let offset = $element.offset();
        let startY = offset.top;
        let array = new Array();
        array.push(startY);
        array.push(startY + $element.height());
        array.push(offset.left);
        return array;
    }
    
    function _getGotoObject(element) {
        let goto = element.dataset.bdfComponentName;
        if (!goto) {
            return null;
        }
        if (goto === "liage") {
            if (element.dataset.bdfField !== "corpus") {
                return null;
            }
        } else if (goto.startsWith("_master_")) {
            if (!goto.startsWith("_master_" + element.dataset.bdfField)) {
                return null;
            }
        } else if (!goto.startsWith(element.dataset.bdfField)) {
            return null;
        }
        let corpusName = null;
        let ficheId = null;
        let $satellite = $(element).parents($$.toCssSelector({bdfMilestone: "satellite"}));
        if ($satellite.length > 0) {
            goto = "satellite_" + $satellite[0].dataset.bdfSatellite + "/" + goto;
        }
        let $fiche = $(element).parents($$.toCssSelector({bdfElement: "fiche"}));
        if ($fiche.length > 0) {
            let fiche = $fiche[0];
            corpusName = fiche.dataset.bdfCorpus;
            ficheId = fiche.dataset.bdfId;
        }
        return {
            goto: goto,
            corpusName: corpusName,
            ficheId: ficheId
        };
    }
};
