<?php
/**
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     i-net software <tools@inetsoftware.de>
 * @author  Gerry Weissbach <gweissbach@inetsoftware.de>
 */

// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();

if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');

/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_translator_translator extends DokuWiki_Syntax_Plugin {

	var $functions = null;
	var $category = null;
	var $languages = null;
	var $currentLanguage = null;
	var $currentVersion = null;
	var $additionalLanguage = null;
	var $version = null;

	/**
	 * return some info
	 */
	function getInfo(){
		return array_merge(confToHash(dirname(__FILE__).'/../info.txt'), array(
				'name' => 'Translator (Syntax Component)',
		));
	}

	function getType(){ return 'substition'; }
	function getPType(){ return 'block'; }
	function getSort(){ return 110; }



	/**
	 * Connect pattern to lexer
	 */
	function connectTo($mode){
		$this->Lexer->addSpecialPattern('~~TRANSLATOR~~',$mode,'plugin_translator_translator');
	}
	/**
	 * Handle the match
	 */
	function handle($match, $state, $pos, &$handler){

		return array('translator');
	}

	/**
	 *  Render output
	 */
	function render($mode, &$renderer, $data) {
		global $ID;

		if ($mode == 'xhtml') {

			$renderer->nocache();

			// Instantiate the helper
			if ( !$this->functions =& plugin_load('helper', 'translator') ) {
				print $this->lang['helpermissing'];
				return false;
			}

			// Connect to the Database and load Languages
			$this->functions->init_database();

			// Setup the Variables
			$this->category = $_REQUEST['Category'];
			$this->languages = $this->functions->_getLanguages();
			$this->version = $_REQUEST['Version'];
			$this->currentLanguage = $_REQUEST['Language'];
			$this->currentVersion = $_REQUEST['Version'];
			$this->additionalLanguage = $_REQUEST['AdditionalLanguage'];

			// check Database
			$renderer->doc .= '<div id="translator">';

			if ( count($this->functions->revertableUpload) > 0 ) {
				$renderer->doc .= $this->functions->_revertManager($this, $this->functions->revertableUpload);
			}

			// test this is the setup page
			if ( empty($this->category) || empty($this->currentLanguage) ) {
				$this->_setupTranslator($renderer);
				$this->_printStatistics($renderer);
			} else {

				if ( $this->languages === false ) {
					$renderer->doc .= $this->locale_xhtml('noauth');
					return false;
				}

				// Print the Translator
				$this->_printTranslator($renderer, intval($_REQUEST['start']), intval($_REQUEST['amount']), $_REQUEST['Display'], $_REQUEST['Filter']);
			}

			$renderer->doc .= '</div>';

			return true;
		}

		return true;
	}

	/*
	 * Create a Setup Fieldset with Category and Language
	 */
	function _setupTranslator(&$renderer) {
		global $INFO;

		$renderer->doc .= $this->locale_xhtml('setup');

		$form = $this->_startFieldSet($this->getLang('SelectCategory'), 'translator_setup');

		list($categories, $changeCategory, $changeVersion) = $this->functions->_getChangerJS(false);

		$form->addElement(form_makeListboxField('Category', array_keys($categories), $_REQUEST['Category'], $this->getLang('Category') . ':', null, null, array('onchange' => $changeCategory)));
		$form->addElement(form_makeTag('br'));
		
		$form->addElement(form_makeListboxField('Version', (empty($categories[$_REQUEST['Category']]['Versions']) ? array('none given') : array_keys($categories[$_REQUEST['Category']]['Versions'])), $_REQUEST['Version'], $this->getLang('Version') . ':', null, null, array('onchange' => $changeVersion)));
		$form->addElement(form_makeTag('br'));
				
		$form->addElement(form_makeField('submit', 'fn[setup]', $this->getLang('Show'), ''));

		$renderer->doc .= $this->_finishFieldset($form);
		return true;
	}

	/*
	 * Find all Categories and create a form field out of them
	 */
	function _categorySelection(&$form, $currentCategory) {
		$this->functions->database->prepare("SELECT CategoryID, Name, FileName FROM tblCategory;");
		$this->functions->database->execute();

		if ( $this->functions->database->num_rows() == 0 ) {
			$form;
			return false;
		}
			
		$categories = array(); $data = array(); $this->functions->database->bind_assoc($data);
		while ( $this->functions->database->fetch() ) {
			$categories[] = $data['Name'];
		}

		$form->addElement(form_makeListboxField('Category', $categories, $currentCategory, $this->getLang('Category') . ':', null, null, array('onchange' => 'var node = this.parentNode.parentNode.getElementsByTagName(\'select\'); for( var i=0; i<node.length; i++ ) { if (node[i].name != \'Version\') { continue; } node[i].parentNode.parentNode.removeChild(node[i].parentNode); break; }')));
		$form->addElement(form_makeTag('br'));

		return true;
	}

	/*
	 * Print the Translators main View
	 */
	function _printTranslator(&$renderer, $start=null, $amount=null, $display=null, $filter=null) {

		if ( empty($display) ) {
			$display = $this->getLang('notTranslated');
		}

		// Translatation Matrix
		list($matrix, $max) = $this->functions->_getTranslationMatrix($this->category, $this->version, $this->currentLanguage, $this->additionalLanguage, $start, $amount, $display, $filter);
		list($categoryID) = $this->functions->_getCategoryFromName($this->category);
		
		//print_r($matrix); exit;
		

		if ( $matrix === false || count($matrix) == 0 ) {
			$renderer->doc .= $this->locale_xhtml('nothingtodo');
			$renderer->doc .= $this->_setPages($start, $amount, $max, $display, true);
			return false;
		}

		$masterLanguage = empty($this->additionalLanguage) ?  $this->getConf('default_language') : $this->additionalLanguage;

		// Print Table Headers
		$form = $this->_startFieldSet($this->getLang('Translator'), "translator_do");

		$form->addElement(form_makeOpenTag("table", array('class' => 'translation_table')));

		$form->addElement(form_makeOpenTag("colgroup"));
		$form->addElement(form_makeOpenTag("col", array('width' => 2)));
		$form->addElement(form_makeOpenTag("col", array('width' => 4)));
		$form->addElement(form_makeOpenTag("col", array('width' => 4)));
		$form->addElement(form_makeOpenTag("col", array('width' => 1)));
		$form->addElement(form_makeCloseTag("colgroup"));


		$form->addElement(form_makeOpenTag("tr"));

		$form->addElement(form_makeOpenTag("th"));
		$form->addElement($this->getLang('RessourceKeyName'));
		$form->addElement(form_makeCloseTag("th"));
			
		$form->addElement(form_makeOpenTag("th"));
		$form->addElement($this->getLang('MasterValue') . " ($masterLanguage)");
		$form->addElement(form_makeCloseTag("th"));
			
		$form->addElement(form_makeOpenTag("th", array('class' => 'translation_editor')));
		$form->addElement($this->getLang('TranslationValue') . " ({$this->currentLanguage})");
		$form->addElement(form_makeCloseTag("th"));
			
		$form->addElement(form_makeCloseTag("tr"));

		$rowHighlight = true;
		$onclick = array(	'class' => 'row_' . intval($rowHighlight),
																'onclick' => 'var elem=getElementsByClass("edit", this, "textarea");
																				elem[0].focus(); elem[0].select();',
		);
		
		
		// Print the Matrix in a table
		foreach ( $matrix as $line ) {
			
			//print $line['ResourceKey'] . "<br>\n";

			$masterValue = !empty($line['AdditionalValue']) ? $line['AdditionalValue'] : $line['MasterValue'];
			$form->addElement(form_makeOpenTag("tr"));

			$form->addElement(form_makeOpenTag("td", array_merge(array('class' => 'resourceKey', 'title' => hsc(stripslashes($line['ResourceKey'])) ), $onclick)));
			$form->addElement(stripslashes(utf8_decode($line['ResourceKey'])));
			$form->addElement(form_makeCloseTag("td"));

			$form->addElement(form_makeOpenTag("td", $onclick));

			$textAreaWidth = 70;
			$form->addElement(form_makeOpenTag("textarea",	array(	'rows' => (ceil(strlen($masterValue) / $textAreaWidth)),
																	'class' => 'edit',
																	'style' => 'width: 95%;',
																	'readonly' => 'readonly')
			));
			$form->addElement(hsc(stripslashes($masterValue)));
			$form->addElement(form_makeCloseTag("textarea"));
			$form->addElement(form_makeCloseTag("td"));

			$form->addElement(form_makeOpenTag("td", array('class' => 'translation_editor')));

			$form->addElement(form_makeOpenTag("textarea",	array(	'rows' => (ceil(strlen($masterValue) / $textAreaWidth)),
																	'style' => 'width: 95%;',
																	'class' => 'edit',
																	'name' => "translation[{$line['KeyID']}]",
																	'id' => "translation_{$line['KeyID']}",)
			));
			$form->addElement(stripslashes($line['TranslationValue']));
			$form->addElement(form_makeCloseTag("textarea"));
			if ( auth_ismanager() && !empty($line['TranslationValue']) ) $form->addElement("(" . tpl_link(wl($ID, array('do' => 'admin', 'page' => 'translator', 'manageUser' => $line['User'] ), true), $line['User'], null, true) . ")");
			$form->addElement(form_makeCloseTag("td"));
			$form->addElement(form_makeOpenTag("td"));
			$form->addElement(form_makeOpenTag("button", array('onclick' => "translator.run('{$this->currentLanguage}', 'translation_{$line['KeyID']}', '{$line['KeyID']}', '{$categoryID}'); return false;")));
			$form->addElement('google');
			$form->addElement(form_makeCloseTag("button"));
			$form->addElement(form_makeCloseTag("td"));

			$form->addElement(form_makeCloseTag("tr"));

			$rowHighlight = !$rowHighlight;
		}

		$form->addElement(form_makeCloseTag("table"));


		$form->addElement(form_makeField('submit', 'fn[setup]', $this->getLang('Cancel'), ''));
		$form->addElement(form_makeField('submit', 'fn[translate]', $this->getLang('Submit'), ''));

		$renderer->doc .= $this->_setPages($start, $amount, $max, $display);
		$renderer->doc .= $this->_finishFieldset($form);
		$renderer->doc .= $this->_setPages($start, $amount, $max, $display);

		return true;
	}

	/*
	 * Display Header and Footer to chane the current selection or page
	 */
	function _setPages($start, $amount, $max, $display, $printGoBack=false) {
		global $ID;

		if ( empty($amount)  || $amount == 0 ) $amount = 25;
		list($categoryID) = $this->functions->_getCategoryFromName($this->category);
		$onChangeEvent = 'document.getElementById(\'fn[setpage][' . $start . ']ID\').click();';

		$form = $this->_startFieldSet($this->getLang('selectedOptions'));
		$form->addElement("<div class='language' style='width:150px;'>{$this->getLang('Category')}:</div><div style='width:200px;float:right'>$this->category</div>");
		$form->addElement(form_makeTag('br'));
		$form->addElement("<div class='language' style='width:150px;'>{$this->getLang('Version')}:</div><div style='width:200px;float:right'>$this->version</div");
		$form->addElement(form_makeTag('br'));
		$form->addElement("<div class='language' style='width:150px;'>{$this->getLang('Permalink')}:</div><div style='width:200px;float:right'>" . tpl_link(wl($ID, array('Category' => $this->category, 'Version' => $this->version, 'Language' => $this->currentLanguage, 'AdditionalLanguage' => $this->additionalLanguage, 'start' => $start, 'amount' => $amount, 'Display' => $display), true), $this->getLang('RightClickNCopy'), null, true) . "</div>");
		$form->addElement(form_makeTag('br'));

		$form->addElement(form_makeListboxField('newAdditionalLanguage', $this->functions->_getAvailableLanguages($categoryID), $_REQUEST['AdditionalLanguage'], $this->getLang('DisplayReferenceLanguage') . ':', null, null, array('onchange' => $onChangeEvent)));
		$form->addElement(form_makeTag('br'));
		$form->addElement(form_makeListboxField('newAmount', array('25', '50', '100', '200'), $amount, $this->getLang('DisplayAmount') . ':', null, null, array('onchange' => $onChangeEvent)));
		$form->addElement(form_makeTag('br'));
		$form->addElement(form_makeTextField('Filter', $_REQUEST['Filter'], 'Filter' . ':', '', 'short'));
		$form->addElement(form_makeTag('br'));
		$form->addElement(form_makeField('submit', 'fn[setpage][0]', 'submit', '', 'fn[setpage][0]ID', 'setpage right'));
		$form->addElement(form_makeTag('br'));

		$countOfPages = ceil($max / $amount);
		for( $i=1; $i <= $countOfPages; $i++ ) {
			$currentPage = floor($start/$amount) == $i-1 ? ' current' : '';
			$form->addElement(form_makeField('submit', 'fn[setpage][' . ($i-1)*$amount . ']', $i, '', 'fn[setpage][' . ($i-1)*$amount . ']ID', 'setpage' . $currentPage));
		}

		if ( $printGoBack ) {
			$form->addElement(form_makeTag('br'));
			$form->addElement(form_makeField('submit', 'fn[setup]', $this->getLang('backToFirstPage'), ''));
		}

		return $this->_finishFieldset($form);
	}

	/*
	 * Print the Main Selector with Statsitics for selected Categroy
	 */
	function _printStatistics($renderer) {
		global $INFO;

		// If no categroy selected return
		if ( empty ( $this->category ) || empty ( $this->currentVersion ) ) {
			return false;
		}

		list($cagtegoryID, $filename) = $this->functions->_getCategoryFromName($this->category);
		$masterValues = $this->functions->_getAmountOfMasterValues($cagtegoryID, $this->currentVersion);
		if ( empty($masterValues) || $masterValues == 0 ) {
			return;
		}

		$renderer->doc .= $this->locale_xhtml('statistics');

		// Start building Form for each version
		$form = $this->_startFieldSet( $this->category . ' ' . $this->getLang('Version') . ' ' . $this->currentVersion );
		$languages = $this->functions->_getAvailableLanguages($cagtegoryID, $this->currentVersion);

		// Hidden global Information
		$form->addHidden('Version', $this->currentVersion);
		$form->addHidden('Category', $this->category);

		$form->addElement(form_makeOpenTag('p'));
		$form->addElement($this->getLang('AmountOfMasterValues') . ': ' . $masterValues);
		$form->addElement(form_makeCloseTag('p'));

		// merge Languages from user and available languages from database
		$languages = array_unique(array_merge($languages, explode('|', $this->languages)));
		sort($languages);

		foreach( $languages as $language ) {
			if ( $language == $this->getConf('default_language') ) continue;
			if ( empty( $language ) ) continue;

			$currentAmount = $this->functions->_getAmountOfLanguageValues($cagtegoryID, $this->currentVersion, $language);

			// Output informative block
			$form->addElement(form_makeOpenTag('div', array('class' => 'language') ));
			$form->addElement($this->functions->_downloadLink($this->category, $this->currentVersion, $language, '[' . $language . ']', true));
			$form->addElement(form_makeCloseTag('div'));

			$form->addElement(form_makeOpenTag('div', array('class' => 'language') ));
			$form->addElement($this->functions->_downloadLink($this->category, $this->currentVersion, $language, '[unicoded]'));
			$form->addElement(form_makeCloseTag('div'));

			$form->addElement(form_makeOpenTag('div', array('class' => 'percent')));
			$form->addElement(sprintf("%.1f%%", $currentAmount / $masterValues * 100 ));
			$form->addElement(form_makeCloseTag('div'));

			// If user has rights to use language, display buttons
			if ( in_array($language, explode('|', $this->languages)) ) {
				$form->addElement(form_makeField('submit', 'fn[setup][' . $language . '][' . $this->getLang('all') . ']', $this->getLang('all'), $this->getLang('Translate') . ':') );
				if ( $currentAmount > 0 ) $form->addElement(form_makeField('submit', 'fn[setup][' . $language . '][' . $this->getLang('translated') . ']', $this->getLang('translated'), '') );
				if ( $currentAmount < $masterValues ) $form->addElement(form_makeField('submit', 'fn[setup][' . $language . '][' . $this->getLang('notTranslated') . ']', $this->getLang('notTranslated'), '') );
			}
			$form->addElement(form_makeTag('br'));
		}

		$renderer->doc .= $this->_finishFieldset($form);
	}

	/*
	 * Fieldsets for the syntax page
	 */
	function _startFieldSet($name, $hid='translator', $formType=null) {
		global $ID;

		$form = new Doku_Form($hid, wl($ID), 'post', $formType);
		$form->startFieldset( $name );
		$form->addHidden('Category', $_REQUEST['Category']);
		$form->addHidden('Version', $_REQUEST['Version']);
		$form->addHidden('Display', $_REQUEST['Display']);
		$form->addHidden('Language', $_REQUEST['Language']);
		$form->addHidden('AdditionalLanguage', $_REQUEST['AdditionalLanguage']);
		$form->addHidden('start', $_REQUEST['start']);
		$form->addHidden('amount', $_REQUEST['amount']);
		return $form;
	}

	/*
	 * Finish a fieldset and capture the output to put it into the renderer document
	 */
	function _finishFieldset($form=null) {
		if ( empty($form) ) return;
			
		$form->endFieldset();
		return $this->functions->capture_form_output($form);
	}

	/**
	 * Allow the plugin to prevent DokuWiki creating a second instance of itself
	 *
	 * @return bool   true if the plugin can not be instantiated more than once
	 */
	function isSingleton() {
		return true;
	}
}
