<?php
/**
 * *****************************************************************************
 * Copyright (c) 2016, 2017 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
 * *****************************************************************************
 */

/*
 * This file defines some functions for generating various sorts of
 * charts using the Google Charts API. When this file is loaded, it
 * adds the necessary JavaScript to pull in the APIs to the page. The
 * individual functions provide relatively high-level APIs for
 * generating content.
 *
 * The $App variable must be defined before this file is included or
 * required.
 */
require_once dirname ( __FILE__ ) . "/../classes/Project.class.php";
require_once dirname ( __FILE__ ) . '/../classes/database.inc';

/**
 * This helper function turns a string expressing a year/month
 * combination (e.g. '2017-03' or '201703') into a more human readable
 * form (e.g. 'March 2017').
 *
 * @param string $period
 * @return string
 */
function asYearMonth($period) {
  // TODO This function probably belongs in a different file.
	if (! preg_match ( '/(\d\d\d\d)\-?(\d\d)/', $period, $matches ))
		return $period;
	$date = strtotime ( $matches [1] . '-' . $matches [2] . '-01' );
	return date ( 'M Y', $date );
}

/**
 * Get information regarding the quarter that occurs before the
 * provided date. The returned value is an array that includes
 * the name of the quarter (e.g. '2017Q1'), and the start and
 * end year/month (e.g. '201701'). This format is very particular
 * to the specific implementation of database tables that represent
 * queries for commit statics (i.e. this is probably not a
 * very generally-useable function).
 *
 * @internal
 * @param int $date UNIX date
 * @return string[]
 */
function getLastQuarter($date) {
 // TODO This function probably belongs in a different file.
	$year = date ( 'Y', $date );
	$current = ceil ( date ( 'n', $date ) / 3 );
	$last = $current - 1;
	if ($last < 1) {
		$year --;
		$last = 4;
	}

	$start = str_pad ( $last * 3 - 2, 2, '0', STR_PAD_LEFT );
	$end = str_pad ( $last * 3, 2, '0', STR_PAD_LEFT );

	return array (
			"${year}Q${last}",
			"${year}${start}",
			"${year}${end}"
	);
}

/**
 * Draw a pie chart. This function emits PHP code directly into
 * the output stream and adds a bit of JavaScript into the page header.
 * By default, the chart consumes 100% of the available width and
 * most of the available height. These options can be overridden
 * or augmented.
 *
 * <p>The global $App variable must be defined.
 *
 * <pre>
 * 	$columns = array (
 *    array (
 *      'label' => 'Project',
 *      'type' => 'string'
 *    ),
 *    array (
 *      'label' => 'CQs',
 *      'type' => 'number'
 *    )
 *  );
 *  $values = array(
 *    array('Dash', 14),
 *    array('Equinox', 5)
 *  );
 *  drawPieChart('Projects', 'Projects and Numbers', $columns, $rows);
 * </pre>
 *
 * @param string $id div identifer. Must be unique on the page
 * @param string $title Title rendered at the top of the chart
 * @param mixed $columns Array with name and type of columns
 * @param unknown $values Array of arrays with values to render
 * @param array $options Optional options.
 */
function drawPieChart($id, $title, $columns, $values, $options = array()) {
	$defaultOptions = array (
			'title' => $title,
			'pieSliceText' => 'label',
	    'legend' => array('position' => 'labeled'),
			'width' => 800,
			'height' => 600,
	    'chartArea' => array('width' => '100%', 'top' => '10%', 'height'=>'85%')
	);
	$options = array_merge ( $defaultOptions, $options );
	drawChart ( 'Pie', $id, $title, $columns, $values, $options );
}

/**
 * Draw a line chart. This function emits PHP code directly into
 * the output stream and adds a bit of JavaScript into the page header.
 *
 * The first column (and corresponding values) are used to label
 * the horizontal axis. All other columns are values related to that
 * label.
 *
 * <p>The global $App variable must be defined.
 *
 * <pre>
 * 	$columns = array (
 *    array (
 *      'label' => 'Month',
 *      'type' => 'string'
 *    ),
 *    array (
 *      'label' => 'Count',
 *      'type' => 'number'
 *    )
 *  );
 *  $values = array(
 *    array('Dash', 14),
 *    array('Equinox', 5)
 *  );
 *  drawLineChart('Projects', 'Projects and Numbers', $columns, $rows);
 * </pre>
 *
 * @param string $id div identifer. Must be unique on the page
 * @param string $title Title rendered at the top of the chart
 * @param mixed $columns Array with name and type of columns
 * @param unknown $values Array of arrays with values to render
 * @param array $options Optional options.
 */
function drawLineChart($id, $title, $columns, $values, $options = array()) {
	$defaultOptions = array (
			'title' => $title,
			'width' => 800,
			'height' => 600
	);
	$options = array_merge ( $defaultOptions, $options );
	drawChart ( 'Line', $id, $title, $columns, $values, $options );
}

function drawBarChart($id, $title, $columns, $values, $options = array()) {
 $defaultOptions = array (
   'title' => $title,
   'width' => 800,
   'height' => 600
 );
 $options = array_merge ( $defaultOptions, $options );
 drawChart ( 'Bar', $id, $title, $columns, $values, $options );
}

function drawChart($chartType, $id, $title, $columns, $values, $options) {
	global $App;

	$columnsJS = '';
	foreach ( $columns as $definition ) {
		$type = $definition ['type'];
		$label = $definition ['label'];
		$columnsJS .= "data.addColumn('$type', '$label');";
	}

	$valuesJSON = json_encode ( $values, JSON_NUMERIC_CHECK );
	$optionsJSON = json_encode ( $options, JSON_NUMERIC_CHECK );
	$js = "
		google.setOnLoadCallback(draw${id}Chart);
		function draw${id}Chart() {
			// Create the data table.
			var data = new google.visualization.DataTable();
			$columnsJS;
			data.addRows($valuesJSON);

			// Set chart options
			var options = $optionsJSON;

			// Instantiate and draw our chart, passing in some options.
			var chart = new google.visualization.{$chartType}Chart(document.getElementById('${id}_div'));
			chart.draw(data, options);

			document.getElementById('${id}_div_png').innerHTML = '<a href=\"' + chart.getImageURI() + '\">Printable version</a>';
		}";

	$App->addExtraHtmlHeader ( "<script type=\"text/javascript\">$js</script>" );

	echo "<div id=\"${id}_div_png\"></div>";
	echo "<div id=\"${id}_div\"></div>";
}

/**
 * This class implements a constructor pattern for building
 * charts. All of the functions answer the receiver so that
 * calls can be chained together. Most of the functions are
 * concerned with configuring the chart; the
 * <code>render()</code> renders the actual chart. Note that
 * the rendering ends up being a combination of JavaScript in
 * the header and some <code>&lt;div&gt;</code> tags in
 * the content.
 *
 * <pre>ChartBuilder::named('chart_id')
 * ->title('The Chart Title')
 * ->query('dashboard', 'select field1, field2 from ...')
 * ->column('Field One', 'field1', 'number')
 * ->render();</pre>
 *
 */
class ChartBuilder {
 var $name;
 var $title = '';
 var $description = '';
 var $database;
 var $query;
 var $substitutions = array();
 var $type = 'Line';
 var $columns = array();
 var $columnFields = array();
 var $options = array();

 public static function named($name) {
  return new ChartBuilder($name);
 }

 private function __construct($name) {
  $this->name = $name;
  $this->options = array (
    'width' => 800,
    'height' => 600,
    'legend' => array('position' => 'top'),
    'chartArea' => array('width' => '80%', 'top' => '10%', 'bottom' => '10%', 'height'=>'80%')
  );
 }

 public function title($title) {
  $this->title = $title;
  return $this;
 }

 public function description($description) {
  $this->description = $description;
  return $this;
 }

 public function query($database, $query) {
  $this->database = $database;
  $this->query = $query;
  return $this;
 }

 public function substitute($key, $value) {
  $this->substitutions[$key] = $value;
  return $this;
 }

 public function pieChart() {
  $this->type = 'Pie';
  $this->options = array_merge($this->options,
    array (
      'pieSliceText' => 'label',
      'legend' => array('position' => 'labeled'),
      'chartArea' => array('width' => '100%', 'top' => '10%', 'height'=>'85%')
    ));
  return $this;
 }

 public function barChart() {
  $this->type = 'Bar';
  return $this;
 }

 public function columnChart() {
  $this->type = 'Column';
  return $this;
 }

 /**
  * Provide information about a single column.
  *
  * @param string $label label for the column.
  * @param string $field name of the field in the SQL query
  * @param string $type type of the column, e.g. 'number' or 'string'
  * @param function $function Optional function to convert the field value before rendering in the chart.
  *
  * @return ChartBuilder The receiver.
  */
 public function column($label, $field, $type = 'number', $function = null) {
  $this->columns[] = array('label' => $label, 'type' => $type);
  $this->columnFields[$field] = $function == null ? function($value) { return $value; } : $function;
  return $this;
 }

 public function option($key, $value) {
  $this->options[$key] = $value;
  return $this;
 }

 public function height($value) {
  return $this->option('height', $value);
 }

 public function width($value) {
  return $this->option('width', $value);
 }

 /**
  * Render the chart with the information contained in the receiver.
  */
 public function render() {
  $rows = array ();
  $receiver = $this;
  query ( $this->database, $this->query, $this->substitutions, function ($row) use (&$receiver, &$rows) {
   $values = array ();
   foreach ( $receiver->columnFields as $field => $function ) {
    $values [] = $function ( $row [$field] );
   }
   $rows [] = $values;
  } );

  $options = array (
    'curveType' => 'function',
    'vAxis' => array (
      'viewWindowMode' => 'explicit',
      'viewWindow' => array (
        'min' => 0
      )
    )
  );

  $options = array_merge($this->options, $options);

  $title = strtr($this->title, $this->substitutions);
  echo "<h3 id=\"{$this->name}\">{$title}</h3>";
  if ($this->description) {
   $description = strtr($this->description, $this->substitutions);
   echo "<p>{$description}</p>";
  }

  drawChart ( $this->type, $this->name, $title, $this->columns, $rows, $options );

//  $function = "draw{$this->type}Chart";
//  $function ( $this->name, $title, $this->columns, $rows, $options );
 }
}

$App->addExtraHtmlHeader ( "<script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>" );
$App->addExtraHtmlHeader ( "<script type=\"text/javascript\">google.load('visualization', '1.0', {'packages':['corechart']});</script>" );

?>