<?php
/* -----------------------------------------------------------------------------------
	This module contains two merge functions, one for date and one for country arrays
		plus ancillary functions.
		(c) Copyright 2004 Arthur Sale, University of Tasmania
----------------------------------------------------------------------------------- */

/* ------------------------------------------------------------------------------
 This function computes an integer datestamp to a month resolution.
 (c) Copyright 2004 Arthur Sale, University of Tasmania
 Parameters:
 	An array and an index into it	
 Returns:
	Result: the datestamp
------------------------------------------------------------------------------ */
	function datestamp(&$x, $j)
	// reference parameter for efficiency, not changed
	// invalid dates return zero, ie earlier than any possible date.
	{
		if ($j < count($x)) {
			// $mo is in {0..11}
			$mo = (int) strpos('JanFebMarAprMayJunJulAugSepOctNovDec', $x[$j]["month"])/3;
			return (int) $x[$j]["year"]*12 + $mo;
		} else {
			return 0;
		}
	}

/* ------------------------------------------------------------------------------
 This function merges two date arrays, to produce a single consolidated array.
 Note that either of the two arrays might be missing a view for a month or more.
 Precondition: both arrays are ordered in descending order of date (latest first)
 	as is the result array.
 (c) Copyright 2004 Arthur Sale, University of Tasmania
 Parameters:
 	Two date-ordered arrays: abstracts and downloads	
 Returns:
	Result: merged array also ordered by date
	
	NJS 2006-01-18: Added count of distinct countries.
------------------------------------------------------------------------------ */
	function merge_dates(&$aa, &$ad)
	// reference parameters for efficiency, not changed
	{
		$merged = array();
		// start of all arrays
		$i = 0;
		$indexa = 0;
		$indexd = 0;
		// set up the rest of the loop invariant
		$datea = datestamp($aa,0);
		$dated = datestamp($ad,0);
		// $datei is initialized to the most recent date for which an access is recorded
		$datei = max($datea, $dated);
		
		while (($datea + $dated) != 0) {
			// Loop invariant: All elements prior to $indexa in $aa and $indexd in $ad 
			//     have been transferred to $merged (ie all dates *after* $datei)
			// Progress: $date1 is decremented by 1 (ie one month *earlier*)
			// Termination: No more elements, signalled by both datestamps == 0.
			if (($datea == $datei) and ($dated == $datei)) {
//				Both are valid and equal to the current date being displayed, the majority case
				$merged[$i] = array(
					"downloads"  => $ad[$indexd]["count"],
					"dcountries" => $ad[$indexd]["countries"],
					"abstracts"  => $aa[$indexa]["count"],
					"acountries" => $aa[$indexa]["countries"],
					"month"      => $ad[$indexd]["month"], // same value as aa
					"year"       => $ad[$indexd]["year"]   // same value as aa
				);
				$indexa++; $indexd++;
				$datea = datestamp($aa,$indexa);
				$dated = datestamp($ad,$indexd);
			} elseif ($datea == $datei) {
//				aa (but not ad) is equal to the current date being displayed
				$merged[$i] = array(
					"downloads"  => 0,
					"dcountries" => 0,
					"abstracts"  => $aa[$indexa]["count"],
					"acountries" => $aa[$indexa]["countries"],
					"month"      => $aa[$indexa]["month"],
					"year"       => $aa[$indexa]["year"]
				);
				$indexa++;
				$datea = datestamp($aa,$indexa);
			} elseif ($dated == $datei) {
//				ad (but not aa) is equal to the current date being displayed
				$merged[$i] = array(
					"downloads"  => $ad[$indexd]["count"],
					"dcountries" => $ad[$indexd]["countries"],
					"abstracts"  => 0,
					"acountries" => 0,
					"month"      => $ad[$indexd]["month"], 
					"year"       => $ad[$indexd]["year"]  
				);
				$indexd++;
				$dated = datestamp($ad,$indexd);
			} else {
//				Neither aa nor ad are equal to the current date being displayed
//				So generate an empty record
				$monthname = array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
				$merged[$i] = array(
					"downloads"  => 0,
					"dcountries" => 0,
					"abstracts"  => 0,
					"acountries" => 0,
					"month"      => $monthname[$datei % 12], 
					// NJS 2006-06-14 BUG FIX: added () around the expression
					// to ensure that the (int) is applied to the whole thing.
					// We were getting fractional years in the output :(
					"year"       => (int) ( $datei / 12 )
				);
			}
			// Progress: one more entry in $merged, and date earlier by one month
			$i++;
			$datei--;
		}
		return $merged;
	}

/* ------------------------------------------------------------------------------
 This function merges two country arrays, to produce a single consolidated array.
 Note that either of the two arrays might be missing a country in the other.
 
 (c) Copyright 2004 Arthur Sale, University of Tasmania
 
 Precondition: both arrays are ordered in descending order of views.
 Postcondition: result array contains records for every country in $aa and $ad, 
 	and is ordered in descending order of download views.
------------------------------------------------------------------------------ */
function merge_countries($aa, &$ad)
// reference parameter $ad for efficiency, not changed, 
//	however the $aa value parameter is altered and is not prapogated back
{
	$merged = array();
	// Copy acrosss the download array, adding counts from the abstract array as needed.
	for ($i=0; $i<count($ad); $i++) {
		$merged[$i] = array(
			"country_code"      => $ad[$i]["country_code"],
			"country_name"      => $ad[$i]["country_name"],
			"country_downloads" => $ad[$i]["count"],
			"country_abstracts" => 0
			);
		$c_code = $merged[$i]["country_code"];
		for ($j=0; $j<count($aa); $j++) {
			if ($c_code == $aa[$j]["country_code"]) {
				// matching country in abstracts
				$merged[$i]["country_abstracts"] = $aa[$j]["count"];
				// render this entry dead in future with reserved country code
				$aa[$j]["country_code"] = '==';
				// and get out of the loop
				break;
			}
		} // for on $j
	} // for on $i
	
	// Copy what is left of the abstract array
	$i = count($merged);
	for ($j=0; $j<count($aa); $j++) {
			if ($aa[$j]["country_code"] != '==') {
				// country with only abstract views, so copy
				$merged[$i] = array(
					"country_code"      => $aa[$j]["country_code"],
					"country_name"      => $aa[$j]["country_name"],
					"country_downloads" => 0,
					"country_abstracts" => $aa[$j]["count"]
					);
				// and increment $i
				$i++;
			}
	} // for on $j
	return $merged;
}
		
?>
