<?php
/**
 * HTML-Klasse
 *
 * @package federleicht
 * @subpacke helper
 * @version 0.3
 */
class html {
	protected $data = array();
	protected $eol = PHP_EOL;
	protected $output_xhtml = true;

	/**
	 * Konstruktor
	 *
	 * @todo Information ueber Einrueckung oder ein Ausgabe-Objekt uebergeben?
	 * @todo Datenobjekt direkt statt der Referenz auf den View uebergeben.
	 * @param view &$view
	 * @param boolean $eol
	 * @param boolean $output_xhtml
	 */
	public function __construct(&$view = null, $eol=true, $output_xhtml=true) {
		if ( $view instanceof view ) {
			$this->set_data( $view->get_data_object() );
		}

		$this->eol = ( $eol )? PHP_EOL: '';
		$this->output_xhtml = (boolean) $output_xhtml;
	}

	/**
	 * Datenquelle setzen
	 *
	 * @param mixed $data
	 */
	public function set_data($data) {
		$this->data = $data;
	}

	/**
	 * HTML ausgeben
	 *
	 * @param string $html
	 */
	protected function output($html) {
		if ( $this->output_xhtml === false ) {
			$html = str_replace(' />', '>', $html);
		}

		echo $html . $this->eol;
	}

	/**
	 * Formulartag erzeugen
	 *
	 * @param string $action
	 * @param string $id
	 * @param string $target
	 * @param string $method
	 * @param string $charset
	 */
	public function form_tag($action, $id='', $target='', $method='post', $charset='UTF-8') {
		$action = ( $action[0] == '/' )? $action: '/'.$action;
		$id = ( $id != '' )? ' id="'.$id.'" name="'.$id.'" ': '';
		$target = ( $target != '' )? ' target="'.$target.'" ': '';

		$html = '<form action="'.$action.'" method="'.$method.'" '. $id . $target .'accept-charset="'.$charset.'">';
		$this->output($html);
	}
	/**
	 * Formulartag schließen
	 */
	public function form_end() {
		$html = '</form>';
		$this->output($html);
	}

	/**
	 * Dropdown erzeugen
	 *
	 * Es wird ein HTML-Dropdown erzeugt. Die einzelnen Dropdownelemente werden
	 * als kommaseparierte Liste in folgendem Format übergeben:
	 *     1=eins,2=zwei,3=drei
	 *
	 * Dies führt zu einem Dropdown mit drei Elementen. Es wird der Text nach dem
	 * Gleichheitszeichen zur Darstellung verwendet, hier also 
	 *     'eins', 'zwei', 'drei'.
	 * Die übergebenen Werte sind dabei der Text vor dem Gleichheitszeichen:
	 *     1, 2, 3.
	 *
	 * Das Dropdown hat die ID, die im ersten Parameter übergeben wird und 
	 * verwendet diesen auch zur Datenübergabe als Array-Schlüssel.
	 *
	 * Wenn bereits Daten geladen wurden, wird versucht, den entsprechenden 
	 * Wert als vorausgewählt darzustellen.
	 *
	 * Das HTML wird ausgegeben.
	 *
	 * @param string $field  	Eindeutiger Bezeichner für das Datenfeld.
	 * @param string $options	Dropdownelemente im Format value=description, kommasepariert
	 * @param string $label   Beschriftung des Dropdowns
	 */
	public function get_dropdown($field, $options, $label='') {
		if ( is_string($options) ) {
			$options = $this->string_to_array($options);
		}

		$html = '';

		if ( $label != '') $html .= $this->get_label($field, $label);

		$html .= '<select name="fl['.$field.']" id="'.$field.'" size="1" class="dropdown">'."\n";

		foreach( $options as $option ) {
			$id   = $this->get_value('id', $option);
			$name = $this->get_value('name', $option);

			$selected = ( $this->get_value($field, $this->data) == $id )? ' selected="selected"': '';
			$html .= "\t<option value=\"".$id.'"'.$selected.'>'.$name."</option>\n";
		}

		$html .= '</select>';

		$this->output($html);
	}

	/**
	 * Dropdown-String zu Array machen
	 *
	 * @param string $string
	 * @return array
	 */
	protected function string_to_array($string) {
		$array = array();

		foreach( explode(',', $string) as $keyvaluepair ) {
			if ( strpos( $keyvaluepair, '=' ) === false ) {
				$id = $name = $keyvaluepair;
			} else {
				list($id, $name) = explode('=', $keyvaluepair, 2);
			}

			$array[] = array(
				'id'=>$id,
				'name'=>$name
			);
		}

		return $array;
	}

	/**
	 * Dropdown-Array zu String machen
	 *
	 * @param array $data
	 * @return string
	 */
	protected function array_to_string($data) {
		foreach( $data as $value) {
			$string[] = $value['id'].'='.$value['name'];
		}

		$string = implode(',', $string);

		return $string;
	}


	/**
	 * Radiobuttons ausgeben
	 *
	 * Radiobuttons werden direkt ausgegeben.
	 * Wrapperfunktion für echo html::return_radios()
	 */
	public function get_radios($field, $options, $tag='p') {
		$html = $this->return_radios($field, $options, $tag);

		$this->output($html);
	}

	/**
	 * Radiobuttons erzeugen
	 *
	 * @todo Dokumentation erstellen
	 */
	public function return_radios($field, $options, $tag='p') {
		$options = explode(',', $options);
		$html = '';

		foreach( $options as $option ) {
			$option = explode('=', $option);
			$option[1] = ( isset($option[1]) )? $option[1]: $option[0];
			$value = $this->get_value('1', $option);

			$selected = ( $this->get_value($field, $this->data) == $option[0] )? ' checked="checked"': '';
			$html .= "\n\t\t\t".'<'.$tag.'><input name="fl['.$field.']" id="'.$field.'-'.$option[0].'" type="radio" class="radio" value="'.$option[0].'"'.$selected.' />' .$this->get_label($field.'-'.$option[0], $value) . '</'.$tag.'>';
		}

		return $html;
	}

	/**
	 * Inputfeld erzeugen
	 *
	 * Das erzeugte HTML wird direkt ausgegeben.
	 *
	 * @param string $field   ID des Formularfelds
	 * @param string $label   zu verwendendes Label
	 * @param array $options  Optionen als assoziatives Array:
	 *                        - type: von text abweichender Typ
	 *                        - size: Länge (inkl. Maximallänge) einstellen
	 */
	public function get_input($field, $label='', $options=array() ) {
		if ( !empty($options) ) {
			$type = ( isset($options['type']) AND !empty($options['type']) )? 
				'type="'.$options['type'].'"': 
				'type="text"';
			$options = ( isset($options['size']) AND !empty($options['size']) )? 
				'maxlength="'.$options['size'].'" size="'.$options['size'].'" ':
				'';
		} else {
			$type = 'type="text"';
			$options = '';
		}

		$html = '';
		if ( $label != '' AND !is_numeric($label) ) {
			$html .= $this->get_label($field, $label);
		}

		$name = ( $type == 'type="file"' )?
			$field:
			'fl['.$field.']';

		$value = $this->get_value($field, $this->data);

		$html .= '<input name="'.$name.'" id="'.$field.'" class="text" '.$type.' '.$options.'value="'.$value.'" />';

		$this->output($html);
	}

	/**
	 * Verstecktes Inputfeld erzeugen
	 *
	 * @param string $field 
	 * @param string $value
	 */
	public function get_hidden($field, $value) {
		$html = '<input name="fl['.$field.']" id="'.$field.'" type="hidden" value="'.$value.'" />';
		$this->output($html);
	}

	/**
	 * Button erzeugen
	 *
	 * @param string $name  ID und name des Buttons
	 * @param string $label optional: Beschriftung
	 * @param string $type  optional: von "submit" abweichender Typ
	 */
	public function get_button($name, $label='', $type='submit') {
		$label = ( $label === '' )? $name: $label;

		$html = '<input id="'.$name.'" type="'.$type.'" value="'.$label.'" />';
		$this->output($html);
	}
	/**
	 * Checkbox erzeugen
	 *
	 * @param string $field   ID des Formularfelds
	 * @param string $label   zu verwendendes Label
	 * @return string
	 */
	public function get_checkbox($field, $label='') {
		$html = '';
		$data = $this->get_value($field, $this->data);

		$checked = ( $data == $field OR $data == 1 )?
			' checked="checked"': 
			'';

		$html .= '<input name="fl['.$field.']" id="'.$field.'" class="checkbox" type="checkbox" value="'.$field.'"'.$checked .' /> ';

		if ( $label != '' AND !is_numeric($label) ) {
			$html .= '<label for="'.$field.'" class="checkbox">'.$label.'</label>';
		}

		$this->output($html);
	}

	/**
	 * Textarea erzeugen
	 *
	 * Es wird ein mehrzeiliges Eingabefeld erzeugt.
	 *
	 * @param string $field
	 * @param string $label
	 * @param array  $options Hash mit Optionen:
	 * 	- rows: Anzahl der Zeilen
	 * 	- cols: Anzahl der Spalten
	 */
	public function get_textarea($field, $label='', $options = array() ) {
		$html = '';
		$rows = ( isset($options['rows']) AND !empty($options['rows']) )? $options['rows']: 5;	
		$cols = ( isset($options['cols']) AND !empty($options['cols']) )? $options['cols']: 30;	

		$value = $this->get_value($field, $this->data);

		if ( $label != '' ) $html .= $this->get_label($field, $label);

		$html .= '<textarea name="fl['.$field.']" id="'.$field.'" rows="'.$rows.'" cols="'.$cols.'">'.$value.'</textarea>';

		$this->output($html);
	}

	/**
	 * Formularvorgabewert oder -beschriftung holen
	 *
	 * @param string $field
	 * @param mixed  $source
	 * @param string $default
	 * @return string
	 */
	protected function get_value($field, $source, $default = '') {
		if ( $source instanceof view_data ) {
			$source->set_raw_output(false);
			$source->set_default($default);
			$value = $source->get($field, 'string');
			$source->set_default('');
			return $value;
		} elseif ( $source instanceof data_wrapper ) {
			return $source->is_set($field) ? $source->get($field): $default;
		}

		if ( !is_array($source) AND !($source instanceof ArrayAccess) ) {
			$source = (array) $source;
		}

		return isset($source[$field]) ? $source[$field]: $default;
	}

	/**
	 * Label erzeugen
	 *
	 * @param string $id
	 * @param string @value
	 * @return string
	 */
	public function get_label( $id, $value ) {
		$label = '<label for="'.$id.'">'.$value.'</label>';

		return $label;
	}
}
