<?php

/*
 * #################################################################################################
 * export with TCPDF provider WITH sub totals
 * ################################################################################################
 */

function export_pdf_with_sub_total_TCPDF_provider($results, $pagesize, $oriantation, $top, $bottom, $left, $right, $width, $max_width, $font, $title_font, $limits, $start, $duration, $records_count, $debug)
{
    global $custom_logo, $all_records, $sub_totals_obj, $sub_totals, $records_per_page, $title, $cells, $file_name, $labels, $title, $empty_report_lang, $default_page_size, $fields, $header, $footer, $calculated_columns,$group_by;

    $actual_fields = array_diff($fields, $group_by);

    if (isset($calculated_columns) && is_array($calculated_columns)) {

        foreach ($calculated_columns as $key => $value) {
            $fields[]     = $key;
            $labels[$key] = $key;
            $cells[$key]  = "value";
        }

    }

    // having two dimentional array

    // header('Pragma: public');

    // header('Expires: 0');

    // header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

    // header('Content-Description: File Transfer');

    // header('Content-Type: application/pdf');

    // header("Content-Disposition:attachment;filename=downloaded.pdf");

    // header('Content-Transfer-Encoding: binary');
    // $date = "Date: " . date("Y-m-d H:i:s");

    $pdf = new MYPDF($oriantation, $pagesize, $title, $date);
    // set margins
    $pdf->SetMargins(PDF_MARGIN_LEFT, 40, PDF_MARGIN_RIGHT);
    $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
    $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

    // set auto page breaks
    $pdf->SetAutoPageBreak(true, PDF_MARGIN_BOTTOM);
    $pdf->AddPage();

    $data = array(array());
    $cols = array();
    $pdf->setFontSubsetting(true);
    // set font
    $pdf->SetFont('freeserif', '', 12);

    foreach ($results as $key => $group) {
        // groups title

        $pdf->SetFont('freeserif', 'B', 14);
        $pdf->writeHTML('<div><span style="color: #337AB7; font-weight: bold;margin-bottom:30px">' . $labels[$sub_totals['group_by']] . ': ' . $key.' </span>', true, 0, true, 0, 'L');
        // $pdf->writeHTML('<div><span style="color: #337AB7; font-weight: bold;margin-bottom:30px">' . $labels[$sub_totals['group_by']] . ': ' . render($key, $cells[$sub_totals['group_by']], $sub_totals['group_by'], true, true, true, true) .' </span>', true, 0, true, 0, 'L');
        // $pdf->ln(0.5);

        $pdf->SetFont('freeserif', '', 9);
        $tbl = '
        <style>
            table {
                width: 100%;
            }
            th {
                border: 0px solid #CCCCCC;

                display: inline-block;
                vertical-align:middle;


            }
                td{
                border: 0px solid #CCCCCC;
                display: inline-block;
                vertical-align:middle;

            }
        </style>
        <table cellpadding="2">
        <tr  style="background-color:#ECF0F1;  ">';

        //table header
        foreach ($actual_fields as $v) {

            $tbl .= ' <th align="center">';
            //$tbl .= '<span style="font-weight: bold;  line-height: 2em;  vertical-align: middle;  display: inline-block;">';
            $tbl .= $labels[$v];
            //$tbl .= '</span>';
            $tbl .= '</th>';
        }

        $tbl .= '</tr>';
        $group_size = count($group);

        //table body

        $group = array_map(function ($item) use ($group_by) {

            foreach ($group_by as $key => $g) {
                unset($item[$g]);
            }

            return $item;
        }, $group);

        foreach ($group as $row) {
            foreach ($calculated_columns as $column => $func) {
                $row[$column] = $func($row);
            }

            $tbl .= '<tr>';
            foreach ($row as $k => $v) {
                $tbl .= ' <td align="center" style="vertical-align: bottom;height:20px">';
                $tbl .= render($row[get_field_part($k, $row)], $cells[$k], $k, true, true, true, true);
                $tbl .= '</td>';
            }

            $tbl .= '</tr>';
        }

        // subtotal row
        if (array_keys($results)[count($results) - 1] != $key || $group_size === $sub_totals_obj->get_records_count($key)) {
            $tbl .= '<tr>';
            $col_index = -1;
            foreach ($fields as $f) {
                $col_index++;
                $is_first = ($col_index === 0) ? true : false;
                if ($is_first) {
                    $tbl .= ' <td align="center">';
                    $tbl .= $sub_totals_obj->apply_sub_total_function($key, $f, false, $is_first);
                    $tbl .= '</td>';
                } else {
                    $tbl .= ' <td align="center" style="font-weight:bold;background-color:#E6EEFD;color:#337AB7;">';
                    $tbl .= $sub_totals_obj->apply_sub_total_function($key, $f, false, $is_first);
                    $tbl .= '</td>';
                }

            }

            $tbl .= '</tr>';
        }

        $tbl .= '</table>';
        //table render
        $pdf->writeHTML($tbl, true, false, false, false, '');
    }
    // var_dump($tbl);

    //grand total title
    $pdf->SetFont('freeserif', 'B', 14);
    $pdf->writeHTML('<span style="color: #337AB7; font-weight: bold;">' . $sub_totals_obj->get_title() . '</span>', true, 0, true, 0, 'L');
    $pdf->ln();
    // grand table
    $Grandtbl = ' <style>
    table {
        width: 100%;
    }
    th {
        border: 0px solid #CCCCCC;

        display: inline-block;
        vertical-align:middle;
        align:center;

    }
        td{
        border: 0px solid #CCCCCC;
        display: inline-block;
        vertical-align:middle;
        align:center;

    }
</style>
    <table border="1" cellpadding="2">
    <tr  style="background-color:#ECF0F1;">';

    foreach ($actual_fields as $v) {
        $Grandtbl .= ' <th  align="center">';
        $Grandtbl .= $labels[$v];
        $Grandtbl .= '</th>';
    }

    $Grandtbl .= '
        </tr>';
    $Grandtbl .= '<tr>';
    $column_index = -1;

    foreach ($actual_fields as $f) {
        $column_index++;
        $cell_grand_total = $sub_totals_obj->get_grand_totals($f);

        if ($column_index == 0 && empty($cell_grand_total)) {
            $Grandtbl .= '<td align="center" style="font-size: 10px;color: #fff; background-color: #337AB7; font-weight: bold; text-align:enter; padding: 10px 0; height:30px;">';
            $Grandtbl .= str_replace(" ", " <br/>", $sub_totals_obj->get_title());
            $Grandtbl .= '</td>';
        } else {
            $Grandtbl .= '<td  align="center" style="vertical-align:middle; color:#337AB7; background-color:#E6EEFD; font-weight:bold;  padding:10px; height:30px;">&nbsp;<br/>';
            $Grandtbl .= $cell_grand_total . "<br/>";
            $Grandtbl .= '</td>';
        }

    }

    $Grandtbl .= '</tr>';
    $Grandtbl .= '</table>';
    // render grand table
    $pdf->SetFont('freeserif', '', 9);
    $pdf->writeHTML($Grandtbl, true, false, false, false, '');
    $filename = explode(".php", $_SESSION["active_report_srm7"])[0];

    if (isset($all_records) && !$limits) {
        $pdf->Output("$filename-allpages.pdf");
    } else {
        $pdf->Output("$filename-singlepage.pdf");
    }

}

function save_pdf_with_sub_total_TCPDF_provider($results, $pagesize, $oriantation, $top, $bottom, $left, $right, $width, $max_width, $font, $title_font, $limits, $start, $duration, $records_count, $debug)
{

    $original = ini_get('memory_limit');
    ini_set('memory_limit', '256M');

    global $custom_logo, $all_records, $sub_totals_obj, $sub_totals, $records_per_page, $title, $cells, $file_name, $labels, $title, $empty_report_lang, $default_page_size, $fields, $header, $footer, $calculated_columns,$group_by;

    $actual_fields = array_diff($fields, $group_by);

    if (isset($calculated_columns) && is_array($calculated_columns)) {

        foreach ($calculated_columns as $key => $value) {
            $fields[]     = $key;
            $labels[$key] = $key;
            $cells[$key]  = "value";
        }

    }

    // having two dimentional array

    // header('Pragma: public');

    // header('Expires: 0');

    // header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

    // header('Content-Description: File Transfer');

    // header('Content-Type: application/pdf');

    // header("Content-Disposition:attachment;filename=downloaded.pdf");

    // header('Content-Transfer-Encoding: binary');
    // $date = "Date: " . date("Y-m-d H:i:s");

    $pdf = new MYPDF($oriantation, $pagesize, $title, $date);
    // set margins
    $pdf->SetMargins(PDF_MARGIN_LEFT, 40, PDF_MARGIN_RIGHT);
    $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
    $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

    // set auto page breaks
    $pdf->SetAutoPageBreak(true, PDF_MARGIN_BOTTOM);
    $pdf->AddPage();

    $data = array(array());
    $cols = array();
    $pdf->setFontSubsetting(true);
    // set font
    $pdf->SetFont('freeserif', '', 12);

    foreach ($results as $key => $group) {
        // groups title

        $pdf->SetFont('freeserif', 'B', 14);
        $pdf->writeHTML('<div><span style="color: #337AB7; font-weight: bold;margin-bottom:30px">' . $labels[$sub_totals['group_by']] . ': ' . $key.' </span>', true, 0, true, 0, 'L');
        // $pdf->writeHTML('<div><span style="color: #337AB7; font-weight: bold;margin-bottom:30px">' . $labels[$sub_totals['group_by']] . ': ' . render($key, $cells[$sub_totals['group_by']], $sub_totals['group_by'], true, true, true, true) .' </span>', true, 0, true, 0, 'L');
        // $pdf->ln(0.5);

        $pdf->SetFont('freeserif', '', 9);
        $tbl = '
        <style>
            table {
                width: 100%;
            }
            th {
                border: 0px solid #CCCCCC;

                display: inline-block;
                vertical-align:middle;


            }
                td{
                border: 0px solid #CCCCCC;
                display: inline-block;
                vertical-align:middle;

            }
        </style>
        <table cellpadding="2">
        <tr  style="background-color:#ECF0F1;  ">';

        //table header
        foreach ($actual_fields as $v) {

            $tbl .= ' <th align="center">';
            //$tbl .= '<span style="font-weight: bold;  line-height: 2em;  vertical-align: middle;  display: inline-block;">';
            $tbl .= $labels[$v];
            //$tbl .= '</span>';
            $tbl .= '</th>';
        }

        $tbl .= '</tr>';
        $group_size = count($group);

        //table body

        $group = array_map(function ($item) use ($group_by) {

            foreach ($group_by as $key => $g) {
                unset($item[$g]);
            }

            return $item;
        }, $group);

        foreach ($group as $row) {
            foreach ($calculated_columns as $column => $func) {
                $row[$column] = $func($row);
            }

            $tbl .= '<tr>';
            foreach ($row as $k => $v) {
                $tbl .= ' <td align="center" style="vertical-align: bottom;height:20px">';
                $tbl .= render($row[get_field_part($k, $row)], $cells[$k], $k, true, true, true, true);
                $tbl .= '</td>';
            }

            $tbl .= '</tr>';
        }

        // subtotal row
        if (array_keys($results)[count($results) - 1] != $key || $group_size === $sub_totals_obj->get_records_count($key)) {
            $tbl .= '<tr>';
            $col_index = -1;
            foreach ($fields as $f) {
                $col_index++;
                $is_first = ($col_index === 0) ? true : false;
                if ($is_first) {
                    $tbl .= ' <td align="center">';
                    $tbl .= $sub_totals_obj->apply_sub_total_function($key, $f, false, $is_first);
                    $tbl .= '</td>';
                } else {
                    $tbl .= ' <td align="center" style="font-weight:bold;background-color:#E6EEFD;color:#337AB7;">';
                    $tbl .= $sub_totals_obj->apply_sub_total_function($key, $f, false, $is_first);
                    $tbl .= '</td>';
                }

            }

            $tbl .= '</tr>';
        }

        $tbl .= '</table>';
        //table render
        $pdf->writeHTML($tbl, true, false, false, false, '');
    }
    // var_dump($tbl);

    //grand total title
    $pdf->SetFont('freeserif', 'B', 14);
    $pdf->writeHTML('<span style="color: #337AB7; font-weight: bold;">' . $sub_totals_obj->get_title() . '</span>', true, 0, true, 0, 'L');
    $pdf->ln();
    // grand table
    $Grandtbl = ' <style>
    table {
        width: 100%;
    }
    th {
        border: 0px solid #CCCCCC;

        display: inline-block;
        vertical-align:middle;
        align:center;

    }
        td{
        border: 0px solid #CCCCCC;
        display: inline-block;
        vertical-align:middle;
        align:center;

    }
</style>
    <table border="1" cellpadding="2">
    <tr  style="background-color:#ECF0F1;">';

    foreach ($actual_fields as $v) {
        $Grandtbl .= ' <th  align="center">';
        $Grandtbl .= $labels[$v];
        $Grandtbl .= '</th>';
    }

    $Grandtbl .= '
        </tr>';
    $Grandtbl .= '<tr>';
    $column_index = -1;

    foreach ($actual_fields as $f) {
        $column_index++;
        $cell_grand_total = $sub_totals_obj->get_grand_totals($f);

        if ($column_index == 0 && empty($cell_grand_total)) {
            $Grandtbl .= '<td align="center" style="font-size: 10px;color: #fff; background-color: #337AB7; font-weight: bold; text-align:enter; padding: 10px 0; height:30px;">';
            $Grandtbl .= str_replace(" ", " <br/>", $sub_totals_obj->get_title());
            $Grandtbl .= '</td>';
        } else {
            $Grandtbl .= '<td  align="center" style="vertical-align:middle; color:#337AB7; background-color:#E6EEFD; font-weight:bold;  padding:10px; height:30px;">&nbsp;<br/>';
            $Grandtbl .= $cell_grand_total . "<br/>";
            $Grandtbl .= '</td>';
        }

    }

    $Grandtbl .= '</tr>';
    $Grandtbl .= '</table>';
    // render grand table
    $pdf->SetFont('freeserif', '', 9);
    $pdf->writeHTML($Grandtbl, true, false, false, false, '');

    $filename = str_replace(' ', '', $_SERVER['HTTP_TASK_NAME']);

    $dashboard_connection = new DatabaseHandler(DEFAULT_HOST, DEFAULT_DBUSER, DEFAULT_DBPASS, DEFAULT_DBNAME);
    $reader               = new Reader(tables_prefix . table_settings, $dashboard_connection);
    $attachmentPath       = $reader->filter_by_column('settings_key', 'pdf_attachments')[0]['settings_value'];
    $installation_method  = $reader->filter_by_column('settings_key', 'installation_method')[0]['settings_value'];

    if (strpos($_SERVER["PHP_SELF"], "public") && $installation_method == "composer") {
        $savePath = $_SERVER['DOCUMENT_ROOT'] . explode('public', $_SERVER["PHP_SELF"])[0] . $attachmentPath;
    } else {
        $savePath = explode('modules', __DIR__)[0] . "dashboard/" . $attachmentPath;
    }

    if (!is_dir($savePath)) {
        @mkdir($savePath, 0775, true);
    }

    if (isset($all_records) && !$limits) {
        $pdf->Output($savePath . "/$filename.pdf", 'F');
    } else {
        $pdf->Output($savePath . "/$filename-singlepage.pdf", 'F');
    }

    ini_set('memory_limit', $original);
}

/*
 * #################################################################################################
 * export with TCPDF provider WITHout sub totals
 * ################################################################################################
 */

function export_pdf_TCPDF_provider($results, $pagesize, $oriantation, $top, $bottom, $left, $right, $width, $max_width, $font, $title_font, $limits, $start, $duration, $records_count, $debug)
{
    global $custom_logo, $all_records,
    $sub_totals, $records_per_page, $title,
    $cells, $file_name, $labels, $title,
    $empty_report_lang, $default_page_size,
    $fields, $header, $calculated_columns,
    $footer, $group_by, $labels,
    $table, $sub_totals_obj;

    if (isset($calculated_columns) && is_array($calculated_columns)) {

        foreach ($calculated_columns as $key => $value) {
            $fields[]     = $key;
            $labels[$key] = $key;
            $cells[$key]  = "value";
        }

    }

    // having two dimentional array

    // header('Pragma: public');

    // header('Expires: 0');

    // header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

    // header('Content-Description: File Transfer');

    // header('Content-Type: application/pdf');

    // header("Content-Disposition:attachment;filename=downloaded.pdf");

    // header('Content-Transfer-Encoding: binary');
    // $date = "Date: " . date("Y-m-d H:i:s");

    $pdf = new MYPDF($oriantation, $pagesize, $title, $date);
    // set margins
    $pdf->SetMargins(PDF_MARGIN_LEFT, 40, PDF_MARGIN_RIGHT);
    $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
    $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

    // set auto page breaks
    $pdf->SetAutoPageBreak(true, PDF_MARGIN_BOTTOM);
    $pdf->AddPage();

    $data = array(array());
    $cols = array();
    $pdf->setFontSubsetting(true);
    // set font
    $span = "colspan='" . count($fields) . (+1) . "'";

    $pdf->SetFont('freeserif', '', 9);
    $tbl = '
        <style>
            table {
                width: 100%;
            }
            th {
                border: 0px solid #CCCCCC;

                display: inline-block;
                vertical-align: middle;


            }
                td{
                border: 0px solid #CCCCCC;
                display: inline-block;
                vertical-align: middle;

            }

            .no-border{
                border: 0px solid #FFFFFF;
                display: inline-block;
                vertical-align: middle;
            }

            .no-border-top{
                border-top: 0px solid #FFFFFF;
                display: inline-block;
                vertical-align: middle;
            }

            .border-bottom {
                border-bottom: 0px solid #CCCCCC
            }

        </style>
        <table cellpadding="3">';

    $group_by_source = $group_by;

    $cur_grouped = array();

    $saved_grouped = array();

    $records = 0;

    $state = true;

    $actual_fields_source = array_values(array_diff($fields, $group_by));

    $tbl .= '<tr style="background-color:#ECF0F1;">';

    foreach ($group_by as $key => $val) {

        $cur_group_ar[$val] = render($row[get_field_part($val, $row)], $cells[$val], $val);
    }

    foreach ($group_by_source as $g) {

        $tbl .= '<td align="center"><b>' . $labels[$g] . '</b></td>';
    }

    foreach ($actual_fields_source as $key => $val) {
        $temp   = explode('.', $val);
        $field_ = "";

        if (count($table) == 0) {
            $field_ = $val;
        } elseif (isset($temp[1])) {
            $field_ = $temp[1];
        }

        if (in_array($field_, $group_by)) {
            continue;
        } else {

            $tbl .= '<td align="center"><b>' . $labels[$val] . '</b> </td>';
        }

    }

    $tbl .= '</tr>';

    //table body

    foreach ($results as $row) {

        if ($datasource == "sql") {

        }

        foreach ($calculated_columns as $key => $value) {
            $row[$key] = $value($row);
        }

        if (isset($sub_totals_obj) && strstr($sub_totals["group_by"], ".")) {
            $tmp                = explode(".", $sub_totals["group_by"]);
            $sub_total_group_by = $tmp[1];
        } else {
            $sub_total_group_by = isset($sub_totals["group_by"]) ? $sub_totals["group_by"] : "";
        }

        if (isset($sub_totals_obj) &&
            array_key_exists($sub_total_group_by, $row)) {
            $last_value = $current_value;

            $last_subgroup_in_report = $sub_totals_obj->get_last_sub_group();

            $current_value = isset($row[$sub_total_group_by]) ? $row[$sub_total_group_by] : $row[$sub_total_group_by];
            $sub_total_max = $sub_totals_obj->get_records_count($current_value);

            $sub_total_previous_value_max = $sub_totals_obj->get_records_count($last_value);

            $sub_total_previous_value_max = $sub_totals_obj->get_records_count($last_value);

            if ($current_value != $last_value) {

                //case last value is extended
                if (isset($sub_total_counter) && $sub_total_counter != 0 && $sub_total_counter != $sub_total_previous_value_max - 1) {
                    //extended group case

                    $sub_totals_obj->render_sub_total($actual_fields, $last_value, $layout);

                    if ($current_value === $last_subgroup_in_report) {
                        $tbl .= $sub_totals_obj->draw_grand_total($actual_fields);
                    }

                }

                $sub_total_counter = $sub_totals_obj->get_row_index_in_group($row, $current_value);
            } else {

                $sub_total_counter++;
            }

        }

        foreach ($group_by as $val) {

            $cur_grouped[$val] = $row[get_field_part($val, $row)];
        }

        // checking the variations

        if (count($saved_grouped) != 0) {

            $index = grouping_diff_index($cur_grouped, $saved_grouped);
        } else {

            if ($records == 0) {

                $index = 0; // intialize the structure
            } else {

                $index = -1; // No grouping and the structure is intialized
            }

        }

        $tbl .= '<tr class="mainpage">';

        if ($index == -1) {

            for ($i = 0; $i < count($group_by); $i++) {

                $tbl .= '<td class="mainpage no-border">&nbsp;</td>';
            }

        } else {

            for ($i = 0; $i < $index; $i++) {

                $tbl .= '<td class="mainpage no-border">&nbsp;</td>';
            }

        }

        if ($index != -1) {

            // things that done only when there is variations

            // if($records != 0 )echo"</table></td></tr>";

            if (!empty($group_by)) {

                for ($i = $index; $i < count($group_by); $i++) {

                    if ($i == 0 && $index == 0) {

                        // main grouping

                        $tbl .= '<td class="no-border border-bottom" align="center" >' . render($row[get_field_part($group_by[0], $row)], $cells[$group_by[0]], $group_by[0], true, true, true, true) . "</td>";
                    } else {

                        // sub grouping

                        $tbl .= '<td class="no-border border-bottom" align="center">' . render($row[get_field_part($group_by[$i], $row)], $cells[$group_by[$i]], $group_by[$i], true, true, true, true) . "</td>";
                    }

                }

            }

            // columns and table head

            // echo"<tr><td><table width='100%' cellspacing='0' cellpadding='10'>";
            // that's all the things that done only when there is variation in grouping array
        }

        // things that should be done weather or not there is a variations

        // adding a data row

        // $state = !$state;

        foreach ($fields as $f) {

            if ($row[get_field_part($f, $row)] === "") {
                $row[$f] = "&nbsp";
            }

            if (in_array($f, $group_by)) {

                continue;
            }

            if ($state) {
                $tbl .= '<td align="center" class="AlternateTableCell">' . render($row[get_field_part($f, $row)], $cells[$f], $f, true, true, true, true) . '</td>';
            } else {
                $tbl .= '<td align="center" class="AlternateTableCell">' . render($row[get_field_part($f, $row)], $cells[$f], $f, true, true, true, true) . '</td>';
            }

            $state = !$state;
        }

        /*  $start = isset($_startRecord_index)? $_startRecord_index : 0;
        echo '<td valign="middle" class="TableCell" ><a href="'."Detailed-view.php".'?detail='. urlencode((int)($start +  $records)).'" title="'.$detail_view_lang .'" ><img src="../shared/images/icons/row-print.png" alt="Detail View"></a></td>';
         */

        $tbl .= "</tr>";

        // updating saved array

        foreach ($group_by as $v) {

            $saved_grouped[$v] = $row[get_field_part($v, $row)];
        }

        if (isset($sub_totals_obj) && $sub_total_counter == $sub_total_max - 1) {
            $sub_totals_obj->render_sub_total(array_unique(array_merge($group_by_source, $fields)), $current_value, $layout);
            if ($current_value === $last_subgroup_in_report) {
                $sub_totals_obj->draw_grand_total(array_unique(array_merge($group_by_source, $fields)));
            }

        }

        $records++;
    }

    $tbl .= '</table>';

    //table render
    $pdf->writeHTML($tbl, true, false, false, false, '');

    $filename = explode(".php", $_SESSION["active_report_srm7"])[0];

    if (isset($all_records) && !$limits) {
        $pdf->Output("$filename-allpages.pdf");
    } else {
        $pdf->Output("$filename-singlepage.pdf");
    }

}

function save_pdf_TCPDF_provider($results, $pagesize, $oriantation, $top, $bottom, $left, $right, $width, $max_width, $font, $title_font, $limits, $start, $duration, $records_count, $debug)
{

    $original = ini_get('memory_limit');
    ini_set('memory_limit', '256M');

    global $custom_logo, $all_records,
    $sub_totals, $records_per_page, $title,
    $cells, $file_name, $labels, $title,
    $empty_report_lang, $default_page_size,
    $fields, $header, $calculated_columns,
    $footer, $group_by, $labels,
    $table, $sub_totals_obj;

    if (isset($calculated_columns) && is_array($calculated_columns)) {

        foreach ($calculated_columns as $key => $value) {
            $fields[]     = $key;
            $labels[$key] = $key;
            $cells[$key]  = "value";
        }

    }

    // having two dimentional array

    // header('Pragma: public');

    // header('Expires: 0');

    // header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

    // header('Content-Description: File Transfer');

    // header('Content-Type: application/pdf');

    // header("Content-Disposition:attachment;filename=downloaded.pdf");

    // header('Content-Transfer-Encoding: binary');
    // $date = "Date: " . date("Y-m-d H:i:s");

    $pdf = new MYPDF($oriantation, $pagesize, $title, $date);
    // set margins
    $pdf->SetMargins(PDF_MARGIN_LEFT, 40, PDF_MARGIN_RIGHT);
    $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
    $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

    // set auto page breaks
    $pdf->SetAutoPageBreak(true, PDF_MARGIN_BOTTOM);
    $pdf->AddPage();

    $data = array(array());
    $cols = array();
    $pdf->setFontSubsetting(true);
    // set font
    $span = "colspan='" . count($fields) . (+1) . "'";

    $pdf->SetFont('freeserif', '', 9);
    $tbl = '
        <style>
            table {
                width: 100%;
            }
            th {
                border: 0px solid #CCCCCC;

                display: inline-block;
                vertical-align: middle;


            }
                td{
                border: 0px solid #CCCCCC;
                display: inline-block;
                vertical-align: middle;

            }

            .no-border{
                border: 0px solid #FFFFFF;
                display: inline-block;
                vertical-align: middle;
            }

            .no-border-top{
                border-top: 0px solid #FFFFFF;
                display: inline-block;
                vertical-align: middle;
            }

            .border-bottom {
                border-bottom: 0px solid #CCCCCC
            }

        </style>
        <table cellpadding="3">';

    $group_by_source = $group_by;

    $cur_grouped = array();

    $saved_grouped = array();

    $records = 0;

    $state = true;

    $actual_fields_source = array_values(array_diff($fields, $group_by));

    $tbl .= '<tr style="background-color:#ECF0F1;">';

    foreach ($group_by as $key => $val) {

        $cur_group_ar[$val] = render($row[get_field_part($val, $row)], $cells[$val], $val);
    }

    foreach ($group_by_source as $g) {

        $tbl .= '<td align="center"><b>' . $labels[$g] . '</b></td>';
    }

    foreach ($actual_fields_source as $key => $val) {
        $temp   = explode('.', $val);
        $field_ = "";

        if (count($table) == 0) {
            $field_ = $val;
        } elseif (isset($temp[1])) {
            $field_ = $temp[1];
        }

        if (in_array($field_, $group_by)) {
            continue;
        } else {

            $tbl .= '<td align="center"><b>' . $labels[$val] . '</b> </td>';
        }

    }

    $tbl .= '</tr>';

    //table body

    foreach ($results as $row) {

        if ($datasource == "sql") {

        }

        foreach ($calculated_columns as $key => $value) {
            $row[$key] = $value($row);
        }

        if (isset($sub_totals_obj) && strstr($sub_totals["group_by"], ".")) {
            $tmp                = explode(".", $sub_totals["group_by"]);
            $sub_total_group_by = $tmp[1];
        } else {
            $sub_total_group_by = isset($sub_totals["group_by"]) ? $sub_totals["group_by"] : "";
        }

        if (isset($sub_totals_obj) &&
            array_key_exists($sub_total_group_by, $row)) {
            $last_value = $current_value;

            $last_subgroup_in_report = $sub_totals_obj->get_last_sub_group();

            $current_value = isset($row[$sub_total_group_by]) ? $row[$sub_total_group_by] : $row[$sub_total_group_by];
            $sub_total_max = $sub_totals_obj->get_records_count($current_value);

            $sub_total_previous_value_max = $sub_totals_obj->get_records_count($last_value);

            $sub_total_previous_value_max = $sub_totals_obj->get_records_count($last_value);

            if ($current_value != $last_value) {

                //case last value is extended
                if (isset($sub_total_counter) && $sub_total_counter != 0 && $sub_total_counter != $sub_total_previous_value_max - 1) {
                    //extended group case

                    $sub_totals_obj->render_sub_total($actual_fields, $last_value, $layout);

                    if ($current_value === $last_subgroup_in_report) {
                        $sub_totals_obj->draw_grand_total($actual_fields);
                    }

                }

                $sub_total_counter = $sub_totals_obj->get_row_index_in_group($row, $current_value);
            } else {

                $sub_total_counter++;
            }

        }

        foreach ($group_by as $val) {

            $cur_grouped[$val] = $row[get_field_part($val, $row)];
        }

        // checking the variations

        if (count($saved_grouped) != 0) {

            $index = grouping_diff_index($cur_grouped, $saved_grouped);
        } else {

            if ($records == 0) {

                $index = 0; // intialize the structure
            } else {

                $index = -1; // No grouping and the structure is intialized
            }

        }

        $tbl .= '<tr class="mainpage">';

        if ($index == -1) {

            for ($i = 0; $i < count($group_by); $i++) {

                $tbl .= '<td class="mainpage no-border">&nbsp;</td>';
            }

        } else {

            for ($i = 0; $i < $index; $i++) {

                $tbl .= '<td class="mainpage no-border">&nbsp;</td>';
            }

        }

        if ($index != -1) {

            // things that done only when there is variations

            // if($records != 0 )echo"</table></td></tr>";

            if (!empty($group_by)) {

                for ($i = $index; $i < count($group_by); $i++) {

                    if ($i == 0 && $index == 0) {

                        // main grouping

                        $tbl .= '<td class="no-border border-bottom" align="center" >' . render($row[get_field_part($group_by[0], $row)], $cells[$group_by[0]], $group_by[0], true, true, true, true) . "</td>";
                    } else {

                        // sub grouping

                        $tbl .= '<td class="no-border border-bottom" align="center">' . render($row[get_field_part($group_by[$i], $row)], $cells[$group_by[$i]], $group_by[$i], true, true, true, true) . "</td>";
                    }

                }

            }

            // columns and table head

            // echo"<tr><td><table width='100%' cellspacing='0' cellpadding='10'>";
            // that's all the things that done only when there is variation in grouping array
        }

        // things that should be done weather or not there is a variations

        // adding a data row

        // $state = !$state;

        foreach ($fields as $f) {

            if ($row[get_field_part($f, $row)] === "") {
                $row[$f] = "&nbsp";
            }

            if (in_array($f, $group_by)) {

                continue;
            }

            if ($state) {
                $tbl .= '<td align="center" class="AlternateTableCell">' . render($row[get_field_part($f, $row)], $cells[$f], $f, true, true, true, true) . '</td>';
            } else {
                $tbl .= '<td align="center" class="AlternateTableCell">' . render($row[get_field_part($f, $row)], $cells[$f], $f, true, true, true, true) . '</td>';
            }

            $state = !$state;
        }

        /*  $start = isset($_startRecord_index)? $_startRecord_index : 0;
        echo '<td valign="middle" class="TableCell" ><a href="'."Detailed-view.php".'?detail='. urlencode((int)($start +  $records)).'" title="'.$detail_view_lang .'" ><img src="../shared/images/icons/row-print.png" alt="Detail View"></a></td>';
         */

        $tbl .= "</tr>";

        // updating saved array

        foreach ($group_by as $v) {

            $saved_grouped[$v] = $row[get_field_part($v, $row)];
        }

        if (isset($sub_totals_obj) && $sub_total_counter == $sub_total_max - 1) {
            $sub_totals_obj->render_sub_total(array_unique(array_merge($group_by_source, $fields)), $current_value, $layout);
            if ($current_value === $last_subgroup_in_report) {
                $sub_totals_obj->draw_grand_total(array_unique(array_merge($group_by_source, $fields)));
            }

        }

        $records++;
    }

    $tbl .= '</table>'; //table render
    $pdf->writeHTML($tbl, true, false, false, false, '');

    $filename = str_replace(' ', '', $_SERVER['HTTP_TASK_NAME']);

    $dashboard_connection = new DatabaseHandler(DEFAULT_HOST, DEFAULT_DBUSER, DEFAULT_DBPASS, DEFAULT_DBNAME);
    $reader               = new Reader(tables_prefix . table_settings, $dashboard_connection);
    $attachmentPath       = $reader->filter_by_column('settings_key', 'pdf_attachments')[0]['settings_value'];
    $installation_method  = $reader->filter_by_column('settings_key', 'installation_method')[0]['settings_value'];

    if (strpos($_SERVER["PHP_SELF"], "public") && $installation_method == "composer") {
        $savePath = $_SERVER['DOCUMENT_ROOT'] . explode('public', $_SERVER["PHP_SELF"])[0] . $attachmentPath;
    } else {
        $savePath = explode('modules', __DIR__)[0] . "dashboard/" . $attachmentPath;
    }

    if (!is_dir($savePath)) {
        @mkdir($savePath, 0775, true);
    }

    if (isset($all_records) && !$limits) {
        $pdf->Output($savePath . "/$filename.pdf", 'F');
    } else {
        $pdf->Output($savePath . "/$filename-singlepage.pdf", 'F');
    }

    ini_set('memory_limit', $original);

}

/*
 * #################################################################################################
 * export with TCPDF overrite provider class
 * ################################################################################################
 */

class MYPDF extends TCPDF
{
    public function __construct($orientation, $format, $title, $date)
    {
        $this->title       = $title;
        $this->date        = $date;
        $this->orientation = $orientation;
        parent::__construct($orientation, $unit = 'mm', $format, $unicode = true, $encoding = 'UTF-8', $diskcache = false, $pdfa = false);
    }

    private function getDbReader()
    {

        $dashboard_connection = new DatabaseHandler(DEFAULT_HOST, DEFAULT_DBUSER, DEFAULT_DBPASS, DEFAULT_DBNAME);
        return new Reader(tables_prefix . table_settings, $dashboard_connection);

    }

    private function getLogoPath()
    {
        $systemLogo = $this->getDbReader()->filter_by_column('settings_key', 'system_logo')[0]['settings_value'];

        $path = explode("modules", __DIR__)[0] . "dashboard/public/";

        if (file_exists($path . 'srm_storage/' . $systemLogo)) {
            return $path . 'srm_storage/' . $systemLogo;
        } else {
            return $path . $systemLogo;
        }

    }

    //Page header
    public function Header()
    {
        global $header;

        $this->SetY(15);

        $this->setFontSubsetting(true);
        $this->SetFont('freeserif', 'B', 14);

        $logo = $this->getLogoPath();

        $html = '
    <table border="0" style="width:100%;">
        <tr>
            <td style="text-align:left; width:80%">
                <span style="font-size:16pt">' . $this->title . '</span><br style="margin-bottom:0px;padding-bottom:0px">
                <span style="font-size:12pt">' . date('d M Y h:i A') . '</span>
            </td>
            <td style="text-align:right; width:20%;">
                <img src="' . $logo . '" width="396" height="71" />
            </td>
        </tr>
    </table>
    <br>
';
        $this->writeHTML($html, true, false, true, false, '');

        $this->Line(12, 29, $this->w - 12, 29);
        $this->Line(12, 30, $this->w - 12, 30);
        $this->Ln();

        $this->SetFont('freeserif', '', 12);

        $this->SetY(32);
        // add header text

        $html = '<div style="font-size:12px">' . $header . '</div>';
        $this->writeHTML($html, false, false, true, false, '');

    }

    // Page footer
    public function Footer()
    {
        global $footer;

        $this->SetY(-23);
        $this->setFontSubsetting(true);
        $this->SetFont('freeserif', '', 12);
        $this->writeHTML("<div style='font-weight:bold'>" . $footer . "</div>", true, false, true, false, '');

        // Position at 15 mm from bottom
        $this->SetY(-15);

        if ($this->orientation == "landscape") {
            $this->Line(12, 195, $this->w - 12, 195);
        } else {
            $this->Line(12, 281, $this->w - 12, 281);
        }

        // Page number
        $this->Cell(0, 10, 'Page ' . $this->getAliasNumPage() . '/' . $this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M');
    }

}
