<?php

class cf_pdf extends FPDF
{
    public $left = 5;
    public $right = 5;
    public $top = 10;
    public $pagewidth = 210;
    public $reportname;
    public $tabletitle;
    public $description;
    public $max_col_height = 4;
    public $logoImage = './images/logo_outside_new.jpg';
    public $f;

    public function Image($file, $x = null, $y = null, $w = 0, $h = 0, $type = '', $link = '')
    {
        if (!isset($this->images[$file])) {
            //Retrieve only meta-information
            $a = getimagesize($file);
            if ($a === false) {
                $this->Error('Missing or incorrect image file: ' . $file);
            }
            $this->images[$file] = ['w' => $a[0], 'h' => $a[1], 'type' => $a[2], 'i' => count($this->images) + 1];
        }
        parent::Image($file, $x, $y, $w, $h, $type, $link);
    }

    public function _endpage()
    {
        parent::_endpage();
        //Write page to file
        $filter = $this->compress ? '/Filter /FlateDecode ' : '';
        $p = $this->compress ? gzcompress($this->buffer) : $this->buffer;
        $this->_newobj();
        $this->_out('<<' . $filter . '/Length ' . strlen($p) . '>>');
        $this->_putstream($p);
        $this->_out('endobj');
        $this->buffer = '';
    }

    public function _putimages()
    {
        foreach (array_keys($this->images) as $file) {
            $type = $this->images[$file]['type'];
            if ($type == 1) {
                $info = $this->_parsegif($file);
            } elseif ($type == 2) {
                $info = $this->_parsejpg($file);
            } elseif ($type == 3) {
                $info = $this->_parsepng($file);
            } else {
                $this->Error('Unsupported image type: ' . $file);
            }
            $this->_putimage($info);
            $this->images[$file]['n'] = $info['n'];
            unset($info);
        }
    }

    #******************************

    public function __construct($orientation = 'p', $unit = 'mm', $format = 'A4')
    {
        parent::__construct($orientation, $unit, $format);

        if ($format == 'A4' && $unit == 'mm') {
            $this->PDFSetMargins(5, 10, 5);
            $this->pagewidth = 210;
        }
    }

    #******************************

    public function PDFSetMargins($left, $top, $right)
    {
        $this->left = $left;
        $this->right = $right;
        $this->top = $top;
        $this->SetMargins($this->left, $this->top, $this->right);
    }

    #******************************

    public function PDFGetLeftMargin()
    {
        return $this->left;
    }

    #******************************

    public function PDFGetRightMargin()
    {
        return $this->right;
    }

    #******************************

    public function PDFSetReportName($name)
    {
        $this->reportname = $name;
    }

    #******************************

    public function PDFGetPageWidth()
    {
        return $this->pagewidth;
    }

    #******************************

    public function PDFSetTableTitle($name)
    {
        $this->tabletitle = $name;
    }

    #******************************

    public function PDFSetDescription($name)
    {
        $this->description = $name;
    }

    #******************************
    #Page header

    public function setLogoImage($imagePath)
    {
        $this->logoImage = $imagePath;
    }

    public function Header()
    {
        if ($this->PageNo() > 1) {
            return;
        }
        $this->SetFont('Arial', '', 8);
        $logo_path = $this->logoImage;
        $this->Image($logo_path, 5, 2);
        $this->Ln(20);
    }

    #******************************
    # Page footer

    public function Footer()
    {
        # Position at 1.5 cm from bottom
        $this->SetY(-15);
        $this->SetFont('Arial', 'I', 8);
        $this->Cell(0, 10, 'Page ' . $this->PageNo(), 0, 0, 'C');

        $this->SetY(-10);
        $this->SetFont('Arial', '', 6);
        $this->Cell(
            0,
            10,
            'Run: ' . date('m.d.y H:i:s', time()) . ' - Powered by CFEngine - ' . $this->reportname,
            0,
            0,
            'C',
        );
    }

    #******************************
    # Title

    public function ReportTitle()
    {
        $this->SetFont('Arial', '', 18);
        $this->SetTextColor(0, 0, 0);
        // $this->SetFillColor(158, 152, 120);
        $this->SetFont('Arial', 'B', 18);
        $this->Cell(40, 10, ucfirst($this->reportname));
        $this->Ln(10);
        $this->SetTextColor(76, 76, 76);
    }

    #******************************
    # Description

    public function ReportDescription()
    {
        $this->SetFont('Arial', '', 10);
        $width = $this->pagewidth - $this->left - $this->right;
        $this->MultiCell($width, 5, $this->description);
        $this->Ln(4);
    }

    #******************************
    # Table Title

    public function RptTableTitle($text, $y) {}

    #******************************
    # Check for page break

    public function CheckPageBreak($h)
    {
        #If the height h would cause an overflow, add a new page immediately
        if ($this->GetY() + $h > $this->PageBreakTrigger) {
            $this->AddPage($this->CurOrientation);
        }
    }

    #******************************
    # Compute the number of lines

    public function NbLines($w, $txt)
    {
        # Computes the number of lines a MultiCell of width w will take
        $cw = &$this->CurrentFont['cw'];
        if ($w == 0) {
            $w = $this->w - $this->rMargin - $this->x;
        }
        $wmax = (($w - 2 * $this->cMargin) * 1000) / $this->FontSize;
        $s = str_replace("\r", '', $txt);
        $nb = strlen($s);
        if ($nb > 0 and $s[$nb - 1] == "\n") {
            $nb--;
        }
        $sep = -1;
        $i = 0;
        $j = 0;
        $l = 0;
        $nl = 1;
        while ($i < $nb) {
            $c = $s[$i];
            if ($c == "\n") {
                $i++;
                $sep = -1;
                $j = $i;
                $l = 0;
                $nl++;
                continue;
            }
            if ($c == ' ') {
                $sep = $i;
            }
            $l += $cw[$c];
            if ($l > $wmax) {
                if ($sep == -1) {
                    if ($i == $j) {
                        $i++;
                    }
                } else {
                    $i = $sep + 1;
                }
                $sep = -1;
                $j = $i;
                $l = 0;
                $nl++;
            } else {
                $i++;
            }
        }
        return $nl;
    }

    #******************************
    # draw table header

    public function DrawTableHeader($header, $count, $w)
    {
        $font_size = 6;
        $this->SetDrawColor(125, 125, 125);
        $this->SetFillColor(225, 225, 225);
        $this->SetXY($this->left, $this->GetY());
        $this->SetFont('Arial', 'B', $font_size);
        $align = 'L';
        $nb = 0;
        for ($i = 0; $i < count($header); $i++) {
            $nb = max($nb, $this->NbLines($w[$i], $header[$i]));
        }

        $headerHeight = $nb * $font_size;
        if ($nb > 2) {
            $headerHeight = $headerHeight - 10;
        }

        for ($i = 0; $i < $count; $i++) {
            if (!isset($header[$i + 1]) && $i < $count - 1) {
                $width = (100 * ($this->pagewidth - $this->left - $this->right)) / 100;
            } else {
                $width = ($w[$i] * ($this->pagewidth - $this->left - $this->right)) / 100;
            }
            if (isset($header[$i])) {
                //$this->Cell($width, $headerHeight, $header[$i], 1, 0, $align, 1, false);
                $x = $this->GetX();
                $y = $this->GetY();
                //Draw the border
                $this->Rect($x, $y, $width, $headerHeight);
                $this->MultiCell($width, 6, $header[$i], 0, $align);
                $this->SetXY($x + $width, $y);
            }
        }
        $this->Ln($headerHeight);
    }

    #******************************
    # section

    public function DrawTableRow($data, $widths = [])
    {
        //Calculate the height of the row
        $nb = 0;
        for ($i = 0; $i < count($data); $i++) {
            $nb = max($nb, $this->NbLines($widths[$i], $data[$i]));
        }
        $h = 5 * $nb;
        //Issue a page break first if needed
        $this->CheckPageBreak($h);
        //Draw the cells of the row
        for ($i = 0; $i < count($data); $i++) {
            $w = $widths[$i];
            $a = isset($this->aligns[$i]) ? $this->aligns[$i] : 'L';
            //Save the current position
            $x = $this->GetX();
            $y = $this->GetY();
            //Draw the border
            $this->Rect($x, $y, $w, $h);
            //Print the text
            $this->MultiCell($w, 5, $data[$i], 0, $a);
            //Put the position to the right of the cell
            $this->SetXY($x + $w, $y);
        }
        //Go to the next line
        $this->Ln($h);
    }

    public function drawTableRowCustomized($rowdata, $cols, $col_len, $header)
    {
        $font_size = 6;
        $this->SetDrawColor(125, 125, 125);
        $this->SetFont('Arial', '', $font_size);
        $align = 1;

        $multi_col = [];
        $nb = 0;
        for ($j = 0; $j < $cols; $j++) {
            $cell = $rowdata;

            $width = ($col_len[$j] * ($this->pagewidth - $this->left - $this->right)) / 100;
            $tmpNumberOfLines = $this->NbLines($width, $cell[$j]);

            if ($tmpNumberOfLines > 1 && $tmpNumberOfLines > $nb) {
                $multi_col[$j] = true;
            } else {
                $multi_col[$j] = false;
            }

            if ($tmpNumberOfLines > $nb) {
                $nb = $tmpNumberOfLines;
            }
        }

        # total y
        $hx = $nb * $font_size;

        #  check for page break
        $startx = $this->left;
        $starty = $this->GetY();
        $rowmaxy = $starty + $hx;
        $newpage = false;
        for ($j = 0; $j < $cols; $j++) {
            if ($j == 0 && $this->GetY() + $hx > $this->PageBreakTrigger) {
                $this->AddPage();
                $this->Ln(5);
                $startx = $this->left;

                $newpage = true;
                $this->DrawTableHeader($header, $cols, $col_len);
                $starty = $this->GetY();
                $rowmaxy = $starty + $hx;
                $this->SetDrawColor(125, 125, 125);
                $this->SetFont('Arial', '', $font_size);
            }

            $this->SetXY($startx, $starty);
            $width = ($col_len[$j] * ($this->pagewidth - $this->left - $this->right)) / 100;
            $this->Rect($startx, $starty, $width, $hx);
            if ($multi_col[$j] == true) {
                $this->MultiCell($width, $font_size, $cell[$j], 0, $align, 0);

                $rowmaxy = $this->GetY();
            } else {
                $this->MultiCell($width, $font_size, $cell[$j], 0, $align, 0);
            }

            $startx += $width;
        }

        $this->SetY($rowmaxy);
    }

    public function DrawTable($ar1, $cols, $col_len, $header, $header_font)
    {
        # $this->CustomHeader();
        $this->SetFont('Arial', '', $header_font);
        $this->DrawTableHeader($header, $cols, $col_len);
        foreach ($ar1 as $data) {
            $this->drawTableRowCustomized($data, $cols, $col_len, $header);
        }
    }

    public function drawMultiTable($maindata, $col_len)
    {
        foreach ($maindata as $topic => $subtopics) {
            if ($topic == 'meta') {
                continue;
            }

            $font_size = 8;
            $align = 1;
            $this->SetFont('Arial', '', $font_size);
            $this->SetDrawColor(125, 125, 125);
            $this->SetFillColor(239, 240, 234);

            $this->Cell(null, 12, $topic, 1, 0, 'L', true);
            $this->Ln(12);
            $columnLabels = array_keys($subtopics['header']);
            $data = $subtopics['data'];
            $cols = count($columnLabels);
            $this->DrawTableHeader($columnLabels, $cols, $col_len);

            foreach ($data as $dataRow) {
                $this->drawTableRowCustomized($dataRow, $cols, $col_len, $columnLabels);
            }
        }
    }
}
