<?php
    global $c;
    global $varPosted;
    global $varRows;

    $strQueryDir = "files/sql";
        
    // $varFiles = is_dir($strQueryDir)? scandir($strQueryDir) : [];
    // $varFiles = array_diff($varFiles, [".", ".."]);

    function removeQueryDir(&$strInput)
    {
        global $strQueryDir;
        $strInput = substr($strInput, strlen($strQueryDir) + 1);
    }

    $strFind    = shell_exec("find {$strQueryDir}/ | grep -Ei \"\.sql$\"");
    $varFiles   = explode("\n", $strFind);
    $varFiles   = array_filter($varFiles);
    
    array_walk($varFiles, "removeQueryDir");

    $strSelection = implode("/", Request::getArgs());
    $strQueryPath = urldecode("{$strQueryDir}/{$strSelection}");
    $strQueryView = null;

    $varInputs      = [[]];
    $varRows        = null;
    $strError       = null;
    $varOptions     = [];

    $intAllowed     = 1; // Default to allowing the user to run the query
    $intSortable    = 1; // By default, make the tables Datatables sortable
    $intSectioned   = 0; // By default, the data is unsectioned

    if ($strSelection !== null && strlen($strSelection) > 0)
    {
        $strSelection       = urldecode($strSelection);
        $strFileDataSource  = file_get_contents("{$strQueryDir}/{$strSelection}");
        $strFileData        = $strFileDataSource;

        // Translate occurrences of {{ Date: next monday }} into yyyy-MM-dd format:
        // Can be used in string literals or default values in comments!
        preg_match_all(
            "/\{\{\s*?Date\:\s*?(.*)\s*?\}\}/i",
            $strFileData,
            $varDateReplacements);

        for ($i = 0; $i < count($varDateReplacements[0]); $i++)
        {
            try
            {
                $strMatch       = $varDateReplacements[0][$i];
                $strMatchSafe   = preg_quote($strMatch);
                $strDateString  = $varDateReplacements[1][$i];
                $strFileData    = preg_replace(
                    "/{$strMatchSafe}/i",
                    date_create($strDateString)->format("Y-m-d"),
                    $strFileData);
            }
            catch (Exception $x) {}
        }

        // WARNING: Can be abused.
        // Translate occurrences of {{ SQL: select 'test' }} into the string value of the first cell of the first row:
        // Can be used in string literals or default values in comments!
        preg_match_all(
            "/\{\{\s*SQL\:\s*(.*)\s+?\}\}/i",
            $strFileData,
            $varSQLReplacements);

        for ($i = 0; $i < count($varSQLReplacements[0]); $i++)
        {
            try
            {
                $strMatch       = $varSQLReplacements[0][$i];
                $strMatchSafe   = preg_quote($strMatch);
                $strSQLString   = $varSQLReplacements[1][$i];
                $varTempRows    = $c->query($strSQLString);

                //Respond::json($varTempRows);

                $strFirstCell = "";
                if (count($varTempRows) > 0)
                    foreach ($varTempRows[0] as $k => $v)
                    {
                        $strFirstCell = $varTempRows[0][$k];
                        break;
                    }

                $strFileData = preg_replace(
                    "/{$strMatchSafe}/i",
                    $strFirstCell,
                    $strFileData);
            }
            catch (Exception $x) {}
        }

        // $_SERVER Key replacements:
        preg_match_all(
            "/\{\{\s*([A-Z_]{1,})\s*\}\}/i",
            $strFileData,
            $varServerKeyReplacements);

        //Respond::json($_SERVER);

        for ($i = 0; $i < count($varServerKeyReplacements[0]); $i++)
        {
            try
            {
                $strMatch       = $varServerKeyReplacements[0][$i];
                $strMatchSafe   = preg_quote($strMatch);
                $strKey         = $varServerKeyReplacements[1][$i];

                if (array_key_exists($strKey, $_SERVER))
                    $strFileData = preg_replace(
                        "/{$strMatchSafe}/i",
                        $_SERVER[$strKey],
                        $strFileData);
            }
            catch (Exception $x) {}
        }

        // Get the inputs:
        preg_match_all(
            "/declare\s+\@([A-Za-z0-9]{1,})\s+(.+)\s+=\s+\?;(\s+-- ([A-Za-z0-9]{1,})\:\s(.*))?/i",
            $strFileData,
            $varInputs);

        // Get the options defined in comments:
        preg_match_all(
            "/--\s+([A-Za-z0-9]{1,})\:\s+(.+)/i",
            $strFileData,
            $varOptionMatches);

        if (count($varOptionMatches[0]) > 0)
        {
            for ($i = 0; $i < count($varOptionMatches[0]); $i++)
            {
                $strKey     = strtolower($varOptionMatches[1][$i]);
                $strValue   = $varOptionMatches[2][$i];
                $varOptions[$strKey] = $strValue;
            }
        }

        if (array_key_exists("nosorting", $varOptions))
            $intSortable = 0;

        if (array_key_exists("allow", $varOptions))
        {
            $intAllowed         = 0;
            $strAllowedObjects  = strtolower($varOptions["allow"]);
            $varAllowedObjects  = explode(",", $strAllowedObjects);
            $varUserObjects     = [];

            if (class_exists("UserAuth"))
            {
                $varUser = UserAuth::getUser();

                if ($varUser !== null)
                {
                    foreach (UserAuth::getUserGroups() as $strGroup)
                        $varUserObjects[] = strtolower($strGroup);

                    $varUserObjects[] = strtolower($varUser["cn"]);
                }
            }

            foreach ($varAllowedObjects as $strObject)
                if (in_array($strObject, $varUserObjects))
                    $intAllowed = 1;
        }

        $varPosted  = Request::getParams();
        $intRun     = 0;
        $intIsPOST  = 0;

        // Merge POST with the GET params:
        // POSTing implies running the query, too.
        foreach (Request::getPosted() as $k => $v)
        {
            $varPosted[$k]  = $v;
            $intRun         = 1;
            $intIsPOST      = 1;
        }

        $intRun     = $varPosted["run"] ?? $intRun;
        $strFormat  = $varPosted["format"] ?? null;

        // Auto-format the output to be JSON when the POSTed Content-Type is JSON:
        if (Request::getHeader("Content-Type") == "application/json")
            $strFormat = "json";

        // Remove these keys from submitted fields:
        foreach (["run", "format"] as $k)
            if (array_key_exists($k, $varPosted))
                unset($varPosted[$k]);

        if ($intRun !== null && $intRun == 1 && $intAllowed == 1)
        {
            try
            {
                $varRows        = $c->query($strQueryPath, $varPosted);
                $strQueryView   = "{$strQueryPath}.php";

                if (count($varRows) > 0)
                {
                    if (array_key_exists("_section", $varRows[0]))
                    {
                        $intSectioned   = 1;
                        $intSortable    = 0;
                    }
                }

                // Allow returning the data as JSON for APIs, maybe:
                if (strtolower($strFormat) == "json")
                    Respond::json($varRows);
            }
            catch (Exception $x)
            {
                $strMessage = $x->getMessage();
                $strError = $strMessage;
                $strError .= "\n\n";

                $strFile = $x->getFile();
                $intLine = $x->getLine();
                
                $strError .= "#-1 {$strFile}({$intLine}): {$strMessage}\n";
                $strError .= $x->getTraceAsString();
            }
        }
    }

    // Fancier title processing:
    $strTitle = "Select Report";

    if ($strSelection !== null && strlen($strSelection) > 0)
        $strTitle = $strSelection;

    if (array_key_exists("title", $varOptions))
        $strTitle = $varOptions["title"];

    // Allow returning a message for POST/form-like inputs:
    $strOutputMessage       = null;
    $strOutputMessageClass  = null;
    $strRedirectURL         = null;

    if ($intIsPOST)
    {
        if ($varRows !== null && count($varRows) == 1)
        {
            $varRow1 = $varRows[0];
            $strOutputMessage       = $varRow1["message"] ?? null;
            $strOutputMessageClass  = $varRow1["message_class"] ?? "";
            $strRedirectURL         = $varRow1["redirect_url"] ?? null;
            $varRows                = null;
        }

        if (array_key_exists("redirecturl", $varOptions))
            $strRedirectURL = $varOptions["redirecturl"];
    }

    // Render the visibility immediately to prevent flicker:
    $strPageInputClass  = "";
    $strPageOutputClass = "d-none";

    if ($varRows !== null && count($varRows) > 0)
    {
        $strPageInputClass  = "d-none";
        $strPageOutputClass = "";
    }
?>

<?php if (array_key_exists("scale", $varOptions)): ?>
    <style>
        #visible-data {
            font-size: <?= $varOptions["scale"]; ?>em;
        }
    </style>
<?php endif; ?>

<title><?= $strTitle; ?></title>

<div class="navbar navbar-expand bg-primary navbar-dark d-print-none">
    <div class="container-fluid justify-content-between">
        <div class="d-inline-flex align-items-center w-100 text-nowrap">
            <a class="nav-item btn btn-outline-light me-2" onclick="fnShowPage('#page-input');"><i class="fa fa-fw fa-cog"></i> <span class="d-none d-lg-inline">Options</span></a>

            <?php if ($varRows !== null && count($varRows) > 0): ?>
                <a class="nav-item btn btn-outline-light me-2" onclick="fnShowPage('#page-output');"><i class="fa fa-fw fa-table"></i> <span class="d-none d-lg-inline">Results</span></a>
                <a class="nav-item btn btn-outline-light me-2" onclick="fnExport();" id="export-csv-button"><i class="fa fa-fw fa-download"></i> <span class="d-none d-lg-inline">.csv</span></a>
                <a class="nav-item btn btn-outline-light me-2" onclick="fnPrint();"><i class="fa fa-fw fa-print"></i> <span class="d-none d-lg-inline">Print</span></a>


                <div class="input-group">
                    <span class="input-group-text bg-primary border-white text-white"><i class="fa fa-fw fa-filter"></i></span>
                    <input type="text" class="form-control bg-primary border-white text-white" placeholder="Filter rows..." value="" id="table-filter-input"></div>
                </div>
            <?php endif; ?>
        </div>


    </div>
</div>

        <div class="navbar navbar-expand bg-secondary-subtle navbar-light d-print-none" id="title-navbar">
            <div class="container-fluid justify-content-between">
                <div class="d-inline-flex align-items-center">
                    <span class="navbar-brand text-wrap"><?= $strTitle; ?></span>
                </div>
            </div>
        </div>

<div class="page <?= $strPageInputClass; ?>" id="page-input">
    <div class="container my-3">

        <?php if ($strError !== null): ?>
            <div class="row">
                <div class="col-md-12">
                    <div class="alert alert-danger">
                        <pre class="mb-0"><?= $strError; ?></pre>
                    </div>
                </div>
            </div>
        <?php endif; ?>

        <?php if ($strRedirectURL !== null): ?>
            <meta http-equiv="refresh" content="5;url=<?= $strRedirectURL; ?>" />
        <?php endif; ?>

        <?php if ($strOutputMessage !== null): ?>

            <div class="row">
                <div class="col-md-12">
                    <div class="<?= $strOutputMessageClass; ?>">
                        <?= $strOutputMessage; ?>
                    </div>
                </div>
            </div>

            <?php $varRows = null; ?>
        <?php else: ?>

            <?php if ($varRows !== null && count($varRows) < 1): ?>
                <div class="row">
                    <div class="col-md-12">
                        <div class="alert alert-warning">
                            No rows returned.
                        </div>
                    </div>
                </div>
            <?php endif; ?>

        <?php endif; ?>

        <div class="row">
            <div class="col-md-6">
                <div class="mb-3" data-report-chooser="1">
                    <label>Choose Query</label>
                    <div class="input-group">
                        <span class="input-group-text"><i class="fa fa-fw fa-folder"></i></span>
                        <input type="text" class="form-control" name="file" placeholder="Search files..." value="<?= $strSelection; ?>" id="file-search-input" />
                    </div>
                    <div class="file-search-results">
                        <?php foreach ($varFiles as $f): ?>
                            <div class="d-none border p-3">
                                <a class="link-underline link-underline-opacity-0" href="/run/<?= $f; ?>">
                                    <i class="fa fa-fw fa-scroll me-2"></i>
                                    <?= $f; ?>
                                </a>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>

                <?php if ($intAllowed == 1): ?>
                    <?php foreach (["description"] as $strClass): ?>
                        <?php if (array_key_exists($strClass, $varOptions)): ?>

                            <div class="mb-3">
                                <?= $varOptions[$strClass]; ?>
                            </div>

                        <?php endif; ?>
                    <?php endforeach; ?>

                    <?php foreach (["danger", "warning", "info"] as $strClass): ?>
                        <?php if (array_key_exists($strClass, $varOptions)): ?>

                            <div class="alert alert-<?= $strClass; ?>">
                                <strong><?= ucfirst($strClass); ?>:</strong> <?= $varOptions[$strClass]; ?>
                            </div>

                        <?php endif; ?>
                    <?php endforeach; ?>

                    <?php
                        $strFormMethod = "get";
                        if (array_key_exists("formmethod", $varOptions))
                            $strFormMethod = $varOptions["formmethod"];
                    ?>

                    <form method="<?= $strFormMethod; ?>">
                        <?php if (count($varInputs[0]) > 0): ?>
                            <?php for ($i = 0; $i < count($varInputs[0]); $i++): ?>
                                <?php
                                    $strInputName = $varInputs[1][$i];
                                    $strInputType = $varInputs[2][$i];

                                    $strInputTypeHTML = "text";

                                    if ($strInputType == "datetime")
                                        $strInputTypeHTML = "date";

                                    $strInputDefaultValue = "";
                                    if (strtolower($varInputs[4][$i]) == "default")
                                        if (strlen($varInputs[5][$i]) > 0)
                                            $strInputDefaultValue = $varInputs[5][$i];

                                    $varInputOptions = [];
                                    if (strtolower($varInputs[4][$i]) == "options")
                                    {
                                        $strOptionsList = $varInputs[5][$i];
                                        $varInputOptions     = explode(",", $strOptionsList);
                                    }
                                ?>

                                <div class="mb-3">
                                    <label><?= $strInputName; ?> <code><?= $strInputType; ?></code></label>

                                    <?php if (count($varInputOptions) > 0): ?>

                                        <div class="input-group">
                                            <span class="input-group-text"><i class="fa fa-fw fa-at"></i></span>

                                            <select class="form-select" name="<?= $strInputName; ?>">
                                                <?php foreach ($varInputOptions as $o): ?>
                                                    <?php
                                                        $strLabel = $o;
                                                        $strValue = $o;

                                                        if (preg_match("/=.+$/i", $o))
                                                        {   
                                                            preg_match("/(.+)=(.+)$/i", $o, $varTempMatches);
                                                            $strLabel = $varTempMatches[1];
                                                            $strValue = $varTempMatches[2];
                                                        }
                                                    ?>

                                                    <option
                                                        value="<?= $strValue; ?>"
                                                        <?= Request::getParam($strInputName) == $strValue? "selected": ""; ?>
                                                        ><?= $strLabel; ?></option>
                                                <?php endforeach; ?>
                                            </select>

                                        </div>
                                    <?php else: ?>
                                        <div class="input-group">
                                            <span class="input-group-text"><i class="fa fa-fw fa-at"></i></span>
                                            <input type="<?= $strInputTypeHTML; ?>" class="form-control" name="<?= $strInputName; ?>" value="<?= Request::getParam($strInputName) ?? $strInputDefaultValue; ?>" />
                                        </div>
                                    <?php endif; ?>
                                </div>
                            <?php endfor; ?>
                        <?php endif; ?>

                        <div class="mb-3">
                            <label>Actions</label>
                            <div>
                                <?php if ($strSelection !== null && strlen($strSelection) > 0): ?>
                                    <?php
                                        $strButtonLabel = $varOptions["buttonlabel"] ?? "Execute";
                                        $strButtonClass = $varOptions["buttonclass"] ?? "btn-primary";
                                        $strButtonIcon  = $varOptions["buttonicon"] ?? "fa-server";
                                    ?>
                                    <a class="btn <?= $strButtonClass; ?> me-1" onclick="fnSubmit(this);"><i class="fa fa-fw <?= $strButtonIcon; ?> me-1"></i> <?= $strButtonLabel; ?></a>
                                <?php endif; ?>

                                <a class="btn btn-outline-secondary me-1" href="<?= Request::getPath(); ?>"><i class="fa fa-fw fa-arrow-rotate-left me-1"></i> Reset</a>
                            </div>
                        </div>

                        <?php if (array_key_exists("related", $varOptions)): ?>

                            <?php
                                $strRelated = $varOptions["related"];
                                $varRelated = explode(",", $strRelated);


                            ?>

                            <div class="mb-3">
                                <label>Related</label>
                                <div>
                                    <?php foreach ($varRelated as $r): ?>
                                        <?php
                                            $strLabel = $r;
                                            $strValue = $r;

                                            if (preg_match("/=.+$/i", $r))
                                            {   
                                                preg_match("/(.+)=(.+)$/i", $r, $varTempMatches);
                                                $strLabel = $varTempMatches[1];
                                                $strValue = $varTempMatches[2];
                                            }
                                        ?>

                                        <?php /*
                                        <a class="btn btn-outline-secondary me-1" href="<?= $strValue; ?>"><i class="fa fa-fw fa-link me-1"></i> <?= $strLabel; ?></a>
                                        */ ?>

                                        <div>
                                            <a class="link-underline link-underline-opacity-0" href="<?= $strValue; ?>"><i class="fa fa-fw fa-link me-1"></i> <?= $strLabel; ?></a>
                                        </div>

                                    <?php endforeach; ?>
                                </div>
                            </div>

                        <?php endif; ?>

                        <input type="hidden" name="run" value="1" />
                    </form>

                <?php else: ?>
                    <div class="text-danger mb-3">
                        The selected report requires being logged in as a user with permission to run it.
                    </div>
                <?php endif; ?>
            </div>

            <?php
                $varDirectories = [];

                foreach ($varFiles as $f)
                {
                    preg_match("/^(.*\/)[^\/]/", $f, $varMatches);
                    $strDirectory = $varMatches[1];

                    if (strlen($strDirectory) > 0)
                        $varDirectories[$strDirectory] = 1;
                }
            ?>
        
            <?php if (count($varDirectories)): ?>
                <div class="col-md-6" data-report-chooser="1">
                    <div class="mb-3">
                        <label>Directories</label>
                        <div class="">

                            <div class="border p-3">
                                <a class="link-underline link-underline-opacity-0" href="/run">
                                    <i class="fa fa-fw fa-home me-2"></i>
                                    Home
                                </a>
                            </div>

                            <?php foreach ($varDirectories as $d => $a): ?>

                                <div class="border p-3">
                                    <a class="link-underline link-underline-opacity-0" href="/run?q=<?= $d; ?>">
                                        <i class="fa fa-fw fa-folder me-2"></i>
                                        <?= $d; ?>
                                    </a>
                                </div>

                            <?php endforeach; ?>
                        </div>
                    </div>
                </div>
            <?php endif; ?>

        </div>


        <?php if ($strSelection !== null && strlen($strSelection) > 0): ?>
            <?php if (array_key_exists("sourcepreview", $varOptions)): ?>
                <style>
                    #source-preview {
                        line-height: 1em;
                        font-family: monospace;
                        min-height: 2in;
                    }
                </style>

                <div class="row">
                    <div class="col-md-12">
                        <div class="mb-3">
                            <label>Source</label>
                            <div class="w-100">
                                <textarea class="w-100 border-0 bg-secondary-subtle p-3" id="source-preview" readonly><?= $strFileDataSource; ?></textarea>
                            </div>
                        </div>
                    </div>
                </div>
            <?php endif; ?>
        <?php endif; ?>

    </div>
</div>

<div class="page <?= $strPageOutputClass; ?>" id="page-output">
    <?php if ($varRows !== null && count($varRows) > 0): ?>

        <?php
            $varRow1    = $varRows[0];
            $varColumns = [];

            foreach ($varRow1 as $k => $v)
                $varColumns[] = $k;

            $strDisplayRowAs = null;
            if (array_key_exists("displayrowas", $varOptions))
                if (preg_match("/^col\-/i", $varOptions["displayrowas"]))
                    $strDisplayRowAs = $varOptions["displayrowas"];
        ?>

        <div class="d-none d-print-block">
            <div class="container-fluid">
                <div class="row">
                    <div class="col-md-12">
                        <h1><?= $strTitle; ?></h1>

                        <?php foreach (["description"] as $strClass): ?>
                            <?php if (array_key_exists($strClass, $varOptions)): ?>
                                <p><?= $varOptions[$strClass]; ?></p>
                            <?php endif; ?>
                        <?php endforeach; ?>

                        <ul>
                            <?php foreach ($varPosted as $k => $v): ?>
                                <li><?= $k; ?>: <?= $v; ?></li>
                            <?php endforeach; ?>
                            <li>Printed: <?= date("Y-m-d H:i:s"); ?></li>
                            <li class="d-none">Filter: <span id="table-filter-text"></span></li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>

        <div id="visible-data">
            <?php if ($strDisplayRowAs !== null): ?>
                <div class="container-fluid">
                    <div class="row my-3">
                        <?php foreach ($varRows as $r): ?>
                            <?php
                                // Allow SQL data to control row classes with _row_class column:
                                $strRowClass = "";
                                if (array_key_exists("_row_class", $r))
                                    $strRowClass = $r["_row_class"];

                                $strNextCellClass = "";
                            ?>

                            <div class="<?= $strDisplayRowAs; ?> filterable">

                                <table class="table table-sm table-striped table-bordered">

                                    <thead>
                                        <tr>
                                            <th class="bg-black text-white"><?= $varColumns[0]; ?></th>
                                            <th class="bg-black text-white"><?= $r[$varColumns[0]]; ?></th>
                                        </tr>
                                    </thead>

                                    <tbody>
                                        

                                        <?php foreach ($varColumns as $col): ?>
                                            <?php
                                                $strCellClass = "";

                                                if (strlen($strRowClass) > 0)
                                                    $strCellClass = $strRowClass;

                                                if (strlen($strNextCellClass) > 0)
                                                    $strCellClass = $strNextCellClass;

                                                // Allow SQL data to controll next cell class with _next_cell_class column:
                                                if (preg_match("/^_next_cell_class/i", $col))
                                                    $strNextCellClass = $r[$col];

                                                // Hide columns that begin with underscore:
                                                if ($col[0] == "_")
                                                    continue;
                                            ?>

                                            <tr>
                                                <td><?= $col; ?></td>
                                                <td class="<?= $strCellClass; ?>"><?= $r[$col]; ?></td>
                                            </tr>

                                            <?php $strNextCellClass = ""; ?>
                                        <?php endforeach; ?>
                                    </tbody>
                                </table>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>

                <script>
                    $(function() {
                        $("#export-csv-button")
                            .first()
                            .addClass("d-none");
                    });
                </script>
            <?php else: ?>

                <div class="table-responsive">
                    <table class="table table-sm table-striped table-bordered w-100" id="table">
                        <thead class="sticky-top">
                            <tr>
                                <?php $intVisibleColumnCount = 0; ?>
                                <?php foreach ($varColumns as $col): ?>
                                    <?php
                                        // Hide columns that begin with underscore:
                                        if ($col[0] == "_")
                                            continue;

                                        $intVisibleColumnCount++;
                                    ?>
                                    <th class="text-nowrap sorting"><?= $col; ?> <?php if ($intSortable) DataTable::sortIcon(); ?></th>
                                <?php endforeach; ?>
                            </tr>
                        </thead>

                        <tbody>
                            <?php
                                $strLastSection     = "";
                                $strSectionClass    = "bg-black fw-bold text-white";

                                if (array_key_exists("sectionclass", $varOptions))
                                    $strSectionClass = $varOptions["sectionclass"];
                            ?>
                            <?php foreach ($varRows as $r): ?>
                                <?php
                                    // Allow SQL data to control row classes with _row_class column:
                                    $strRowClass = "";
                                    if (array_key_exists("_row_class", $r))
                                        $strRowClass = $r["_row_class"];

                                    $strNextCellClass = "";
                                ?>

                                <?php if ($intSectioned && $strLastSection !== $r["_section"]): ?>
                                    <tr>
                                        <td class="<?= $strSectionClass; ?>" colspan="<?= $intVisibleColumnCount; ?>"><?= $r["_section"]; ?></td>
                                    </tr>
                                    <?php
                                        $strLastSection = $r["_section"];
                                    ?>
                                <?php endif; ?>

                                <tr class="filterable">
                                    <?php foreach ($varColumns as $col): ?>
                                        <?php
                                            $strCellClass = "";

                                            if (strlen($strRowClass) > 0)
                                                $strCellClass = $strRowClass;

                                            if (strlen($strNextCellClass) > 0)
                                                $strCellClass = $strNextCellClass;

                                            // Allow SQL data to controll next cell class with _next_cell_class column:
                                            if (preg_match("/^_next_cell_class/i", $col))
                                                $strNextCellClass = $r[$col];

                                            // Hide columns that begin with underscore:
                                            if ($col[0] == "_")
                                                continue;
                                        ?>

                                        <td class="<?= $strCellClass; ?>" data-column-name="<?= $col; ?>"><?= $r[$col]; ?></td>

                                        <?php
                                            $strNextCellClass = "";
                                        ?>
                                    <?php endforeach; ?>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
            <?php endif; ?>
        </div>
    <?php endif; ?>
</div>

<script>
    $(function() {
        var fileSearchInput     = $("#file-search-input").first();
        var tableFilterInput    = $("#table-filter-input").first();

        fileSearchInput.on("focus", function() {
            fileSearchInput.trigger("input");
            fileSearchInput.select();
        });

        fileSearchInput.on("input", function() {
            var q = fileSearchInput.val();

            $(".file-search-results div").each(function(i, x) {
                x = $(x);
                x.addClass("d-none");

                var fileName = x.text();

                if (fileName.includesAll(q))
                    x.removeClass("d-none");
            });
        });

        if (tableFilterInput)
        {
            var filterText = $("#table-filter-text").first();

            tableFilterInput.on("input", function() {
                var q = tableFilterInput.val();

                filterText.html(q);

                filterText
                    .parents("li")
                    .first()
                    .addClass("d-none");

                if (q.length > 0)
                {
                    filterText
                        .parents("li")
                        .first()
                        .removeClass("d-none");
                }

                $(".filterable").each(function(i, x) {
                    x = $(x);
                    x.addClass("d-none");

                    var filterableText = x.text();

                    if (filterableText.includesAll(q))
                        x.removeClass("d-none");
                });
            });
        }

        fnShowPage = function(id)
        {
            $("div.page").addClass("d-none");
            $(id).removeClass("d-none");
        };

        fnSubmit = function(x)
        {
            x = $(x);
            x.parents("form").first().submit();
        };

        fnExport = function()
        {
            fnShowPage("#page-output");
            $("#table").exportCSV({name: "<?= $strSelection; ?>"});
        };

        fnPrint = function()
        {
            var restoreDark = false;
            if ($("body").attr("data-bs-theme") == "dark")
                restoreDark = true;

            $("body").attr("data-bs-theme", "");
            fnShowPage("#page-output");
            window.print();

            if (restoreDark)
                $("body").attr("data-bs-theme", "dark");
        };

        fnGetRowAsQueryString = function()
        {

        };
    });
</script>

<?php if ($varRows !== null && count($varRows) > 0): ?>
    <?php
        // Only allow Datatables for "sortable" rowsets:
        if ($intSortable)
            DataTable::js("#table");
    ?>

    <?php if (array_key_exists("outputonly", $varOptions)): ?>
        <script>
            $(function() {
                $(".navbar").addClass("d-none");
                // $("#title-navbar").removeClass("d-none");
            });
        </script>
    <?php endif; ?>

<?php else: ?>

    <?php if (array_key_exists("autorun", $varOptions) || Request::getParam("autorun") !== null): ?>
        <script>
            $(function() {
                $("#page-input form")
                    .first()
                    .submit();
            });
        </script>
    <?php else: ?>

        <script>
            $(function() {
                var chosen = 0;
                $("input[type='text']").each((i, x) => {
                    if (chosen)
                        return;

                    x = $(x);

                    if (x.val().length < 1)
                    {
                        x.focus();
                        chosen = 1;
                    }
                });
            });
        </script>

    <?php endif; ?>

<?php endif; ?>

<?php
    $strSearchQuery = Request::getParam("q");
?>

<?php if ($strSearchQuery !== null && strlen($strSearchQuery) > 0): ?>
    <script>
        $(function() {
            $("#file-search-input")
                .first()
                .val("<?= $strSearchQuery; ?>")
                .trigger("input");
        });
    </script>
<?php endif; ?>

<?php if (array_key_exists("inputonly", $varOptions)): ?>
    <script>
        $(function() {
            $("[data-report-chooser='1']").addClass("d-none");
        });
    </script>
<?php endif; ?>


<?php
    // Load a custom view if there is one:
    if ($strQueryView !== null)
        if (file_exists($strQueryView))
            require $strQueryView;
?>

<?php if (array_key_exists("autorefresh", $varOptions)): ?>
    <meta http-equiv="refresh" content="<?= $varOptions["autorefresh"]; ?>">
<?php endif; ?>

