<?php

/**
 * Calculate CCITT-CRC16 checksum
 */
if (! function_exists('crc16')) {
    function crc16($data)
    {
        $crc = 0x0000;
        for ($i = 0; $i < strlen($data); $i++)
        {
            $x = (($crc >> 8) ^ ord($data[$i])) & 0xFF;
            $x ^= $x >> 4;
            $crc = (($crc << 8) ^ ($x << 12) ^ ($x << 5) ^ $x) & 0xFFFF;
        }
        return $crc;
    }
}

/**
 * Dump out data into a hex dump
 */
if (! function_exists('hex_dump')) {
	function hex_dump($data,$newline="\n",$width=16)
	{
		$result = '';

		$pad = '.'; # padding for non-visible characters
		$to = $from = '';

		for ($i=0; $i<=0xFF; $i++)
		{
			$from .= chr($i);
			$to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
		}

		$hex = str_split(bin2hex($data),$width*2);
		$chars = str_split(strtr($data,$from,$to),$width);

		$offset = 0;
		foreach ($hex as $i => $line)
		{
			$result .= sprintf('%08X: %-48s  [%s]%s',
				$offset,
				substr_replace(implode(' ',str_split($line,2)),' ',8*3,0),
				$chars[$i],
				$newline);

			$offset += $width;
		}

		return $result;
	}
}

/**
 * Split out an FTN address into its parts
 *
 * This function takes a fully qualified FTN address and splits it out into
 * its components:
 * Z:N/F.P@D
 */
if (! function_exists('ftn_address_split')) {
	function ftn_address_split(string $address,$key=NULL)
	{
		if ($key AND ! in_array($key,['z','n','f','p','d']))
		{
			throw new \Exception('Unknown key :'.$key.' for '.$address);
		}

		//$data = "10:12/909";
		//$data = "10:12/909.5";
		//$data = "10:12/909@foo";
		//$data = "10:12/909.5@foo";
		$z = substr($address,0,strpos($address,':'));

		if ($key == 'z')
			return $z;

		$x = strpos($address,':')+1;
		$n = substr($address,$x,strpos($address,'/')-$x);

		if ($key == 'n')
			return $n;

		$x = strpos($address,'/')+1;
		$f = substr($address,$x,
			(strpos($address,'.') ?:
				(strpos($address,'@') ?: strlen($address)))-$x);

		if ($key == 'f')
			return $f;

		$x = strpos($address,'.');
		$p = $x ? substr($address,$x+1,(strpos($address,'@') ?: strlen($address))-$x-1) : 0;

		if ($key == 'p')
			return $p;

		// @todo We dont handle domain yet.
		$x = strpos($address,'@');
		$d = $x ? substr($address,$x+1) : NULL;

		if ($key == 'd')
			return $d;

		return ['z'=>$z,'n'=>$n,'f'=>$f,'p'=>$p,'d'=>$d];
	}
}