<?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) {
  if ($value !== null)
    $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>" );

?>