<?php
namespace App\Amadeus\FileParser;

/**
 * Parser for the U-MCO lines
 * @author Lucian
 */
class Line_U_18 extends \App\Amadeus\FileParser\Line_U_17
{
	/**
	 * 4.52. U- MCO Segment
	 * see page 157(199)
	 *
	 * This segment contains an MCO element from the PNR.
	 */
	protected $structure_18 = [
		['name'=> 'MSGTAG',     'val' => 'U-',    'type' => 'AN',      'req' => 'M',                                      'len' => 2,],                          // 1 : Message Tag (U-)
		['name'=> 'TTONBR',                       'type' => 'N',       'req' => 'M',                                      'len' => 3,],                          // 2 : Tattoo Number in the PNR
		['name'=> 'DATAMODI',                     'type' => 'AN',                                                         'len' => 1,],                          // 3 : Modification indicator.
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 4 : Delimiter (Constant value of ";")
		['name'=> 'ELMNBR',                       'type' => 'NI',      'req' => 'M',                                      'len' => 3,],                          // 5 : Element number in the PNR
		['name'=> 'MCOTAG',     'val' => 'MCO',   'type' => 'AN',      'req' => 'M',                                      'len' => 3,],                          // 6 : Constant value of "MCO"
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 7 : Delimiter (Constant value of ";")
		['name'=> 'AIRCDE',                       'type' => 'AN',      'req' => 'M',                                      'len_min' => 1,   'len_max' => 3,],    // 8 : Airline Code/Supplier Code. "XD" for ARC MCO for Service Fees. Airline Code for other
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 9 : Delimiter (Constant value of ";")
		['name'=> 'NUMAIR',                       'type' => 'N',       'req' => 'M',                                      'len' => 3,],                          // 10 : Numeric Airline Code including Check digit
		['name'=> 'NUMAIRCK',                     'type' => 'N',       'req' => 'M',                                      'len' => 1,],
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 11 : Delimiter (Constant value of ";")
		['name'=> 'ISSAIR',                       'type' => 'AN',      'req' => 'M',                                      'len_min' => 1,   'len_max' => 99,],   // 12 : Issuing Airline Name
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 13 : Delimiter (Constant value of ";")
		['name'=> 'CITYCDE',                      'type' => 'AN',      'req' => 'M',                                      'len_min' => 3,   'len_max' => 5,],    // 14 : Airport/City Code
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 15 : Delimiter (Constant value of ";")
		['name'=> 'TOTAG',      'val' => 'TO-',   'type' => 'AN',      'req' => 'M',                                      'len' => 3,],                          // 16 : "TO" tag (constant value of "TO-")
		['name'=> 'TOINFO',                       'type' => 'AN',                                                         'len_min' => 1,   'len_max' => 74,],   // 17 : "TO" Carrier/Operator to whom document will be presented If blank in TSM then equals decode of AIRCDE
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 18 : Delimiter (Constant value of ";")
		['name'=> 'ATTAG',      'val' => 'AT-',   'type' => 'AN',      'req' => 'M',                                      'len' => 3,],                          // 19 : "AT" tag (constant value of "AT-")
		['name'=> 'ATINFO',                       'type' => 'AN',                                                         'len_min' => 1,   'len_max' => 74,],   // 20 : "AT" Location where document will be presented
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 21 : Delimiter (Constant value of ";")
		['name'=> 'DEPDATE',                      'type' => 'D:DDMMM:PNRDTE', 'req' => 'M',                                      'len' => 5,],                          // 22 : Date (DDMMM)
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 23 : Delimiter (Constant value of ";")
		['name'=> 'MCOID',                        'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 24 : MCO element identifier/Document type
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 25 : Delimiter (Constant value of ";")
		['name'=> 'REASON',                       'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 26 : Reason for Issuance Code
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 27 : Delimiter (Constant value of ";")
		['name'=> 'SVCTYPE',                      'type' => 'AN',                                                         'len_min' => 1,   'len_max' => 70,],   // 28 : Type of Service
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 29 : Delimiter (Constant value of ";")
		['name'=> 'ADTAG',      'val' => '**-',   'type' => 'AN',      'req' => 'M',                                      'len' => 3,],                          // 30 : Additional information tag (constant value of "**-")
		['name'=> 'ADINFO',                       'type' => 'AN',                                                         'len_min' => 1,   'len_max' => 25,],   // 31 : Additional information
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 32 : Delimiter (Constant value of ";")
		['name'=> 'REMARK',                       'type' => 'AN',                                                         'len_min' => 1,   'len_max' => 260,],  // 33 : Additional Remarks
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 34 : Delimiter (Constant value of ";")
		['name'=> 'ISSUE',                        'type' => 'AN',                                                         'len' => 1,],                          // 35 : Issue Identifier("F" = First Issue, "R" = Reissue)
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 36 : Delimiter (Constant value of ";")
		['name'=> 'BASECURCODE',                  'type' => 'AN',                                                         'len' => 3,],                          // 37 : Currency Code
		['name'=> 'BASE',                         'type' => 'N',                                                          'len' => 11,],                         // 38 : Total Base Amount (Exchange Value)
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 39 : Delimiter (Constant value of ";")
		['name'=> 'TAX',                          'type' => 'AN',                                                         'len' => 1,],                          // 40 : Inclusive of Tax Indicator. 'Y' - Yes = Tax included in base fare. 'N' - No = Tax not included in base fare
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 41 : Delimiter (Constant value of ";")
		['name'=> 'EQVCURCODE',                   'type' => 'AN',                                                         'len' => 3,],                          // 42 : Currency Code
		['name'=> 'EQVAMNT',                      'type' => 'AN',                                                         'len' => 11,],                         // 43 : Equivalent Amount or one/two currency codes
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 44 : Delimiter (Constant value of ";")
		['name' => 'TAXFLDE',                     'type' =>'composite',                                                   'rep' => 30,                                        // 45 TAX FIELD - TAX ON MCO
		 'childs' => [
		   ['name'=> 'OTAXI',                     'type' => 'S:trim',                                                     'len' => 1,],                          // 46 : Tax Indicator. Blank = new tax
		   ['name'=> 'TCURR',                     'type' => 'AN',                                                         'len' => 3,],                          // 47 : Currency Code. Blank = new tax
		   ['name'=> 'TAXA',                      'type' => 'N',                                                          'len' => 9,],                          // 48 : Tax amount
		   ['name'=> 'TAXC',                      'type' => 'S:trim',                 'requires' => ['TAXA'],             'len' => 3,],                          // 49 : Tax code
		   ['name'=> 'TAXN',                      'type' => 'AN',                     'requires' => ['TAXC'],             'len' => 2,],                          // 50 : Nature code
		   ['name'=> 'DELIM',   'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 51 : Delimiter (Constant value of ";")
		 ]],                                                                                                                                                            // 52 END OF COMPOSITE ELEMENT

		['name'=> 'CHARGESCURCODE',               'type' => 'AN',                                                         'len' => 3,],                          // 53 : Currency Code
		['name'=> 'CHARGES',                      'type' => 'AN',                     'requires' => ['CHARGESCURCODE',],  'len' => 11,],                         // 54 : Amount of other fees or charges
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 55 : Delimiter (Constant value of ";")
		['name'=> 'TOTCURCODE',                   'type' => 'AN',                                                         'len' => 3,],                          // 56 : Currency Code
		['name'=> 'TOTAMT',                       'type' => 'N',                                                          'len' => 11,],                         // 57 : Total amount collected
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 58 : Delimiter (Constant value of ";")
		['name'=> 'SELLBUY1',                     'type' => 'NF',                                                         'len' => 11,],                         // 59 : Banker's Selling/Buying Rate (First)
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 60 : Delimiter (Constant value of ";")
		['name'=> 'SELLBUY2',                     'type' => 'NF',                                                         'len' => 11,],                         // 61 : Banker's Selling/Buying Rate (Second)
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 62 : Delimiter (Constant value of ";")
		['name'=> 'CONTKT',                       'type' => 'AN',                                                         'len_min' => 1,   'len_max' => 40,],   // 63 : Connection Ticket Number
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 64 : Delimiter (Constant value of ";")
		['name'=> 'OPTALINF',                     'type' => 'AN',                                                         'len_min' => 1,   'len_max' => 26,],   // 65 : Optional Airline Information
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 66 : Delimiter (Constant value of ";")
		['name'=> 'INDALUSE',                     'type' => 'AN',                                                         'len_min' => 1,   'len_max' => 23,],   // 67 : Individual Airline Use
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 68 : Delimiter (Constant value of ';')
		['name'=> 'TRANCURR',                     'type' => 'AN',                                                         'len' => 3,],                          // 69 : Transitional Currency Code. Indicates transitional currency when second bankers' selling/buying rate exists.
		['name'=> 'EQOCHARGESCURCODE',            'type' => 'AN',                                                         'len' => 3,],                          // 70 : Equivalent other charges currency
		['name'=> 'EQOCHARGES',                   'type' => 'AN',                    'requires' => ['TRANCURR',],],                                      // 71 : Equivalent other charges amount
		['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],                          // 72 : Delimiter (Constant value of ';')

		// wondering what is PTA? @see http://www.airliners.net/aviation-forums/general_aviation/read.main/1923587/
		#Array( 'name' => 'PTAFARE',                     'type' =>'composite',                                                   'rep_min' =>0,    'rep_max' =>1,       // 73 PTA fares. This is a composite element
		# 'childs' => Array(
		#   Array( 'name'=> 'EXCHTYP',                   'type' => 'AN',      'if:regex'=>'[A-Z]{4}',                            'len' => 1,),                          // 74 : Exchange value type
		#   Array( 'name'=> 'EXCHCURCODE',               'type' => 'AN',      'if:regex'=>'[A-Z]{4}',                            'len' => 3,),                          // 75 : Exchange value currency code
		#   Array( 'name'=> 'EXCHAMT',                   'type' => 'N',                    ),                                                                           // 76 : Exchange value amount
		#   Array( 'name'=> 'DELIM',   'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,),                          // 77 : Delimiter (constant value of ";")
		#   Array( 'name'=> 'XCHEQVCURCODE',             'type' => 'AN',                                                         'len' => 3,),                          // 78 : Equivalent exchange value currently
		#   Array( 'name'=> 'XCHEQVAMNT',                'type' => 'N',                    ),                                                                           // 79 : Equivalent exchange value amount
		#   Array( 'name'=> 'DELIM',   'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,),                          // 80 : Delimiter (constant value of ";")
		#   Array( 'name'=> 'SVCTYP',                    'type' => 'AN',                                                         'len' => 1,),                          // 81 : Service charges type
		#   Array( 'name'=> 'SVCCURCODE',                'type' => 'AN',                                                         'len' => 3,),                          // 82 : Service charges currency code
		#   Array( 'name'=> 'SVCAMT',                    'type' => 'N',                    ),                                                                           // 83 : Service charges amount
		#)),                                                                                                                                                            // 84 END OF COMPOSITE ELEMENT

		#Array( 'name'=> 'DELIM',      'val' => ';',     'type' => 'AN',                     'requires' => Array( 'PTAFARE'),    'len' => 1,),                          // 85 : Delimiter ";". Conditional = Depends on T29/B29 OFP indicators
		#Array( 'name'=> 'NETCURCODE',                   'type' => 'AN',                                                         'len' => 3,),                          // 86 : Net fare currency code
		#Array( 'name'=> 'NETFARE',                      'type' => 'N',                      'requires' => Array( 'NETCURCODE'),),                                      // 87 : Net Fare amount
		#Array( 'name'=> 'DELIM',      'val' => ';',     'type' => 'AN',                     'requires' => Array( 'NETFARE'),    'len' => 1,),                          // 88 : Delimiter (constant value of ";")
		#Array( 'name'=> 'INTIND',                       'type' => 'AN',                                                         'len' => 1,),                          // 89 : International Indicator. Possible values are: 'I' stands for "International", 'D' stands for "Domestic", [blank] , if no value entered

		#Array( 'name'=> 'DELIM',   'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,),                          // 77 : Delimiter (constant value of ";")
		#Array( 'name'=> 'DELIM',   'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,),                          // 80 : Delimiter (constant value of ";")

		#Array( 'name'=> 'DELIM',      'val' => ';',     'type' => 'AN',  'len' => 1,),
		##Array( 'name'=> 'PSGASS',     'val' => 'P',     'type' => 'ASSOC:loose', ),
		#Array( 'name'=> 'DELIM',      'val' => ';',     'type' => 'AN',  'len' => 1,),
		#Array( 'name'=> 'SEGASS',     'val' => 'S',    'type' => 'ASSOC:loose', ),
	];

	/**
	 * If handler_LineNotCompletlyProcessed_18) get called recursivelly, it should increment this, to detect more-than-level1 calls. They should be avoided as it introduces a LOT of complexity
	 * @var int
	 */
	protected $handler_LineNotCompletlyProcessed_18_depth = 0;

	/**
	 * Called from handler_LineNotCompletlyProcessed
	 * @return multitype:
	 */
	protected function handler_LineNotCompletlyProcessed_18($index, $content, $structIndex, $contentLength, $tree)
	{
		$struct = [
			10 => ['name'=> 'DELIM',   'val' => ';',        'type' => 'AN',                                                         'len' => 1,],

			45 => ['name'=> 'NETCURCODE',                   'type' => 'AN',                                                         'len' => 3,],
			46 => ['name'=> 'NETFARE',                      'type' => 'N',],

			60 => ['name'=> 'DELIM',   'val' => ';',        'type' => 'AN',      'req' => 'M',                                      'len' => 1,],
			61 => ['name'=> 'DELIM',   'val' => ';',        'type' => 'AN',                                                         'len' => 1,],

			65 => ['name'=> 'SVCCURCODE',                   'type' => 'AN',                                                         'len' => 3,],
			66 => ['name'=> 'SVCAMT',                       'type' => 'N',],
			67 => ['name'=> 'DELIM',   'val' => ';',        'type' => 'AN',      'req' => 'M',                                      'len' => 1,],
			68 => ['name'=> 'DELIM',   'val' => ';',        'type' => 'AN',      'req' => 'M',                                      'len' => 1,],

			85 => ['name'=> 'INTIND',                       'type' => 'AN',                                                         'len' => 1,],
			86 => ['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',      'req' => 'M',                                      'len' => 1,],

			90 => ['name'=> 'PSGASS',     'val' => 'P',     'type' => 'ASSOC:loose',],
			91 => ['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',                                                         'len' => 1,],
			92 => ['name'=> 'SEGASS',     'val' => 'S',     'type' => 'ASSOC:loose',],
		];

		$remainingContent = substr($content, $index);
		$remainingContent = ltrim($remainingContent);

		if($this->handler_LineNotCompletlyProcessed_18_depth==0){
			if(!preg_match("/^\;[A-Z]{3}[\s]+/i", $remainingContent)){
				unset($struct[10]);
			}

			if(count(explode(";", $remainingContent))==5){
				unset($struct[85]);
				unset($struct[86]);
			}

			$this->handler_LineNotCompletlyProcessed_18_depth++;
			$tree1 = $this->parseFromStructure(array_values($struct), $remainingContent);
			$this->handler_LineNotCompletlyProcessed_18_depth--;
		}else{
			return parent::handler_LineNotCompletlyProcessed($index, $content, $structIndex, $contentLength, $tree);
		}

		return array_merge($tree, $tree1);
	}

	/**
	 * Handle unprocessed lines
	 * @return multitype:
	 */
	protected function handler_LineNotCompletlyProcessed_18_($index, $content, $structIndex, $contentLength, $tree)
	{
		$struct = [
			10 => ['name'=> 'DELIM',   'val' => ';',        'type' => 'AN',                                                         'len' => 1,],

			15 => ['name'=> 'NETCURCODE',                   'type' => 'AN',                                                         'len' => 3,],
			16 => ['name'=> 'NETFARE',                      'type' => 'N',],

			21 => ['name'=> 'DELIM',   'val' => ';',        'type' => 'AN',      'req' => 'M',                                      'len' => 1,],
			22 => ['name'=> 'DELIM',   'val' => ';',        'type' => 'AN',      'req' => 'M',                                      'len' => 1,],
			23 => ['name'=> 'DELIM',   'val' => ';',        'type' => 'AN',      'req' => 'M',                                      'len' => 1,],
			24 => ['name'=> 'DELIM',   'val' => ';',        'type' => 'AN',      'req' => 'M',                                      'len' => 1,],

			30 => ['name'=> 'INTIND',                       'type' => 'AN',                                                         'len' => 1,],
			31 => ['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',     'req' => 'M',                                       'len' => 1,],

			40 => ['name'=> 'PSGASS',     'val' => 'P',     'type' => 'ASSOC:loose',],
			41 => ['name'=> 'DELIM',      'val' => ';',     'type' => 'AN',                                                         'len' => 1,],
			42 => ['name'=> 'SEGASS',     'val' => 'S',     'type' => 'ASSOC:loose',],
		];

		$remainingContent = substr($content, $index);
		$remainingContent = ltrim($remainingContent);

		if($this->handler_LineNotCompletlyProcessed_18_depth==0){
			if(!preg_match("/^\;[A-Z]{3}[\s]+/i", $remainingContent)){
				unset($struct[10]);
			}

			if(count(explode(";", $remainingContent))==5){
				#unset($struct[30]);
				#unset($struct[31]);
			}

			$this->handler_LineNotCompletlyProcessed_18_depth++;
			$tree1 = $this->parseFromStructure(array_values($struct), $remainingContent);
			$this->handler_LineNotCompletlyProcessed_18_depth--;
		}else{
			return parent::handler_LineNotCompletlyProcessed($index, $content, $structIndex, $contentLength, $tree);
		}

		return array_merge($tree, $tree1);
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Amadeus\FileParser\Line_U_09::postParse()
	 */
	protected function postParse()
	{
		parent::postParse();
		if($this->tree['_type'] == '18'){	// MCO
			$this->tree['TAXFLDE'] = self::rtrimArrDeep($this->tree['TAXFLDE']);
		}
	}

}
