<?PHP

#
#   Axis--PSTable.php
#   A PHP Object for Adding a Table to a PostScript Document (PSDocument)
#
#   Copyright 1999-2001 Axis Data
#   This code is free software that can be used or redistributed under the
#   terms of Version 2 of the GNU General Public License, as published by the
#   Free Software Foundation (http://www.fsf.org).
#
#   Author:  Edward Almasy (almasy@axisdata.com)
#
#   Part of the AxisPHP library v1.2.4
#   For more information see http://www.axisdata.com/AxisPHP/
#


class PSTable {

    # ---- PUBLIC INTERFACE --------------------------------------------------

    # object constructor
    function PSTable(&$Document)
    {
        # save pointer to document we use for output
        $this->Doc = &$Document;
    }

    # table parameter access functions
    function XOrigin($NewXOrigin = -1) {  if ($NewXOrigin != -1) {  $this->XOrigin = $NewXOrigin;  }  return (int)$this->XOrigin;  }
    function YOrigin($NewYOrigin = -1) {  if ($NewYOrigin != -1) {  $this->YOrigin = $NewYOrigin;  }  return (int)$this->YOrigin;  }
    function XSize($NewXSize = -1) {  if ($NewXSize != -1) {  $this->XSize = $NewXSize;  $this->RecalcActualColumnWidths();  }  return (int)$this->XSize;  }
    function YSize($NewYSize = -1) {  if ($NewYSize != -1) {  $this->YSize = $NewYSize;  $this->RecalcActualRowHeights();  }  return (int)$this->YSize;  }
    function NumCols($NewNumCols = -1) {  if ($NewNumCols != -1) {  $this->NumCols = $NewNumCols;  $this->RecalcActualColumnWidths();  }  return (int)$this->NumCols;  }
    function NumRows($NewNumRows = -1) {  if ($NewNumRows != -1) {  $this->NumRows = $NewNumRows;  $this->RecalcActualRowHeights();  }  return (int)$this->NumRows;  }
    function ShadeColumnHeadings($NewShadeColumnHeadings = -1) {  if ($NewShadeColumnHeadings != -1) {  $this->ShadeColumnHeadings = $NewShadeColumnHeadings;  }  return (int)$this->ShadeColumnHeadings;  }

    # return position of table cell on page
    function CellXPos($Col) {  return $this->XOrigin + $this->ColumnStartPoints[$Col];  }
    function CellYPos($Row) {  return $this->YOrigin - $this->RowStartPoints[$Row];  }

    # set/get column/row width/height
    function ColWidth($Col, $Width = -1) 
    {
        # if column width specified
        if ($Width >= 0)
        {
            # set requested column width
            $this->RequestedColumnWidths[$Col] = $Width;

            # recalculate actual column widths
            $this->RecalcActualColumnWidths();
        }

        # return actual column width to caller
        return (int)$this->ColumnWidths[$Col];
    }
    function RowHeight($Row, $Width = -1) 
    {
        # if row width specified
        if ($Width >= 0)
        {
            # set requested row width
            $this->RequestedRowHeights[$Row] = $Width;

            # recalculate actual row widths
            $this->RecalcActualRowHeights();
        }

        # return actual row width to caller
        return (int)$this->RowHeights[$Row];
    }

    function PrintTextInCell($Row, $Col, $TextToPrint)
    {
        # distance that text is printed from edge of cell
        $CellPadding = 3;

        if ($this->Doc->TextAngle() == 90)
        {
            $this->Doc->PrintTextAt(
                    ($this->CellXPos($Col + 1) - $CellPadding),
                    ($this->CellYPos($Row) - $CellPadding),
                    $TextToPrint);
        }
        else
        {
            $this->Doc->PrintTextAt(
                    ($this->CellXPos($Col) + $CellPadding),
                    ($this->CellYPos($Row) - $CellPadding),
                    $TextToPrint);
        }
    }

    # print table on document
    function PrintTable()
    {
        # write comment on what we're doing
        $this->Doc->PrintRaw(sprintf("
                %% PSTable->Print()  
                %%     XOrigin=%3s   YOrigin=%3s 
                %%     NumCols=%3s   NumRows=%3s
                %%       XSize=%3s     YSize=%3s
                %%    AdjXSize=%3s  AdjYSize=%3s
                ", 
                $this->XOrigin, $this->YOrigin, 
                $this->NumCols, $this->NumRows, 
                $this->XSize,   $this->YSize,
                $this->AdjXSize,$this->AdjYSize));

        # move to start point
        $this->Doc->PrintRaw(sprintf("
                %s %s moveto
                ", (int)$this->XOrigin, (int)$this->YOrigin));

        # start in positive direction (going right on page)
        $DirMult = 1;

        # for each row
        for ($Index = 0;  $Index <= $this->NumRows;  $Index++)
        {
            # draw horizontal line and move to next row
            $this->Doc->PrintRaw(sprintf("
                    %s 0 rlineto
                    0 %s rmoveto
                    ", 
                    ($this->AdjXSize * $DirMult), 
                    (0 - $this->RowHeight($Index + 1))));

            # switch directions
            $DirMult = 0 - $DirMult;
        }

        # move to start point
        $this->Doc->PrintRaw(sprintf("
                %s %s moveto
                ", (int)$this->XOrigin, (int)$this->YOrigin));

        # start in negative direction (going down on page)
        $DirMult = -1;

        # for each column
        for ($Index = 0;  $Index <= $this->NumCols;  $Index++)
        {
            # draw vertical line and move to next column
            $this->Doc->PrintRaw(sprintf("
                    0 %s rlineto
                    %s 0 rmoveto
                    ", 
                    ($this->AdjYSize * $DirMult), 
                    $this->ColWidth($Index + 1)));

            # switch directions
            $DirMult = 0 - $DirMult;
        }

        # shade column heading cells if requested
        if ($this->ShadeColumnHeadings == "TRUE")
        {
            $this->Doc->PrintRaw(sprintf("
                    0.90 setgray
                    %% rectfill: X Y Width Height
                    %d %d %d %d rectfill
                    0.00 setgray
                    ", 
                    $this->XOrigin,  $this->CellYPos(2), 
                    $this->AdjXSize, $this->RowHeight(1)));
        }

        # realize table
        $this->Doc->PrintRaw("
                stroke
                ");
    }


    # ---- PRIVATE INTERFACE -------------------------------------------------

    # recalculate row heights and positions
    function RecalcActualRowHeights()
    {
        # total up requested height values
        $TotalHeight = 0;
        $NumSizedRows = 0;
        for ($Row = 1;  $Row <= $this->NumRows;  $Row++)
        {
            if ($this->RequestedRowHeights[$Row] > 0)
            {
                $TotalHeight += $this->RequestedRowHeights[$Row];
                $NumSizedRows++;
            }
        }

        # calculate size of remaining rows
        if ($this->NumRows == $NumSizedRows)
        {
            $HeightOfRemainingRows = 1;
        }
        else
        {
            $HeightOfRemainingRows = (int)(($this->YSize - $TotalHeight) 
                    / ($this->NumRows - $NumSizedRows));
        }

        # set actual row heights and row begin points
        $CurrentStartPoint = $this->YSize;
        $this->AdjYSize = 0;
        for ($Row = 1;  $Row <= $this->NumRows;  $Row++)
        {
            if ($this->RequestedRowHeights[$Row] > 0)
            {
                $this->RowHeights[$Row] = $this->RequestedRowHeights[$Row];
            }
            else
            {
                $this->RowHeights[$Row] = $HeightOfRemainingRows;
            }

            $CurrentStartPoint -= $this->RowHeights[$Row];
            $this->RowStartPoints[$Row] = $this->AdjYSize;
            $this->AdjYSize += $this->RowHeights[$Row];
        }
    }

    # recalculate column widths and positions
    function RecalcActualColumnWidths()
    {
        # total up requested width values
        $TotalWidth = 0;
        $NumSizedColumns = 0;
        for ($Col = 1;  $Col <= $this->NumCols;  $Col++)
        {
            if ($this->RequestedColumnWidths[$Col] > 0)
            {
                $TotalWidth += $this->RequestedColumnWidths[$Col];
                $NumSizedColumns++;
            }
        }

        # calculate size of remaining columns
        $WidthOfRemainingColumns = (int)(($this->XSize - $TotalWidth) 
                / ($this->NumCols - $NumSizedColumns));

        # set actual column widths and column begin points
        $CurrentStartPoint = 0;
        $this->AdjXSize = 0;
        for ($Col = 1;  $Col <= $this->NumCols;  $Col++)
        {
            if ($this->RequestedColumnWidths[$Col] > 0)
            {
                $this->ColumnWidths[$Col] = $this->RequestedColumnWidths[$Col];
            }
            else
            {
                $this->ColumnWidths[$Col] = $WidthOfRemainingColumns;
            }

            $this->ColumnStartPoints[$Col] = $CurrentStartPoint;
            $CurrentStartPoint += $this->ColumnWidths[$Col];
            $this->AdjXSize += $this->ColumnWidths[$Col];
        }

        # save start point of one column beyond table so we'll have
        #       it available for text positioning
        $this->ColumnStartPoints[$Col] = $CurrentStartPoint;
    }

    # table size in points
    var $XSize = 300;
    var $YSize = 300;

    # table size in points (adjusted to accomodate even row/column sizes)
    var $AdjXSize = 300;
    var $AdjYSize = 300;

    # number of columns and rows
    var $NumCols = 3;
    var $NumRows = 3;

    # requested column and row sizes
    var $RequestedColumnWidths;
    var $RequestedRowHeights;

    # actual column and row sizes
    var $ColumnWidths;
    var $RowHeights;

    # column and row start points
    var $ColumnStartPoints;
    var $RowStartPoints;

    # table origin on page
    var $XOrigin = 100;
    var $YOrigin = 400;

    # document to use for output
    var $Doc;

    # whether to give column headings a grey background
    var $ShadeColumnHeadings = "FALSE";
}


?>
