<?php

// TODO: rename "reservation flag" to "order flag"

namespace App\Config;

class OrderFlags extends XmlDynamicRecordsAbstract
{


	/**
	 * Stores the configuration file (relative to the "files/config/" dir). For config files stored
	 * inside subdirectories, the subdirectory is included (Ex: services/servicesList.xml).
	 * @var String
	 */
	protected $fileName=CONFIG_FILE_RESERVATIONS_FLAGS;


	/**
	 * The list of codes for the allowed flags.
	 * @var array
	 */
	private $allowedCodes= ['Blue', 'Green', 'Orange', 'Pink', 'Purple', 'Red', 'Yellow'];

	/**
	 * (non-PHPdoc)
	 * @see \App\Config\XmlDynamicRecordsAbstract::getAll_rawData_extractDataFromFile_list()
	 */
	protected function getAll_rawData_extractDataFromFile_list(\SimpleXMLElement $xml)
	{
		// gets the final list of items to be returned
		$return = [];
		foreach($xml->resFlag  as $flag) {
			$return [ (String)$flag['code'] ] = (String)$flag;
		}
		return $return;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Config\XmlDynamicRecordsAbstract::getAll_rawData_extractDataFromFile_default()
	 */
	protected function getAll_rawData_extractDataFromFile_default(\SimpleXMLElement $xml)
	{
		return (String)$xml['default'].'';
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Config\XmlDynamicRecordsAbstract::getAll_rawData_extractDataFromFile_mandatory()
	 */
	protected function getAll_rawData_extractDataFromFile_mandatory(\SimpleXMLElement $xml)
	{
		return (Int)$xml['mandatory'];
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Config\XmlDynamicRecordsAbstract::itemCheck()
	 */
	protected function itemCheck($code, $itemDetails)
	{
		// check itemDetails
		if (!is_string($itemDetails)) throw new \Exception('Order flag name must be set as a string.');
		// check code
		if (!$code) $this->addErrorMessage('The order flag `code` was not defined.');
		// check name
		if (!$itemDetails) $this->addErrorMessage('The order flag `name` was not defined.');
		// check name length
		if (mb_strlen($itemDetails)>50) $this->addErrorMessage('The order flag `name` length must be smaller than 50 chars.');

		if (htmlClean($itemDetails) != $itemDetails) $this->addErrorMessage('The order flag `name` must not contain html special characters.');

		// check that the name dows not already exist
		foreach($this->itemsList as $c=>$n) {
			if ($c!=$code and $itemDetails==$n) {
				$this->addErrorMessage('This order flag `name` already exists.');
			}
		}
		// check that the code is in the allowed flag codes
		if (!in_array($code, $this->allowedCodes)) $this->addErrorMessage('This order flag `code` is not valid.');
	}


	/**
	 * (non-PHPdoc)
	 * @see \App\Config\BaseAbstract::save_check()
	 */
	protected function save_check()
	{ }


	/**
	 * (non-PHPdoc)
	 * @see \App\Config\XmlBasicAbstract::save_write_do_getXml()
	 */
	protected function save_write_do_getXml()
	{

		// start composing the XML object
		$xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8"?><reservationFlagList/>');

		// LOOP THROUGH EACH SERVICE CODE AVAILABLE IN THE APP ------------------------------------
		foreach ($this->itemsList as $code=>$name) {
			$servObj = $xml->addChild('resFlag ', $name);
			$servObj['code'] = $code;
		}

		// set the mandatory and the default flag
		$xml['mandatory'] = $this->mandatory;
		$xml['default'] = $this->defaultItem;

		// return the simplexml object
		return $xml;

	}


	/**
	 * Returns the list of allowed flag codes.
	 * @return Array
	 */
	public function getAllowedCodes()
	{
		return $this->allowedCodes;
	}

	/**
	 * Returns the list of available flag codes.
	 * @throws \Exception - if constructor type is invalid
	 * @return Array
	 */
	public function getAvailableCodes()
	{
		// check constructor type
		if ($this->constructType != 'admin') throw new \Exception("You can use the method `".get_called_class().'::'.__FUNCTION__."` only if the constructor type is `admin`.");
		// full list of available codes
		$availCodes = $this->allowedCodes;
		// eliminate the used ones
		foreach($this->itemsList as $c => $val) {
			$pos = array_search($c, $availCodes);
			if ($pos !== false) unset($availCodes[$pos]);
		}
		return $availCodes;
	}

}
