import merge_default from "../../../../lodash-es/merge.js";
import last_default from "../../../../lodash-es/last.js";
import forEach_default from "../../../../lodash-es/forEach.js";
import find_default from "../../../../lodash-es/find.js";
import map_default from "../../../../lodash-es/map.js";
import forIn_default from "../../../../lodash-es/forIn.js";
import values_default from "../../../../lodash-es/values.js";
import mapValues_default from "../../../../lodash-es/mapValues.js";
import max_default from "../../../../lodash-es/max.js";
import min_default from "../../../../lodash-es/min.js";
import minBy_default from "../../../../lodash-es/minBy.js";
import range_default from "../../../../lodash-es/range.js";
import reduce_default from "../../../../lodash-es/reduce.js";
import sortBy_default from "../../../../lodash-es/sortBy.js";
import { Graph } from "../../graphlib/graph.js";
import "../../graphlib/index.js";
import { buildLayerMatrix } from "../util.js";
function findType1Conflicts(e, y) {
	var b = {};
	function x(y, x) {
		var S = 0, C = 0, w = y.length, T = last_default(x);
		return forEach_default(x, function(_, y) {
			var E = findOtherInnerSegmentNode(e, _), D = E ? e.node(E).order : w;
			(E || _ === T) && (forEach_default(x.slice(C, y + 1), function(_) {
				forEach_default(e.predecessors(_), function(v) {
					var y = e.node(v), x = y.order;
					(x < S || D < x) && !(y.dummy && e.node(_).dummy) && addConflict(b, v, _);
				});
			}), C = y + 1, S = D);
		}), x;
	}
	return reduce_default(y, x), b;
}
function findType2Conflicts(e, _) {
	var y = {};
	function b(_, b, x, S, C) {
		var w;
		forEach_default(range_default(b, x), function(b) {
			w = _[b], e.node(w).dummy && forEach_default(e.predecessors(w), function(_) {
				var v = e.node(_);
				v.dummy && (v.order < S || v.order > C) && addConflict(y, _, w);
			});
		});
	}
	function x(_, y) {
		var x = -1, S, C = 0;
		return forEach_default(y, function(v, w) {
			if (e.node(v).dummy === "border") {
				var T = e.predecessors(v);
				T.length && (S = e.node(T[0]).order, b(y, C, w, x, S), C = w, x = S);
			}
			b(y, C, y.length, S, _.length);
		}), y;
	}
	return reduce_default(_, x), y;
}
function findOtherInnerSegmentNode(e, _) {
	if (e.node(_).dummy) return find_default(e.predecessors(_), function(_) {
		return e.node(_).dummy;
	});
}
function addConflict(e, _, v) {
	if (_ > v) {
		var y = _;
		_ = v, v = y;
	}
	Object.prototype.hasOwnProperty.call(e, _) || Object.defineProperty(e, _, {
		enumerable: !0,
		configurable: !0,
		value: {},
		writable: !0
	});
	var b = e[_];
	Object.defineProperty(b, v, {
		enumerable: !0,
		configurable: !0,
		value: !0,
		writable: !0
	});
}
function hasConflict(e, _, v) {
	if (_ > v) {
		var y = _;
		_ = v, v = y;
	}
	return !!e[_] && Object.prototype.hasOwnProperty.call(e[_], v);
}
function verticalAlignment(e, _, y, b) {
	var x = {}, S = {}, C = {};
	return forEach_default(_, function(e) {
		forEach_default(e, function(e, _) {
			x[e] = e, S[e] = e, C[e] = _;
		});
	}), forEach_default(_, function(e) {
		var _ = -1;
		forEach_default(e, function(e) {
			var v = b(e);
			if (v.length) {
				v = sortBy_default(v, function(e) {
					return C[e];
				});
				for (var w = (v.length - 1) / 2, T = Math.floor(w), E = Math.ceil(w); T <= E; ++T) {
					var D = v[T];
					S[e] === e && _ < C[D] && !hasConflict(y, e, D) && (S[D] = e, S[e] = x[e] = x[D], _ = C[D]);
				}
			}
		});
	}), {
		root: x,
		align: S
	};
}
function horizontalCompaction(e, _, y, b, x) {
	var S = {}, C = buildBlockGraph(e, _, y, x), w = x ? "borderLeft" : "borderRight";
	function T(e, _) {
		for (var v = C.nodes(), y = v.pop(), b = {}; y;) b[y] ? e(y) : (b[y] = !0, v.push(y), v = v.concat(_(y))), y = v.pop();
	}
	function E(e) {
		S[e] = C.inEdges(e).reduce(function(e, _) {
			return Math.max(e, S[_.v] + C.edge(_));
		}, 0);
	}
	function D(_) {
		var v = C.outEdges(_).reduce(function(e, _) {
			return Math.min(e, S[_.w] - C.edge(_));
		}, Infinity), y = e.node(_);
		v !== Infinity && y.borderType !== w && (S[_] = Math.max(S[_], v));
	}
	return T(E, C.predecessors.bind(C)), T(D, C.successors.bind(C)), forEach_default(b, function(e) {
		S[e] = S[y[e]];
	}), S;
}
function buildBlockGraph(e, _, y, b) {
	var x = new Graph(), S = e.graph(), C = sep(S.nodesep, S.edgesep, b);
	return forEach_default(_, function(_) {
		var b;
		forEach_default(_, function(_) {
			var v = y[_];
			if (x.setNode(v), b) {
				var S = y[b], w = x.edge(S, v);
				x.setEdge(S, v, Math.max(C(e, _, b), w || 0));
			}
			b = _;
		});
	}), x;
}
function findSmallestWidthAlignment(e, _) {
	return minBy_default(values_default(_), function(_) {
		var v = -Infinity, y = Infinity;
		return forIn_default(_, function(_, b) {
			var x = width(e, b) / 2;
			v = Math.max(_ + x, v), y = Math.min(_ - x, y);
		}), v - y;
	});
}
function alignCoordinates(e, _) {
	var y = values_default(_), b = min_default(y), x = max_default(y);
	forEach_default(["u", "d"], function(y) {
		forEach_default(["l", "r"], function(v) {
			var E = y + v, D = e[E], O;
			if (D !== _) {
				var k = values_default(D);
				O = v === "l" ? b - min_default(k) : x - max_default(k), O && (e[E] = mapValues_default(D, function(e) {
					return e + O;
				}));
			}
		});
	});
}
function balance(e, _) {
	return mapValues_default(e.ul, function(v, y) {
		if (_) return e[_.toLowerCase()][y];
		var x = sortBy_default(map_default(e, y));
		return (x[1] + x[2]) / 2;
	});
}
function positionX(_) {
	var y = buildLayerMatrix(_), x = merge_default(findType1Conflicts(_, y), findType2Conflicts(_, y)), w = {}, T;
	return forEach_default(["u", "d"], function(e) {
		T = e === "u" ? y : values_default(y).reverse(), forEach_default(["l", "r"], function(v) {
			v === "r" && (T = map_default(T, function(e) {
				return values_default(e).reverse();
			}));
			var y = (e === "u" ? _.predecessors : _.successors).bind(_), E = verticalAlignment(_, T, x, y), D = horizontalCompaction(_, T, E.root, E.align, v === "r");
			v === "r" && (D = mapValues_default(D, function(e) {
				return -e;
			})), w[e + v] = D;
		});
	}), alignCoordinates(w, findSmallestWidthAlignment(_, w)), balance(w, _.graph().align);
}
function sep(e, _, v) {
	return function(y, b, x) {
		var S = y.node(b), C = y.node(x), w = 0, T;
		if (w += S.width / 2, Object.prototype.hasOwnProperty.call(S, "labelpos")) switch (S.labelpos.toLowerCase()) {
			case "l":
				T = -S.width / 2;
				break;
			case "r":
				T = S.width / 2;
				break;
		}
		if (T && (w += v ? T : -T), T = 0, w += (S.dummy ? _ : e) / 2, w += (C.dummy ? _ : e) / 2, w += C.width / 2, Object.prototype.hasOwnProperty.call(C, "labelpos")) switch (C.labelpos.toLowerCase()) {
			case "l":
				T = C.width / 2;
				break;
			case "r":
				T = -C.width / 2;
				break;
		}
		return T && (w += v ? T : -T), T = 0, w;
	};
}
function width(e, _) {
	return e.node(_).width;
}
export { positionX };
