/**
  * Convert contry string (e.g. United States of America) into 2 or 3 letter (e.g. US or USA)
  * Or country 2 or 3 letters code to country string in English
  * Or betweeen country codes: Values for $nbLetters:
  * 3  : country   -> 3 letters
  * 2  : country   -> 2 letters
  * -2 : 2 letters -> country
  * -3 : 3 letters -> country
  * 23 : 2 letters -> 3 letters
  * 32 : 3 letters -> 2 letters
  *
  * @param  string $country    Full text country name (if $nbLetters = 2 or 3) or country code (if $nbLetters = -2 or -3 or 23 or 32)
  * @param  int    $nbLetters  Number of letters code (2 or 3 for full name to code and -2 or -3 for code to name)
  * @return string             2/3/full-letters country name
  */
 protected function countryToLetters($country, $nbLetters)
 {
     $countries = new cbpaidCountries();
     switch ($nbLetters) {
         case 3:
             $ret = $countries->countryToThreeLetters($country);
             break;
         case 2:
             $ret = $countries->countryToTwoLetters($country);
             break;
         case -2:
             $ret = $countries->twoLettersToCountry($country);
             break;
         case -3:
             $ret = $countries->threeLettersToCountry($country);
             break;
         case 23:
             $ret = $countries->twoToThreeLettersCountry($country);
             break;
         case 32:
             $ret = $countries->threeToTwoLettersCountry($country);
             break;
         default:
             trigger_error('Unknown nbLetters in countryToLetters', E_USER_WARNING);
             $ret = null;
             break;
     }
     if ($ret === null) {
         $n = $nbLetters < 0 ? 255 : $nbLetters % 10;
         $ret = substr($country, 0, $n);
     }
     return $ret;
 }
	/**
	 * Prepares and signs payflow payment $requestParams
	 *
	 * @param cbpaidPaymentBasket $paymentBasket
	 * @param bool $subscription
	 * @return array $requestParams
	 */
	private function _payflowPayment( $paymentBasket, $subscription = false )
	{
		$requestParams									=	array();

		if ( $this->hasPaypalPayflow() ) {
			$countries									=	new cbpaidCountries();

			if ( $paymentBasket->period3 ) {
				if ( $paymentBasket->period1 ) {
					$amount								=	sprintf( '%.2f', $paymentBasket->mc_amount1 );
				} else {
					$amount								=	sprintf( '%.2f', $paymentBasket->mc_amount3 );
				}
			} else {
				$amount									=	sprintf( '%.2f', $paymentBasket->mc_gross );
			}

			if ( $this->getAccountParam( 'normal_gateway' ) == '0' ) {
				$requestParams['MODE']					=	'TEST';
			}

			$request									=	array(	'PARTNER' => 'PayPal',
																	'VENDOR' => $this->getAccountParam( 'paypal_payflow_vendor' ),
																	'USER' => $this->getAccountParam( 'paypal_payflow_user' ),
																	'PWD' => $this->getAccountParam( 'paypal_payflow_password' ),
																	'TRXTYPE' => 'S',
																	'AMT' => $amount,
																	'CREATESECURETOKEN' => 'Y',
																	'SECURETOKENID' => uniqid(),
																	'TEMPLATE' => $this->getAccountParam( 'template_layout', 'MINLAYOUT' ),
																	'ORDERDESC' => $paymentBasket->item_name,
																	'INVNUM' => $paymentBasket->invoice,
																	'CURRENCY' => $paymentBasket->mc_currency,
																	'USER1' => $paymentBasket->id,
																	'USER2' => $paymentBasket->user_id,
																	'USER3' => $paymentBasket->item_number,
																	'USER4' => ( $subscription ? 'R' : 'S' )
																);

			if ( $subscription ) {
				$request['RECURRING']					=	'Y';
			}

			if ( $this->getAccountParam( 'givehiddenbillemail' ) && ( strlen( $paymentBasket->payer_email ) <= 127 ) ) {
				$request['EMAIL']						=	$paymentBasket->payer_email;
			}

			if ( $this->getAccountParam( 'givehiddenbilladdress' ) ) {
				cbimport( 'cb.tabs' );

				$addressFields							=	array(	'BILLTOFIRSTNAME' => array( $paymentBasket->first_name, 30 ),
																	'BILLTOLASTNAME' => array( $paymentBasket->last_name, 30 ),
																	'BILLTOSTREET' => array( $paymentBasket->address_street, 150 ),
																	'BILLTOZIP' => array( $paymentBasket->address_zip, 9 ),
																	'BILLTOCITY' => array( $paymentBasket->address_city, 45 ),
																	'BILLTOCOUNTRY' => array( $countries->countryToTwoLetters( $paymentBasket->address_country ), 2 )
																);

				if ( $paymentBasket->address_state != 'other' ) {
					$addressFields['BILLTOSTATE']		=	array( substr( $paymentBasket->address_state, -2 ), 2 );
				}

				foreach ( $addressFields as $k => $valueMaxlength ) {
					$adrField							=	cbIsoUtf_substr( $valueMaxlength[0], 0, $valueMaxlength[1] );

					if ( $adrField ) {
						$request[$k]					=	$adrField;
					}
				}
			}

			if ( $this->getAccountParam( 'givehiddenbilltelno' ) && ( strlen( $paymentBasket->contact_phone ) <= 50 ) ) {
				$request['BILLTOPHONENUM']				=	$paymentBasket->contact_phone;
			}

			if ( $this->getAccountParam( 'givehiddenshipemail' ) && ( strlen( $paymentBasket->payer_email ) <= 127 ) ) {
				$request['SHIPTOEMAIL']					=	$paymentBasket->payer_email;
			}

			if ( $this->getAccountParam( 'givehiddenshipaddress' ) ) {
				cbimport( 'cb.tabs' );

				$addressFields							=	array(	'SHIPTOFIRSTNAME' => array( $paymentBasket->first_name, 30 ),
																	'SHIPTOLASTNAME' => array( $paymentBasket->last_name, 30 ),
																	'SHIPTOSTREET' => array( $paymentBasket->address_street, 150 ),
																	'SHIPTOZIP' => array( $paymentBasket->address_zip, 9 ),
																	'SHIPTOCITY' => array( $paymentBasket->address_city, 45 ),
																	'SHIPTOCOUNTRY' => array( $countries->countryToThreeLetters( $paymentBasket->address_country ), 3 )
																);

				if ( $paymentBasket->address_state != 'other' ) {
					$addressFields['SHIPTOSTATE']		=	array( substr( $paymentBasket->address_state, -2 ), 2 );
				}

				foreach ( $addressFields as $k => $valueMaxlength ) {
					$adrField							=	cbIsoUtf_substr( $valueMaxlength[0], 0, $valueMaxlength[1] );

					if ( $adrField ) {
						$request[$k]					=	$adrField;
					}
				}
			}

			if ( $this->getAccountParam( 'givehiddenshiptelno' ) && ( strlen( $paymentBasket->contact_phone ) <= 50 ) ) {
				$request['SHIPTOPHONENUM']				=	$paymentBasket->contact_phone;
			}

			$formUrl									=	array();

			foreach ( $request as $k => $v ) {
				$formUrl[$k]							=	$k . '=' . $v;
			}

			$formUrl									=	implode( '&', $formUrl );

			$results									=	array();
			$response									=	null;
			$status										=	null;
			$error										=	$this->_httpsRequest( $this->gatewayUrl( 'psp' ), $formUrl, 105, $response, $status, 'post', 'normal' );

			if ( $response ) {
				parse_str( $response, $results );
			}

			if ( $error || ( $status != 200 ) || ( ! $response ) ) {
				$this->_setLogErrorMSG( 3, null, $this->getPayName() . ' HTTPS POST request to payment gateway server failed.', CBPTXT::T( "Submitted subscription payment didn't return an error but didn't complete." ) . ' ' . CBPTXT::T( 'Please contact site administrator to check error log.' ) );
			} else {
				if ( cbGetParam( $results, 'RESULT' ) == '0' ) {
					$requestParams['SECURETOKEN']		=	cbGetParam( $results, 'SECURETOKEN' );
					$requestParams['SECURETOKENID']		=	cbGetParam( $results, 'SECURETOKENID' );
				} else{
					$this->_setLogErrorMSG( 3, null, $this->getPayName() . ' Paypal Payflow error returned. ERROR: ' . cbGetParam( $results, 'RESPMSG' ), CBPTXT::T( 'Please contact site administrator to check error log.' ) );
				}
			}
		}

		return $requestParams;
	}