<?php 
/*******************************************************************************
 * Copyright (c) 2011 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:
 *   Eclipse Foundation- initial API and implementation
 *******************************************************************************/
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/app.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/nav.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/menu.class.php");
$App = new App();
$Nav = new Nav();
$Menu = new Menu();
include($App->getProjectCommon());

$App->setOutDated();

$pageTitle 		= "Eclipse SCM Countdown";
$pageAuthor		= "Wayne Beaton";
$pageKeywords	= "eclipse,scm,vcs,dvcs,git,cvs,svn";

require_once dirname(__FILE__) . '/classes/Project.class.php';
require_once dirname(__FILE__) . '/classes/images.inc';
require_once dirname(__FILE__) . '/classes/common.php';
require_once dirname(__FILE__) . '/classes/debug.php';

$projects = getActiveProjects();
$repositories = array();
foreach($projects as $project) {
	foreach($project->getSourceRepositories() as $repository) {
		$project = $repository->project->getName();
		$name = $repository->getName();
		if (preg_match('/^\/cvsroot\/org\.eclipse\//', $name)) continue; // Skip websites
		$repositories[$repository->getType()][$project] = 1;
	}
}

function getProjectGitInfo() {
	$projects = getActiveProjects();

	$allGit = array();
	$someGit = array();
	$noGit = array();
	$unknown = array();

	foreach($projects as $project) {
		switch ($project->getGitStatus()) {
			case PROJECT_REPO_ALL_GIT: $allGit[$project->getName()] = $project; break;
			case PROJECT_REPO_SOME_GIT: $someGit[$project->getName()] = $project; break;
			case PROJECT_REPO_NO_GIT: $noGit[$project->getName()] = $project; break;
			default: $unknown[] = $project;
		}
	}

	return array(
		'All Git' => $allGit,
		'Some Git' => $someGit,
		'No Git' => $noGit
	);
}

function getRepositoriesChartHtml($repositories, $width=450, $height=300) {	
	$info = array(
		'Git' => $repositories['git'],
		'SVN' => $repositories['svn'],
		'CVS' => $repositories['cvs'],
	);

	return buildChart('ScmChart', $info, $width, $height);
}

function buildChart($divName, $info, $width, $height) {
	requiresGoogleChartsSupport();
	global $App;
	$chartJS = getScmChartJS($divName, $info, $width, $height);
	$App->AddExtraHtmlHeader("<script type=\"text/javascript\">$chartJS</script>");

	return "<div id=\"$divName\"></div>";
}

function getScmChartJS($divName, $info, $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', 'Title');
        	data.addColumn('number', 'Count');";
	 
	$total = count($info);
	 
	$js .= "data.addRows($total);";
	$index = 0;
	foreach ($info as $name => $entries) {
		$count = count($entries);
		$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;
}

$days = floor((strtotime('2012-12-21') - strtotime('now')) / (24 * 60 * 60)) + 1;

ob_start();
?>
<div style="display:block">
	<div style="position:relative">
		<div class="homeitem" style="float:left;margin:1%;width:30%">
			<p>Eclipse projects manage their code in Git, <strike>CVS</strike>, or Subversion (SVN) code repositories. 
			Here is the breakdown by repository. Note that some projects have multiple repositories,
			and/or use a combination of Git, SVN, and <strike>CVS</strike>.</p>
			<?php echo getRepositoriesChartHtml($repositories, 300, 200); ?>
			
			<p>Here is the breakdown by project.</p>
			<?php echo buildChart('projectSCM', getProjectGitInfo(), 300, 200); ?>	
		</div>
		<div class="homeitem" style="float:left;margin:1%;padding-top:100px;width:60%;">
			<p>CVS was retired at 12:00 PM EST on December 21/2012 (it has been made read-only). Eclipse projects
			that have not completed their migration from CVS are either in the process of, or are candidates for
			termination.</p>
			<span style="font-size:36px;line-height:40px">Ding dong, the witch is dead.</span>
		</div>
	</div>
</div>
<div style="clear:both"></div>

<?php
	$html = ob_get_contents();
	ob_end_clean();
	$App->generatePage('Nova', $Menu, null, $pageAuthor, $pageKeywords, $pageTitle, $html);
?>