<?php
/*
 *
 * @package		ARI Smart Content
 * @author		ARI Soft
 * @copyright	Copyright (c) 2011 www.ari-soft.com. All rights reserved
 * @license		GNU/GPL (http://www.gnu.org/copyleft/gpl.html)
 * 
 */

defined('_JEXEC') or die;

require_once JPATH_ADMINISTRATOR . '/components/com_arismartcontent/kernel/class.AriKernel.php';

require_once JPATH_LIBRARIES . '/arismartcontent/htmltable/htmltable.php';

AriKernel::import('Parameters.ParametersHelper');
AriKernel::import('Application.ARISmartContent.Utils.ApplicationHelper');
AriKernel::import('Application.ARISmartContent.Providers.ProvidersHelper');
AriKernel::import('Web.JSON.JSON');
AriKernel::import('Document.DocumentHelper');

class AriSmartContentWidgetGChart
{
	var $_params;
	var $_id;

	function __construct($id, $params)
	{
		$this->_id = $id;
		$this->_params = AriParametersHelper::flatParametersToArray($params);
	}
	
	function getId()
	{
		return $this->_id;
	}
	
	function loadAssets()
	{
		static $loaded;

		if ($loaded)
			return ;
		
		$appHelper = AriSmartContentApplicationHelper::getInstance();
		$appHelper->loadJQuery();

		$baseUri = JURI::root(true) . '/media/arismartcontent/gchart/';
		$jsUri = $baseUri . 'js/';
		$params = $this->_params;
		
		$doc = JFactory::getDocument();

		AriDocumentHelper::includeJsFile('//www.google.com/jsapi');
		AriDocumentHelper::includeJsFile($jsUri . 'jquery.gchart.js');
		$doc->addScriptDeclaration(';google.load("visualization", "1", {packages: ["corechart"]});');

		$loaded = true;
	}

	function registerClientInstance($data)
	{
		$params = $this->_params;
		$mainParams = AriUtils::getParam($params, '_default');

		$jsOptions = $this->getJsOptions($data);
		$jsCode = sprintf('var options = %2$s;options["data"] = %3$s;$("#%1$s_chart").gChart(options);',
			$this->getId(),
			!empty($jsOptions) ? json_encode($jsOptions) : '{}',
			json_encode($data)
		);

		$document = JFactory::getDocument();
		$loadMethod = AriUtils::getParam($mainParams, 'loadMethod', 'ready');
		if ($loadMethod == 'load')
			$document->addScriptDeclaration(';(window["ascJQuery"] || jQuery)(window).load(function() { var $ = window["ascJQuery"] || jQuery;' . $jsCode . '});');
		else
			$document->addScriptDeclaration(';(window["ascJQuery"] || jQuery)(document).ready(function($) { ' . $jsCode . '});');
	}

	function getJsOptions()
	{
		$params = $this->_params;
		$id = $this->getId();
		$mainParams = AriUtils::getParam($params, '_default');
		$options = AriUtils::getParam($params, 'gchart');

		$defOptions = array(
			'chartType' => 'LineChart',
			'hideTable' => true
		);
		
		$defChartOptions = array(
			'PieChart' => array(
				'width' => '',
				'height' => 0,
				'backgroundColor' => '#FFF',
				'colors' => '',
				'fontSize' => '',
				'legendFontSize' => '',
				'legendTextColor' => '',
				'reverseCategories' => false,
				'titleColor' => '#000',
				'titleFontSize' => '',
				'tooltip' => array(
					'textStyle' => array(
						'color' => '',
						'fontSize' => ''
					)
				),
		
				'legend' => 'right',
				'is3D' => false
			),

			'LineChart' => array(
				'width' => '',
				'height' => 0,
				'backgroundColor' => '#FFF',
				'colors' => '',
				'fontSize' => '',
				'legendFontSize' => '',
				'legendTextColor' => '',
				'reverseCategories' => false,
				'titleColor' => '#000',
				'titleFontSize' => '',
				'tooltip' => array(
					'textStyle' => array(
						'color' => '',
						'fontSize' => ''
					)
				),
			
				'chartArea' => array(
					'height' => '',
					'width' => ''
				),
				'curveType' => 'none',
				'legend' => 'right',
				'lineWidth' => 2,
				'pointSize' => 7,
				'hAxis' => array(
					'textColor' => '#000',
					'title' => '',
					'titleColor' => '#000',
					'gridlines' => array(
						'color' => '#ccc',
						'count' => 5
					)
				),
				'vAxis' => array(
					'baseline' => -99999,
					'baselineColor' => '#000',
					'logScale' => false,
					'textColor' => '#333',
					'title' => '',
					'titleColor' => '#000',
					'maxValue' => -99999,
					'minValue' => -99999,
					'gridlines' => array(
						'color' => '#ccc',
						'count' => 5
					)
				)
			),
			
			'AreaChart' => array(
				'width' => '',
				'height' => 0,
				'backgroundColor' => '#FFF',
				'colors' => '',
				'fontSize' => '',
				'legendFontSize' => '',
				'legendTextColor' => '',
				'reverseCategories' => false,
				'titleColor' => '#000',
				'titleFontSize' => '',
				'tooltip' => array(
					'textStyle' => array(
						'color' => '',
						'fontSize' => ''
					)
				),
			
				'isStacked' => false,
				'legend' => 'right',
				'lineWidth' => 2,
				'pointSize' => 7,
				'hAxis' => array(
					'textColor' => '#000',
					'title' => '',
					'titleColor' => '#000',
					'gridlines' => array(
						'color' => '#ccc',
						'count' => 5
					)
				),
				'vAxis' => array(
					'baseline' => -99999,
					'baselineColor' => '#000',
					'logScale' => false,
					'textColor' => '#333',
					'title' => '',
					'titleColor' => '#000',
					'maxValue' => -99999,
					'minValue' => -99999,
					'gridlines' => array(
						'color' => '#ccc',
						'count' => 5
					)
				)
			),
			
			'BarChart' => array(
				'width' => '',
				'height' => 0,
				'backgroundColor' => '#FFF',
				'colors' => '',
				'fontSize' => '',
				'legendFontSize' => '',
				'legendTextColor' => '',
				'reverseCategories' => false,
				'titleColor' => '#000',
				'titleFontSize' => '',
				'tooltip' => array(
					'textStyle' => array(
						'color' => '',
						'fontSize' => ''
					)
				),
			
				'isStacked' => false,
				'legend' => 'right',
				'chartArea' => array(
					'height' => '',
					'width' => ''
				),
				'vAxis' => array(
					'textColor' => '#333',
					'title' => '',
					'titleColor' => '#000'
				),
				'hAxis' => array(
					'baseline' => -99999,
					'baselineColor' => '#000',
					'logScale' => false,
					'textColor' => '#000',
					'title' => '',
					'titleColor' => '#000',
					'maxValue' => -99999,
					'minValue' => -99999,
					'gridlines' => array(
						'color' => '#ccc',
						'count' => 5
					)
				)
			),
			
			'ColumnChart' => array(
				'width' => '',
				'height' => 0,
				'backgroundColor' => '#FFF',
				'colors' => '',
				'fontSize' => '',
				'legendFontSize' => '',
				'legendTextColor' => '',
				'reverseCategories' => false,
				'titleColor' => '#000',
				'titleFontSize' => '',
				'tooltip' => array(
					'textStyle' => array(
						'color' => '',
						'fontSize' => ''
					)
				),
			
				'isStacked' => false,
				'legend' => 'right',
				'chartArea' => array(
					'width' => ''
				),
				'bar' => array(
					'groupWidth' => ''
				),
				'hAxis' => array(
					'textColor' => '#000',
					'title' => '',
					'titleColor' => '#000'
				),
				'vAxis' => array(
					'baseline' => -99999,
					'baselineColor' => '#000',
					'logScale' => false,
					'textColor' => '#333',
					'title' => '',
					'titleColor' => '#000',
					'maxValue' => -99999,
					'minValue' => -99999,
					'gridlines' => array(
						'color' => '#ccc',
						'count' => 5
					)
				)
			)
		);
		
		$autoOptions = array(
			'LineChart' => array(
				'vAxis' => array(
					'baseline' => '',
					'maxValue' => '',
					'minValue' => ''
				)
			),
			'AreaChart' => array(
				'vAxis' => array(
					'baseline' => '',
					'maxValue' => '',
					'minValue' => ''
				)
			),
			'BarChart' => array(
				'hAxis' => array(
					'baseline' => '',
					'maxValue' => '',
					'minValue' => ''
				)
			),
			'ColumnChart' => array(
				'vAxis' => array(
					'baseline' => '',
					'maxValue' => '',
					'minValue' => ''
				)
			)
		);

		$jsOptions = AriParametersHelper::getUniqueOverrideParameters($defOptions, $options, true);
		
		$chartSettings = array_merge(
			AriUtils::getParam($options, $options['chartType'], array()),
			AriUtils::getParam($options, 'chartSettings', array()));
		$defChartSettings = AriUtils::getParam($defChartOptions, $options['chartType']);
		
		if ($defChartSettings && $chartSettings)
		{
			if (isset($autoOptions[$options['chartType']]))
				$chartSettings = AriParametersHelper::removeSameParameters($chartSettings, $autoOptions[$options['chartType']]);
			
			$jsOptions['chartSettings'] = AriParametersHelper::getUniqueOverrideParameters($defChartSettings, $chartSettings, true);
			if (isset($jsOptions['chartSettings']['width']))
			{
				$width = $jsOptions['chartSettings']['width'];
				if (strpos($width, '%') !== false)
				{
					$jsOptions['chartSettings']['responsive'] = true;
				}
				else 
				{
					$jsOptions['chartSettings']['width'] = intval($width, 10);
				}
			}
		}

		if (!empty($jsOptions['chartSettings']['colors']) && !is_array($jsOptions['chartSettings']['colors']))
		{
			$colors = array();
			$sColors = explode("\n", $jsOptions['chartSettings']['colors']);
			foreach ($sColors as $color)
			{
				$color = trim($color);
				if ($color) $colors[] = $color;
			}
			
			$jsOptions['chartSettings']['colors'] = $colors;
		}

		$jsOptions['formatters'] = $this->getFormatters($options);
		$jsOptions['formatterSettings'] = $this->getFormatterSettings($options);

		return $jsOptions;
	}
	
	function getFormatterSettings($options)
	{
		$defOptions = array(
			'labelLength' => 0,
			'labelMore' => ''
		);

		if (empty($options['formatterSettings']))
			return null;
			
		return AriParametersHelper::getUniqueOverrideParameters($defOptions, $options['formatterSettings'], true);
	}

	function getFormatters($options)
	{
		$defChartFormatters = array(
			'DateFormat' => array(
				'formatType' => '',
				'pattern' => '',
				'timeZone' => 0
			),
			'NumberFormat' => array(
				'decimalSymbol' => '.',
				'fractionDigits' => 2,
				'groupingSymbol' => ',',
				'negativeColor' => '',
				'negativeParens' => true,
				'prefix' => '',
				'suffix' => ''
			)
		);
		
		if (empty($options['formatters']))
			return null;

		$formatters = json_decode(addcslashes($options['formatters'], "\r\n"), true);
		if (empty($formatters))
			return null;

		$retFormatters = array();
		foreach ($formatters as $formatter)
		{
			$idx = @trim($formatter['index']);
			if (strlen($idx) == 0)
				continue ;
				
			$idx = intval($idx, 10);
			if ($idx < 0)
				continue ;

			$type = $formatter['type'];
			if (!isset($defChartFormatters[$type]))
				continue ;

			$retFormatters[$idx] = array('type' => $type);

			if (empty($formatter['params']))
				continue ;

			$defSettings = $defChartFormatters[$type];
			$params = explode("\n", $formatter['params']);

			array_walk($params, 'trim');
			$colSettings = array();
			foreach ($params as $param)
			{
				@list($key, $value) = explode('=', $param, 2);
				if (empty($key))
					continue ;
					
				$colSettings[$key] = $value;
			}

			$colSettings = AriParametersHelper::getUniqueOverrideParameters($defSettings, $colSettings, true);
			if (count($colSettings) > 0)
				$retFormatters[$idx]['settings'] = $colSettings;
		}

		return count($retFormatters) > 0 ? $retFormatters : null;
	}

	function render()
	{
		$mainParams = AriUtils::getParam($this->_params, '_default');

		$source = AriUtils::getParam($mainParams, 'source');
		$sourceData = AriSmartContentProvidersHelper::resolveSource($source);
		$data = $this->prepareData(AriSmartContentProvidersHelper::getData($sourceData, null));

		$columns = AriUtils::getParam($sourceData, 'columns');
		$columnsSettings = AriUtils::getParam($sourceData, 'settings');
		$hiddenColumns = AriSmartContentFormattersHelper::getHiddenColumns($columns, $columnsSettings);

		$this->loadAssets();
		$this->registerClientInstance($data);

		echo '<div id="' . $this->getId() . '_chart" class="gchart"></div>';
	}
	
	function prepareData($data)
	{
		$preparedData = array();
		
		if (!is_array($data) || count($data) == 0)
			return $preparedData;

		$firstRow = reset($data);		
		foreach ($firstRow as $key => $val)
			$preparedData[] = array('' . $key);

		foreach ($data as $row)
		{
			$colIdx = 0;
			foreach ($row as $key => $val)
			{
				$preparedData[$colIdx][] = $val;
				
				++$colIdx;
			}
		}

		return $preparedData;
	}
}