<?php

namespace App\Media\MSVideo\Containers;

/*
 * https://netghost.narod.ru/gff/graphics/summary/micriff.htm
 *
 * Indicate the format of the data stream(s) stored in the file
 */

use Illuminate\Support\Collection;

use App\Media\MSVideo\Container;
use App\Media\MSVideo\Containers\rlist\movi;

class rlist extends Container
{
	private const container_classes = 'App\\Media\\MSVideo\\Containers\\rlist\\';

	public function __construct(int $offset,int $size,string $filename,bool $be,?string $data)
	{
		parent::__construct($offset,$size,$filename,$be,$data);

		$this->containers = $this->parseContainer($data);

		// For debugging
		if (FALSE)
			$this->debug = hex_dump($data ?: $this->data(min($size,256)));
	}

	private function parseContainer(string $bytes=NULL): Collection
	{
		$this->be = FALSE;	// @todo

		$rp = 0;
		if (! $bytes) {
			$fh = fopen($this->filename,'r');
			fseek($fh,$this->offset);
		}

		$result = collect();

		// Our first container should be hrl
		$read = $bytes ? substr($bytes,$rp,4) : fread($fh,4);
		$rp += 4;
		$header = unpack('a4name',$read);

		switch ($header['name']) {
			case 'hdrl':
			case 'strl':
			case 'INFO':
				while ($rp < $this->size) {
					$read = $bytes ? substr($bytes,$rp,8) : fread($fh,8);
					$rp += 8;

					$header = unpack('a4name/Vsize',$read);

					// We cant have a php function named 'list', so we change it to rlist
					if ($header['name'] === 'LIST')
						$header['name'] = 'RLIST';

					$class = self::container_classes.strtolower($header['name']);

					$data = $bytes
						? substr($bytes,$rp,$header['size'])
						: ($header['size'] && ($header['size'] <= self::record_size) ? fread($fh,$header['size']) : NULL);

					if ($header['size']) {
						$o = class_exists($class)
							? new $class($this->offset+$rp,$header['size'],$this->filename,$this->be,$data)
							: new Unknown($this->offset+$rp,$header['size'],$this->filename,$header['name'],$this->be,$data);

						$result->push($o);

						$rp += $header['size'];

						// Only need to seek if we didnt read all the data
						if ((! $bytes) && ($header['size'] > self::record_size))
							fseek($fh,$this->offset+$rp);

					} else {
						dd([get_class($this) => $data,'header'=>$header,'ptr'=>$rp,'size'=>$this->size,'bytes'=>$bytes]);
					}
				}

				break;

			case 'movi':
				$result->push(new movi($this->offset,$this->size,$this->filename,$this->be));

				break;

			default:
				throw new \Exception('Unhandled header type: '.$header['name']);
		}

		if (! $bytes) {
			fclose($fh);
			unset($fh);
		}

		return $result;
	}
}