<%@ language="javascript"%>
<% /*
     $Revision$
     $Id$

     File:          ins_deelkoppelingen.asp
     Beschrijving:  Presenteert de relaties van het gegeven object, om op door te klikken..
                    Zou een alternatief kunnen zijn voor ins_list.asp?koppel_key=, maar daar kun je beheren,
                    en hier vooralsnog niet.

*/%>
<!--#include file="../Shared/common.inc"-->
<!--#include file="../Shared/discx3d.inc" -->
<!--#include file="../Shared/iface.inc" -->
<!--#include file="../Shared/resultset_table_v2.inc" -->
<!--#include file="ins.inc" -->
<%
var ins_key  = getQParamInt("ins_key");
var urole    = getQParamSafe("urole");
var autfunction = "";
switch(urole) {
  case "fe": autfunction = "WEB_INSUSE";
           break;
  case "fo": autfunction = "WEB_INSFOF";
           break;
  case "bo": autfunction = "WEB_INSMAN";
           break;
}

var outputmode = getQParamInt("outputmode", 0);
var direction  = getQParamSafe("dir", "UD"); // Direction in [UD, DU, LR, RL]

var transitParam = buildTransitParam(["urole", "ins_key"]);

FCLTHeader.Requires({ plugins: ["jQuery", "vis-network"] });

var this_ins = ins.func_enabled_deel(ins_key);
user.auth_required_or_abort(this_ins.canReadAny);

%>
<html>
  <head>
<%  FCLTHeader.Generate({ outputmode: outputmode }); %>
    <script>
      function swap_dir() {
        window.location.href = "?dir=<%=(direction === "LR" ? "UD" : "LR")%><%=transitParam%>";
      }
      function goto_ins() {
        window.location.href = "ins_deel.asp?urole=<%=urole%>&ins_key=<%=ins_key%>";
      }
    </script>
  </head>
  <body class="listmode">
<%
PAGE_START();
  var buttons = [{
    icon: (direction === "LR" ? "fa-code-branch fa-flip-vertical" : "fa-code-branch fa-rotate-90"),
    title: (direction === "LR" ? L("lcl_facmgt_vertical") : L("lcl_facmgt_horizontal")),
    action: "swap_dir()"
  }, {
    icon: "fa-arrow-up-right-from-square",
    title: L("lcl_ins_object"),
    action: "goto_ins()"
  }];
  IFRAMER_HEADER(null, buttons);
%>  <div id="diagram"></div>
<%
  var nodes = [];
  var edges = [];

  // Eerst mijzelf maar eens
  var sql = "SELECT sd.ins_srtdeel_key"
          + "     , sd.ins_srtdeel_omschrijving"
          + "     , id.ins_deel_omschrijving"
          + "  FROM ins_v_deelenonderdeel id"
          + "     , ins_srtdeel sd"
          + " WHERE id.ins_srtdeel_key = sd.ins_srtdeel_key"
          + "   AND id.ins_deel_key = " + ins_key;
  var oRs = Oracle.Execute(sql);
  var this_ins_oms = oRs("ins_deel_omschrijving").Value;
  nodes.push({ id: "0" + ins_key, label: oRs("ins_srtdeel_omschrijving").Value + "\n" + this_ins_oms, level: 0 });
  oRs.Close();

  var sql_select = "SELECT origin_key"
                 + "     , to_key"
                 + "     , to_oms"
                 + "     , to_srt_key"
                 + "     , to_srt_oms"
                 + "     , niveau";
  var sql_order = "   ORDER BY niveau, to_srt_key, to_key";
  // De objecten die beginnen bij mij
  var sql_to_select = "  SELECT d_from.ins_deel_key            origin_key"
                    + "       , d_to.ins_deel_key              to_key"
                    + "       , d_to.ins_deel_omschrijving     to_oms"
                    + "       , sd_to.ins_srtdeel_key          to_srt_key"
                    + "       , sd_to.ins_srtdeel_omschrijving to_srt_oms"
                    + "       , LEVEL                        niveau";
  var sql_to_from =   "    FROM ins_v_deelenonderdeel d_from"
                  +   "       , ins_v_deelenonderdeel d_to"
                  +   "       , ins_deelkoppeling dk"
                  +   "       , ins_srtdeel    sd_to";
  var sql_to_where1 = "   WHERE d_to.ins_srtdeel_key = sd_to.ins_srtdeel_key"
                    + "     AND dk.ins_deelkoppeling_van_key = d_from.ins_deel_key"
                    + "     AND dk.ins_deelkoppeling_naar_key = d_to.ins_deel_key"
                    + "     AND (   d_to.ins_deel_vervaldatum IS NULL"
                    + "          OR d_to.ins_deel_vervaldatum > TRUNC (SYSDATE))"
                    + "     AND LEVEL <= " + Math.abs(S("ins_related_diagram_depth_max"));

  // Dit hoort er ook nog bij, maar na de WHERE clause (die discx3d aanvult)
  var sql_to_where2 = "   START WITH dk.ins_deelkoppeling_van_key = " + ins_key
                    + " CONNECT BY PRIOR dk.ins_deelkoppeling_naar_key = dk.ins_deelkoppeling_van_key";

  // De objecten die eindigen bij mij
  var sql_from_select = "  SELECT d_from.ins_deel_key            origin_key"
                      + "       , d_to.ins_deel_key              to_key"
                      + "       , d_to.ins_deel_omschrijving     to_oms"
                      + "       , sd_to.ins_srtdeel_key          to_srt_key"
                      + "       , sd_to.ins_srtdeel_omschrijving to_srt_oms"
                      + "       , -LEVEL                         niveau";
  var sql_from_from =   "    FROM ins_v_deelenonderdeel d_from"
                      + "       , ins_v_deelenonderdeel d_to"
                      + "       , ins_deelkoppeling dk"
                      + "       , ins_srtdeel    sd_to";
  var sql_from_where1 = "   WHERE d_to.ins_srtdeel_key = sd_to.ins_srtdeel_key"
                      + "     AND dk.ins_deelkoppeling_van_key = d_to.ins_deel_key" // Om het makkelijk te maken ..
                      + "     AND dk.ins_deelkoppeling_naar_key = d_from.ins_deel_key"
                      + "     AND (   d_to.ins_deel_vervaldatum IS NULL"
                      + "          OR d_to.ins_deel_vervaldatum > TRUNC (SYSDATE))"
                      + "     AND LEVEL <= " + Math.abs(S("ins_related_diagram_depth_min"));

  // Dit hoort er ook nog bij, maar na de WHERE clause (die discx3d aanvult)
  var sql_from_where2 = "   START WITH dk.ins_deelkoppeling_naar_key = " + ins_key
                      + " CONNECT BY PRIOR dk.ins_deelkoppeling_van_key = dk.ins_deelkoppeling_naar_key";

  // Afdeling gebonden objecten
  var sql_to_A = sql_to_select
               + sql_to_from
               + ", prs_v_afdeling_boom ab"
               + ", prs_bedrijf b"
               + sql_to_where1
               + " AND d_to.ins_alg_ruimte_type = 'A'"
               + " AND d_to.ins_alg_ruimte_key = ab.prs_afdeling_key"
               + " AND ab.prs_bedrijf_key = b.prs_bedrijf_key";
  sql_to_A = discx3d (sql_to_A,
                      "d_to.ins_discipline_key",
                      "",
                      "",
                      "",
                      "",
                      "",
                      "",
                      "b.prs_bedrijf_key",
                      "ab.prs_afdeling_key",
                      autfunction,
                      [],
                      1)
           + sql_to_where2;

  var sql_from_A = sql_from_select
                 + sql_from_from
                 + ", prs_v_afdeling_boom ab"
                 + ", prs_bedrijf b"
                 + sql_from_where1
                 + " AND d_to.ins_alg_ruimte_type = 'A'"
                 + " AND d_to.ins_alg_ruimte_key = ab.prs_afdeling_key"
                 + " AND ab.prs_bedrijf_key = b.prs_bedrijf_key";
  sql_from_A = discx3d (sql_from_A,
                        "d_to.ins_discipline_key",
                        "",
                        "",
                        "",
                        "",
                        "",
                        "",
                        "b.prs_bedrijf_key",
                        "ab.prs_afdeling_key",
                        autfunction,
                        [],
                        1)
             + sql_from_where2;

  // Persoonsgebonden objecten
  var sql_to_P = sql_to_select
               + sql_to_from
               + ", prs_perslid p"
               + ", prs_v_afdeling_boom ab"
               + ", prs_bedrijf b"
               + sql_to_where1
               + " AND d_to.ins_alg_ruimte_type = 'P'"
               + " AND p.prs_afdeling_key = ab.prs_afdeling_key"
               + " AND ab.prs_bedrijf_key = b.prs_bedrijf_key"
               + " AND d_to.ins_alg_ruimte_key = p.prs_perslid_key";
  sql_to_P = discx3d (sql_to_P,
                      "d_to.ins_discipline_key",
                      "",
                      "",
                      "",
                      "",
                      "",
                      "",
                      "b.prs_bedrijf_key",
                      "ab.prs_afdeling_key",
                      autfunction,
                      [],
                      1)
           + sql_to_where2;

  var sql_from_P = sql_from_select
                 + sql_from_from
                 + ", prs_perslid p"
                 + ", prs_v_afdeling_boom ab"
                 + ", prs_bedrijf b"
                 + sql_from_where1
                 + " AND d_to.ins_alg_ruimte_type = 'P'"
                 + " AND p.prs_afdeling_key = ab.prs_afdeling_key"
                 + " AND ab.prs_bedrijf_key = b.prs_bedrijf_key"
                 + " AND d_to.ins_alg_ruimte_key = p.prs_perslid_key";
  sql_from_P = discx3d (sql_from_P,
                        "d_to.ins_discipline_key",
                        "",
                        "",
                        "",
                        "",
                        "",
                        "",
                        "b.prs_bedrijf_key",
                        "ab.prs_afdeling_key",
                        autfunction,
                        [],
                        1)
             + sql_from_where2;

  // Plaatsgebonden objecten ([R]uimte, [T]errein, [W]erkplek)
  var sql_to_ALG = sql_to_select
                 + sql_to_from
                 + ", (SELECT d.alg_regio_key"
                 + "        , d.alg_district_key"
                 + "        , o.alg_locatie_key"
                 + "        , o.alg_gebouw_key"
                 + "        , o.alg_verdieping_key"
                 + "        , o.alg_ruimte_key"
                 + "        , alg_onroerendgoed_keys"
                 + "        , alg_onroerendgoed_type"
                 + "     FROM ins_v_alg_overzicht o"
                 + "        , alg_locatie l"
                 + "        , alg_district d"
                 + "    WHERE l.alg_district_key = d.alg_district_key"
                 + "      AND o.alg_locatie_key = l.alg_locatie_key) onr"
                 + sql_to_where1
                 + " AND d_to.ins_alg_ruimte_type IN ('R', 'T', 'W')"
                 + " AND onr.alg_onroerendgoed_keys = d_to.ins_alg_ruimte_key"
                 + " AND onr.alg_onroerendgoed_type = d_to.ins_alg_ruimte_type";
  sql_to_ALG = discx3d (sql_to_ALG,
                        "d_to.ins_discipline_key",
                        "onr.alg_regio_key",
                        "onr.alg_district_key",
                        "onr.alg_locatie_key",
                        "onr.alg_gebouw_key",
                        "onr.alg_verdieping_key",
                        "onr.alg_ruimte_key",
                        "",
                        "",
                        autfunction,
                        [],
                        0,
                        sql_to_where2); // Eigenlijk de group_by parameter, hier misbruikt als subquery-postfix

  var sql_from_ALG = sql_from_select
                   + sql_from_from
                 + ", (SELECT d.alg_regio_key"
                 + "        , d.alg_district_key"
                 + "        , o.alg_locatie_key"
                 + "        , o.alg_gebouw_key"
                 + "        , o.alg_verdieping_key"
                 + "        , o.alg_ruimte_key"
                 + "        , alg_onroerendgoed_keys"
                 + "        , alg_onroerendgoed_type"
                 + "     FROM ins_v_alg_overzicht o"
                 + "        , alg_locatie l"
                 + "        , alg_district d"
                 + "    WHERE l.alg_district_key = d.alg_district_key"
                 + "      AND o.alg_locatie_key = l.alg_locatie_key) onr"
                 + sql_from_where1
                 + " AND d_to.ins_alg_ruimte_type IN ('R', 'T', 'W')"
                 + " AND onr.alg_onroerendgoed_keys = d_to.ins_alg_ruimte_key"
                 + " AND onr.alg_onroerendgoed_type = d_to.ins_alg_ruimte_type";
  sql_from_ALG = discx3d (sql_from_ALG,
                          "d_to.ins_discipline_key",
                          "onr.alg_regio_key",
                          "onr.alg_district_key",
                          "onr.alg_locatie_key",
                          "onr.alg_gebouw_key",
                          "onr.alg_verdieping_key",
                          "onr.alg_ruimte_key",
                          "",
                          "",
                          autfunction,
                          [],
                          1)
               + sql_from_where2;

  // En nu allemaal !
  var sql = sql_to_A
          + " UNION ALL "
          + sql_from_A
          + " UNION ALL "
          + sql_to_P
          + " UNION ALL "
          + sql_from_P
          + " UNION ALL "
          + sql_to_ALG
          + " UNION ALL "
          + sql_from_ALG
          + sql_order;

  // Unauthorized query; only for debugging purposes
  // sql = "  SELECT d1.ins_deel_key              origin_key,"
  //     + "         d2.ins_deel_key              to_key,"
  //     + "         d2.ins_deel_omschrijving     to_oms,"
  //     + "         sd2.ins_srtdeel_key          to_srt_key,"
  //     + "         sd2.ins_srtdeel_omschrijving to_srt_oms,"
  //     + "         LEVEL                        niveau"
  //     + "    FROM ins_v_deelenonderdeel d1,"
  //     + "         ins_v_deelenonderdeel d2,"
  //     + "         ins_deelkoppeling dk,"
  //     + "         ins_srtdeel    sd1,"
  //     + "         ins_srtdeel    sd2"
  //     + "   WHERE d1.ins_srtdeel_key = sd1.ins_srtdeel_key"
  //     + "     AND d2.ins_srtdeel_key = sd2.ins_srtdeel_key"
  //     + "     AND dk.ins_deelkoppeling_van_key = d1.ins_deel_key"
  //     + "     AND dk.ins_deelkoppeling_naar_key = d2.ins_deel_key"
  //     + "     AND (   d2.ins_deel_vervaldatum IS NULL"
  //     + "          OR d2.ins_deel_vervaldatum > TRUNC (SYSDATE))"
  //     + "     AND LEVEL <= " + Math.abs(S("ins_related_diagram_depth_max"))
  //     + "   START WITH dk.ins_deelkoppeling_van_key = " + ins_key
  //     + " CONNECT BY PRIOR dk.ins_deelkoppeling_naar_key = dk.ins_deelkoppeling_van_key"
  //     + "  UNION"
  //     + "  SELECT d2.ins_deel_key              origin_key,"
  //     + "         d1.ins_deel_key              to_key,"
  //     + "         d1.ins_deel_omschrijving     to_oms,"
  //     + "         sd1.ins_srtdeel_key          to_srt_key,"
  //     + "         sd1.ins_srtdeel_omschrijving to_srt_oms,"
  //     + "         -LEVEL                       niveau"
  //     + "    FROM ins_deel       d1,"
  //     + "         ins_deel       d2,"
  //     + "         ins_deelkoppeling dk,"
  //     + "         ins_srtdeel    sd1,"
  //     + "         ins_srtdeel    sd2"
  //     + "   WHERE d1.ins_srtdeel_key = sd1.ins_srtdeel_key"
  //     + "     AND d2.ins_srtdeel_key = sd2.ins_srtdeel_key"
  //     + "     AND dk.ins_deelkoppeling_van_key = d1.ins_deel_key"
  //     + "     AND dk.ins_deelkoppeling_naar_key = d2.ins_deel_key"
  //     + "     AND (   d1.ins_deel_vervaldatum IS NULL"
  //     + "          OR d1.ins_deel_vervaldatum > TRUNC (SYSDATE))"
  //     + "     AND LEVEL <= " + Math.abs(S("ins_related_diagram_depth_min"))
  //     + "   START WITH dk.ins_deelkoppeling_naar_key = " + ins_key
  //     + " CONNECT BY PRIOR dk.ins_deelkoppeling_van_key = dk.ins_deelkoppeling_naar_key"
  //     + "   ORDER BY niveau, to_srt_key, to_key";

  oRs = Oracle.Execute(sql);

  while (!oRs.eof) {
    nodes.push({
      id: String(2*oRs("niveau").Value) + oRs("to_key").Value,
      label: oRs("to_srt_oms").Value + "\n" + oRs("to_oms").Value,
      oms: oRs("to_oms").Value,
      srt_key: oRs("to_srt_key").Value,
      srt_oms: oRs("to_srt_oms").Value,
      parent: String((oRs("niveau").Value > 0 ? -2 : 2) + 2 * oRs("niveau").Value) + oRs("origin_key").Value,
      level: 2 * oRs("niveau").Value
    });
    oRs.moveNext();
  }
  oRs.Close();

  var groupedNodes = {};
  for (var i in nodes) {
    var key = nodes[i].parent + "-" + nodes[i].srt_key;
    if (!groupedNodes[key]) {
        groupedNodes[key] = [];
    }
    groupedNodes[key].push(nodes[i]);
  }

  var extraNodes = [];
  for (var key in groupedNodes) {
    if (groupedNodes.hasOwnProperty(key)) {
      var group = groupedNodes[key];
      if (group.length > 1) {

        // Creëer een nieuwe extra node
        var extraNode = {
          label: group[0].srt_oms,
          parent: group[0].parent
        };
        extraNode.level = (group[0].level > 0 ? -1 : 1) + group[0].level;
        extraNode.id = String(extraNode.level) + group[0].srt_key;

        extraNodes.push(extraNode);

        // Verbind de oorspronkelijke nodes met de nieuwe extra node
        for (var j = 0; j < group.length; j++) {
          group[j].parent = extraNode.id;
          group[j].label = group[j].oms;
        }
      }
    }
  }

  nodes = extraNodes.concat(nodes);

  for (var i = 0; i < nodes.length; i++) {
    if (nodes[i].parent !== null) {
      edges.push({ from: nodes[i].parent, to: nodes[i].id });
    }
  }
%>
    <script>
        FcltMgr.setTitle("<%=safe.jsstring(this_ins_oms)%>");

        const container = $("#diagram").get(0);
        const nodes = <%=JSON.stringify(nodes)%>;
        const edges = <%=JSON.stringify(edges)%>;
        const networkData = {
            nodes: new vis.DataSet(nodes),
            edges: new vis.DataSet(edges),
        };
        const options = visnetwork.getDefaultOptions("<%=direction%>");
        const network = new vis.Network(container, networkData, options);

        network.on("doubleClick", function (params) {
            if (params?.nodes?.length === 1) {
                var node = null;
                for (var i in nodes) {
                    if (nodes[i].id === params.nodes[0]) {
                        node = nodes[i];
                        break;
                    }
                }
                if (node != null && node.level % 2 === 0) {
                    if (node.id != "<%="0" + ins_key%>") {
                        window.location.href = "ins_deelkoppelingen.asp?urole=<%=urole%>&ins_key=" + String(Math.abs(node.id)).slice(1) + "&dir=<%=direction%>";
                    } else {
                        network.focus("<%="0" + ins_key%>");
                    }
                }
            }
        });
        $(_ => {
            network.selectNodes(["<%="0" + ins_key%>"], false);
        });
    </script>
<%
PAGE_END();
%>
  </body>
</html>
<%
ASPPAGE_END(); %>