<?php 
/*******************************************************************************
 * Copyright (c) 2010 Eclipse Foundation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Wayne Beaton (Eclipse Foundation)- initial API and implementation
 *******************************************************************************/
require_once(dirname(__FILE__) . "/Project.class.php");
require_once(dirname(__FILE__) . "/images.inc");
require_once(dirname(__FILE__) . "/debug.php");
trace_file_info(__FILE__);

class ProjectSummary {
	/**
	 * @var Project
	 */
	var $project;
	
	function __construct($project) {
		$this->project = $project;
	}
	
	/**
	 * Answer some HTML describing the repositories.
	 * 
	 * @return string
	 */
	function getSourceRepositoriesHtml($max = 25) {
		$repositories = $this->project->getSourceRepositories();
		if (!$repositories) return null;
		
		$html = "<p>Eclipse projects store all of their source code in public revision control systems.</p>";			
		$html .= "<ul>";
		foreach($repositories as $repository) {
			if ($max-- <= 0) {
				$html .= "<li>...</li>";
				break;
			}
			$name = $repository->getName();
			$link = $repository->getLink();
			$type = $repository->getType();
			$item = "<a href=\"$link\">$name</a> ($type)";
			if ($type == 'git') {
				$git = $repository->getGitUrl();
				$item .= "<ul>
					<li>Clone: $git</li>
					<li><a href=\"https://github.com/eclipse/$name\">Clone on GitHub</a></li>
				</ul>";				
			} else {
			}
			$html .= "<li>$item</li>";
		}	
		$html .= "</ul>";
		
		return $html;
	}
	
	function getUpdateSiteHtml() {
		$site = $this->project->getUpdateSiteUrl();
		if (!$site) return null;
	
		$html = "<p>This project maintains a p2 repository of binary artifacts. 
			Copy and paste this link into the &quot;Install New Software&quot; dialog
			to install this project's software.</p><p style=\"text-align:center\"><code>$site</code></p>
			<p>Note that the repository link will not necessarily display anything meaningful
			in your browser.</p>";

		return $html;
	}
	
	/**
	 * Answer some HTML describing the releases.
	 * 
	 * @param int $count (Optional) the maximum number of releases to show (5 by default).
	 */
	function getReleasesHtml($count = 10) {
		if (!$this->project->hasReleases()) return;
		/* @var App */
		global $App;
		
		$releases = array_reverse($this->project->getReleases());
		
		$html = "<table>";
		foreach($releases as $release) {
			/* @var $release Release */
			if($count-- <= 0) break;
			
			$name = $release->getName();
			$status = $release->getStatus();
			$download = $release->getDownload();
			$plan = $release->getPlan();
			$noteworthy = $release->getNoteworthyUrl();
			$date = $App->getFormattedDate($release->getDate(), 'short');
			
			$title = $name;
			if ($release->getDownload()) $title = "<a href=\"$download\">$title</a>";
			
			if ($plan) {
				// if the URL ends with .xml, assume a standard format plan and provide a
				// URL that redirects to the standard plan formatter. Otherwise, just use
				// the provided URL.
				$planurl = preg_match('/\\.xml$/', $plan) ? "/projects/project-plan.php?planurl=$plan" : $plan;
				$plan = "<a href=\"$planurl\"><img title=\"Plan for $name\" src=\"http://dev.eclipse.org/small_icons/mimetypes/x-office-presentation.png\"/></a>";
			}
			$noteworthy = $noteworthy ? "<a href=\"$noteworthy\"><img title=\"New and Noteworthy for $name\" src=\"http://dev.eclipse.org/small_icons/mimetypes/x-office-document.png\"/></a>" : "";
			$html .= "<tr><td>$date</td><td>$title $status $plan $noteworthy</td></tr>";
		}
		$html .= "</table>";

		return $html;
	}
	
	function getForumsHtml() {		
		if (!$this->project->getNewsgroups()) return null;
		
		$newsgroups = $this->project->getNewsgroups();
		usort($newsgroups, array('ProjectSummary','_sortProjectForums'));
		
		$html = "<p>This project uses the following <a href=\"/forums\">forums</a>:</p>";
		$html .= "<ul>";
		foreach ($newsgroups as $newsgroup) {
			/* @var $newsgroup Newsgroup */
			$name = $newsgroup->getName();
			if (!$name) continue;
			$forumUrl = "http://www.eclipse.org/forums/$name";
			
			$info = "<a href=\"$forumUrl\">$name</a> ";
			if ($newsgroup->getType() == 'main') $info .= ' (main)';
			
			$description = $newsgroup->getDescription();
			if ($description) $info .= "<br/>$description";
			
			$html .= "<li>$info</li>";
		}
		$html .= "</ul>";
		
		return $html;
	}
	
	/**
	 * This function is used to sort both newsgroups and mailing lists.
	 * Any entry designated as 'main' are at the top. The rest are listed
	 * below. Entries in the respective groups are sorted by name.
	 * 
	 * @internal
	 * @param Newsgroup $a
	 * @param newsgroup $b
	 * @return number
	 */
	function _sortProjectForums($a, $b) {
		$typeA = $a->getType();
		$typeB = $b->getType();
		
		if (($typeA == 'main') && ($typeB != 'main')) return -1;
		if (($typeA != 'main') && ($typeB == 'main')) return 1;
				
		return strcasecmp($a->getName(), $b->getName());
	}
	
	function getCommittersHtml() {
		require_once 'Committer.class.php';
		
		$committers = getCommittersForProject($this->project->getId());
		$html = "<h6>Project Leads</h6><ul>";
		foreach ($committers as $committer) {
			if (!$committer->isProjectLead($this->project->getId())) continue;
			$name = htmlentities("$committer->$firstName $committer->lastName");
			$html .= "<li>$name</li>";
		}
		$html .= "</ul>";
		
		$html .= "</ul>";
		
		$html .= "<h6>Committers</h6><ul>";
		foreach ($committers as $committer) {
			$name = htmlentities("$committer->$firstName $committer->lastName");
			$html .= "<li>$name</li>";
		}
		$html .= "</ul>";
	
		return $html;
	}
	
	function getMailingListsHtml() {
		$mailinglists = $this->project->getMailingLists();
		if (!$mailinglists) return;
		
		usort($mailinglists, array('ProjectSummary','_sortProjectForums'));
		
		$html = "<p>This project uses the following <a href=\"/mail\">mailing lists</a>:</p>";
		
		$html .= "<ul>";
		$hasDevList = false;
		foreach ($mailinglists as $list) {
			$name = $list->getName();
			$listUrl = "http://dev.eclipse.org/mailman/listinfo/$name";
			
			$info = "<a href=\"$listUrl\">$name</a> ";
			
			if ($list->getType() == 'main') $info .= ' (main)';
			
			$description = $list->getDescription();
			if ($description) $info .= "<br/>$description";
			
			if (preg_match('/\-(dev|pmc)$/', $name)) $hasDevList = true;
			
			$html .= "<li>$info</li>";
		}
		$html .= "</ul>";
		
		if ($hasDevList) 
			$html .= "<p>Note that -dev and -pmc lists are intended for project-related
				communications among project developers.</p>";
		
		return $html;
	}
		
	function getCommitsActivityHtml($width=800, $height=100) {
		if (!$this->project->getCommitActivity()) return null;
		
		$this->requiresGoogleChartsSupport();
		
		global $App;
		$divName = 'CommitActivityDiv';
		$chartJS = $this->getCommitActivityJS($divName, $width, $height);
		$App->AddExtraHtmlHeader("<script type=\"text/javascript\">$chartJS</script>");
				
		return "<div id=\"$divName\"></div>";
	}
	/**
	* Private - Generate the JavaScript code required to render the
	* commit activity pie chart using Google Chart APIs.
	*
	* THIS METHOD IS NOT PUBLIC API.
	*
	* @internal
	* @param string $divName Name of the div that contains the chart.
	* @param int $width Width of the chart (defaults to 800px)
	* @param int $height Height of the chart (defaults to 100px).
	*
	* @return string
	*/
	function getCommitActivityJS($divName, $width=800, $height=100) {
		$js = "google.load(\"visualization\", \"1\", {packages:[\"corechart\"]});";
      	$js .= "google.setOnLoadCallback(drawChart_$divName);";
      	
		$js .= "function drawChart_$divName() {
	        	var data = new google.visualization.DataTable();
	        	data.addColumn('string', 'Period');
	        	data.addColumn('number', 'Commits');";
		 
		$activity = $this->project->getCommitActivity();
		$range = $this->getPeriodRange(array_keys($activity));
		
		$total = count($range);
		 
		$js .= "data.addRows($total);";
		$index = 0;
		foreach ($range as $period => $label) {
			$count = isset($activity[$period]) ? $activity[$period] : 0;
			$js .= "data.setValue($index, 0, '$label');";
			$js .= "data.setValue($index, 1, $count);";
			$index++;
		}
		 
		$js .= "var chart = new google.visualization.ColumnChart(document.getElementById('$divName'));";
      	$js .= "chart.draw(data,{titlePosition:\"none\",width:$width, height:$height,hAxis: {title: \"Period\"},legend: \"none\"});";
		$js .= "}";
		 
		return $js;
	}
	
	function getPeriodRange($periods) {
		sort($periods);
		$min = reset($periods);
		$max = end($periods);
		
		// TODO deal with malformed data.
		preg_match('/^(\d\d\d\d)(\d\d)$/', $min, $matches);
		$year = $matches[1];
		$month = $matches[2];
		
		$range = array();
		while (true) {			
			$period = (int)sprintf('%04d%02d', $year, $month);
			$date = date("F Y", strtotime("$year-$month-01"));
			$range[$period] = $date;
			if ($period == $max) break;
			if (++$month > 12) {
				$year++;
				$month = 1;
			}
		}
		return $range;
	}
	
	function requiresGoogleChartsSupport() {		
		require_once dirname(__FILE__) . '/util/google-charts.php';
	}
	
	/**
	 * Return HTML that provides a "company commit activity" pie chart
	 * using the Google Chart APIs. Note that calling this method will
	 * automatically add the necessary JavaScript libraries to the page.
	 * 
	 * Only the last three months of activity is reported.
	 *
	 * @see Project#getCompanyCommitActivity();
	 * 
	 * @return string|null
	 */
	function getCompanyCommitActivityHtml($width=450, $height=300) {
		if (!$this->project->getCompanyCommitActivity()) return null;
		
		$this->requiresGoogleChartsSupport();
		
		global $App;
		$divName = 'CompanyCommitDiv';
		$chartJS = $this->getCompanyCommitActivityJS($divName, $width, $height);
		$App->AddExtraHtmlHeader("<script type=\"text/javascript\">$chartJS</script>");
		
		return "<div id=\"$divName\"></div>";
	}
	
	function getCommitterCommitActivityHtml($width=450, $height=300) {
		if (!$this->project->getCommitterCommitActivity()) return null;
	
		$this->requiresGoogleChartsSupport();
	
		global $App;
		$divName = 'CommitterCommitDiv';
		$chartJS = $this->getCommitterCommitActivityJS($divName, $width, $height);
		$App->AddExtraHtmlHeader("<script type=\"text/javascript\">$chartJS</script>");
	
		return "<div id=\"$divName\"></div>";
	}
	/**
	 * Private - Generate the JavaScript code required to render the
	 * commit activity pie chart using Google Chart APIs.
	 * 
	 * THIS METHOD IS NOT PUBLIC API.
	 * 
	 * @internal
	 * @param string $divName Name of the div that contains the chart.
	 * @param int $width Width of the chart (defaults to 450px)
	 * @param int $height Height of the chart (defaults to 300px).
	 * 
	 * @return string
	 */
	function getCompanyCommitActivityJS($divName, $width=450, $height=300) {
		$js = "google.load(\"visualization\", \"1\", {packages:[\"corechart\"]});";
		$js .= "google.setOnLoadCallback(drawChart_$divName);";
      	$js .= "function drawChart_$divName() {
        	var data = new google.visualization.DataTable();
        	data.addColumn('string', 'Company');
        	data.addColumn('number', 'Commits');";
      	
      	$activity = $this->project->getCompanyCommitActivity();
      	$total = count($activity);
      	
      	$js .= "data.addRows($total);";
      	$index = 0;
      	foreach ($activity as $company => $count) {
      		$js .= "data.setValue($index, 0, '$company');";
        	$js .= "data.setValue($index, 1, $count);";
        	$index++;
      	}
      	
      	$js .= "var chart = new google.visualization.PieChart(document.getElementById('$divName'));";
        $js .= "chart.draw(data, {titlePosition:\"none\",width:$width,height:$height});";
      	$js .= "}";
      	
      	return $js;
	}	
	
	/**
	 * Private - Generate the JavaScript code required to render the
	 * commit activity pie chart using Google Chart APIs.
	 * 
	 * THIS METHOD IS NOT PUBLIC API.
	 * 
	 * @internal
	 * @param string $divName Name of the div that contains the chart.
	 * @param int $width Width of the chart (defaults to 450px)
	 * @param int $height Height of the chart (defaults to 300px).
	 * 
	 * @return string
	 */
	function getCommitterCommitActivityJS($divName, $width=450, $height=300) {
		// TODO Refactoring opportunity
		require_once(dirname(__FILE__) . "/Committer.class.php");
		
		$js = "google.load(\"visualization\", \"1\", {packages:[\"corechart\"]});";
		$js .= "google.setOnLoadCallback(drawChart_$divName);";
      	$js .= "function drawChart_$divName() {
        	var data = new google.visualization.DataTable();
        	data.addColumn('string', 'Committers');
        	data.addColumn('number', 'Commits');";
      	
      	$activity = $this->project->getCommitterCommitActivity();
      	$names = getCommitterNames(array_keys($activity));
      	
      	$total = count($activity);
      	
      	$js .= "data.addRows($total);";
      	$index = 0;
      	foreach ($activity as $committer => $count) {
      		$name = isset($names[$committer]) ? utf8_encode($names[$committer]) : $committer;
      		$js .= "data.setValue($index, 0, '$name');";
        	$js .= "data.setValue($index, 1, $count);";
        	$index++;
      	}
      	
      	$js .= "var chart = new google.visualization.PieChart(document.getElementById('$divName'));";
        $js .= "chart.draw(data, {titlePosition:\"none\",width:$width,height:$height});";
      	$js .= "}";
      	
      	return $js;
	}
				
	function renderReleases() {
		if (!$this->project->getReleases()) return;
		
		// TODO What do we do if the preview and full are the same length?
		$preview = $this->getReleasesHtml(5);
		$full = $this->getReleasesHtml(1000);
		
		// TODO Need to better understand function scope in JavaScript.
		// i.e. what happens if I include this twice on the same page?
		$html = "
			<script language=\"JavaScript\">
				function ShowFullReleases() {
					document.getElementById('previewReleases').style.display = 'none';
					document.getElementById('fullReleases').style.display = '';
				}
				function ShowPreviewReleases() {
					document.getElementById('fullReleases').style.display = 'none';
					document.getElementById('previewReleases').style.display = '';
				}
			</script>
			<div id=\"previewReleases\">
				$preview
				<p><a href=\"javascript:ShowFullReleases();\">more</a></p>
			</div>
			<div id=\"fullReleases\"style=\"display:none\">
				$full
				<p><a href=\"javascript:ShowPreviewReleases();\">less</a></p>
			</div>";

		$this->renderBox('Releases', "http://dev.eclipse.org/large_icons/mimetypes/package-x-generic.png", $html);
	}


	function getReviewsHtml($max = 10) {
		global $App;
		
		$reviews = $this->project->getReviews();
		if (!$reviews) return;
		
		$html = "<p><table>\n";
		$count = 0;
		foreach($reviews as $review) {
			/* @var $release Release */
			if($count++ >= $max) break;
			
			$projectName = $review->getProjectName();
			$reviewName = $review->getReviewName();
			$documentUrl = $review->getSlidesUrl();
			$date = $App->getFormattedDate($review->getReviewDate(), 'short');
			$date = str_replace(' ', '&nbsp;', $date);
			$iplogUrl = $review->getIplogUrl();
			
			$title = "$projectName $reviewName Review";
			if ($documentUrl) $title = "<a href=\"$documentUrl\">$title</a>";
			if ($review->isWithdrawn()) $title = "<span style=\"color:grey\">$title (withdrawn)</span>";
			
			$icons = '';
			if ($iplogUrl) 
				$icons .= "<a href=\"$iplogUrl\"><img style=\"vertical-align:top\" title=\"IP Log\" src=\"http://dev.eclipse.org/small_icons/status/dialog-information.png\"/></a>";
			if ($review->isSuccessful()) 
				$icons .= "<img style=\"vertical-align:top\" title=\"Review Successful\" src=\"/projects/images/ok.gif\">";		
			if ($review->isUnsuccessful()) 
				$icons .= "<img style=\"vertical-align:top\" title=\"Review Unsuccessful\" src=\"http://dev.eclipse.org/small_icons/actions/process-stop.png\">";
		
			$html .= "<tr><td>$date</td><td>$title $icons</td></tr>\n";
		}
		$html .= "</table></p>\n";
		
		return $html;
	}
	
	function getCommitsActivityHomeItem() {
		$activity = $this->getCommitsActivityHtml(450, 200);
		
		if (!$activity) return null;
		
		return "<div class=\"homeitem\">
			<h3>Overall Commit Activity</h3>
			<p>Commits on this project (lifetime).</p>
			$activity
		</div>";
	}
	
	function getCommitterCommitsActivityHomeItem() {
		$activity = $this->getCommitterCommitActivityHtml(450, 300);
		
		if (!$activity) return null;
		
		return "<div class=\"homeitem\">
			<h3>Committer Activity</h3>
			<p>Commits on this project by committers over the last three months.</p>
			$activity
		</div>";
	}
	
	function getCompanyCommitsActivityHomeItem() {
		$activity = $this->getCompanyCommitActivityHtml(450, 300);
		
		if (!$activity) return null;
		
		return "<div class=\"homeitem\">
			<h3>Organization Commit Activity</h3>
			<p>Commits on this project by supporting organization over the last three months.</p>
			$activity
		</div>";
	}
	
	function getSourceRepositoriesHomeItem() {
		$html = $this->getSourceRepositoriesHtml();
		if (!$html) return null;
		
		return "<div class=\"homeitem\">
		<h3>Source Repositories</h3>
			$html
		</div>";
	}
	
	function getUpdateSiteHomeItem() {
		$html = $this->getUpdateSiteHtml();
		if (!$html) return null;
		
		return "<div class=\"homeitem\">
		<h3>Software Repository</h3>
			$html
		</div>";
	}
	
	function getReleasesHomeItem($max = 5) {
		$html = $this->getReleasesHtml($max);
		if (!$html) return null;
	
		return "<div class=\"homeitem\">
			<h3>Releases</h3>
				$html
			</div>";
	}
	
	function getReviewsHomeItem($max = 10) {
		$html = $this->getReviewsHtml($max);
		if (!$html) return null;
	
		return "<div class=\"homeitem\">
				<h3>Reviews</h3>
					$html
			</div>";
	}
		
	
	function getCommunicationHomeItem() {
		$html = $this->getForumsHtml() . $this->getMailingListsHtml();
		if (!$html) return null;
	
		return "<div class=\"homeitem\">
				<h3>Communication</h3>
					$html
			</div>";
	}
			
		
	function getIncubationSideItem() {
		if (!$this->project->isInIncubationPhase()) return '';
		global $images;
		
		$headerImg = $this->project->isInIncubationConformingPhase() ?
			$images->incubation_conforming_small :
			$images->incubation_nonconforming_small;
		
		return "<div class=\"sideitem\">
			<h6><img src=\"$headerImg\" align=\"right\"/>Incubation</h6>
			<div style=\"text-align:center\"><a href=\"/projects/what-is-incubation.php\"><img
					align=\"center\" src=\"$images->incubation_large\"
					border=\"0\" alt=\"Incubation\" /></a></div>
			</div>";
	}
	
	function getCommittersSideItem() {
		global $images;
		require_once 'Committer.class.php';
		/*
		 * "Require once" the script that adds the necessary JavaScript
		 * (including JQuery) to the header. By using require_once, we
		 * don't have to worry about whether or not we've already done
		 * this.
		 */
		require_once dirname(__FILE__) . '/util/summary.php';
		
		$id = $this->project->getId();
		$people = $this->project->getPeople();
		
		$pmcLeads = array();
		$pmcMembers = array();
		$leads = array();
		$committers = array();
		$emeritus = array();
		$mentors = array();
		$organizations = array();
		
		foreach($people as $person) {
			if ($person->isCommitter($id)) $committers[] = $person;
			if ($person->isEmeritus($id)) $emeritus[] = $person;
			if ($person->isProjectLead($id)) $leads[] = $person;
			if ($person->isPmcLead($id)) $pmcLeads[] = $person;
			else if ($person->isPmcMember($id)) $pmcMembers[] = $person;
			if ($person->isMentor($id)) $mentors[] = $person;
			if ($person->isActive($id)) {
				$organization = $person->getOrganization();
				if ($organization && $organization->isMember()) {
					$organizations[$organization->getId()] = $organization;
				}
			}
			
		}
		
		$html = "<div class=\"sideitem\">";
		$this->dumpCommittersSideItem($html, "PMC Leads", null, $images->pl_large, $pmcLeads);
		$this->dumpCommittersSideItem($html, "PMC Members", null, $images->pl_large, $pmcMembers);
		$this->dumpCommittersSideItem($html, "Project Leads", null, $images->pl_large, $leads);
		$this->dumpCommittersSideItem($html, "Committers", "Current project committers", $images->committers_large, $committers);
		$this->dumpCommittersSideItem($html, "Committers Emeritus", "Inactive committers who have made significant contributions to the project", $images->emeritus_large, $emeritus);
		if ($this->project->isInIncubationPhase()) $this->dumpCommittersSideItem($html, "Mentors", "Mentors from the Architecture Council provide guidance for this project.", $images->mentor_large, $mentors);
		
		$this->dumpCompaniesSideItem($html, $organizations);
		
		$html .= "</div>";
		
		return $html;
	}
	
	/* private */ function dumpCommittersSideItem(&$html, $title, $description, $image, $committers) {
		if (!$committers) return;
		
		global $images;
		
		$projectId = $this->project->getId();
		
		$html .= "<img src=\"$image\" align=\"right\"/><h6>$title</h6>";
		// TODO Sort out CSS issues
		//if ($description) $html .= "<p>$description</p>";
		$html .= "<ul>";
		foreach ($committers as $committer) {
			$committerId = $committer->id;
			$name = "$committer->firstName $committer->lastName";
			$name = htmlentities($name);
			$commitsUrl = "http://dash.eclipse.org/dash/commits/web-app/summary.cgi?type=y&month=x&project=$projectId&login=$committerId";
			if ($committer->isActive($projectId)) $name = "<b>$name</b>";
			
			$actions = '';
			if ($committer->hasCommits($projectId))
				$actions .= "<a href=\"$commitsUrl\"><img src=\"$images->commits_small\" title=\"Commits\" alt=\"[commits]\ target=\"_dash\"/></a>";
			
			$html .= "<li class=\"actions_holder\">$name <span class=\"actions\">$actions</span></li>";
		}
		$html .= "</ul>";
	}
	
	/* private */ function dumpCompaniesSideItem(&$html, $companies) {
		if (!$companies) return;
		global $images;
		
		$html .= "<img src=\"$images->company_large\" align=\"right\"/><h6>Supporting Organizations</h6>";

		foreach ($companies as $id => $organization) {
			$name = $organization->getName();
			$src = "http://www.eclipse.org/membership/scripts/get_image.php?id=$id&size=small"; 
			$link = "http://www.eclipse.org/membership/showMember.php?member_id=$id";
			$html .= "<div style=\"text-align:center;margin-bottom:20px\">";
			$html .= "<a href=\"$link\"><img src=\"$src\" align=\"center\" alt=\"$name\" title=\"$name\" /></a>";
			$html .= "</div>";
		}
	}
}


?>