<?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';

class ChartContext {
	var $start, $end;

	function __construct($age = 5) {
		$this->start = new DateTime('first day of this month');
		$this->start->sub(new DateInterval("P{$age}Y"));
		$this->end = new DateTime('last day of previous month');
	}

	function getCurrent() {
		return $this->getEnd();
	}

	function getStart() {
		return clone $this->start;
	}

	function getEnd() {
		return clone $this->end;
	}

	/**
	 * Convenience function to create a date from an expression.
	 * Primarily, this function exists because you can't dispatch
	 * a message to the result of calling a constructor, which makes
	 * inlining a date expression impossible.
	 *
	 * e.g. $context->getDateTime('sunday last week')->format('Y-m-d');
	 *
	 * @param string $expression
	 * @return DateTime
	 */
	function getDateTime($expression) {
		return new DateTime($expression);
	}

	/**
	 * Get information regarding the last complete quarter before
	 * the a particular date.
	 *
	 * @internal
	 * @param int $date UNIX date
	 * @return Quarter
	 */
	private function getLastQuarter($date) {
		$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 new Quarter("${year}Q${last}",new DateTime("${year}${start}"),
				"${year}${end}"
		);
	}
}

/**
 * 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 mixed $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 mixed $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 $dataFunction;
 var $substitutions = array();
 var $type = 'Line';
 var $columns = array();
 var $columnFields = array();
 var $options = array();

 var $titleString = "<h3 id=\":id\">:title</h3>";

 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 dataFunction($callable) {
 	$this->dataFunction = $callable;
 	return $this;
 }

 public function query($database, $query) {
 	$receiver = $this;
 	$this->dataFunction = function() use (&$database, &$query, &$receiver) {
 		$rows = array();
 		query ( $database, $query, $this->substitutions, function ($row) use (&$receiver, &$rows) {
 			$values = array ();
 			foreach ( $receiver->columnFields as $field => $function ) {
 				$values [] = call_user_func( $function, $row [$field] );
 			}
 			$rows [] = $values;
 		} );
 		return $rows;
 	};
  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 callable $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 titleString($value) {
 	$this->titleString = $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 = call_user_func($this->dataFunction);

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

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

  if ($this->title) {
	  $title = strtr($this->title, $this->substitutions);
	  echo strtr($this->titleString, array(':id' => $this->name, ':title' => $title));
  }
  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>" );

?>