<?php

// abs_lib.php
// -------------------------------------------------------------------------------------------------
// PHP functionality for menu construction and rebranding
//
// Project    > A16-dmABS-1.5-Feb09
// Copyright  > (C) Digital Mail Limited (2005 - 2009)
// Author     > Richard Knight (RAK) for DML
// -------------------------------------------------------------------------------------------------

function abs_get_site_options($mode)
{
	// Get site options

	global $abs_root, $abs_debug;

	$abs_debug->heading(__FUNCTION__ . '(' . $mode . ')');
	$abs_opt = array();
	
	switch ($mode)
	{
		case 'AFFILIATE':
			$abot_set = 'NO';
			if (isset($_SESSION['ABS_OPT']))
			{
				// Retrieve site options from cache
				$abs_debug->msg('Loading brand options from session cache');
				$abs_opt = $_SESSION['ABS_OPT'];
				return $abs_opt;
			}

			// Defaults: Get site options from abs_options.php, as in 'ADAPTED' mode
			@include(DOCROOT . $abs_root . '/config/abs_options.php');

			// CHECK FOR ABOTs (Affiliate Brand Override Triggers)

			if (isset($_GET['dmx_did']))  $p['DealerID']  = $_GET['dmx_did'];
			if (isset($_GET['dmx_name'])) $p['BrandName'] = $_GET['dmx_name'];
			if (!in_array($_SERVER['HTTP_HOST'], $GLOBALS['abs_default_domains'])) $p['FQDN'] = $_SERVER['HTTP_HOST'];
			if (!isset($p))
			{
				$abs_debug->msg('No ABOTs detected, so using options from abs_options.php');
 				break;
 			}

			// ABOTs found... PERFORM BRAND REQUEST
			// Obtain site options for first time, form DML server
			
			$abot_set = 'TRYING';

			global $dmshop; // Piggback request on dmx's $dmshop object
			$abs_debug->msg('<b>ABOT detected, so Get Brand</b>');
			$dmshop->_R = $p;
			$dmshop->_R['Cmd'] = 'GetBrand';
			$dmshop->request();

			if ($dmshop->result->status == false || !count($dmshop->result->response)) break;

			$response = $dmshop->result->response;
			if ($response['Cmd'] != 'GetBrandAck') break;

			// Decode brand details (XDetails), filter results for valid $abs_opt keys, and perform the brand overlay
			$dmshop->debug->msg('<b>Now decode XDetails node</b>');
			$overlay = $dmshop->decode_pwp($response['XDetails']);
			$abs_opt = array_merge($abs_opt, array_intersect_key($overlay, $abs_opt));
			$abs_opt['dealer_id'] = $overlay['DealerID'];
			$abs_opt['brand'] 	  = $overlay['BrandName'];
			
			$abs_opt['cols1'] = abs_generate_shades($abs_opt['col1']);			
			$abs_opt['cols2'] = abs_generate_shades($abs_opt['col2']);			
			
			$abot_set = 'SUCCESS';

			unset($_SESSION['ABS_SUB']); // Clear substitutions, as we have received new brand info

			break;
			
		case 'ADAPTED':
		default:
			// Get site options from abs_options.php
			$abs_debug->msg('Loading brand options from abs_options.php');
			@include(DOCROOT . $abs_root . '/config/abs_options.php');
			break;
	}

	if (count($abs_opt)) $abs_opt = array_change_key_case($abs_opt, CASE_LOWER);
	
	// Set default values for options if these haven't been specified
	include(DOCROOT . $abs_root . '/config/abs_options_defaults.php');
	$abs_opt = array_merge($abs_opt_default, $abs_opt);

	if ($abs_opt['contact_alltalk_no'] == $abs_opt_default['contact_alltalk_no'])
	{
		$abs_opt['contact_alltalk_ppm'] = $abs_opt_default['contact_alltalk_ppm'];
	}
	
	if ($mode == 'AFFILIATE' && $abot_set != 'NO')
	{
		$abs_debug->msg($dmshop->debug->flush());
		$abs_debug->inspect('Results of Brand Overlay: $abs_opt', $abs_opt);
		if ($abot_set == 'SUCCESS') $_SESSION['ABS_OPT'] = $abs_opt;
	}

	return $abs_opt;
}
	
// -------------------------------------------------------------------------------------------------

function abs_read_easy_seo_data()
{
	// Compile EasySEO data from CSV file and store in the session
	
	global $abs_root, $abs_debug;

	$abs_debug->heading(__FUNCTION__);

	if (isset($_SESSION['ABS_SEO']))
	{
		$abs_debug->msg('Loading Easy SEO data from session cache');
		$abs_debug->inspect('', $_SESSION['ABS_SEO']);
		return(array('seo' => $_SESSION['ABS_SEO']));
	}
	
	if (!$csv = @file_get_contents(DOCROOT . $abs_root . '/config/easy_seo.csv'))
	{
		$abs_debug->msg('Could not find /config/easy_seo.csv');
		return(array('seo' => array()));
	}
	
	// Convert linebreaks from Mac or Windows format if necessary
	$win = strpos($csv, "\r\n") !== FALSE;
	$mac = strpos($csv, "\r"  ) !== FALSE;
	if (PHP_EOL == "\n" && ($win || $mac))
	{
		$csv = str_replace("\r\n", "\n", $csv); // Windows 	-> Unix
		$csv = str_replace("\r",   "\n", $csv); // Mac		-> Unix
		file_put_contents(DOCROOT . $abs_root . '/config/easy_seo.csv', $csv);
	}
	
	function trim_vals($val)
	{
		return trim($val);
	}
	
	// Read easy_seo_data.csv
	$abs_debug->msg('Loading Easy SEO data from config file');
	$seo_arr = array();
	$invalid = array();
	$fp = fopen(DOCROOT . $abs_root . '/config/easy_seo.csv', 'r');
	fgets($fp, 10000);
	while ($line = @fgetcsv($fp, 10000))
	{
		list($real_url, $desired_url, $title, $description, $keywords) = array_pad(array_map('trim_vals', $line), 5, '');

		if ($desired_url)
		{
			if (!preg_match('/^\/[\w\.-_\/]+$/', $desired_url))
			{
				array_push($invalid, array('real_url' => $real_url, 'desired_url' => $desired_url));
				$desired_url = NULL;
			}
		}

		if ($desired_url || $title || $description || $keywords)
		{
			$seo_arr[$real_url] = array(
				'desired_url' 	=> $desired_url,
				'title' 		=> htmlentities($title),
				'description' 	=> htmlentities($description),
				'keywords'	 	=> htmlentities($keywords)
			);
		}
	}
	fclose($fp);
	$_SESSION['ABS_SEO'] = $seo_arr;
	$abs_debug->inspect('', $seo_arr);
	return(array('seo' => $seo_arr, 'invalid' => $invalid));
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// TST ADDITIONAL PARAMS

function abs_get_tst_additional_params_json()
{
	// CONSIDER MOVING TO XCOMPONENTS LAYER... (see also /ens/index.php)
	//
	if (!$GLOBALS['abs_site_entry']) return '{}';
	$ta = new stdclass; 										// HOLDS TST_ADDITIONAL PARAMS
	$ta->tstw = 'dmABS';										// WebApp
	$ta->tstv = $GLOBALS['dmx_version'];						// Version -- Should this be dmABS version specifically?
	$ta->tstf = abs_get_tst_flags();							// WebApp-specific flags
	$d = $GLOBALS['dmx_debug_settings'];
	if (!isset($_GET['tstd']) && isset($d->send_tstd) && $d->tstd) $ta->tstd = $d->tstd; // Debug string (can not override tstd in URL)
	$json = new Services_JSON();
	$tst_additional_params_json = $json->encode($ta);
	return $tst_additional_params_json;
	//
	// END CONSIDER MOVING TO XCOMPONENTS LAYER
}

// -------------------------------------------------------------------------------------------------

function abs_get_tst_flags()
{
	// Add dmABS-specific analytics flags to TST data
	
	global $dmx_options, $abs_opt, $abs_sitemode, $abs_seo;
	
	$f = '';

	// Is site in ADAPTED or AFFILIATE mode?
	if ($abs_sitemode == 'ADAPTED') 				$f .= 'D';
	if ($abs_sitemode == 'AFFILIATE')				$f .= 'F';

	// Is site showing the dealer tab, and if so, for what type of signup?
	if ($abs_opt['dealer_tab'])
	{
		if ($abs_opt['dealer_type'] == 'CLASSIC')
		{
			$f .= 'C';
		}
		else if ($abs_opt['dealer_type'] == 'ASSOCIATE')
		{
			$f .= 'A';
		}
	}
	
	// Is site using Easy SEO?
	if (!empty($abs_seo))							$f .= 'S';
	
	// CONSIDER MOVING TO XCOMPONENTS LAYER... (see also /ens/index.php)
	//
	// Is site using Google Analytics?
	if ($dmx_options['ganal']['accno'] != 'OFF') 	$f .= 'G';

	// Does URL contain NumberChooser control parameters?
	function preg_array($pattern, $array)
	{
		$match = FALSE;
		foreach ($array as $key => $value)
		{
			if (preg_match($pattern, $value))
			{
				$match = TRUE;
				break;
			}
		}
		return $match;
	}
	$url_keys = array_keys($_GET);
	if (preg_array('/dmx_range*/', 		$url_keys))	$f .= 'N';
	if (preg_array('/dmx_service*/', 	$url_keys))	$f .= 'N';
	if (preg_array('/dmx_plan*/', 		$url_keys))	$f .= 'N';
	if (preg_array('/dmx_gold*/', 		$url_keys))	$f .= 'N';
	if (preg_array('/dmx_areacode*/', 	$url_keys))	$f .= 'N';
	$f = preg_replace('/N+/', 'N', $f);
	//
	// END CONSIDER MOVING TO XCOMPONENTS LAYER
	
	return $f;
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// MENU BAR

function abs_construct_menu($menu, $url)
{
	// Build the tabbed menu from the information supplied in $menu
	// and the links for the page footer
	global $abs_root, $abs_path, $abs_xstate;
	
	// Get the NumberChooser State to display on RHS
	$nc_state  = $abs_xstate->range . ' ';
	$nc_state .= $abs_xstate->areaname ? '(' . $abs_xstate->areaname . ') ' : ' ';
	$nc_state .= abs_translate_service($abs_xstate->service) . ' ';
	$nc_state .= abs_translate_plan($abs_xstate->plan);
	
	// Get LoginStatus
	ob_start();
	$xparams['textonly'] = 1;
	$xparams['result_loginregister'] = $abs_root . '/numbers/ukgeo/login.php';
	dmx_render('dmshop.loginstatus', 'TheLogger', $xparams);
	$lst = ob_get_clean();
	
	// Build the tabbed menu from the information supplied in $menu array
	$tabs  = "<div id=\"tabbed_menu\">\n"; // Holds HTML for tabs
	$tabs .= "<span id=\"login_state\"> |&nbsp; $lst</span>\n";
	$tabs .= "<a id=\"nc_state\" href=\"$abs_root/numbers/{$abs_xstate->range}/choose.php\">$nc_state</a>\n";
	$tabs .= "\t<ul>\n";
	$footer_links = '';
	$num_tabs = count($menu) - 1; // -1 to allow for $menu['sub'] - the common RHS of the submenu
	for ($i=0; $i<$num_tabs; $i++)
	{
		$add_class = '';
		if (strpos(strtolower($menu[$i]['link']), $abs_path['tab']))
		{
			$tabs .= "\t\t<li class=\"current\"><a href=\"" . $abs_root . $menu[$i]['link']. "\" onmouseover=\"sub_menu_show('sub_menu_content');\">" . $menu[$i]['text'] . "</a></li>\n";			
			$selected_tab = $i;
		}
		else
		{
			$tabs .= "\t\t<li><a href=\"" . $abs_root . $menu[$i]['link']. "\" onmouseover=\"sub_menu_show('sub_menu_$i');\">" . $menu[$i]['text'] . "</a></li>\n";			
		}
		$footer_links .= "\t\t\t<a href=\"" . $abs_root . $menu[$i]['link']. "\">" . $menu[$i]['text'] . "</a>\n\t\t\t|\n";			
	}
	$tabs .= "\t</ul>\n</div>\n";
	$footer_links = substr($footer_links, 0, -5) . "\n\t\t\t<br>\n\n";
	
	// Build the common submneu RHS
	$rhs = '';
	$num_items = count($menu['sub']['rhs']);
	for ($i=0; $i<$num_items; $i++)
	{
		$rhs .= "\t\t\t<a href=\"" . $abs_root . $menu['sub']['rhs'][$i]['link'] . "\">" . $menu['sub']['rhs'][$i]['text'] . "</a>\n";			
		$rhs .= "\t\t\t&nbsp;|&nbsp;\n";
	}
	$rhs = substr($rhs, 0, -17);
	
	// Build the selected submenu
	if (!isset($selected_tab)) $selected_tab = 0;
	$submenu = $menu[$selected_tab]['sub'];
	$sub  = "\t<div id=\"sub_menu_content\" onmouseover=\"abs_do_they_dally();\">\n";
	$sub .= "\t\t<div id=\"sub_menu_rhs\">\n";
	$sub .= $rhs;
	$sub .= "\t\t</div>\n";
	$num_items = count($submenu);
	for ($i=0; $i<$num_items; $i++)
	{
		$add_class = '';
		if (strpos(strtolower($submenu[$i]['link']), strtolower($abs_path['sub'])))
		{
			$add_class = ' class="current"';
		}
		$sub .= "\t\t<a href=\"" . $abs_root . $submenu[$i]['link']. "\"$add_class>" . $submenu[$i]['text'] . "</a>\n\t\t|\n";			
		$footer_links .= "\t\t\t<a href=\"" . $abs_root . $submenu[$i]['link']. "\">" . $submenu[$i]['text'] . "</a>\n\t\t\t|\n";
	}
	$sub = substr($sub, 0, -4) . "\n\t</div>\n\n";
	$footer_links = substr($footer_links, 0, -5);
	
	// Build the hidden sub-menus from the information supplied in $menu
	$hid = '';
	for ($i=0; $i<$num_tabs; $i++)
	{
		if ($i == $selected_tab) continue;
		$hid .= "\t<!-- HIDDEN SUB-MENU $i -->\n";
		$hid .= "\t<div class=\"hidden_sub_menu\" style=\"z-index: " . (100 + $i) ."\" id=\"sub_menu_$i\" onmouseover=\"abs_do_they_dally();\">\n";
		$hid .= "\t\t<div class=\"hidden_sub_menu_content\">\n";
		$hid .= "\t\t\t<div class=\"hidden_sub_menu_rhs\">\n";
		$hid .= $rhs;
		$hid .= "\t\t\t</div>\n";
		$submenu = $menu[$i]['sub'];
		$num_items = count($submenu);
		for ($j=0; $j<$num_items; $j++)
		{
			$hid .= "\t\t<a href=\"" . $abs_root . $submenu[$j]['link']. "\">" . $submenu[$j]['text'] . "</a>\n\t\t|\n";			
		}
		$hid = substr($hid, 0, -4) . "\t\t</div>\t</div>\n";
		$hid .= "\t<!-- END HIDDEN SUB-MENU $i -->\n\n";
	}
	return array($tabs, $sub, $hid, $footer_links);
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// PATH, PAGE, SERVICE AND PLAN

function abs_analyse_path($path)
{
	global $abs_root;
	if ($abs_root) $path = str_replace($abs_root, '', $path);
	$parts = array_pad(explode('/', substr($path, 1)), 3, NULL);
	if (count(array_filter($parts)) > 1)
	{
		return array('full' => $parts, 'tab' => $parts[0], 'sub' => $parts[1], 'remainder' => array_slice($parts, 2));
	}
	else
	{ 
		return array('full' => $parts, 'tab' => 'home', 'sub' => $parts[0], 'remainder' => array()); // Site index page only
	}
}

// -------------------------------------------------------------------------------------------------

function abs_get_page_subject()
{
	// Try to determinde what the page is about from the URL and request parameters
	global $abs_path;
	$subject = array('range' => '', 'service' => '');
	switch($abs_path['tab'])
	{
		case 'numbers':
			$subject['range'] = strpos($abs_path['sub'], '.') > -1 ? strtoupper(substr($abs_path['sub'], 0, strpos($abs_path['sub'], '.'))) : $abs_path['sub'];
			$subject['range_disp'] = $subject['range'];
			switch($subject['range_disp'])
			{
				case 'ukgeo':
					$subject['range_disp'] = 'Local';
					break;
				case '07d':
					$subject['range_disp'] = '07-D';
					break;
				case '07k':
					$subject['range_disp'] = '07-K';
					break;
				case '07pn2':
					$subject['range_disp'] = '07-PN2';
					break;
				case 'GOLD_NUMBERS':
					$subject['range_disp'] = '';
					break;
			}
			break;
		case 'services':
			$subject['service'] = strpos($abs_path['sub'], '.') > -1 ? substr($abs_path['sub'], 0, strpos($abs_path['sub'], '.')) : $abs_path['sub'];
			break;
		default:
	}
	
	// Request parameters can override subject determination based on URL
	// CHECH THAT THIS IS STILL THE CASE - OR SUPERCEDED BY NCP
	//
	if (isset($_REQUEST['abs_range'])) $subject['range'] = $_REQUEST['abs_range'];
	if (isset($_REQUEST['abs_service'])) $subject['service'] = $_REQUEST['abs_service'];
	return $subject;
}

// -------------------------------------------------------------------------------------------------

function abs_translate_service($service)
{
	switch(strtolower($service))
	{
		case 'connect':
		case 'dmconnect':
			return '{GLOS:connect}';
		case 'voice':
		case 'dmvoice':
			return '{GLOS:voice}';
		case 'fax':
		case 'dmfax':
			return '{GLOS:fax}';
		case 'switchboard':
		case 'dmswitchboard':
			return '{GLOS:switchboard}';
		default:
			return 'Unknown Service';
	}
}

// -------------------------------------------------------------------------------------------------

function abs_translate_plan($plan)
{
	switch(strtolower($plan))
	{
		case 'bas':
			return '{GLOS:bas}';
		case 'pro':
			return '{GLOS:pro}';
		case 'ent':
			return '{GLOS:ent}';
		default:
			return 'Unknown Plan';
	}
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// CONTENT VERSIONS, PANELS AND FRAGMENTS

function abs_resolve_version()
{
	global $abs_root, $abs_authorised;
	if (isset($abs_authorised) && $abs_authorised && isset($_COOKIE['abs_content']))
	{
		// Get version, editmode_status and 'today' from cookie
		list($lv['version'], $lv['today'], $lv['editmode_status']) = explode('__', $_COOKIE['abs_content']);
	}
	else
	{
		$lv['version']  		= $GLOBALS['abs_opt']['version'];
		$lv['today'] 			= gmdate('Ymd');
		$lv['editmode_status'] 	= 'off';
		if (!isset($_COOKIE['abs_content'])) setcookie('abs_content', $lv['version'] . '__' . $lv['today'] . '__off', time() + 60*60*24, $abs_root ? $abs_root : '/');
	}
	$lv['default']  = $GLOBALS['abs_opt']['version_default'];
	return $lv;
}

// -------------------------------------------------------------------------------------------------

function abs_inc_panel($panel_id)
{
	// Get a page panel
	//
	global $panel, $abs_xstate;
	$owner = str_replace('.php', '', implode('-', array_filter($GLOBALS['abs_path']['full'])));
	$extra = array($abs_xstate->service, $abs_xstate->plan);
	$panel->render($owner, $panel_id, $extra);
}

// -------------------------------------------------------------------------------------------------

function abs_inc_fragment($panel_id)
{
	// Get a shared panel (fragment)
	//
	global $panel, $abs_xstate;
	$extra = array($abs_xstate->service, $abs_xstate->plan);
	$panel->render('fragment', $panel_id, $extra);
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// SUBSTITUTIONS

function abs_compile_substitutions()
{
	global $abs_glos, $abs_root, $abs_opt, $abs_seo, $abs_debug;

	$abs_debug->heading(__FUNCTION__);

	if (isset($_SESSION['ABS_SUB']))
	{
		// Load from session cache
		$abs_debug->msg('Loading substitutions from session cache');
		$abs_glos->search  = $_SESSION['ABS_SUB']['search'];
		$abs_glos->replace = $_SESSION['ABS_SUB']['replace'];
		return;
	}
	
	$abs_debug->msg('Compliling substitutions');

	// Define dynamic terms FIRST
	// (may be expanded to other glossary terms)
	$search = array ('{SUB:dmid}',
					 '{SUB:company_brandname}',
					 '{SUB:company_fullname}',
					 '{SUB:company_displayname}',
					 '{SUB:company_logo}',
					 '{SUB:company_website}',
					 '{SUB:contact_tel}',
					 '{SUB:contact_email}',
					 '{SUB:contact_address}',
					 '{SUB:contact_skype}',
					 '{SUB:contact_alltalk_no}',
					 '{SUB:contact_alltalk_no_int}',
					 '{SUB:contact_alltalk_ppm}',
					 '{SUB:login_status}'
					 );
	
	$replace = array ($GLOBALS['dmx_options']['dealer_id'],
					  $abs_opt['company_brandname'],
					  $abs_opt['company_fullname'],
					  $abs_opt['company_displayname'],
					  $abs_opt['company_logo'],
					  $abs_opt['company_website'],
					  $abs_opt['contact_tel'],
					  $abs_opt['contact_email'],
					  $abs_opt['contact_address'],
					  $abs_opt['contact_skype'],
					  $abs_opt['contact_alltalk_no'],
					  $abs_opt['contact_alltalk_no_int'],
					  $abs_opt['contact_alltalk_ppm'],
					  isset($GLOBALS['abs_login_status']) ? $GLOBALS['abs_login_status'] : ''
					  );
	
	$abs_glos->append($search, $replace);
	$abs_glos->append_from_file(DOCROOT . $GLOBALS['abs_root'] . '/config/glossary.php');

	// Define special paths LAST
	// (other glossary terms may contain path placeholders)
	$search = array ('{THEME}',
					 '{GLIB}',
					 '{ROOT}'
					 );
	
	$replace = array ($abs_root . '/themes/' . $abs_opt['theme'],
					  $abs_root . '/themes/' . $abs_opt['theme'] . '/sgm',
					  $abs_root
					  );

	$abs_glos->append($search, $replace);
	
	if (isset($abs_seo) && !empty($abs_seo)) abs_add_outbound_url_mappings($abs_seo);
	
	// Cache in session
	$_SESSION['ABS_SUB']['search'] 	= $abs_glos->search;
	$_SESSION['ABS_SUB']['replace'] = $abs_glos->replace;
}

// -------------------------------------------------------------------------------------------------

function abs_add_outbound_url_mappings($seo_arr)
{
	global $abs_opt, $abs_glos, $abs_debug;
	
	if (!$abs_opt['url_mapping']) return;
	
	$abs_debug->heading(__FUNCTION__);

	$search  = array();
	$replace = array();
	foreach($seo_arr as $real_url => $seo)
	{
		if ($seo['desired_url'])
		{			
			// Assumes consistent use of double quotes at start of href=" or action=" in HTML
			array_push($search,  '"' . $real_url.'.php');
			array_push($replace, '"' . $seo['desired_url'].'.php');
		}
	}
	ob_flush();
	$abs_glos->append($search, $replace);
}

// -------------------------------------------------------------------------------------------------

function abs_prepend_dynamic_substitutions()
{
	global $abs_glos, $abs_subject, $abs_tariff, $abs_xstate;

	$range_disp = strtoupper($abs_xstate->range);
	switch($abs_xstate->range)
	{
		case 'ukgeo':
			$range_disp = 'Local';
			if ($abs_subject['range'] == '0207') $range_disp = '0207';
			break;
		case '07d':
			$range_disp = '07-D';
			break;
		case '07k':
			$range_disp = '07-K';
			break;
		case '07pn2':
			$range_disp = '07-PN2';
			break;
	}
	if ($abs_xstate->range == 'ukgeo' && $abs_xstate->areaname)
	{
		$range_disp = $abs_xstate->areaname;
		$icon_range = '<span class="infotext">' . $abs_xstate->areacode . '<span class="tipcontents">' . $abs_xstate->areacode . ' (' . $abs_xstate->areaname . ') numbers</span></span>';
	}
	else
	{
		$icon_range = '{GLOS:icon_range_' . $abs_xstate->range . '}';
		if ($abs_subject['range'] == '0207') $icon_range = '{GLOS:icon_range_0207}';
	}

	// tf stands for trolley focus
	$search = array ('{DYN:range}',
					 '{DYN:rangeiconmid}',
					 '{DYN:rangelink}',
					 '{DYN:service}',
					 '{DYN:plan}',
					 '{DYN:areacode}',
					 '{DYN:areaname}',
					 '{DYN:tf_number}',
					 '{DYN:tf_service}',
					 '{DYN:tf_plan}',
					 );
		
	$replace = array ($range_disp,
					  $icon_range,
					 isset($abs_subject['range']) ? strtolower($abs_subject['range']) : '',
					  $abs_xstate->service,
					  $abs_xstate->plan,
					  $abs_xstate->areacode,
					  $abs_xstate->areaname,
					  isset($GLOBALS['dmx_focus']) ? $GLOBALS['dmx_focus']['number'] 							: 'Unknown Number',
					  isset($GLOBALS['dmx_focus']) ? abs_translate_service($GLOBALS['dmx_focus']['service']) 	: 'Unknown Service',
					  isset($GLOBALS['dmx_focus']) ? abs_translate_plan($GLOBALS['dmx_focus']['plan']) 			: 'Unknown Plan',
					  );
					  
	$abs_glos->prepend($search, $replace);
}

// -------------------------------------------------------------------------------------------------
// INBOUND URL MAPPINGS

function abs_create_inbound_url_mappings($seo_arr)
{
	global $abs_opt, $abs_debug;
	
	if (!$abs_opt['url_mapping']) return 'URL_MAPPING_NOT_ENABLED';
	
	$abs_debug->heading(__FUNCTION__);

	$abs_debug->msg('Creating .htaccess file for inbound URL mappings');
	$fp = @fopen(DOCROOT . $GLOBALS['abs_root'] . '/.htaccess', 'w');
	if (!$fp)
	{
		$abs_debug->msg('Cound not write to ' . DOCROOT . $GLOBALS['abs_root'] . '/.htaccess - Permission Denied');
		return 'PERMISSION_DENIED';
	}
	fwrite($fp, 'RewriteEngine On' . PHP_EOL);
	fwrite($fp, PHP_EOL);
	fwrite($fp, '## -------------------------------------------------------------------------------------------------' . PHP_EOL);
	fwrite($fp, '## ## Inbound dmABS URL mappings...' . PHP_EOL);
	fwrite($fp, '## -------------------------------------------------------------------------------------------------' . PHP_EOL);
	fwrite($fp, PHP_EOL);
	$count = 0;
	foreach($seo_arr as $real_url => $seo)
	{
		if ($seo['desired_url'])
		{
			fwrite($fp, sprintf('RewriteRule ^%-50s %-50s[L]'.PHP_EOL, substr($seo['desired_url'].'\.php$', 1), substr($real_url, 1) . '.php'));
			$count++;
		}
	}
	fclose($fp);
	return $count ? 'SUCCESS' : 'NO_MAPPINGS_DEFINED';
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------

function get_login_status()
{
	// Get the login status XComponenet
	ob_start();
	$xparams['result_loginregister'] = $GLOBALS['abs_root'] . '/login.php';
	$xparams['textonly'] = 1;
	dmx_render('dmshop.loginstatus', 'TheLogger', $xparams);
	$login_status = ob_get_contents();
	ob_end_clean();
	return $login_status;
}

// -------------------------------------------------------------------------------------------------

function abs_linewrap($string, $width=75, $break="\n", $cut='0')
{
	// See PHP wordwrap() documentation for explanation of parameters
	$array = explode("\n", $string);
	$string = '';
	foreach($array as $key => $val)
	{
		$string .= wordwrap($val, $width, $break, $cut);
		$string .= "\n";
	}
	return $string;
}

// -------------------------------------------------------------------------------------------------
// ------------ C O L O U R   U T I L I T Y   R O U T I N E S --------------------------------------
// -------------------------------------------------------------------------------------------------

function abs_decide_text_colour($col_string)
{
	list($r, $g, $b) = abs_get_rgb($col_string);
	$hsv = abs_rgb_to_hsv($r, $g, $b);
	if ($hsv['v'] < 65) return 'white';
	if ($hsv['s'] > 50) return 'white';
	return 'black';
	// $rgb = abs_hsv_to_rgb($hsv['h'], 100, 20);
	// return $rgb['hex'];
}

// -------------------------------------------------------------------------------------------------

function abs_generate_shades($col_string)
{
	// Return an array containg RGB values of shades of the spplied colour
	// and shades of its complimentary colour
	// 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%, 100%
	list($r, $g, $b) = abs_get_rgb($col_string);
	$hsv = abs_rgb_to_hsv($r, $g, $b);
	$hc = ($hsv['h'] + 180) % 360;
	$wb = ($hsv['h'] + 40) % 360;
	$cwb = ($hsv['h'] + 220) % 360;
	for ($i=0; $i<101; $i+=10)
	{
		$shade['sat'][$i]   = abs_hsv_to_rgb($hsv['h'], $i,        $hsv['v']);
		$shade['val'][$i]   = abs_hsv_to_rgb($hsv['h'], $hsv['s'], $i       );
		$shade['csat'][$i]  = abs_hsv_to_rgb($hc,       $i,        $hsv['v']);
		$shade['cval'][$i]  = abs_hsv_to_rgb($hc,       $hsv['s'], $i       );
		$shade['wsat'][$i]  = abs_hsv_to_rgb($wb,       $i,        $hsv['v']);
		$shade['wval'][$i]  = abs_hsv_to_rgb($wb,       $hsv['s'], $i       );
		$shade['cwsat'][$i] = abs_hsv_to_rgb($cwb,      $i,        $hsv['v']);
		$shade['cwval'][$i] = abs_hsv_to_rgb($cwb,      $hsv['s'], $i       );
	}
	return $shade;
}

// -------------------------------------------------------------------------------------------------

function abs_get_rgb($col_string)
{
	if (substr($col_string, 0, 1) != '#') $col_string = '#' . dechex($col_string); // Value is DECIMAL, so convert to HEX
	if (strlen($col_string) > 4)
	{
		// 6-digit
		$r = '0x' . substr($col_string, 1, 2);
		$g = '0x' . substr($col_string, 3, 2);
		$b = '0x' . substr($col_string, 5, 2);
	}
	else
	{
		// 3-digit
		$r = substr($col_string, 1, 1);
		$g = substr($col_string, 2, 1);
		$b = substr($col_string, 3, 1);
		$r = '0x' . $r . $r;
		$g = '0x' . $g . $g;
		$b = '0x' . $b . $b;
	}
	$r = hexdec($r);
	$g = hexdec($g);
	$b = hexdec($b);
	return array($r, $g, $b);
}

// -------------------------------------------------------------------------------------------------

function abs_rgb_to_hsv($r, $g, $b)
{
	// Convert from RGB to HSV colourspace
	// $r, $g and $b are red, green and blue values between 0 and 255

	$r/=255; $g/=255; $b/=255; // Get RGB values between 0 and 1
	$min = min($r, $g, $b); // Min. value of RGB
	$max = max($r, $g, $b); // Max. value of RGB
	$delta = $max - $min;   // Delta RGB value
	
	if ($delta == 0)
	{
		// This is a gray, no chroma
		$h = 0;
		$s = 0;
	}
	else
	{
		// Chromatic data...
		if      ($r == $max) $h = 60 * ($g - $b) / $delta;
		else if ($g == $max) $h = 60 * ($b - $r) / $delta + 120;
		else if ($b == $max) $h = 60 * ($r - $g) / $delta + 240;
		if ($h < 0)   $h += 360;
		if ($h > 360) $h -= 360;
		$s = $delta / $max * 100;
	}
	$v = $max * 100;

	// $h is hue - position on colour wheel: 0 - 360 degrees
	// $s is saturation                    : 0 - 100 %
	// $v is value (or brightnesss)        : 0 - 100 %
	abs_hsv_to_rgb($h, $s, $v);
	return array('h' => $h, 's' => $s, 'v' => $v);
}

// -------------------------------------------------------------------------------------------------

function abs_hsv_to_rgb($h, $s, $v)
{
	// Convert from HSV to RGB colourspace
	// $h is hue - position on colour wheel: 0 - 360 degrees
	// $s is saturation                    : 0 - 100 %
	// $v is value (or brightnesss)        : 0 - 100 %
	
	$h/=360; $s/=100; $v/=100; // Get HSV values between 0 and 1
	if ($s == 0)
	{
	   $r = $g = $b = $v * 255; // No chroma
	}
	else
	{
	   $var_h = $h * 6;
	   if ($var_h == 6) $var_h = 0; // H must be < 1
		   $var_i = floor($var_h);
		   $var_1 = $v * (1 - $s);
		   $var_2 = $v * (1 - $s * ($var_h - $var_i));
		   $var_3 = $v * (1 - $s * (1 - ($var_h - $var_i)));
		   if      ($var_i == 0) { $var_r = $v     ; $var_g = $var_3 ; $var_b = $var_1; }
		   else if ($var_i == 1) { $var_r = $var_2 ; $var_g = $v     ; $var_b = $var_1; }
		   else if ($var_i == 2) { $var_r = $var_1 ; $var_g = $v     ; $var_b = $var_3; }
		   else if ($var_i == 3) { $var_r = $var_1 ; $var_g = $var_2 ; $var_b = $v    ; }
		   else if ($var_i == 4) { $var_r = $var_3 ; $var_g = $var_1 ; $var_b = $v    ; }
		   else                  { $var_r = $v     ; $var_g = $var_1 ; $var_b = $var_2; }
		   $r = $var_r * 255;
		   $g = $var_g * 255;
		   $b = $var_b * 255;
	}
	$hex = '#' . strtoupper(str_pad(dechex($r), 2, '0', STR_PAD_LEFT) . str_pad(dechex($g), 2, '0', STR_PAD_LEFT) . str_pad(dechex($b), 2, '0', STR_PAD_LEFT)); // Web ready hex string
	return array('r' => $r, 'g' => $g, 'b' => $b, 'hex' => $hex);
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------

function abs_get_ip()
{
	// Get info about users IP and proxy for security
	$proxy = '';
	if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
	{
		if (isset($_SERVER['HTTP_CLIENT_IP']))
		{
			$proxy = $_SERVER['HTTP_CLIENT_IP'];
		}
		else
		{
			$proxy = $_SERVER['REMOTE_ADDR'];
		}
		$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
	}
	else
	{
		if (isset($_SERVER['HTTP_CLIENT_IP']))
		{
			$ip = $_SERVER['HTTP_CLIENT_IP'];
		}
		else
		{
			$ip = $_SERVER['REMOTE_ADDR'];
		}
	}
	return $ip . $proxy;
}

?>