1<?php
2
3namespace Mpdf\Barcode;
4
5/**
6 * MSI - Variation of Plessey code, with similar applications
7 * Contains digits (0 to 9) and encodes the data only in the width of bars.
8 */
9class Msi extends \Mpdf\Barcode\AbstractBarcode implements \Mpdf\Barcode\BarcodeInterface
10{
11
12	/**
13	 * @param int $code
14	 * @param bool $checksum
15	 */
16	public function __construct($code, $checksum = false, $quiet_zone_left = null, $quiet_zone_right = null)
17	{
18		$this->init($code, $checksum);
19
20		$this->data['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
21		$this->data['nom-H'] = 10;  // Nominal value for Height of Full bar in mm (non-spec.)
22		$this->data['lightmL'] = ($quiet_zone_left !== null ? $quiet_zone_left : 12); // LEFT light margin =  x X-dim (spec.)
23		$this->data['lightmR'] = ($quiet_zone_right !== null ? $quiet_zone_right : 12); // RIGHT light margin =  x X-dim (spec.)
24		$this->data['lightTB'] = 0; // TOP/BOTTOM light margin =  x X-dim (non-spec.)
25	}
26
27	/**
28	 * @param int $code
29	 * @param bool $checksum
30	 */
31	private function init($code, $checksum)
32	{
33		$chr = [
34			'0' => '100100100100',
35			'1' => '100100100110',
36			'2' => '100100110100',
37			'3' => '100100110110',
38			'4' => '100110100100',
39			'5' => '100110100110',
40			'6' => '100110110100',
41			'7' => '100110110110',
42			'8' => '110100100100',
43			'9' => '110100100110',
44			'A' => '110100110100',
45			'B' => '110100110110',
46			'C' => '110110100100',
47			'D' => '110110100110',
48			'E' => '110110110100',
49			'F' => '110110110110',
50		];
51
52		$checkdigit = '';
53
54		if ($checksum) {
55			// add checksum
56			$clen = strlen($code);
57			$p = 2;
58			$check = 0;
59			for ($i = ($clen - 1); $i >= 0; --$i) {
60				$check += (hexdec($code[$i]) * $p);
61				++$p;
62				if ($p > 7) {
63					$p = 2;
64				}
65			}
66			$check %= 11;
67			if ($check > 0) {
68				$check = 11 - $check;
69			}
70			$code .= $check;
71			$checkdigit = $check;
72		}
73		$seq = '110'; // left guard
74		$clen = strlen($code);
75		for ($i = 0; $i < $clen; ++$i) {
76			$digit = $code[$i];
77			if (!isset($chr[$digit])) {
78				// invalid character
79				throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid character "%s" in MSI barcode value "%s"', $digit, $code));
80			}
81			$seq .= $chr[$digit];
82		}
83		$seq .= '1001'; // right guard
84		$bararray = ['code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => []];
85		$bararray['checkdigit'] = $checkdigit;
86
87		$this->data = $this->binseqToArray($seq, $bararray);
88	}
89
90	/**
91	 * @inheritdoc
92	 */
93	public function getType()
94	{
95		return 'MSI';
96	}
97
98}
99