<%
/*
    $Revision$
    $Id$

    File:           FGII.inc
    Description:    Common functies voor FGII
    Parameters:
    Context:
    Note:
*/

var MODE_IN = 0;
var MODE_OUT = 1;

// dwfmode afwezig/0=normaal, 1=conceptfolder, 2=vluchtplan mode
function FindDWF(drawing, scenario_key, dwfmode)
{
    // Strip eventuele DWG en DWF van filenaam
    var fname = drawing.replace(/.dwg$/ig,'');
    var fname = fname.replace(/.dwf$/ig,'');
    switch (dwfmode)
    {
        case 1: var fullpath = S("fg_dwf_path_concept");
                break;
        case 2: var fullpath = S("fg_vlucht_path");
                break;
        default: var fullpath = S("fg_dwf_path");
    }
    var fullname = fullpath + fname + ".dwf"

    var fullnameScenario = S("fg_dwf_path_prj") + scenario_key + "\\" + fname + ".dwf";
    __Log("fullnameScenario: " + fullnameScenario);
    var fso = new ActiveXObject("Scripting.FileSystemObject");

    if (scenario_key > 0 && fso.FileExists( fullnameScenario))
    {
        __Log("Gebruik scenario tekening (op webserver): " + fullnameScenario );
        return fullnameScenario;
    }
    if (!fso.FolderExists(fullpath))
    {
        __Log("Unable to find/read folder: " + fullpath + "<BR>Security problem?")
        return "";
    }

    if (fso.FileExists(fullname))
    {
        __Log("Gebruik tekening (op webserver): " + fullname );
        return fullname;
    }

    return "";
}

// Momenteel gebruiken we dezelfde DWF voor plan en voor cont
// Result: dwfPath als gevonden, false/error als niet gevonden
function SetVerdPlanDWF(pvKey, inoutMode, scenario_key, dwfmode, dwfName)
{

    if (dwfmode == 2) // Ontruimingsplan mode
    {
        if ( dwfName)
        {
            var fname = FindDWF("V" + pvKey + "/" + dwfName, scenario_key, dwfmode);
            if (fname)
                return fname;
        }
    }
    // Als voorkeur naam niet gevonden wordt teruggevallen op database naam
    if (inoutMode == MODE_IN)
    {
        var sql = "SELECT cad_tekening_key,"
                + "       cad_tekening_filenaam,"
                + "       cad_tekening_type, cad_tekening_key"
                + "  FROM cad_tekening ct, "
                + "       alg_verdieping av"
                + " WHERE ct.alg_verdieping_key = av.alg_verdieping_key"
                + "   AND cad_tekening_verwijder is null"
                + "   AND cad_tekening_type = 'P'"
                + "   AND ct.alg_verdieping_key = " + pvKey
    }
    else
    {
        var sql = "SELECT cad_tekening_key,"
                + "       cad_tekening_filenaam,"
                + "       cad_tekening_type, cad_tekening_key"
                + "  FROM cad_tekening ct, "
                + "       alg_locatie al"
                + " WHERE ct.alg_locatie_key = al.alg_locatie_key"
                + "   AND cad_tekening_verwijder is null"
                + "   AND cad_tekening_type = 'P'"
                + "   AND ct.alg_verdieping_key is null"
                + "   AND ct.alg_locatie_key  = " + pvKey;
    }

    var oRs = Oracle.Execute(sql);
    if (oRs.eof)
    {
        new SLNKDWF({}).Warning(L("lcl_fg_nodrawing"));
        return false;
    }
    else
    {
        var teknaam = oRs("CAD_TEKENING_FILENAAM").value;

        var fname = FindDWF(teknaam, scenario_key, dwfmode);
        if( fname == "" )
        {
            switch (dwfmode)
            {
                case 1: var fullpath = L("lcl_fg_conceptnotfound");
                        break;
                case 2: var msg = L("lcl_fg_nodrawing"); // niet aangetroffen
                        break;
                default: var msg = L("lcl_fg_drawingnotfound") + "\n" + teknaam;
                         if (user.checkAutorisation("WEB_PRSSYS", true))
                            msg += "\nIn: " + S("fg_dwf_path");
            }
            new SLNKDWF({}).Warning(msg);
            return false;
        }
        else
        {
            return fname;
        }
    }
    oRs.Close();
}

/************************************************************\
* Lever een reguliere expressie met te tonen lagen
* pDiscs_arr is comma-separated lijst met discipline-keys
* Vooraan -1 is contouren, -2 is alt1 en -3 is alt2
\************************************************************/
function myFilterLayer(pDiscs_arr)
{
    var toBeShown = "{SLNK Symbols}|{SLNK Symbol Labels}";
    if (pDiscs_arr.length > 0 && pDiscs_arr.join(",").indexOf("-1") == -1)
    {
        var sql = "SELECT t.ins_disc_params_cadlayers "     // Formaat: {ADMIN\|.*}|{ADMIN!.}
                + "  FROM ins_disc_params t"
                + " WHERE t.ins_discipline_key IN (" + pDiscs_arr.join(",") + ")"
        var oRs = Oracle.Execute(sql);
        while (!oRs.EOF)
        {
            lname = oRs(0).value;
            //toBeShown= "|{" + lname + "\\|.*}"+toBeShown; // laag VEIL|AA65.....
            //toBeShown= "|{" + lname + "!.}"+toBeShown;    // laag VEIL (exact, vooraan)
            toBeShown= toBeShown+"|" + lname;
            oRs.MoveNext();
        }
        oRs.Close();
        toBeShown="{SLNK Labels}|"+toBeShown;
        if (pContmode>=0) // Contouren aan
            toBeShown="{SLNK Contours}|"+toBeShown;
    }
    else if (pContmode>=0) // Geen disciplines dan minstens contouren aan
        toBeShown="{SLNK Labels}|{SLNK Contours}|"+toBeShown;

    __Log("toBeShown layers: " + toBeShown)
    return toBeShown;
}

// buildDobbel: bouw een dobbelsteen voor ‚‚n ruimte
// dobbelProps
//   ruimte: ruimte_key
//   aantal: integer
//   sql   : levert key, symbolname en oms
//     fnProcess: optional functie die symbol en Recordset meekrijgt
//                Geschikt om bijvoorbeeld extra te inkleuren o.i.d.
//     fnLabel: optional functie die van Recordset een label tekst oplevert
// result: array of SLNKSymbol's
function buildDobbel(cHandle, dobbelProps)
{
    var symArray = [];
    var cnt = cHandle.Contour("R:" + dobbelProps.ruimte);
    if (cnt) // Ruimte gevonden in de tekening
    {
        // Markeer center var symbol = cHandle.AddSymbol(cnt.Center.dwgX,cnt.Center.dwgY,"*STAR");

        var dxRoom = cnt.Extents.max.dwgX - cnt.Extents.min.dwgX; // Voor aspect ratio
        var dyRoom = cnt.Extents.max.dwgY - cnt.Extents.min.dwgY;

        var dx=0;
        var dy=0; // Onze dobbelsteen bouwen

        var symbX = S("fg_dobbelDist"); //grootte symbool
        var symbY = S("fg_dobbelDist");
        var wx = Math.min(dobbelProps.aantal, Math.ceil(Math.sqrt(dobbelProps.aantal)/dyRoom*dxRoom)); // Aantal kolommen
        var wy = Math.ceil(dobbelProps.aantal / wx); // Aantal rijen
        wx = Math.ceil(dobbelProps.aantal / wy); // ipv. 3,1 willen we 2,2
        var cX = cnt.Center.dwgX - symbX/2*(wx-1);   // Linksboven beginnen
        var cY = cnt.Center.dwgY + symbY/2*(wy-1);

        // Nu: Alle symbolen binnen onze ene ruimte zonder X en Y
        oRsDobbel = Oracle.Execute(dobbelProps.sql);

    	while (!oRsDobbel.EOF)
    	{
            if (dobbelProps.fnPreProcess)
                dobbelProps.fnPreProcess(oRsDobbel, cHandle, cX+symbX*dx, cY+symbY*dy, S("fg_dobbelScale"), dobbelProps);
    	    var symbolName = DefineSymbol(cHandle, oRsDobbel("symbolName").Value);
            var symbol = cHandle.AddSymbol(cX+symbX*dx, cY+symbY*dy, symbolName);
            symbol.Contour.Key = oRsDobbel("key").Value;
            symArray[symbol.Contour.Key] = {s: symbol, x: cX+symbX*dx, y: cY+symbY*dy}; // Onthouden voor later
            symbol.Scale = S("fg_dobbelScale");
            symbol.Contour.LabelPosition = dobbelProps.labelPosition || 5; // 5 is OUTSIDEBOTTOM

            if (dobbelProps.fnLabel)
                symbol.Contour.Label = dobbelProps.fnLabel(oRsDobbel);
            else
                symbol.Contour.Label = "[c][s30][c000000]"+ safe.nvl(oRs("oms").Value);
            symbol.Contour.SetUrl("", safe.nvl(oRsDobbel("oms").Value));
            //symbol.Contour.SetColor(0xFF0000,64);
            if (dobbelProps.fnProcess) dobbelProps.fnProcess(symbol, oRsDobbel, cHandle, dobbelProps);

            dx++;
            if (dx >= wx)
            {   // Volgende regel
                dy--;
                dx = 0;
            }

          	oRsDobbel.MoveNext();
        }
      	oRsDobbel.Close();
    }
    else
    {
        // Ruimte niet gevonden in de tekening. Wat nu?
    }
    return symArray;
}

// buildSymbols: bouw de symbolen (delen of werkplekken) met XY-coordinaten
// symbolProps
//     sql   : levert key, oms, dwgx, dwgy, rot, scl en symbolname
//     fnLabel: optional functie die van Recordset een label tekst oplevert
//     fnProcess: optional functie die symbol en Recordset meekrijgt
//                Geschikt om bijvoorbeeld extra te inkleuren o.i.d.
// result: array of SLNKSymbol's
function buildSymbols(cHandle, symbolProps)
{
    var symArray = [];
    var oRs = Oracle.Execute(symbolProps.sql);

	while (!oRs.EOF)
    {
        if (symbolProps.fnPreProcess)
            symbolProps.fnPreProcess(oRs, cHandle, oRs("dwgX").value, oRs("dwgY").value, oRs("scl").value, symbolProps)

   	    var symbolName = DefineSymbol(cHandle, oRs("symbolname").Value);
        var symbol = cHandle.AddSymbol(oRs("dwgX").Value, oRs("dwgY").Value,symbolName);
        if (oRs("rot").value != null)
            symbol.rotation = (oRs("rot")+360)%360;
        var scl = 1.0;
        if (oRs("scl").value != null)
            scl = oRs("scl").value;
        symbol.scale = scl;

        symbol.Contour.LabelPosition = symbolProps.labelPosition || 5; // 5 is OUTSIDEBOTTOM

        symbol.Contour.Key = oRs("key").Value;
        symArray[symbol.Contour.Key] = {s: symbol, x: oRs("dwgX").value, y: oRs("dwgy").value}; // Onthouden voor later
        if (symbolProps.fnLabel)
            symbol.Contour.Label = symbolProps.fnLabel(oRs);
        else
            symbol.Contour.Label = "[c][s30][c000000]"+ safe.nvl(oRs("oms").Value);
        symbol.Contour.SetUrl("", safe.nvl(oRs("oms").Value));

        if (symbolProps.fnProcess) symbolProps.fnProcess(symbol, oRs, cHandle, symbolProps)

        // Controleer of hij wel in de goede ruimte is geplaatst
        // Zoniet markeer hem dan met een *STAR er achter
        var rnr = cHandle.FindInContour(oRs("dwgX"), oRs("dwgY"));
        // Let op: Sinds 5.3.2 zit R:12345 in de dwf-contour-key
        if (!rnr || !rnr.match(/^R:/) || rnr.substr(2) != oRs("cadkey").Value)
        {
            var symbol = cHandle.AddSymbol(oRs("dwgX").Value+scl*S("fg_dobbelDist")/2, oRs("dwgY").Value+scl*S("fg_dobbelDist")/2,"*STAR");
            symbol.Scale = scl*0.25;
            symbol.Contour.SetColor(0xFFFF00, 255);
            //symbol.Contour.Hatch = 3;
            symbol.Contour.SetUrl("", "Symbool hoort in ruimte: " + oRs("dblabel").Value);
        }
        oRs.MoveNext();
    }
    oRs.Close();

    return symArray;
}

// labelProps
//      symbols is null voor ruimtes en bevat array van symbolen voor werkplek/objecten
// JGL 09-2012: Volgens mij helemaal niet gebruikt voor ruimtes? Die doen het in myContourProcessor?
//      labelThema: key in CAD_LABEL
//      fnSQL(viewname) levert key en waarde op
function labelThema(cHandle, labelProps)
{
    // Haal de label definitie op
    var sql = "SELECT cad_label_view"
            + "     , cad_label_size"
            + "     , cad_label_visible"
            + "  FROM cad_label"
            + " WHERE cad_label_key = " + labelProps.labelThema_key
    var oRs = Oracle.Execute(sql)
    var viewName = oRs("Cad_Label_View").value;
    var zichtbaar = oRs("cad_label_visible").value;
    var ls = oRs("cad_Label_Size").value;
    var lh = (ls * 100 / S("fg_inLabelSize") ).toFixed(0);
    oRs.Close();
    var labelCleared = [];
    var sql = labelProps.fnSql(viewName);
    var oRs = Oracle.Execute(sql);
    var hasPhotoField = false;
    for (i=0; i<oRs.Fields.Count; i++)
    {
        if (oRs.Fields(i).Name.toUpperCase() == "PHOTO")
            hasPhotoField = true;
    }
	while (!oRs.EOF)
    {
        if (labelProps.symbols)
        {
            var cnt = labelProps.symbols[oRs("Key").Value];
            if (cnt)
            {
                photo_x = cnt.x; // helaas geen cnt.Center.DwgX
                photo_y = cnt.y;
                cnt = cnt.s.Contour;
            }
        }
        else
        {
            var cnt=cHandle.Contour(oRs("alg_ruimte_key").Value);
            photo_x = cnt.Center.DwgX;
            photo_y = cnt.Center.DwgY;
        }
        if (cnt && !zichtbaar && !labelCleared[oRs("Key").Value])
        {
            cnt.Label = "";
            labelCleared[oRs("Key").Value] = true;
        }

        if (cnt && oRs("Waarde").value !== null)
        {
            cnt.fontHeight = ls;
            var w = String(oRs("WAARDE").value);
            if (hasPhotoField && oRs("photo").value)
            {
                var symbolname = oRs("photo").value;
                var module = symbolname.split(":")[0];;
                var key = symbolname.split(":")[1];
                var symbolFile = Server.MapPath("../Pictures/avatar0.jpg");
                var flexparam = flexProps(module, key, null, null, { getFiles: true });
                if (flexparam.files.length)
                {
                    var file = flexparam.files[0];
                    symbolFile = flexparam.AttachPath + file.name;
                }

                var symcnt = cHandle.DefineBitmapSymbol(symbolname, symbolFile, 600);
                var symbol = cHandle.AddSymbol(photo_x, photo_y, symbolname);
                cnt.LabelPosition = 5; // 5 is OUTSIDEBOTTOM
            }
            if (w.substring(0,1)=="[") w = "[" + w;
            cnt.Label += "\n" + w;
        }
        oRs.MoveNext();
    }
    oRs.Close();
}

// kleurProps
//      symbols is null voor ruimtes en bevat array van symbolen voor werkplek/objecten
//      labelThema: key in CAD_THEMA
//      fnSQL(viewname) levert key en waarde op
//      colorSymbol: optional: als true dan wordt het symbool zelf gekleurd ipv de contour
function kleurThema(cHandle, kleurProps)
{   // Haal de schema definitie op
    var sql = "SELECT cad_thema_view, "
            + "       l.cad_legenda_key, "
            + "       l.cad_legenda_discreet, "
            + "       cad_thema_type, "
            + "       cad_thema_onclick_url, "
            +        lcl.xsqla('cad_thema_omschrijving', 'cad_thema_key')
            + " FROM cad_thema T, cad_legenda L "
            + " WHERE T.cad_thema_key=" + kleurProps.kleurThema_key
            + " AND T.cad_legenda_key = L.cad_legenda_key";

    var oRs = Oracle.Execute(sql)
    var viewName = oRs("cad_thema_view").value;
    var schKey = oRs("cad_legenda_key").value;
    var discreet=oRs("cad_legenda_discreet").value;
    var themaName =oRs("cad_thema_omschrijving").value;
    var themaType =oRs("cad_thema_type").value;
    switch (themaType & 0x18)
    {
        case 0x00:
            /*global*/ thema_click_urlR = oRs("cad_thema_onclick_url").Value;
            break;
        case 0x10:
            /*global*/ thema_click_urlI = oRs("cad_thema_onclick_url").Value;
            break;
        case 0x08:
            /*global*/ thema_click_urlW = oRs("cad_thema_onclick_url").Value;
            break;
    }
    oRs.Close();

    var legenda = {}; // Legenda in wording
    // Doorloop alle ruimtes van onze verdieping en zoek de schema-kleur er bij

    if (discreet=='1' ) {
        // themawaarde moet 1-op-1 in de legenda voorkomen (anders geen kleur)
        var sql = kleurProps.fnSql(viewName);
        // themawaarde moet 1-op-1 in de legenda voorkomen (anders geen kleur)
        sql = "SELECT th.key, TI.cad_legendawaarde_rgb, TI.cad_legendawaarde_value,"
            + lcl.xsqla('TI.cad_legendawaarde_omschr', 'TI.cad_legendawaarde_key')
            + "  FROM (" + sql + ") th, cad_legendawaarde TI"
            + " WHERE TI.cad_legendawaarde_value = TH.waarde "
            + "   AND TI.cad_legenda_key = " + schKey
            + " ORDER BY cad_legendawaarde_omschr";

        rs_r = Oracle.Execute(sql);
        while (!rs_r.EOF)
        {
            var kleur = parseInt(rs_r("cad_legendawaarde_rgb").value, 16);
            if (!(rs_r("cad_legendawaarde_value").Value in legenda))
                legenda[rs_r("cad_legendawaarde_value").Value] = { kleur: kleur, count: 0, tekst: rs_r("cad_legendawaarde_omschr").Value };

            var cnt = null;
            if (kleurProps.symbols)
            {
                var cntS = kleurProps.symbols[rs_r("KEY")];
                if (cntS) cnt = cntS.s.Contour;
            }
            else
            {
                var cnt = cHandle.Contour(rs_r("KEY"));
            }
            if (cnt)
            {
                if (kleurProps.colorSymbol)
                    cntS.SetColor(kleur, 255); // Het symbool
                else
                {
                    cnt.SetColor(kleur, S("fg_ThemaAlpha")); // De contour
                    if (kleurProps.symbols) // ook randje meekleuren
                        cnt.SetoutlineColor(kleur, S("fg_ThemaAlpha"));
                        //cnt.SetoutlineColor(0x000000, 255);
                }
                //cntS.SetColor(kleur ^ 0xFFFFFF, 128);
                // URL tekst komt uiteindelijk in de tooltip
                cnt.SetUrl("", rs_r("CAD_LEGENDAWAARDE_OMSCHR"));
            }
            rs_r.MoveNext();
        }
        rs_r.Close();
    } else {
        var sql = kleurProps.fnSql(viewName);
        // we moeten het interval bepalen waarin deze waarde zit
        sql = "SELECT th.key, th.waarde"
            + "  FROM (" + sql + ") th"
            + " ORDER BY fac.safe_to_number(th.waarde)"

        var rs_r = Oracle.Execute(sql);
        var sql2 = "SELECT ti.cad_legendawaarde_rgb"
                 + "     , "+ lcl.xsqla('ti.cad_legendawaarde_omschr', 'ti.cad_legendawaarde_key')
                 + "     ,        fac.safe_to_number(Ti.cad_legendawaarde_value) waarde"
                 + "  FROM cad_legendawaarde ti"
                 + "  WHERE ti.cad_legenda_key = " + schKey
                 + " ORDER BY fac.safe_to_number(ti.cad_legendawaarde_value)";
        var rs_r2 = Oracle.Execute(sql2);
        var prevColor = parseInt(rs_r2("cad_legendawaarde_rgb").value, 16)
        while (!rs_r.EOF)
        {
            // Schuif rs_r2 vooruit om te zien waar onze range eindigt
            while (!rs_r2.EOF && rs_r2("waarde").value <= rs_r("waarde").value)
            {
                prevColor = parseInt(rs_r2("cad_legendawaarde_rgb").value, 16)
                rs_r2.MoveNext();
            }
            // prevColor is nu de laatste kleur die nog kleiner is

            var cnt = null;
            if (kleurProps.symbols)
            {
                var cntS=kleurProps.symbols[rs_r("KEY")];
                if (cntS) cnt = cntS.s.Contour;
            }
            else
                var cnt=cHandle.Contour(rs_r("KEY"));

            // URL tekst komt uiteindelijk in de tooltip (echte waarde, niet de themawaarde)
            if (cnt)
            {
                if (kleurProps.colorSymbol)
                    cntS.SetColor(prevColor, 255); // Het symbool
                else
                {
                    cnt.SetColor(prevColor, S("fg_ThemaAlpha")); // De contour
                    if (kleurProps.symbols) // ook randje meekleuren
                        cnt.SetoutlineColor(prevColor, S("fg_ThemaAlpha"));
                }
                cnt.SetUrl("", rs_r("WAARDE").Value||"");
            }
            rs_r.MoveNext();
        }
        rs_r2.Close();
        rs_r.Close();
    }
}

// FSN#27251: tempfiles opruimen
// Merk op dat het heel goed mogelijk is dat het niet je eigen file is die
// je opruimt. Het kan zelfs van een andere klant zijn. Allemaal niet erg na 24 uur.
var cleanup_regexp = /^rad.....\.tmp$/;
function cleanup_tempfolder ()
{
    var tempFolder = Server.MapPath("../../Temp");
    var fso = new ActiveXObject("Scripting.FileSystemObject");

    var f1 = fso.GetFolder(tempFolder);
    var fc4 = new Enumerator(f1.files);
    var expire = new Date();
    expire.setHours(expire.getHours() - 24); // Na 24 uur weg
    for (; !fc4.atEnd(); fc4.moveNext())
    {
        var vFile = fc4.item();
        var vName = vFile.Name;
        if (vName.match(cleanup_regexp))
        {
            var dt = vFile.DateLastModified;
            if (dt < expire)
            {
                __DoLog("Auto deleting temp file: " + vName + " "  + toDateTimeString(vFile.DateLastModified));
                try { vFile.Delete(); } catch (e) { __DoLog("FAILED", "#f00"); };
            }
            else
                __Log("Skipping: " + vName + " "  + toDateTimeString(vFile.DateLastModified));

        }
    }
}
%>
