<?php

// +-------------------------------------------------+
// | 2002-2011 PMB Services / www.sigb.net pmb@sigb.net et contributeurs (voir www.sigb.net)
// +-------------------------------------------------+
// $Id: c128bobject.php,v 1.4.12.1.2.1 2025/03/27 13:24:17 dbellamy Exp $

/*
 * Barcode Render Class for PHP using the GD graphics library
 * Copyright (C) 2001 Karim Mribti
 *
 * Version 0.0.7a 2001-04-01
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Copy of GNU Lesser General Public License at: http://www.gnu.org/copyleft/lesser.txt
 *
 * Source code home page: http://www.mribti.com/barcode/
 * Contact author at: barcode@mribti.com
 */

/*
 * Render for Code 128-B
 * Code 128-B is a continuous, multilevel and full ASCII code .
 */
class C128BObject extends BarcodeObject
{

    public $mCharSet, $mChars, $mValue;

    public function __construct($Width, $Height, $Style, $Value)
    {
        parent::__construct($Width, $Height, $Style);
        $this->mValue = $Value;
        $this->mChars = " !\"#$%&'()*+´-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{ }~";
        $this->mCharSet = array(
            "212222",   /*   00 */
            "222122",   /*   01 */
            "222221",   /*   02 */
            "121223",   /*   03 */
            "121322",   /*   04 */
            "131222",   /*   05 */
            "122213",   /*   06 */
            "122312",   /*   07 */
            "132212",   /*   08 */
            "221213",   /*   09 */
            "221312",   /*   10 */
            "231212",   /*   11 */
            "112232",   /*   12 */
            "122132",   /*   13 */
            "122231",   /*   14 */
            "113222",   /*   15 */
            "123122",   /*   16 */
            "123221",   /*   17 */
            "223211",   /*   18 */
            "221132",   /*   19 */
            "221231",   /*   20 */
            "213212",   /*   21 */
            "223112",   /*   22 */
            "312131",   /*   23 */
            "311222",   /*   24 */
            "321122",   /*   25 */
            "321221",   /*   26 */
            "312212",   /*   27 */
            "322112",   /*   28 */
            "322211",   /*   29 */
            "212123",   /*   30 */
            "212321",   /*   31 */
            "232121",   /*   32 */
            "111323",   /*   33 */
            "131123",   /*   34 */
            "131321",   /*   35 */
            "112313",   /*   36 */
            "132113",   /*   37 */
            "132311",   /*   38 */
            "211313",   /*   39 */
            "231113",   /*   40 */
            "231311",   /*   41 */
            "112133",   /*   42 */
            "112331",   /*   43 */
            "132131",   /*   44 */
            "113123",   /*   45 */
            "113321",   /*   46 */
            "133121",   /*   47 */
            "313121",   /*   48 */
            "211331",   /*   49 */
            "231131",   /*   50 */
            "213113",   /*   51 */
            "213311",   /*   52 */
            "213131",   /*   53 */
            "311123",   /*   54 */
            "311321",   /*   55 */
            "331121",   /*   56 */
            "312113",   /*   57 */
            "312311",   /*   58 */
            "332111",   /*   59 */
            "314111",   /*   60 */
            "221411",   /*   61 */
            "431111",   /*   62 */
            "111224",   /*   63 */
            "111422",   /*   64 */
            "121124",   /*   65 */
            "121421",   /*   66 */
            "141122",   /*   67 */
            "141221",   /*   68 */
            "112214",   /*   69 */
            "112412",   /*   70 */
            "122114",   /*   71 */
            "122411",   /*   72 */
            "142112",   /*   73 */
            "142211",   /*   74 */
            "241211",   /*   75 */
            "221114",   /*   76 */
            "413111",   /*   77 */
            "241112",   /*   78 */
            "134111",   /*   79 */
            "111242",   /*   80 */
            "121142",   /*   81 */
            "121241",   /*   82 */
            "114212",   /*   83 */
            "124112",   /*   84 */
            "124211",   /*   85 */
            "411212",   /*   86 */
            "421112",   /*   87 */
            "421211",   /*   88 */
            "212141",   /*   89 */
            "214121",   /*   90 */
            "412121",   /*   91 */
            "111143",   /*   92 */
            "111341",   /*   93 */
            "131141",   /*   94 */
            "114113",   /*   95 */
            "114311",   /*   96 */
            "411113",   /*   97 */
            "411311",   /*   98 */
            "113141",   /*   99 */
            "114131",   /*  100 */
            "311141",   /*  101 */
            "411131" /* 102 */
        );
    }

    public function GetCharIndex($char)
    {
        for ($i = 0; $i < 95; $i ++) {
            if (substr($this->mChars, $i, 1) == $char)
                return $i;
        }
        return - 1;
    }

    public function GetBarSize($xres, $char)
    {
        switch ($char) {
            case '1':
                $cVal = BCD_C128_BAR_1;
                break;
            case '2':
                $cVal = BCD_C128_BAR_2;
                break;
            case '3':
                $cVal = BCD_C128_BAR_3;
                break;
            case '4':
                $cVal = BCD_C128_BAR_4;
                break;
            default:
                $cVal = 0;
        }
        return $cVal * $xres;
    }

    public function GetSize($xres)
    {
        $len = strlen($this->mValue);

        if ($len == 0) {
            $this->mError = "Null value";
            return false;
        }
        $ret = 0;
        for ($i = 0; $i < $len; $i ++) {
            if (($id = $this->GetCharIndex($this->mValue[$i])) == - 1) {
                $this->mError = "C128B not include the char '" . $this->mValue[$i] . "'";
                return false;
            } else {
                $cset = $this->mCharSet[$id];
                $ret += $this->GetBarSize($xres, $cset[0]);
                $ret += $this->GetBarSize($xres, $cset[1]);
                $ret += $this->GetBarSize($xres, $cset[2]);
                $ret += $this->GetBarSize($xres, $cset[3]);
                $ret += $this->GetBarSize($xres, $cset[4]);
                $ret += $this->GetBarSize($xres, $cset[5]);
            }
        }
        /* length of Check character */
        $cset = $this->GetCheckCharValue();
        $CheckSize = 0;
        for ($i = 0; $i < 6; $i ++) {
            $CheckSize += $this->GetBarSize($cset[$i], $xres);
        }

        $StartSize = 2 * BCD_C128_BAR_2 * $xres + 3 * BCD_C128_BAR_1 * $xres + BCD_C128_BAR_4 * $xres;
        $StopSize = 2 * BCD_C128_BAR_2 * $xres + 3 * BCD_C128_BAR_1 * $xres + 2 * BCD_C128_BAR_3 * $xres;

        return $StartSize + $ret + $CheckSize + $StopSize;
    }

    public function GetCheckCharValue()
    {
        $len = strlen($this->mValue);
        $sum = 104; // 'B' type;
        for ($i = 0; $i < $len; $i ++) {
            $sum += $this->GetCharIndex($this->mValue[$i]) * ($i + 1);
        }
        $check = $sum % 103;
        return $this->mCharSet[$check];
    }

    public function DrawStart($DrawPos, $yPos, $ySize, $xres)
    { /* Start code is '211214' */
        $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize('2', $xres), $ySize);
        $DrawPos += $this->GetBarSize('2', $xres);
        $DrawPos += $this->GetBarSize('1', $xres);
        $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize('1', $xres), $ySize);
        $DrawPos += $this->GetBarSize('1', $xres);
        $DrawPos += $this->GetBarSize('2', $xres);
        $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize('1', $xres), $ySize);
        $DrawPos += $this->GetBarSize('1', $xres);
        $DrawPos += $this->GetBarSize('4', $xres);
        return $DrawPos;
    }

    public function DrawStop($DrawPos, $yPos, $ySize, $xres)
    { /* Stop code is '2331112' */
        $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize('2', $xres), $ySize);
        $DrawPos += $this->GetBarSize('2', $xres);
        $DrawPos += $this->GetBarSize('3', $xres);
        $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize('3', $xres), $ySize);
        $DrawPos += $this->GetBarSize('3', $xres);
        $DrawPos += $this->GetBarSize('1', $xres);
        $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize('1', $xres), $ySize);
        $DrawPos += $this->GetBarSize('1', $xres);
        $DrawPos += $this->GetBarSize('1', $xres);
        $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize('2', $xres), $ySize);
        $DrawPos += $this->GetBarSize('2', $xres);
        return $DrawPos;
    }

    public function DrawCheckChar($DrawPos, $yPos, $ySize, $xres)
    {
        $cset = $this->GetCheckCharValue();
        $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize($cset[0], $xres), $ySize);
        $DrawPos += $this->GetBarSize($cset[0], $xres);
        $DrawPos += $this->GetBarSize($cset[1], $xres);
        $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize($cset[2], $xres), $ySize);
        $DrawPos += $this->GetBarSize($cset[2], $xres);
        $DrawPos += $this->GetBarSize($cset[3], $xres);
        $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize($cset[4], $xres), $ySize);
        $DrawPos += $this->GetBarSize($cset[4], $xres);
        $DrawPos += $this->GetBarSize($cset[5], $xres);
        return $DrawPos;
    }

    public function DrawObject($xres)
    {
        $len = strlen($this->mValue);
        if (($size = $this->GetSize($xres)) == 0) {
            return false;
        }

        if ($this->mStyle & BCS_ALIGN_CENTER)
            $sPos = (integer) (($this->mWidth - $size) / 2);
        else if ($this->mStyle & BCS_ALIGN_RIGHT)
            $sPos = $this->mWidth - $size;
        else
            $sPos = 0;

        /* Total height of bar code -Bars only- */
        if ($this->mStyle & BCS_DRAW_TEXT)
            $ysize = $this->mHeight - BCD_DEFAULT_MAR_Y1 - BCD_DEFAULT_MAR_Y2 - $this->GetFontHeight($this->mFont);
        else
            $ysize = $this->mHeight - BCD_DEFAULT_MAR_Y1 - BCD_DEFAULT_MAR_Y2;

        /* Draw text */
        if ($this->mStyle & BCS_DRAW_TEXT) {
            if ($this->mStyle & BCS_STRETCH_TEXT) {
                for ($i = 0; $i < $len; $i ++) {
                    $this->DrawChar($this->mFont, $sPos + (2 * BCD_C128_BAR_2 * $xres + 3 * BCD_C128_BAR_1 * $xres + BCD_C128_BAR_4 * $xres) + ($size / $len) * $i, $ysize + BCD_DEFAULT_MAR_Y1 + BCD_DEFAULT_TEXT_OFFSET, $this->mValue[$i]);
                }
            } else { /* Center */
                $text_width = $this->GetFontWidth($this->mFont) * strlen($this->mValue);
                $this->DrawText($this->mFont, $sPos + (($size - $text_width) / 2) + (2 * BCD_C128_BAR_2 * $xres + 3 * BCD_C128_BAR_1 * $xres + BCD_C128_BAR_4 * $xres), $ysize + BCD_DEFAULT_MAR_Y1 + BCD_DEFAULT_TEXT_OFFSET, $this->mValue);
            }
        }

        $cPos = 0;
        $DrawPos = $this->DrawStart($sPos, BCD_DEFAULT_MAR_Y1, $ysize, $xres);
        do {
            $c = $this->GetCharIndex($this->mValue[$cPos]);
            $cset = $this->mCharSet[$c];
            $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize($cset[0], $xres), $ysize);
            $DrawPos += $this->GetBarSize($cset[0], $xres);
            $DrawPos += $this->GetBarSize($cset[1], $xres);
            $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize($cset[2], $xres), $ysize);
            $DrawPos += $this->GetBarSize($cset[2], $xres);
            $DrawPos += $this->GetBarSize($cset[3], $xres);
            $this->DrawSingleBar($DrawPos, BCD_DEFAULT_MAR_Y1, $this->GetBarSize($cset[4], $xres), $ysize);
            $DrawPos += $this->GetBarSize($cset[4], $xres);
            $DrawPos += $this->GetBarSize($cset[5], $xres);
            $cPos ++;
        } while ($cPos < $len);
        $DrawPos = $this->DrawCheckChar($DrawPos, BCD_DEFAULT_MAR_Y1, $ysize, $xres);
        $DrawPos = $this->DrawStop($DrawPos, BCD_DEFAULT_MAR_Y1, $ysize, $xres);
        return true;
    }
}
