<?php
/**
* @version	$Id: zones_tag_processor.php 16516 2017-01-20 14:12:22Z alex $
* @package	In-Commerce
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license	Commercial License
* This software is protected by copyright law and international treaties.
* Unauthorized reproduction or unlicensed usage of the code of this program,
* or any portion of it may result in severe civil and criminal penalties,
* and will be prosecuted to the maximum extent possible under the law
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/

defined('FULL_PATH') or die('restricted access!');

class ZonesTagProcessor extends kDBTagProcessor
{
	function ShowCountries($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		$destination_table = $this->getDestinationsTable($params);
		$selected_country_id = (int)$this->Application->GetVar('CountrySelector');

		$name_field = 'l' . $this->Application->GetVar('m_lang') . '_Name';
		$id_field = $this->Application->getUnitOption('country-state', 'IDField');
		$table_name = $this->Application->getUnitOption('country-state', 'TableName');

		switch ($params['show']) {
			case 'current':
				// selected countries in current zone
				$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
						FROM ' . $table_name . ' cs
						LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
						WHERE cs.Type = ' . DESTINATION_TYPE_COUNTRY . ' AND zd.ShippingZoneId = ' . $object->GetID() . '
						ORDER BY cs.' . $name_field;
				break;

			case 'available':
				// available countries in current zone
				$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
						FROM ' . $table_name . ' cs
						LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
						WHERE cs.Type = ' . DESTINATION_TYPE_COUNTRY . ' AND zd.ShippingZoneId IS NULL
						ORDER BY cs.' . $name_field;
				break;

			case 'all':
				// always preselect 1st country, when user haven't selected any
				if (!$selected_country_id) {
					$sql = 'SELECT StdDestId
							FROM ' . $destination_table . '
							WHERE ShippingZoneId = ' . $object->GetID();
					$selected_country_id = $this->Conn->GetOne($sql);

					if ($selected_country_id) {
						$this->Application->SetVar('CountrySelector', $selected_country_id);
					}
				}

				// all countries
				$sql = 'SELECT ' . $name_field . ', ' . $id_field . '
						FROM ' . $table_name . '
						WHERE Type = ' . DESTINATION_TYPE_COUNTRY . '
						ORDER BY ' . $name_field;
				break;

			case 'has_states':
				/** @var kCountryStatesHelper $cs_helper */
				$cs_helper = $this->Application->recallObject('CountryStatesHelper');

				$has_states = $cs_helper->getCountriesWithStates();

				if ($selected_country_id && !array_key_exists($selected_country_id, $has_states)) {
					list ($selected_country_id, ) = each($has_states);
					$this->Application->SetVar('CountrySelector', $selected_country_id);
				}

				// preselect country from 1st found state
				if (!$selected_country_id) {
					$sql = 'SELECT cs.StateCountryId
							FROM ' . $table_name . ' cs
							LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
							WHERE (cs.Type = ' . DESTINATION_TYPE_STATE . ') AND (zd.ShippingZoneId = ' . $object->GetID() . ')';
					$selected_country_id = $this->Conn->GetOne($sql);

					if ($selected_country_id) {
						$this->Application->SetVar('CountrySelector', $selected_country_id);
					}
					else {
						list ($selected_country_id, ) = each($has_states);
						$this->Application->SetVar('CountrySelector', $selected_country_id);
					}
				}

				// gets only countries with states
				$sql = 'SELECT ' . $name_field . ', ' . $id_field . '
						FROM ' . $table_name . '
						WHERE Type = ' . DESTINATION_TYPE_COUNTRY . ' AND ' . $id_field . ' IN (' . implode(',', array_keys($has_states)) . ')
						ORDER BY ' . $name_field;
				break;

			default:
				throw new Exception('Unknown "show" parameter value "' . $params['show'] . '" used');
				break;
		}

		$ret = '';
		$countries = $this->Conn->GetCol($sql, $id_field);

		$block_params = $this->prepareTagParams($params);
		$block_params['name'] = $params['block'];

		foreach ($countries as $country_id => $country_name) {
			$block_params['id'] = $country_id;
			$block_params['destination_title'] = $country_name;
			$block_params['selected'] = $selected_country_id == $country_id ? ' selected="selected"' : '';

			$ret .= $this->Application->ParseBlock($block_params);
		}

		return $ret;
	}

	function ShowStates($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		$destination_table = $this->getDestinationsTable($params);

		$name_field = 'l' . $this->Application->GetVar('m_lang') . '_Name';
		$id_field = $this->Application->getUnitOption('country-state', 'IDField');
		$table_name = $this->Application->getUnitOption('country-state', 'TableName');

		$country_id = $this->Application->GetVar('CountrySelector');

		switch ($params['show']) {
			case 'current':
				// selected states for current country and zone
				$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
						FROM ' . $table_name . ' cs
						LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
						WHERE
							cs.Type = ' . DESTINATION_TYPE_STATE . ' AND
							cs.StateCountryId = ' . $country_id . ' AND
							zd.ShippingZoneId = ' . $object->GetID() . '
						ORDER BY cs.' . $name_field;
				break;

			case 'available':
				// available states for current country and zone
				$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
						FROM ' . $table_name . ' cs
						LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
						WHERE
							cs.Type = ' . DESTINATION_TYPE_STATE . '
							AND zd.ShippingZoneId IS NULL
							AND cs.StateCountryId = ' . $country_id . '
						ORDER BY cs.' . $name_field;
				break;

			case 'all':
				// all possible states for selected country
				$sql = 'SELECT ' . $name_field . ', ' . $id_field . '
						FROM ' . $table_name . '
						WHERE Type = ' . DESTINATION_TYPE_STATE . ' AND StateCountryId = ' . $country_id . '
						ORDER BY ' . $name_field;
				break;

			default:
				throw new Exception('Unknown "show" parameter value "' . $params['show'] . '" used');
				break;
		}

		$ret = '';
		$states = $this->Conn->GetCol($sql, $id_field);

		$block_params = $this->prepareTagParams($params);
		$block_params['name'] = $params['block'];

		foreach($states as $state_id => $state_name) {
			$block_params['id'] = $state_id;
			$block_params['destination_title'] = $state_name;

			$ret .= $this->Application->ParseBlock($block_params);
		}

		return $ret;
	}

	function ShowZips($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		$destination_table = $this->getDestinationsTable($params);

		$country_id = (int)$this->Application->GetVar('CountrySelector');

		$current_sql = 'SELECT DestValue
						FROM ' . $destination_table . '
						WHERE
							COALESCE(DestValue, "") <> "" AND
							ShippingZoneID = ' . $object->GetID() . '
						ORDER BY DestValue';

		switch ($params['show']) {
			case 'current':
				$sql = $current_sql;
				break;

			case 'available':
				$selected_zips = $this->Conn->GetCol($current_sql);
				$selected_zips = $this->Conn->qstrArray($selected_zips);

				$sql = 'SELECT DISTINCT DestValue
						FROM ' . $this->Application->getUnitOption('dst', 'TableName') . '
						WHERE
							COALESCE(DestValue, "") <> "" AND
							ShippingZoneID <> ' . $object->GetID() . ' AND
							' . ($selected_zips ? 'DestValue NOT IN (' . implode(',', $selected_zips) . ') AND' : '') . '
							StdDestId = ' . $country_id . '
							ORDER BY DestValue';
				break;

			default:
				throw new Exception('Unknown "show" parameter value "' . $params['show'] . '" used');
				break;
		}

		$zips = $this->Conn->GetCol($sql);

		$ret = '';
		$block_params = $this->prepareTagParams($params);
		$block_params['name'] = $params['block'];

		foreach($zips as $zip) {
			$block_params['id'] = '0|' . $zip;
			$block_params['destination_title'] = $zip;

			$ret .= $this->Application->ParseBlock($block_params);
		}

		return $ret;
	}

	/**
	 * Returns table for shipping zone destinations
	 *
	 * @param Array $params
	 * @return string
	 */
	function getDestinationsTable($params)
	{
		static $table_name = '';

		if (!$table_name) {
			/** @var kDBItem $object */
			$object = $this->getObject($params);

			$table_name = $this->Application->getUnitOption('dst', 'TableName');

			if ($object->IsTempTable()) {
				$table_name = $this->Application->GetTempName($table_name, 'prefix:' . $this->Prefix);
			}
		}

		return $table_name;
	}
}